updated packages
parent
aba5233694
commit
26b65fab46
|
@ -1,6 +1,4 @@
|
||||||
import domain.*;
|
|
||||||
import facade.FactorySystem;
|
import facade.FactorySystem;
|
||||||
import safety.robot_exceptions.RobotException;
|
|
||||||
import ui.UI;
|
import ui.UI;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package domain;
|
package domain;
|
||||||
|
|
||||||
import safety.robot_exceptions.ExceptionStorage;
|
import utility.robot_exceptions.ExceptionStorage;
|
||||||
import safety.robot_exceptions.RobotException;
|
import utility.robot_exceptions.RobotException;
|
||||||
import safety.robot_exceptions.robotExceptions;
|
import utility.robot_exceptions.robotExceptions;
|
||||||
|
|
||||||
public class C3PO extends Robot {
|
public class C3PO extends Robot {
|
||||||
public C3PO(int id, String name){
|
public C3PO(int id, String name){
|
||||||
|
@ -44,14 +44,39 @@ public class C3PO extends Robot {
|
||||||
//throw new RobotMagicValueException(getName() + " has an unknown error. Code 42");
|
//throw new RobotMagicValueException(getName() + " has an unknown error. Code 42");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts any given array of integers with the insertion Sort algorithm.
|
||||||
|
* @param input int [ ]
|
||||||
|
* @return input int [ ] (sorted)
|
||||||
|
* @throws RobotException
|
||||||
|
*/
|
||||||
|
public int[] insertionSort(int[] input) throws RobotException {
|
||||||
|
if (checkArray(input)) {
|
||||||
|
for (int i = 1; i < input.length; i++) {
|
||||||
|
int b = i - 1;
|
||||||
|
int key = input[i];
|
||||||
|
while (b >= 0 && input[b] > key) input[b + 1] = input[b--];
|
||||||
|
input[b + 1] = key;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}else{
|
||||||
|
RobotException robotexception = new RobotException(robotExceptions.MAGICVALUE, getName());
|
||||||
|
this.exceptions = new ExceptionStorage(robotexception);
|
||||||
|
throw robotexception;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] think(int[] input) throws RobotException {
|
public int[] think(int[] input) throws RobotException {
|
||||||
//Insertionsort
|
//Insertionsort
|
||||||
if(isPowerOn()){
|
if(isPowerOn()){
|
||||||
return sorting(input);
|
return sorting(input);
|
||||||
}else{
|
}else{
|
||||||
throw new RobotException(robotExceptions.ILLEGALSTATE, getName());
|
RobotException robotException = new RobotException(robotExceptions.ILLEGALSTATE, getName());
|
||||||
// throw new RobotIllegalStateException(getName() + " is turned off.");
|
this.exceptions = new ExceptionStorage(robotException);
|
||||||
|
throw robotException;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package domain;
|
package domain;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import safety.robot_exceptions.RobotException;
|
import utility.robot_exceptions.RobotException;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import java.util.HashMap;
|
||||||
public class Factory implements Serializable {
|
public class Factory implements Serializable {
|
||||||
private HashMap<Integer, Robot> robots = new HashMap<>();
|
private HashMap<Integer, Robot> robots = new HashMap<>();
|
||||||
private int c3poID = 0;
|
private int c3poID = 0;
|
||||||
private int r2d2ID = 1000;
|
private int r2d2ID = 10000;
|
||||||
|
|
||||||
public Factory(){
|
public Factory(){
|
||||||
|
|
||||||
|
@ -31,5 +31,9 @@ public class Factory implements Serializable {
|
||||||
robots.put(r.getId(), r);
|
robots.put(r.getId(), r);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Robot getRobotOfList(int id){
|
||||||
|
return robots.get(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package domain;
|
package domain;
|
||||||
|
|
||||||
|
|
||||||
import safety.robot_exceptions.ExceptionStorage;
|
import utility.robot_exceptions.ExceptionStorage;
|
||||||
import safety.robot_exceptions.RobotException;
|
import utility.robot_exceptions.RobotException;
|
||||||
import safety.robot_exceptions.robotExceptions;
|
import utility.robot_exceptions.robotExceptions;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class R2D2 extends Robot {
|
public class R2D2 extends Robot {
|
||||||
/**
|
/**
|
||||||
|
@ -20,7 +18,7 @@ public class R2D2 extends Robot {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see safety.interfaces.RobotInstructions
|
* @see utility.interfaces.RobotInstructions
|
||||||
*/
|
*/
|
||||||
public int[] think(int[] input) throws RobotException {
|
public int[] think(int[] input) throws RobotException {
|
||||||
if(isPowerOn()){
|
if(isPowerOn()){
|
||||||
|
@ -32,9 +30,39 @@ public class R2D2 extends Robot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts any given array of integers with the selection Sort algorithm.
|
||||||
|
* @param input
|
||||||
|
* @return
|
||||||
|
* @throws RobotException
|
||||||
|
*/
|
||||||
|
public int[] selectionSort(int[] input) throws RobotException{
|
||||||
|
if(checkArray(input)){
|
||||||
|
int small;
|
||||||
|
for(int i = 0; i < input.length; i++){
|
||||||
|
small = i;
|
||||||
|
for(int j = i + 1; j < input.length; j++){
|
||||||
|
if(input[j] < input[small]){
|
||||||
|
small = j;
|
||||||
|
// System.out.println(small);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int temp = input[i];
|
||||||
|
input[i] = input[small];
|
||||||
|
input[small] = temp;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}else{
|
||||||
|
RobotException robotexception = new RobotException(robotExceptions.MAGICVALUE, getName());
|
||||||
|
this.exceptions = new ExceptionStorage(robotexception);
|
||||||
|
throw robotexception;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see safety.interfaces.RobotInstructions
|
* @see utility.interfaces.RobotInstructions
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String speak(int[] input) throws RobotException {
|
public String speak(int[] input) throws RobotException {
|
||||||
|
|
|
@ -96,7 +96,6 @@ public abstract class Robot implements utility.interfaces.Robot, Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method uses Streams to join any given array to a String.
|
* This method uses Streams to join any given array to a String.
|
||||||
*
|
|
||||||
* @param input int [ ]
|
* @param input int [ ]
|
||||||
* @param delemiter String
|
* @param delemiter String
|
||||||
* @return String (array as String)
|
* @return String (array as String)
|
||||||
|
@ -114,57 +113,11 @@ public abstract class Robot implements utility.interfaces.Robot, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sorts any given array of integers with the insertion Sort algorithm.
|
|
||||||
* @param input int [ ]
|
|
||||||
* @return input int [ ] (sorted)
|
|
||||||
* @throws RobotException
|
|
||||||
*/
|
|
||||||
public int[] insertionSort(int[] input) throws RobotException {
|
|
||||||
if (checkArray(input)) {
|
|
||||||
for (int i = 1; i < input.length; i++) {
|
|
||||||
int b = i - 1;
|
|
||||||
int key = input[i];
|
|
||||||
while (b >= 0 && input[b] > key) input[b + 1] = input[b--];
|
|
||||||
input[b + 1] = key;
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}else{
|
|
||||||
RobotException robotexception = new RobotException(robotExceptions.MAGICVALUE, getName());
|
|
||||||
this.exceptions = new ExceptionStorage(robotexception);
|
|
||||||
throw robotexception;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sorts any given array of integers with the selection Sort algorithm.
|
|
||||||
* @param input
|
|
||||||
* @return
|
|
||||||
* @throws RobotException
|
|
||||||
*/
|
|
||||||
public int[] selectionSort(int[] input) throws RobotException{
|
|
||||||
if(checkArray(input)){
|
|
||||||
int small;
|
|
||||||
for(int i = 0; i < input.length; i++){
|
|
||||||
small = i;
|
|
||||||
for(int j = i + 1; j < input.length; j++){
|
|
||||||
if(input[j] < input[small]){
|
|
||||||
small = j;
|
|
||||||
// System.out.println(small);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int temp = input[i];
|
|
||||||
input[i] = input[small];
|
|
||||||
input[small] = temp;
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}else{
|
|
||||||
RobotException robotexception = new RobotException(robotExceptions.MAGICVALUE, getName());
|
|
||||||
this.exceptions = new ExceptionStorage(robotexception);
|
|
||||||
throw robotexception;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public String getType(){
|
||||||
|
return this.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package facade;
|
package facade;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import domain.*;
|
import domain.*;
|
||||||
|
@ -15,9 +16,10 @@ public class FactorySystem {
|
||||||
if(Persistenz.existsSavedData(factoryName)){
|
if(Persistenz.existsSavedData(factoryName)){
|
||||||
try{
|
try{
|
||||||
this.factory = (Factory) Persistenz.loadFactoryData(factoryName);
|
this.factory = (Factory) Persistenz.loadFactoryData(factoryName);
|
||||||
|
System.out.println("Loading of old factory successful");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("Loading of old factory not possible");
|
System.out.println("Loading of old factory not possible");
|
||||||
System.out.println(e.getCause());
|
System.out.println(e.getMessage());
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
this.factory = new Factory();
|
this.factory = new Factory();
|
||||||
|
@ -38,9 +40,17 @@ public class FactorySystem {
|
||||||
public boolean buildNewRobot(String name, int type){
|
public boolean buildNewRobot(String name, int type){
|
||||||
boolean check = factory.buildNewRobot(name, type);
|
boolean check = factory.buildNewRobot(name, type);
|
||||||
if(check) {
|
if(check) {
|
||||||
|
try {
|
||||||
Persistenz.saveFactoryData(factory, factoryName);
|
Persistenz.saveFactoryData(factory, factoryName);
|
||||||
|
}catch(Exception e){
|
||||||
|
System.out.println(e.getCause());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return check;
|
return check;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Robot searchForRobot(int id){
|
||||||
|
return factory.getRobotOfList(id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,10 @@ public class Persistenz {
|
||||||
return new File(name + FACTORY_DATA).exists();
|
return new File(name + FACTORY_DATA).exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveFactoryData(Object Factory, String name){
|
public static void saveFactoryData(Object Factory, String name) throws Exception{
|
||||||
try{
|
|
||||||
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(name + FACTORY_DATA));
|
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(name + FACTORY_DATA));
|
||||||
oos.writeObject(Factory);
|
oos.writeObject(Factory);
|
||||||
oos.close();
|
oos.close();
|
||||||
}catch(Exception e){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object loadFactoryData(String name) throws Exception{
|
public static Object loadFactoryData(String name) throws Exception{
|
||||||
|
|
Binary file not shown.
|
@ -26,8 +26,8 @@
|
||||||
* [Factrory](#-classe-factory-)
|
* [Factrory](#-classe-factory-)
|
||||||
* ### [Infrastructure](#infratructure-1)
|
* ### [Infrastructure](#infratructure-1)
|
||||||
* [Persistenz](#-classe-persistenz-)
|
* [Persistenz](#-classe-persistenz-)
|
||||||
* ### [safety](#robot-1)
|
* ### [utility](#robot-1)
|
||||||
* ### [safety](#exceptions-1)
|
* ### [utility](#exceptions-1)
|
||||||
* [RobotException](#-class-robotexception-)
|
* [RobotException](#-class-robotexception-)
|
||||||
* [RobotIllegalStateException](#-class-robotillegalstateexception-)
|
* [RobotIllegalStateException](#-class-robotillegalstateexception-)
|
||||||
* [RobotMagicValueException](#-class-robotmagicvalueexception-)
|
* [RobotMagicValueException](#-class-robotmagicvalueexception-)
|
||||||
|
@ -45,15 +45,21 @@
|
||||||
|
|
||||||
# TO-Dos:
|
# TO-Dos:
|
||||||
|
|
||||||
* Sortier Algorythem C3PO, R2D2 (mit Ausgabe)
|
* Sortier Algorythem C3PO, R2D2 (mit Ausgabe) --[done]--
|
||||||
|
|
||||||
* Bei Erstellung eines Roboters wird einne SerienNr erstellt
|
* Bei Erstellung eines Roboters wird einne SerienNr erstellt --[done]--
|
||||||
|
|
||||||
* Wichtige getter for Robots (getName)
|
* Wichtige getter for Robots (getName) --[done]--
|
||||||
|
|
||||||
* Exception Classes (Throwable einfügen)
|
* Exception Classes (Throwable einfügen) --[done]--
|
||||||
|
|
||||||
* RobotFactory, die mit enum(RobotType) Objekt von R2 und C3PO erstellen kann
|
* RobotFactory, die mit enum(RobotType) Objekt von R2D2 und C3PO erstellen kann --[abgewandelt für Exceptions]--
|
||||||
|
|
||||||
|
* Persistenz einrichten
|
||||||
|
|
||||||
|
* funktionalitäten der UI zusammenfassen
|
||||||
|
|
||||||
|
* funtkionalitäten der UI implementieren
|
||||||
|
|
||||||
* Nexus6(Singleton) implementieren, kann nichts (Illegal-State)
|
* Nexus6(Singleton) implementieren, kann nichts (Illegal-State)
|
||||||
|
|
||||||
|
@ -199,9 +205,9 @@ ___
|
||||||
|
|
||||||
`loadFactoryData():Object -> throws`
|
`loadFactoryData():Object -> throws`
|
||||||
|
|
||||||
## safety
|
## utility
|
||||||
|
|
||||||
### safety
|
### utility
|
||||||
|
|
||||||
<h2 align="center">
|
<h2 align="center">
|
||||||
Class RobotException
|
Class RobotException
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
29
ui/UI.java
29
ui/UI.java
|
@ -1,5 +1,8 @@
|
||||||
package ui;
|
package ui;
|
||||||
|
|
||||||
|
import domain.C3PO;
|
||||||
|
import domain.R2D2;
|
||||||
|
import domain.Robot;
|
||||||
import facade.FactorySystem;
|
import facade.FactorySystem;
|
||||||
import infrastructure.Persistenz;
|
import infrastructure.Persistenz;
|
||||||
|
|
||||||
|
@ -34,12 +37,12 @@ public class UI {
|
||||||
mainloop:
|
mainloop:
|
||||||
while(true){
|
while(true){
|
||||||
System.out.println();
|
System.out.println();
|
||||||
System.out.println("______________________");
|
System.out.println("____________________________");
|
||||||
System.out.println("Sie haben folgende optionen:");
|
System.out.println("Sie haben folgende optionen:");
|
||||||
System.out.println("-1- show all robots ----");
|
System.out.println("-1- --- show all robots ----");
|
||||||
System.out.println("-2- build new robot ----");
|
System.out.println("-2- --- build new robot ----");
|
||||||
System.out.println("-3- empty --------------");
|
System.out.println("-3- ------- use robot ------");
|
||||||
System.out.println("-4- Exit ---------------");
|
System.out.println("-4- --------- Exit ---------");
|
||||||
System.out.print(" > ");
|
System.out.print(" > ");
|
||||||
try{
|
try{
|
||||||
int input = Integer.parseInt(sc.nextLine());
|
int input = Integer.parseInt(sc.nextLine());
|
||||||
|
@ -47,7 +50,7 @@ public class UI {
|
||||||
case 1:
|
case 1:
|
||||||
listAllRobots();break;
|
listAllRobots();break;
|
||||||
case 2: buildNewRobot();break;
|
case 2: buildNewRobot();break;
|
||||||
case 3: System.out.println("u pressed 3");break;
|
case 3: useRobot();break;
|
||||||
case 4: break mainloop;
|
case 4: break mainloop;
|
||||||
default:
|
default:
|
||||||
System.out.println("this is an invalid option"); break;
|
System.out.println("this is an invalid option"); break;
|
||||||
|
@ -94,4 +97,18 @@ public class UI {
|
||||||
System.out.println("Anlegen des Roboters fehlgeschlagen");
|
System.out.println("Anlegen des Roboters fehlgeschlagen");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void useRobot(){
|
||||||
|
System.out.println("Which robot do you want to use?");
|
||||||
|
listAllRobots();
|
||||||
|
System.out.print(" ID > ");
|
||||||
|
int input = Integer.parseInt(sc.nextLine());
|
||||||
|
Robot r = fs.searchForRobot(input);
|
||||||
|
System.out.println("You choose " + r.getName() + " of type " + r.getType());
|
||||||
|
System.out.println("Yout have following options");
|
||||||
|
mainloop:
|
||||||
|
while(true){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* (c) 2012 Thomas Smits */
|
/* (c) 2012 Thomas Smits */
|
||||||
package safety.interfaces;
|
package utility.interfaces;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package safety.interfaces;
|
package utility.interfaces;
|
||||||
import safety.robot_exceptions.RobotException;
|
import utility.robot_exceptions.RobotException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Das Interface repräsentiert einen einfachen Roboter mit seinen Funktionen.
|
* Das Interface repräsentiert einen einfachen Roboter mit seinen Funktionen.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package safety.interfaces;
|
package utility.interfaces;
|
||||||
|
|
||||||
import safety.robot_exceptions.RobotException;
|
import utility.robot_exceptions.RobotException;
|
||||||
import safety.robot_exceptions.RobotIllegalStateException;
|
import utility.robot_exceptions.RobotIllegalStateException;
|
||||||
import safety.robot_exceptions.RobotMagicValueException;
|
import utility.robot_exceptions.RobotMagicValueException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package safety.robot_exceptions;
|
package utility.robot_exceptions;
|
||||||
|
|
||||||
public class ArrayEmptyException extends RobotException{
|
public class ArrayEmptyException extends RobotException{
|
||||||
public ArrayEmptyException(robotExceptions type,String errorMessage){
|
public ArrayEmptyException(robotExceptions type,String errorMessage){
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package safety.robot_exceptions;
|
package utility.robot_exceptions;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
public class ExceptionStorage {
|
public class ExceptionStorage implements Serializable {
|
||||||
private RobotException message;
|
private RobotException message;
|
||||||
private LocalDateTime date;
|
private LocalDateTime date;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package safety.robot_exceptions;
|
package utility.robot_exceptions;
|
||||||
|
|
||||||
public class RobotException extends Exception{
|
public class RobotException extends Exception{
|
||||||
robotExceptions currentType;
|
robotExceptions currentType;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package safety.robot_exceptions;
|
package utility.robot_exceptions;
|
||||||
|
|
||||||
public class RobotIllegalStateException extends RobotException{
|
public class RobotIllegalStateException extends RobotException{
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package safety.robot_exceptions;
|
package utility.robot_exceptions;
|
||||||
|
|
||||||
public class RobotMagicValueException extends RobotException {
|
public class RobotMagicValueException extends RobotException {
|
||||||
public RobotMagicValueException(robotExceptions type, String errormessage) {
|
public RobotMagicValueException(robotExceptions type, String errormessage) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package safety.robot_exceptions;
|
package utility.robot_exceptions;
|
||||||
|
|
||||||
public enum robotExceptions {
|
public enum robotExceptions {
|
||||||
ILLEGALSTATE("ist in einem illegalen Zustand"),
|
ILLEGALSTATE("ist in einem illegalen Zustand"),
|
||||||
|
|
Loading…
Reference in New Issue