Xcos MVC: implement XCOS / ZCOS file saving
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / io / sax / CustomHandler.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2015-2015 - Scilab Enterprises - Clement DAVID
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  *
11  */
12
13 package org.scilab.modules.xcos.io.sax;
14
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.Map.Entry;
18 import java.util.Optional;
19 import java.util.logging.Level;
20 import java.util.stream.Stream;
21
22 import javax.naming.LimitExceededException;
23
24 import org.scilab.modules.xcos.Kind;
25 import org.scilab.modules.xcos.ObjectProperties;
26 import org.scilab.modules.xcos.VectorOfDouble;
27 import org.scilab.modules.xcos.VectorOfInt;
28 import org.scilab.modules.xcos.graph.ScicosParameters;
29 import org.scilab.modules.xcos.graph.model.ScicosObjectOwner;
30 import org.scilab.modules.xcos.graph.model.XcosCell;
31 import org.scilab.modules.xcos.graph.model.XcosCellFactory;
32 import org.scilab.modules.xcos.io.HandledElement;
33 import org.scilab.modules.xcos.io.sax.XcosSAXHandler.UnresolvedReference;
34 import org.scilab.modules.xcos.port.BasicPort;
35 import org.scilab.modules.xcos.port.Orientation;
36 import org.xml.sax.Attributes;
37
38 class CustomHandler implements ScilabHandler {
39
40     private final XcosSAXHandler saxHandler;
41
42     /**
43      * Default constructor
44      *
45      * @param saxHandler
46      *            the shared sax handler
47      */
48     CustomHandler(XcosSAXHandler saxHandler) {
49         this.saxHandler = saxHandler;
50     }
51
52     @Override
53     @SuppressWarnings({ "fallthrough" })
54     public Object startElement(HandledElement found, final Attributes atts) {
55         long uid = 0l;
56         String v;
57
58         switch (found) {
59             case Orientation: {
60                 // defensive programming
61                 if (!(saxHandler.parents.peek() instanceof BasicPort)) {
62                     return null;
63                 }
64                 BasicPort parent = (BasicPort) saxHandler.parents.peek();
65
66                 v = atts.getValue("value");
67                 if (v != null) {
68                     final String orientationString = v;
69                     Optional<Orientation> orientation = Stream.of(Orientation.values()).filter(o -> o.name().equals(orientationString)).findFirst();
70                     if (orientation.isPresent()) {
71                         parent.setOrientation(orientation.get());
72                     }
73                 }
74
75                 return null;
76             }
77             case XcosDiagram:
78                 if (XcosSAXHandler.LOG.isLoggable(Level.FINER)) {
79                     XcosSAXHandler.LOG.entering(CustomHandler.class.getName(), "startElement(\"XcosDiagram\", ...)");
80                 }
81
82                 // do not allocate this is already allocated as #root
83                 uid = saxHandler.root.getUID();
84
85                 /*
86                  * Decode some graph properties
87                  */
88                 v = atts.getValue("savedFile");
89                 if (v != null) {
90                     saxHandler.controller.setObjectProperty(uid, Kind.DIAGRAM, ObjectProperties.PATH, v);
91                 }
92
93                 /*
94                  * Decode simulation properties
95                  */
96                 VectorOfDouble properties = new VectorOfDouble();
97                 saxHandler.controller.getObjectProperty(uid, Kind.DIAGRAM, ObjectProperties.PROPERTIES, properties);
98
99                 v = atts.getValue("finalIntegrationTime");
100                 if (v != null) {
101                     properties.set(ScicosParameters.FINAL_INTEGRATION_TIME, Double.valueOf(v));
102                 }
103                 v = atts.getValue("integratorAbsoluteTolerance");
104                 if (v != null) {
105                     properties.set(ScicosParameters.INTEGRATOR_ABSOLUTE_TOLERANCE, Double.valueOf(v));
106                 }
107                 v = atts.getValue("integratorRelativeTolerance");
108                 if (v != null) {
109                     properties.set(ScicosParameters.INTEGRATOR_RELATIVE_TOLERANCE, Double.valueOf(v));
110                 }
111                 v = atts.getValue("toleranceOnTime");
112                 if (v != null) {
113                     properties.set(ScicosParameters.TOLERANCE_ON_TIME, Double.valueOf(v));
114                 }
115                 v = atts.getValue("maxIntegrationTimeinterval");
116                 if (v != null) {
117                     properties.set(ScicosParameters.MAX_INTEGRATION_TIME_INTERVAL, Double.valueOf(v));
118                 }
119                 v = atts.getValue("maximumStepSize");
120                 if (v != null) {
121                     properties.set(ScicosParameters.MAXIMUM_STEP_SIZE, Double.valueOf(v));
122                 }
123                 v = atts.getValue("realTimeScaling");
124                 if (v != null) {
125                     properties.set(ScicosParameters.REAL_TIME_SCALING, Double.valueOf(v));
126                 }
127                 v = atts.getValue("solver");
128                 if (v != null) {
129                     properties.set(ScicosParameters.SOLVER, Double.valueOf(v));
130                 }
131
132                 saxHandler.controller.setObjectProperty(uid, Kind.DIAGRAM, ObjectProperties.PROPERTIES, properties);
133
134             // no break on purpose, we decode non-root specific properties later
135             case SuperBlockDiagram:
136                 final Kind kind;
137                 if (uid == 0l) {
138                     XcosCell parent = saxHandler.lookupForParentXcosCellElement();
139                     uid = parent.getUID();
140                     kind = parent.getKind();
141                 } else {
142                     kind = Kind.DIAGRAM;
143                 }
144
145                 /*
146                  * Decode the properties shared between a DIAGRAM and a BLOCK
147                  */
148                 VectorOfInt colors = new VectorOfInt();
149                 saxHandler.controller.getObjectProperty(uid, kind, ObjectProperties.COLOR, colors);
150                 v = atts.getValue("background");
151                 if (v != null) {
152                     colors.set(0, Integer.valueOf(v));
153                 }
154                 v = atts.getValue("gridEnabled");
155                 if (v != null) {
156                     colors.set(1, Integer.valueOf(v));
157                 }
158                 saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.COLOR, colors);
159
160                 v = atts.getValue("title");
161                 if (v != null) {
162                     saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.TITLE, v);
163                 }
164
165                 /*
166                  * Update some states
167                  */
168                 saxHandler.allChildren.push(new HashMap<>());
169                 return new ScicosObjectOwner(uid, kind);
170             default:
171                 throw new IllegalArgumentException();
172         }
173     }
174
175     @Override
176     public void endElement(HandledElement found) {
177         switch (found) {
178             case Orientation:
179                 break;
180             case XcosDiagram:
181                 resolve();
182                 saxHandler.allChildren.pop();
183                 XcosCellFactory.insertChildren(saxHandler.controller, saxHandler.root);
184
185                 if (XcosSAXHandler.LOG.isLoggable(Level.FINER)) {
186                     XcosSAXHandler.LOG.exiting(CustomHandler.class.getName(), "endElement(\"XcosDiagram\")");
187                 }
188                 break;
189             case SuperBlockDiagram:
190                 resolve();
191                 saxHandler.allChildren.pop();
192                 break;
193             default:
194                 throw new IllegalArgumentException();
195         }
196     }
197
198     private void resolve() {
199         HashMap<String, Long> allLocalChildren = saxHandler.allChildren.peek();
200
201         for (Entry<String, ArrayList<UnresolvedReference>> entry : saxHandler.unresolvedReferences.entrySet()) {
202             Long uidObject = allLocalChildren.get(entry.getKey());
203             if (uidObject != null) {
204                 long uid = uidObject.longValue();
205
206                 for (UnresolvedReference unresolvedReference : entry.getValue()) {
207                     unresolvedReference.resolve(saxHandler.controller, uid, saxHandler.controller.getKind(uid));
208                 }
209             }
210         }
211     }
212 }