package ui.controller; import classes.*; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.utils.IOUtils; import ui.model.Model; import java.awt.*; import java.awt.geom.Point2D; import java.io.*; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; /** * Controller for the Loading. * * @author Gruppe14 */ public class LoadController { private Model model; private CategoryController cgC; private CanvasController cvsC; private ObjectController objC; private NodeController uppC; private MultiPurposeController mpC; private JsonParser parser; /** * Constructor. * * @param model Model * @param cg CategoryController * @param cvs CanvasController * @param obj ObjectController * @param mp MultiPurposeController */ LoadController(Model model, CategoryController cg, CanvasController cvs, ObjectController obj, NodeController uppC, MultiPurposeController mp) { this.model = model; this.cgC = cg; this.cvsC = cvs; this.objC = obj; this.uppC = uppC; this.mpC = mp; this.parser = new JsonParser(); } /** * Reads the the JSON File and load the state into the Model. * * @param path the Path * @throws IOException exception */ void readSave(String path) throws IOException, ArchiveException { File src = new File(path); File folder = readArchive(src); folder.deleteOnExit(); String trim = folder.getPath().substring(0, folder.getPath().lastIndexOf(folder.getName()) + folder.getName().length()); forwardFiles(folder, trim); } /** * reads the dimensions file containing the saved position and dimensions of the frame * * @return a list of the form [x, y, width, height] */ ArrayList readWindowDimensions(String path) throws FileNotFoundException { JsonObject json = (JsonObject) parser.parse(new FileReader(path)); ArrayList dimensions = new ArrayList<>(); List keys = getKeys(json); for (int i = 1; i < 5; i++) { dimensions.add(json.get(keys.get(i)).getAsInt()); } return dimensions; } void readJson(String path) throws IOException { JsonObject json = (JsonObject) parser.parse(new FileReader(path)); // get all keys via stream List keys = getKeys(json); List edges = keys.stream().filter(key -> key.contains("EDGE")) .collect(Collectors.toCollection(ArrayList::new)); HashMap objDispatch = new HashMap<>(); HashMap eleDispatch = new HashMap<>(); initialize(json); forwardObjects(keys, json, objDispatch, eleDispatch); forwardEdges(edges, json, objDispatch); } /** * Loads the Files from the Savefile * * @param trim the part of the file's path to be trimmed * @throws IOException if anythings goes wrong reading the files */ private void forwardFiles(File folder, String trim) throws IOException { for (File file : folder.listFiles()) { File dst = new File( System.getProperty("user.home") + "/.config/HolonGUI/" + file.getPath().replace(trim, "")); if (file.getName().contains(".json")) readJson(file.getPath()); else if (file.isDirectory()) forwardFiles(file, trim); else { dst.getParentFile().mkdirs(); Files.copy(file.toPath(), dst.toPath(), StandardCopyOption.REPLACE_EXISTING); } } } /** * distribute the Edges */ private void forwardEdges(List edges, JsonObject json, HashMap objDispatch) { for (String edge : edges) { if (edge.contains("CVSEDGE")) loadEdge(EDGETYPE.CANVAS, json.get(edge), objDispatch); if (edge.contains("CONNEDGE")) loadEdge(EDGETYPE.CONNECTION, json.get(edge), objDispatch); if (edge.contains("NODE")) loadEdge(EDGETYPE.NODE, json.get(edge), objDispatch); if (edge.contains("OLD")) loadEdge(EDGETYPE.OLD, json.get(edge), objDispatch); } } /** * Distribute the given keys for right processing */ private void forwardObjects(List keys, JsonObject json, HashMap objDispatch, HashMap eleDispatch) { for (String key : keys) { if (key.contains("CATEGORY")) loadCategory(json.get(key)); if (key.contains("CGOBJECT")) loadCategoryObject(json.get(key)); if (key.contains("CGELEMENT")) loadCategoryElements(json.get(key), eleDispatch);//TODO if (key.contains("CVSOBJECT")) loadCanvasObject(json.get(key), objDispatch); if (key.contains("CVSELEMENT")) loadCanvasElements(json.get(key), objDispatch, eleDispatch); if (key.contains("SWUNITGRAPH")) loadUnitGraph(GRAPHTYPE.SWITCH, json.get(key), objDispatch, null); if (key.contains("ELEUNITGRAPH")) loadUnitGraph(GRAPHTYPE.ELEMENT, json.get(key), null, eleDispatch); if (key.contains("ELETESTUNITGRAPH")) loadUnitGraph(GRAPHTYPE.TESTELEMENT, json.get(key), null, eleDispatch); if (key.contains("TRACKED")) loadTracked(json.get(key), objDispatch); if (key.contains("STATSGRAPH")) loadStatisticGraph(json.get(key)); } } /** * Init the Global Parameters */ private void initialize(JsonObject json) { switch (MODE.valueOf(json.get("MODE").getAsString())) { case COMPLETE: model.setCvsObjIdx(new HashMap<>()); model.setObjectsOnCanvas(new ArrayList<>()); model.setEdgesOnCanvas(new ArrayList<>()); model.setTrackingObj(new ArrayList<>()); model.setStatisticData(new ArrayList<>()); model.setHashcodeMap(new HashMap<>()); model.setCanvasX(json.get("CANVAS_SIZE_X").getAsInt()); model.setCanvasX(json.get("CANVAS_SIZE_Y").getAsInt()); IdCounter.setCounter(json.get("IDCOUNTER").getAsInt()); IdCounterElem.setCounter(json.get("IDCOUNTERELEMENT").getAsInt()); break; case PARTIAL: model.setCvsObjIdx(new HashMap<>()); model.setObjectsOnCanvas(new ArrayList<>()); model.setEdgesOnCanvas(new ArrayList<>()); model.setHashcodeMap(new HashMap<>()); model.setCanvasX(json.get("CANVAS_SIZE_X").getAsInt()); model.setCanvasX(json.get("CANVAS_SIZE_Y").getAsInt()); IdCounter.setCounter(json.get("IDCOUNTER").getAsInt()); IdCounterElem.setCounter(json.get("IDCOUNTERELEMENT").getAsInt()); break; case CATEGORY: model.setCgIdx(new HashMap<>()); model.setCategories(new ArrayList<>()); default: break; } } /** * Load a given Category */ private void loadCategory(JsonElement jsonElement) { if (mpC.searchCat(jsonElement.getAsString()) == null) cgC.addCategory(new Category(jsonElement.getAsString())); } /** * Load a given Object in Category by Deserialization */ private void loadCategoryObject(JsonElement jsonElement) { AbstractCanvasObject temp = model.getGson().fromJson(jsonElement.getAsJsonObject(), AbstractCanvasObject.class); temp.setImage(checkOS(temp.getImage())); initObjects(temp); if (mpC.searchCatObj(mpC.searchCat(temp.getSav()), temp.getObjName()) != null) cgC.deleteObject(temp.getSav(), temp.getObjName()); cgC.addObject(mpC.searchCat(temp.getSav()), temp); } /** * Load a given Element in Category by Deserialization * @param eleDispatch */ private void loadCategoryElements(JsonElement jsonElement, HashMap eleDispatch) { HolonElement temp = model.getGson().fromJson(jsonElement.getAsJsonObject().get("properties").getAsJsonObject(), HolonElement.class); eleDispatch.put(temp.getId(), temp); initElements(temp); objC.addElementIntoCategoryObject(temp.getSaving().getKey(), temp.getSaving().getValue(), temp); } /** * Load a given Object in Canvas by Deserialization */ private void loadCanvasObject(JsonElement jsonElement, HashMap objDispatch) { AbstractCanvasObject temp = null; if(jsonElement.getAsJsonObject().get("type").getAsString().equals("CpsUpperNode")) { //Change Old Name jsonElement.getAsJsonObject().addProperty("type", "GroupNode"); } try{ temp = model.getGson().fromJson(jsonElement.getAsJsonObject(), AbstractCanvasObject.class); }catch(java.lang.ClassCastException e) { System.err.println("ClassRenameError"); e.printStackTrace(); return; } initObjects(temp); temp.setImage(checkOS(temp.getImage())); if (temp instanceof GroupNode) { model.getHashcodeMap().put(jsonElement.getAsJsonObject().get("hash").getAsInt(), (GroupNode) temp); ((GroupNode) temp).setLeftBorder(jsonElement.getAsJsonObject().get("properties").getAsJsonObject().get("leftBorder").getAsInt()); } // if its stored before on the canvas just put it there if (temp.getSav().equals("CVS")) { cvsC.addObject(temp, false); } else { // else look up the table and put it into the right Uppernode GroupNode temp2 = (GroupNode) objDispatch.get(Integer.parseInt(temp.getSav())); if(temp2 != null) uppC.addObjectInUpperNode(temp, temp2, false); else{ /** * if null try to load on canvas */ cvsC.addObject(temp, false); } } objDispatch.put(temp.getId(), temp); } /** * Load a given Element in Canvas by Deserialization */ private void loadCanvasElements(JsonElement jsonElement, HashMap objDispatch, HashMap eleDispatch) { JsonObject object = jsonElement.getAsJsonObject(); HolonElement temp = model.getGson().fromJson(object.get("properties"), HolonElement.class); initElements(temp); temp.flexList = model.getGson().fromJson(object.get("FlexList"), new TypeToken>() {}.getType()); //object.get("FlexList").getAsJsonArray().forEach(jo -> System.out.println("Hallo")); //object.get("FlexList").getAsJsonArray().forEach(flexJson -> flexJson.getAsJsonObject().get("constrainList").getAsJsonArray().forEach(constrainJson -> System.out.println("Constrain:" + constrainJson.getAsJsonObject().get("name").getAsString()))); temp.flexList.stream().forEach(flex -> { flex.setElement(temp); flex.constrainList.forEach(con -> con.fixJson()); }); // id which Object it was stored before int stored = object.get("ID").getAsInt(); // lookup that object HolonObject temp2 = (HolonObject) objDispatch.get(stored); // add it objC.addElement(temp2, temp); // store element also inside a table eleDispatch.put(temp.getId(), temp); } /** * Load a given Edge by Deserialization */ private void loadEdge(EDGETYPE type, JsonElement jsonElement, HashMap objDispatch) { JsonObject object = jsonElement.getAsJsonObject(); Edge temp = model.getGson().fromJson(object.get("properties"), Edge.class); initCpsEdge(temp); // look for A and B inside the Table temp.setA(objDispatch.get(object.get("A").getAsInt())); temp.setB(objDispatch.get(object.get("B").getAsInt())); model.getEdgesOnCanvas().add(temp); } /** * Load a Unitgraph by Deserialization */ private void loadUnitGraph(GRAPHTYPE type, JsonElement jsonElement, HashMap objDispatch, HashMap eleDispatch) { //TODO Make UnitGraph unterscheidung hinf�llig!!!! JsonObject object = jsonElement.getAsJsonObject(); List keys = getKeys(object); String p; int mid; int sav = 0; LinkedList graphpointTEST = new LinkedList<>(); for (String k : keys) { if (!k.equals("ID")) { p = object.get(k).getAsString(); mid = p.indexOf(':'); double x1 = Double.parseDouble(p.substring(0, mid)); double y1 = Double.parseDouble(p.substring(mid + 1, p.length())); graphpointTEST.add(new Point2D.Double(x1, y1)); } else // else its an ID sav = object.get(k).getAsInt(); } switch (type) { case SWITCH: HolonSwitch sw = (HolonSwitch) objDispatch.get(sav); sw.setGraphPoints(graphpointTEST); sw.sampleGraph(); break; case ELEMENT: System.out.println("Write me new"); break; case TESTELEMENT: HolonElement ele1 = eleDispatch.get(sav); ele1.setGraphPoints(graphpointTEST); ele1.sampleGraph(); break; default: break; } } private void loadStatisticGraph(JsonElement jsonElement) { JsonObject object = jsonElement.getAsJsonObject(); model.getGraphTable().clear(); model.getStatisticData().add(object); } private void loadTracked(JsonElement jsonElement, HashMap objDispatch) { JsonObject object = jsonElement.getAsJsonObject(); List keys = getKeys(object); for (String k : keys) { int id = object.get(k).getAsInt(); model.getTrackingObj().add(objDispatch.get(id)); model.addObjectsToGraphListeners(); if (objDispatch.get(id) instanceof HolonObject) { ((HolonObject) objDispatch.get(id)).updateTrackingInfo(); } } } private File readArchive(File src) throws IOException, ArchiveException { File tmp = Files.createTempDirectory("tmpHolon").toFile(); tmp.deleteOnExit(); InputStream input = new FileInputStream(src); ArchiveInputStream stream = new ArchiveStreamFactory().createArchiveInputStream(ArchiveStreamFactory.ZIP, input); ArchiveEntry entry = stream.getNextEntry(); while (entry != null) { // String entryName = checkOS(entry.getName()); File file = new File(tmp, entry.getName()); file.getParentFile().mkdirs(); OutputStream output = new FileOutputStream(file); IOUtils.copy(stream, output); output.close(); // file.createNewFile(); entry = stream.getNextEntry(); } stream.close(); input.close(); return tmp; } private String checkOS(String entryName) { String os = System.getProperty("os.name").toLowerCase(); String ret = entryName; // String partition = System.getProperty("user.home"); if (!ret.contains("HolonGUI")) return ret; if (os.contains("windows")) { ret = ret.replace("/", "\\"); ret = System.getProperty("user.home") + "\\.config" + ret.substring(ret.indexOf("\\HolonGUI\\"), ret.length()); } if (os.contains("mac")) { // dosmth ret = ret.replace("\\", "/"); ret = System.getProperty("user.home") + "/.config" + ret.substring(ret.indexOf("/HolonGUI/"), ret.length()); } if (os.contains("linux")) { // dosmth ret = ret.replace("\\", "/"); ret = System.getProperty("user.home") + "/.config" + ret.substring(ret.indexOf("/HolonGUI/"), ret.length()); } // if (os.contains("solaris")) { // // dosmth // } return ret; } /** * Init new Arrays which haven't been serialized along the object */ void initObjects(AbstractCanvasObject obj) { obj.setConnections(new ArrayList<>()); obj.setTags(new ArrayList<>()); obj.setPseudoTags(new ArrayList<>()); if (obj instanceof HolonObject) { ((HolonObject) obj).setElements(new ArrayList<>()); ((HolonObject) obj).setTrackingProd(new float[100]); ((HolonObject) obj).setTrackingCons(new float[100]); } if (obj instanceof HolonSwitch) { ((HolonSwitch) obj).setGraphPoints(new LinkedList<>()); ((HolonSwitch) obj).reset(); ((HolonSwitch) obj).sampleGraph(); } if (obj instanceof GroupNode) { ((GroupNode) obj).setNodes(new ArrayList<>()); ((GroupNode) obj).setNodesIdx(new HashMap<>()); } } /** * Init Elements (set available energy, set new graph points) * * @param ele the element to be initialized */ void initElements(HolonElement ele) { ele.flexList = new ArrayList(); ele.setGraphPoints(new LinkedList<>()); ele.reset(); } /** * Init Edges (set tags and reset source and target) * * @param edge the edge to be initialized */ void initCpsEdge(Edge edge) { edge.setTags(new ArrayList<>()); edge.setPseudoTag(new ArrayList<>()); edge.setA(null); edge.setB(null); } /** * Get Set of Keys * * @return the keys from the json object */ List getKeys(JsonObject json) { return json.entrySet().stream().map(i -> i.getKey()).collect(Collectors.toCollection(ArrayList::new)); } /** * enum Mode. (in SaveController there is an additional mode called SIZE, * it is not currently needed here and was therefore not added) */ public enum MODE { COMPLETE, PARTIAL, CATEGORY } public enum EDGETYPE { CANVAS, CONNECTION, NODE, OLD } public enum GRAPHTYPE { SWITCH, ELEMENT, TESTELEMENT } }