package de.tu_darmstadt.informatik.tk.scopviz.main; import java.math.BigDecimal; import java.math.BigInteger; import de.tu_darmstadt.informatik.tk.scopviz.graphs.GraphManager; import de.tu_darmstadt.informatik.tk.scopviz.io.GraphMLExporter; import de.tu_darmstadt.informatik.tk.scopviz.ui.GraphDisplayManager; import de.tu_darmstadt.informatik.tk.scopviz.ui.OptionsManager; import de.tu_darmstadt.informatik.tk.scopviz.ui.handlers.MyAnimationTimer; import javafx.animation.AnimationTimer; import javafx.stage.Stage; /** * Main Class to contain all core functionality. Built as a Singleton, use * getInstance() to get access to the functionality * * @author Jan Enders (jan.enders@stud.tu-darmstadt.de) * @version 1.0 * */ public final class Main { /** * Singular instance of the Class, facilitates Singleton pattern. */ private static Main instance; /** * Current mode of the application for creating new Nodes and Edges. */ private CreationMode creationMode = CreationMode.CREATE_NONE; /** * The root window of the application. */ private Stage primaryStage; /** * Private constructor to prevent initialization, facilitates Singleton * pattern. Initializes an AnimationTimer to call all Functionality that * needs to be executed every Frame. */ private Main() { AnimationTimer alwaysPump = new MyAnimationTimer(); alwaysPump.start(); } /** * Returns the singular instance of the Class, grants access to the * Singleton. Initializes the instance when called for the first time. * * @return the singular instance of the class */ public static Main getInstance() { if (instance == null) { initialize(); } return instance; } /** * Initializes the singular instance. */ private static void initialize() { instance = new Main(); } /** * Returns a reference to the GraphManager object currently used by the app. * * @return the visualizer in use */ public GraphManager getGraphManager() { return GraphDisplayManager.getGraphManager(); } /** * Returns a unique id for a new Node or Edge not yet used by the graph. * * @return a new unused id as a String */ public String getUnusedID() { int i = 0; while (true) { String tempID = i + ""; if (getGraphManager().getGraph().getNode(tempID) == null && getGraphManager().getGraph().getEdge(tempID) == null && getGraphManager().getGraph().getNode(getGraphManager().getGraph().getId()+tempID) == null) { return (tempID); } else { i++; } } } public String getUnusedID(GraphManager gm) { int i = 0; while (true) { String tempID = i + ""; if (gm.getGraph().getNode(tempID) == null && gm.getGraph().getEdge(tempID) == null && gm.getGraph().getNode(gm.getGraph().getId()+tempID) == null){ return (tempID); } else { i++; } } } /** * Returns the primary Stage for the Application Window. * * @return the primary Stage */ public Stage getPrimaryStage() { return primaryStage; } /** * Sets the Reference to the primary Stage of the Application Window. * * @param primaryStage * the primary Stage of the Window. */ public void setPrimaryStage(Stage primaryStage) { this.primaryStage = primaryStage; } /** * Returns the current Creation Mode. * * @return the current creationMode */ public CreationMode getCreationMode() { return creationMode; } /** * Switches the App to a given Creation Mode. * * @param creationMode * the creationMode to switch to */ public void setCreationMode(CreationMode creationMode) { this.creationMode = creationMode; } // TODO replace throw by something better for debug /** * Converts a given Attribute into the type of result * * @param attribute * the Attribute to be converted. supported types: byte, short, * integer, long, float, double, BigInteger, BigDecimal, String * * @param result * the Attribute will be written in here after the conversion. * the supported types are the same as above except for String * * @return the value of result */ // don't worry I checked all the conversions @SuppressWarnings("unchecked") public T convertAttributeTypes(Object attribute, T result) { if (attribute == null) { return null; } String currentType = attribute.getClass().getSimpleName().toLowerCase(); String targetType = result.getClass().getSimpleName().toLowerCase(); switch (targetType) { case "byte": switch (currentType) { case "byte": case "short": case "integer": case "long": case "biginteger": case "float": case "double": case "bigdecimal": result = (T) new Byte(((Number) attribute).byteValue()); break; case "string": result = (T) new Byte(new BigDecimal((String) attribute).byteValue()); break; default: throw new IllegalArgumentException("invalid type: " + attribute.getClass()); } break; case "short": switch (currentType) { case "byte": case "short": case "integer": case "long": case "biginteger": case "float": case "double": case "bigdecimal": result = (T) new Short(((Number) attribute).shortValue()); break; case "string": result = (T) new Short(new BigDecimal((String) attribute).shortValue()); break; default: throw new IllegalArgumentException("invalid type: " + attribute.getClass()); } break; case "integer": switch (currentType) { case "byte": case "short": case "integer": case "long": case "biginteger": case "float": case "double": case "bigdecimal": result = (T) new Integer(((Number) attribute).intValue()); break; case "string": result = (T) new Integer(new BigDecimal((String) attribute).intValue()); break; default: throw new IllegalArgumentException("invalid type: " + attribute.getClass()); } break; case "long": switch (currentType) { case "byte": case "short": case "integer": case "long": case "biginteger": case "float": case "double": case "bigdecimal": result = (T) new Long(((Number) attribute).longValue()); break; case "string": result = (T) new Long(new BigDecimal((String) attribute).longValue()); break; default: throw new IllegalArgumentException("invalid type: " + attribute.getClass()); } break; case "biginteger": BigInteger integer; switch (currentType) { case "byte": integer = new BigInteger(Byte.toString((byte) attribute)); break; case "short": integer = new BigInteger(Short.toString((short) attribute)); break; case "integer": integer = new BigInteger(Integer.toString((int) attribute)); break; case "long": integer = new BigInteger(Long.toString((long) attribute)); break; case "float": integer = new BigInteger(Integer.toString((int) (float) attribute)); break; case "double": integer = new BigInteger(Long.toString((long) (double) attribute)); break; case "biginteger": integer = (BigInteger) attribute; break; case "bigdecimal": integer = ((BigDecimal) attribute).toBigInteger(); break; case "string": integer = new BigDecimal((String) attribute).toBigInteger(); break; default: throw new IllegalArgumentException("invalid type: " + attribute.getClass()); } result = (T) integer; break; case "float": switch (currentType) { case "byte": case "short": case "integer": case "long": case "biginteger": case "float": case "double": case "bigdecimal": result = (T) new Float(((Number) attribute).floatValue()); break; case "string": result = (T) new Float(new BigDecimal((String) attribute).floatValue()); break; default: throw new IllegalArgumentException("invalid type: " + attribute.getClass()); } break; case "double": switch (currentType) { case "byte": case "short": case "integer": case "long": case "biginteger": case "float": case "double": case "bigdecimal": result = (T) new Double(((Number) attribute).doubleValue()); break; case "string": result = (T) new Double(new BigDecimal((String) attribute).doubleValue()); break; default: throw new IllegalArgumentException("invalid type: " + attribute.getClass()); } break; case "bigdecimal": BigDecimal decimal; switch (currentType) { case "byte": decimal = new BigDecimal((byte) attribute); break; case "short": decimal = new BigDecimal((short) attribute); break; case "integer": decimal = new BigDecimal((int) attribute); break; case "long": decimal = new BigDecimal((long) attribute); break; case "float": decimal = new BigDecimal((float) attribute); break; case "double": decimal = new BigDecimal((double) attribute); break; case "biginteger": decimal = new BigDecimal((BigInteger) attribute); break; case "bigdecimal": decimal = (BigDecimal) attribute; break; case "string": decimal = new BigDecimal((String) attribute); break; default: throw new IllegalArgumentException("invalid type: " + attribute.getClass()); } result = (T) decimal; break; } return result; } public void closeProgram() { GraphMLExporter exp = new GraphMLExporter(); exp.writeGraph(GraphDisplayManager.getGraphManager(Layer.UNDERLAY).getGraph(), "underlay-shutdown.graphml", false); exp.writeGraph(GraphDisplayManager.getGraphManager(Layer.OPERATOR).getGraph(), "operator-shutdown.graphml", false); OptionsManager.save(); System.exit(0); } }