Xcos MVC: handle XCOS / ZCOS file loading
[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.stream.Stream;
20
21 import org.scilab.modules.xcos.Kind;
22 import org.scilab.modules.xcos.ObjectProperties;
23 import org.scilab.modules.xcos.VectorOfDouble;
24 import org.scilab.modules.xcos.VectorOfInt;
25 import org.scilab.modules.xcos.graph.ScicosParameters;
26 import org.scilab.modules.xcos.graph.model.ScicosObjectOwner;
27 import org.scilab.modules.xcos.graph.model.XcosCell;
28 import org.scilab.modules.xcos.graph.model.XcosCellFactory;
29 import org.scilab.modules.xcos.io.sax.SAXHandler.UnresolvedReference;
30 import org.scilab.modules.xcos.port.BasicPort;
31 import org.scilab.modules.xcos.port.Orientation;
32 import org.xml.sax.Attributes;
33
34 class CustomHandler implements ScilabHandler {
35
36     private final SAXHandler saxHandler;
37
38     /**
39      * Default constructor
40      *
41      * @param saxHandler
42      *            the shared sax handler
43      */
44     CustomHandler(SAXHandler saxHandler) {
45         this.saxHandler = saxHandler;
46     }
47
48     @Override
49     @SuppressWarnings({ "fallthrough" })
50     public Object startElement(HandledElement found, final Attributes atts) {
51         long uid = 0l;
52         String v;
53
54         switch (found) {
55             case Orientation: {
56                 // defensive programming
57                 if (!(saxHandler.parents.peek() instanceof BasicPort)) {
58                     return null;
59                 }
60                 BasicPort parent = (BasicPort) saxHandler.parents.peek();
61
62                 v = atts.getValue("value");
63                 if (v != null) {
64                     final String orientationString = v;
65                     Optional<Orientation> orientation = Stream.of(Orientation.values()).filter(o -> o.name().equals(orientationString)).findFirst();
66                     if (orientation.isPresent()) {
67                         parent.setOrientation(orientation.get());
68                     }
69                 }
70
71                 return null;
72             }
73             case XcosDiagram:
74                 // do not allocate this is already allocated as #root
75                 uid = saxHandler.root.getUID();
76
77                 /*
78                  * Decode some graph properties
79                  */
80                 v = atts.getValue("savedFile");
81                 if (v != null) {
82                     saxHandler.controller.setObjectProperty(uid, Kind.DIAGRAM, ObjectProperties.PATH, v);
83                 }
84
85                 /*
86                  * Decode simulation properties
87                  */
88                 VectorOfDouble properties = new VectorOfDouble();
89                 saxHandler.controller.getObjectProperty(uid, Kind.DIAGRAM, ObjectProperties.PROPERTIES, properties);
90
91                 v = atts.getValue("finalIntegrationTime");
92                 if (v != null) {
93                     properties.set(ScicosParameters.FINAL_INTEGRATION_TIME, Double.valueOf(v));
94                 }
95                 v = atts.getValue("integratorAbsoluteTolerance");
96                 if (v != null) {
97                     properties.set(ScicosParameters.INTEGRATOR_ABSOLUTE_TOLERANCE, Double.valueOf(v));
98                 }
99                 v = atts.getValue("integratorRelativeTolerance");
100                 if (v != null) {
101                     properties.set(ScicosParameters.INTEGRATOR_RELATIVE_TOLERANCE, Double.valueOf(v));
102                 }
103                 v = atts.getValue("toleranceOnTime");
104                 if (v != null) {
105                     properties.set(ScicosParameters.TOLERANCE_ON_TIME, Double.valueOf(v));
106                 }
107                 v = atts.getValue("maxIntegrationTimeinterval");
108                 if (v != null) {
109                     properties.set(ScicosParameters.MAX_INTEGRATION_TIME_INTERVAL, Double.valueOf(v));
110                 }
111                 v = atts.getValue("maximumStepSize");
112                 if (v != null) {
113                     properties.set(ScicosParameters.MAXIMUM_STEP_SIZE, Double.valueOf(v));
114                 }
115                 v = atts.getValue("realTimeScaling");
116                 if (v != null) {
117                     properties.set(ScicosParameters.REAL_TIME_SCALING, Double.valueOf(v));
118                 }
119                 v = atts.getValue("solver");
120                 if (v != null) {
121                     properties.set(ScicosParameters.SOLVER, Double.valueOf(v));
122                 }
123
124                 saxHandler.controller.setObjectProperty(uid, Kind.DIAGRAM, ObjectProperties.PROPERTIES, properties);
125
126             // no break on purpose, we decode non-root specific properties later
127             case SuperBlockDiagram:
128                 final Kind kind;
129                 if (uid == 0l) {
130                     XcosCell parent = saxHandler.lookupForParentXcosCellElement();
131                     uid = parent.getUID();
132                     kind = parent.getKind();
133                 } else {
134                     kind = Kind.DIAGRAM;
135                 }
136
137                 /*
138                  * Decode the properties shared between a DIAGRAM and a BLOCK
139                  */
140                 VectorOfInt colors = new VectorOfInt();
141                 saxHandler.controller.getObjectProperty(uid, kind, ObjectProperties.COLOR, colors);
142                 v = atts.getValue("background");
143                 if (v != null) {
144                     colors.set(0, Integer.valueOf(v));
145                 }
146                 v = atts.getValue("gridEnabled");
147                 if (v != null) {
148                     colors.set(1, Integer.valueOf(v));
149                 }
150                 saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.COLOR, colors);
151
152                 v = atts.getValue("title");
153                 if (v != null) {
154                     saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.TITLE, v);
155                 }
156
157                 /*
158                  * Update some states
159                  */
160                 saxHandler.allChildren.push(new HashMap<>());
161                 return new ScicosObjectOwner(uid, kind);
162             default:
163                 throw new IllegalArgumentException();
164         }
165     }
166
167     @Override
168     public void endElement(HandledElement found) {
169         switch (found) {
170             case Orientation:
171                 break;
172             case XcosDiagram:
173                 resolve();
174                 saxHandler.allChildren.pop();
175                 XcosCellFactory.insertChildren(saxHandler.controller, saxHandler.root);
176                 break;
177             case SuperBlockDiagram:
178                 resolve();
179                 saxHandler.allChildren.pop();
180                 break;
181             default:
182                 throw new IllegalArgumentException();
183         }
184     }
185
186     private void resolve() {
187         HashMap<String, Long> allLocalChildren = saxHandler.allChildren.peek();
188
189         for (Entry<String, ArrayList<UnresolvedReference>> entry : saxHandler.unresolvedReferences.entrySet()) {
190             Long uidObject = allLocalChildren.get(entry.getKey());
191             if (uidObject != null) {
192                 long uid = uidObject.longValue();
193
194                 for (UnresolvedReference unresolvedReference : entry.getValue()) {
195                     unresolvedReference.resolve(saxHandler.controller, uid);
196                 }
197             }
198         }
199     }
200 }