StoreController.java 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. package ui.controller;
  2. import java.awt.Color;
  3. import java.awt.Point;
  4. import java.io.FileWriter;
  5. import java.io.IOException;
  6. import java.util.ArrayDeque;
  7. import java.util.ArrayList;
  8. import java.util.LinkedList;
  9. import com.google.gson.Gson;
  10. import com.google.gson.GsonBuilder;
  11. import com.google.gson.JsonObject;
  12. import com.google.gson.JsonPrimitive;
  13. import TypeAdapter.AbstractCpsObjectAdapter;
  14. import TypeAdapter.ColorAdapter;
  15. import TypeAdapter.PositionAdapter;
  16. import classes.Category;
  17. import classes.CpsEdge;
  18. import classes.CpsUpperNode;
  19. import classes.AbstractCpsObject;
  20. import classes.HolonElement;
  21. import classes.HolonObject;
  22. import classes.HolonSwitch;
  23. import classes.IdCounter;
  24. import classes.IdCounterElem;
  25. import classes.Position;
  26. import ui.model.Model;
  27. /**
  28. * Controller for Storage.
  29. *
  30. * @author Gruppe14
  31. */
  32. public class StoreController {
  33. public enum MODE {
  34. COMPLETE, PARTIAL
  35. }
  36. public enum TYPE {
  37. CATEGORY, CANVAS
  38. }
  39. public enum EDGETYPE {
  40. CANVAS, CONNECTION, NODE, OLD, LAYER
  41. }
  42. public enum NUMTYPE {
  43. CATEGORY, OBJECT, ELEMENT, EDGE, CONNECTION, NODEEDGE, OLDEDGE, UNITGRAPH
  44. }
  45. public enum GRAPHTYPE {
  46. SWITCH, ELEMENT
  47. }
  48. private Model model;
  49. private Gson gson;
  50. private int nCat, nObj, nEle, nEdge, nConn, nNodeEdge, nOldEdge, nUnitGraph;
  51. /**
  52. * Constructor.
  53. *
  54. * @param model
  55. * the Model
  56. */
  57. public StoreController(Model model) {
  58. this.model = model;
  59. initGson();
  60. }
  61. /**
  62. * Writes the current State of the Modelling into a JSON File which can be
  63. * loaded.
  64. *
  65. * @param path
  66. * the Path
  67. *
  68. * @throws IOException
  69. * exception
  70. */
  71. public void writeSaveFile(String path) throws IOException {
  72. initNumeration();
  73. JsonObject file = new JsonObject();
  74. initialize(MODE.COMPLETE, file);
  75. storeCategory(file);
  76. storeCanvas(file);
  77. FileWriter writer = new FileWriter(path);
  78. writer.write(gson.toJson(file));
  79. writer.flush();
  80. writer.close();
  81. }
  82. /**
  83. * Writes the Autosave File.
  84. *
  85. * @param path
  86. * the Path
  87. * @throws IOException
  88. * Exception
  89. */
  90. public void writeAutosaveFile(String path) throws IOException {
  91. initNumeration();
  92. JsonObject file = new JsonObject();
  93. initialize(MODE.PARTIAL, file);
  94. storeCanvas(file);
  95. FileWriter writer = new FileWriter(path);
  96. writer.write(gson.toJson(file));
  97. writer.flush();
  98. writer.close();
  99. }
  100. /**
  101. * Write needed default parameter into the JsonObject. Can be extended later
  102. * on
  103. *
  104. * @param mode
  105. * @param file
  106. */
  107. private void initialize(MODE mode, JsonObject file) {
  108. // TODO Auto-generated method stub
  109. switch (mode) {
  110. case COMPLETE:
  111. file.add("MODE", new JsonPrimitive(mode.name()));
  112. file.add("IDCOUNTER", new JsonPrimitive(IdCounter.getCounter()));
  113. file.add("IDCOUNTERELEMENT", new JsonPrimitive(IdCounterElem.getCounter()));
  114. file.add("CANVAS_SIZE_X", new JsonPrimitive(model.getCanvasX()));
  115. file.add("CANVAS_SIZE_Y", new JsonPrimitive(model.getCanvasY()));
  116. break;
  117. case PARTIAL:
  118. file.add("MODE", new JsonPrimitive(mode.name()));
  119. file.add("IDCOUNTER", new JsonPrimitive(IdCounter.getCounter()));
  120. file.add("IDCOUNTERELEMENT", new JsonPrimitive(IdCounterElem.getCounter()));
  121. break;
  122. default:
  123. break;
  124. }
  125. }
  126. /**
  127. * Store all Categories and Object into a Json File via Serialization
  128. *
  129. * @param file
  130. */
  131. private void storeCategory(JsonObject file) {
  132. // TODO Auto-generated method stub
  133. // forall categories store them into the jsontree
  134. for (Category cat : model.getCategories()) {
  135. String key = "CATEGORY" + getNumerator(NUMTYPE.CATEGORY);
  136. file.add(key, new JsonPrimitive(cat.getName()));
  137. // forall object in the category store them into the jsontree
  138. for (AbstractCpsObject obj : cat.getObjects()) {
  139. file.add("CGOBJECT" + getNumerator(NUMTYPE.OBJECT), gson.toJsonTree(obj, AbstractCpsObject.class));
  140. // if its a holonobject add elements too
  141. if (obj instanceof HolonObject)
  142. elementsToJson(TYPE.CATEGORY, file, obj);
  143. }
  144. }
  145. }
  146. /**
  147. * Travers through all Objects via BFS and Stores everything relevant
  148. *
  149. * @param file
  150. */
  151. private void storeCanvas(JsonObject file) {
  152. // TODO Auto-generated method stub
  153. ArrayDeque<AbstractCpsObject> queue = new ArrayDeque<>();
  154. AbstractCpsObject u = null;
  155. // put all objects into queue since there is not starting object
  156. for (AbstractCpsObject cps : model.getObjectsOnCanvas()) {
  157. queue.add(cps);
  158. }
  159. // while quene not empty
  160. while (!queue.isEmpty()) {
  161. // u = current node
  162. u = queue.pop();
  163. // add currentnode into jsontree
  164. String key = "CVSOBJECT" + getNumerator(NUMTYPE.OBJECT);
  165. file.add(key, gson.toJsonTree(u, AbstractCpsObject.class));
  166. // and its connections too
  167. edgeToJson(EDGETYPE.CONNECTION, file, u.getID(), u.getConnections());
  168. // if holonobject elements too
  169. if (u instanceof HolonObject)
  170. elementsToJson(TYPE.CANVAS, file, u);
  171. // if switch graphpoints too
  172. if (u instanceof HolonSwitch)
  173. if (((HolonSwitch) u).getGraphPoints().size() != 0)
  174. unitgraphToJson(GRAPHTYPE.SWITCH, file, u.getID(), ((HolonSwitch) u).getGraphPoints());
  175. // if uppernode put all nodes inside the uppernode into queue
  176. if (u instanceof CpsUpperNode) {
  177. for (AbstractCpsObject adjacent : ((CpsUpperNode) u).getNodes()) {
  178. queue.add(adjacent);
  179. }
  180. // dont forget to add the nodeedges and oldedges
  181. edgeToJson(EDGETYPE.NODE, file, u.getID(), ((CpsUpperNode) u).getNodeEdges());
  182. edgeToJson(EDGETYPE.OLD, file, u.getID(), ((CpsUpperNode) u).getOldEdges());
  183. }
  184. }
  185. // lastly add canvasedges into json
  186. edgeToJson(EDGETYPE.CANVAS, file, 0, model.getEdgesOnCanvas());
  187. }
  188. /**
  189. * Stores Category or Canvas Elements into Json
  190. *
  191. * @param type
  192. * @param gson
  193. * @param file
  194. * @param obj
  195. */
  196. public void elementsToJson(TYPE type, JsonObject file, AbstractCpsObject obj) {
  197. // TODO Auto-generated method stub
  198. JsonObject temp = new JsonObject();
  199. String key = null;
  200. // forall elements store them into json and include the id of the object
  201. for (HolonElement ele : ((HolonObject) obj).getElements()) {
  202. temp.add("properties", gson.toJsonTree(ele));
  203. temp.add("ID", new JsonPrimitive(obj.getID()));
  204. // switch for deciding the key
  205. switch (type) {
  206. case CANVAS:
  207. key = "CVSELEMENT" + getNumerator(NUMTYPE.ELEMENT);
  208. break;
  209. case CATEGORY:
  210. key = "CGELEMENT" + getNumerator(NUMTYPE.ELEMENT);
  211. break;
  212. default:
  213. break;
  214. }
  215. file.add(key, gson.toJsonTree(temp));
  216. // if there are gps add them into
  217. if (ele.getGraphPoints().size() != 0)
  218. unitgraphToJson(GRAPHTYPE.ELEMENT, file, ele.getId(), ele.getGraphPoints());
  219. temp = new JsonObject();
  220. }
  221. }
  222. /**
  223. * Put the UnitGraphs of Switches or Elements into Json
  224. *
  225. * @param ele
  226. */
  227. public void unitgraphToJson(GRAPHTYPE type, JsonObject file, int id, LinkedList<Point> graph) {
  228. JsonObject temp = new JsonObject();
  229. String key = null;
  230. // forall points add them
  231. for (int i = 0; i < graph.size(); i++) {
  232. temp.add("" + i, new JsonPrimitive(graph.get(i).x + ":" + graph.get(i).y));
  233. }
  234. // decide key
  235. switch (type) {
  236. case SWITCH:
  237. key = "SWUNITGRAPH" + getNumerator(NUMTYPE.UNITGRAPH);
  238. break;
  239. case ELEMENT:
  240. key = "ELEUNITGRAPH" + getNumerator(NUMTYPE.UNITGRAPH);
  241. break;
  242. default:
  243. break;
  244. }
  245. // add id of element so it can be found again
  246. temp.add("ID", new JsonPrimitive(id));
  247. file.add(key, gson.toJsonTree(temp));
  248. }
  249. /**
  250. * Canvas-Edge, Connections, Node-Edge and Old-Edges to json
  251. *
  252. * @param type
  253. * @param file
  254. * @param id
  255. * @param arr
  256. */
  257. public void edgeToJson(EDGETYPE type, JsonObject file, int id, ArrayList<CpsEdge> arr) {
  258. // TODO Auto-generated method stub
  259. String k = null;
  260. boolean b = false;
  261. JsonObject temp = new JsonObject();
  262. for (CpsEdge edge : arr) {
  263. // add properties and only the ids from a and b
  264. temp.add("properties", gson.toJsonTree(edge));
  265. temp.add("A", new JsonPrimitive(edge.getA().getID()));
  266. temp.add("B", new JsonPrimitive(edge.getB().getID()));
  267. // Key and occasionally the id of Uppernode
  268. switch (type) {
  269. case CANVAS:
  270. k = "CVSEDGE" + getNumerator(NUMTYPE.EDGE);
  271. break;
  272. case CONNECTION:
  273. k = "CONNEDGE" + getNumerator(NUMTYPE.CONNECTION);
  274. break;
  275. case NODE:
  276. temp.add("ID", new JsonPrimitive(id));
  277. k = "NODEEDGE" + getNumerator(NUMTYPE.NODEEDGE);
  278. break;
  279. case OLD:
  280. temp.add("ID", new JsonPrimitive(id));
  281. k = "OLDEDGE" + getNumerator(NUMTYPE.OLDEDGE);
  282. break;
  283. default:
  284. break;
  285. }
  286. // lookup if the CVS, NODE or OLDEDGE are also connections
  287. if (edge.getA().getConnections().contains(edge) && edge.getA().getConnections().contains(edge)
  288. && !type.equals(EDGETYPE.CONNECTION))
  289. b = true;
  290. temp.add("connection", new JsonPrimitive(b));
  291. file.add(k, gson.toJsonTree(temp));
  292. temp = new JsonObject();
  293. }
  294. }
  295. /**
  296. * Initialize the Gson with wanted parameters
  297. */
  298. private void initGson() {
  299. // TODO Auto-generated method stub
  300. GsonBuilder builder = new GsonBuilder();
  301. builder.excludeFieldsWithoutExposeAnnotation().serializeNulls().setPrettyPrinting();
  302. builder.registerTypeAdapter(AbstractCpsObject.class, new AbstractCpsObjectAdapter());
  303. builder.registerTypeAdapter(Position.class, new PositionAdapter());
  304. builder.registerTypeAdapter(Color.class, new ColorAdapter());
  305. // use the builder and make a instance of the Gson
  306. this.gson = builder.create();
  307. }
  308. /**
  309. * Just initialize the Numerators for the Json Keys. Maybe bad Style..
  310. */
  311. public void initNumeration() {
  312. this.nCat = this.nObj = this.nEle = this.nEdge = this.nConn = this.nNodeEdge = this.nOldEdge = 0;
  313. }
  314. /**
  315. * Get the wanted numerator and increment it
  316. *
  317. * @param type
  318. * @return
  319. */
  320. public int getNumerator(NUMTYPE type) {
  321. switch (type) {
  322. case CATEGORY:
  323. return nCat++;
  324. case OBJECT:
  325. return nObj++;
  326. case ELEMENT:
  327. return nEle++;
  328. case EDGE:
  329. return nEdge++;
  330. case CONNECTION:
  331. return nConn++;
  332. case NODEEDGE:
  333. return nNodeEdge++;
  334. case OLDEDGE:
  335. return nOldEdge++;
  336. case UNITGRAPH:
  337. return nUnitGraph++;
  338. default:
  339. break;
  340. }
  341. return -1;
  342. }
  343. }