2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2015-2015 - Scilab Enterprises - Clement DAVID
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
13 package org.scilab.modules.xcos.io.sax;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.HashMap;
20 import org.scilab.modules.types.ScilabBoolean;
21 import org.scilab.modules.types.ScilabDouble;
22 import org.scilab.modules.types.ScilabInteger;
23 import org.scilab.modules.types.ScilabIntegerTypeEnum;
24 import org.scilab.modules.types.ScilabList;
25 import org.scilab.modules.types.ScilabMList;
26 import org.scilab.modules.types.ScilabString;
27 import org.scilab.modules.types.ScilabTList;
28 import org.scilab.modules.types.ScilabType;
29 import org.scilab.modules.xcos.ObjectProperties;
30 import org.scilab.modules.xcos.VectorOfDouble;
31 import org.scilab.modules.xcos.VectorOfString;
32 import org.scilab.modules.xcos.graph.XcosDiagram;
33 import org.scilab.modules.xcos.graph.model.ScicosObjectOwner;
34 import org.scilab.modules.xcos.graph.model.XcosCell;
35 import org.scilab.modules.xcos.io.HandledElement;
36 import org.scilab.modules.xcos.io.ScilabTypeCoder;
37 import org.scilab.modules.xcos.io.scicos.DiagramElement;
38 import org.scilab.modules.xcos.io.scicos.ScicosFormatException;
39 import org.xml.sax.Attributes;
41 import com.mxgraph.model.mxGeometry;
42 import com.mxgraph.util.mxPoint;
43 import org.scilab.modules.xcos.VectorOfInt;
45 class RawDataHandler implements ScilabHandler {
47 static class RawDataDescriptor {
48 final ObjectProperties as;
49 final HandledElement found;
50 final String scilabClass;
53 public RawDataDescriptor(ObjectProperties as, HandledElement found, String scilabClass, Object container) {
56 this.scilabClass = scilabClass;
57 this.value = container;
61 private final XcosSAXHandler saxHandler;
62 private final Map<String, ObjectProperties> propertyMap;
68 * the shared sax handler
70 RawDataHandler(XcosSAXHandler saxHandler) {
71 this.saxHandler = saxHandler;
73 Map<String, ObjectProperties> localPropertyMap = new HashMap<>();
74 localPropertyMap.put("context", ObjectProperties.DIAGRAM_CONTEXT);
75 localPropertyMap.put("exprs", ObjectProperties.EXPRS);
76 localPropertyMap.put("realParameters", ObjectProperties.RPAR);
77 localPropertyMap.put("integerParameters", ObjectProperties.IPAR);
78 localPropertyMap.put("objectsParameters", ObjectProperties.OPAR);
79 localPropertyMap.put("nbZerosCrossing", ObjectProperties.NZCROSS);
80 localPropertyMap.put("nmode", ObjectProperties.NMODE);
81 localPropertyMap.put("state", ObjectProperties.STATE);
82 localPropertyMap.put("dState", ObjectProperties.DSTATE);
83 localPropertyMap.put("oDState", ObjectProperties.ODSTATE);
84 localPropertyMap.put("equations", ObjectProperties.EQUATIONS);
85 localPropertyMap.put("points", ObjectProperties.CONTROL_POINTS);
86 propertyMap = Collections.unmodifiableMap(localPropertyMap);
90 * Implement the ScilabHandler interface to decode the data
94 public Object startElement(HandledElement found, Attributes atts) {
99 // no break on purpose
101 // no break on purpose
103 // no break on purpose
105 // no break on purpose
107 String as = atts.getValue("as");
110 * first : try to retrieve the already decoded binary data
112 boolean binary = false;
115 v = atts.getValue("binary");
117 binary = Boolean.valueOf(v);
119 v = atts.getValue("position");
121 position = Integer.valueOf(v);
125 saxHandler.dictionary != null &&
126 (0 <= position && position < saxHandler.dictionary.size())) {
127 final ObjectProperties asProp = propertyMap.get(as);
128 return new RawDataDescriptor(asProp, found, null, saxHandler.dictionary.get(position));
132 * otherwise : this is not a binary, decode it
136 String scilabClass = "ScilabDouble";
138 v = atts.getValue("height");
140 height = Integer.valueOf(v);
142 v = atts.getValue("width");
144 width = Integer.valueOf(v);
146 v = atts.getValue("scilabClass");
151 // allocate the right class and push it to a descriptor
152 final Object container = allocateDataType(found, atts, height, width, scilabClass);
153 final ObjectProperties asProp = propertyMap.get(as);
154 return new RawDataDescriptor(asProp, found, scilabClass, container);
157 // defensive programming
158 if (!(saxHandler.parents.peek() instanceof RawDataDescriptor)) {
161 RawDataDescriptor fieldValue = (RawDataDescriptor) saxHandler.parents.peek();
163 switch (fieldValue.as) {
164 case DIAGRAM_CONTEXT: {
165 @SuppressWarnings("unchecked")
166 ArrayList<String> container = ((ArrayList<String>) fieldValue.value);
167 container.add(atts.getValue("value"));
176 // defensive programming
177 if (!(saxHandler.parents.peek() instanceof RawDataDescriptor)) {
180 RawDataDescriptor fieldValue = (RawDataDescriptor) saxHandler.parents.peek();
183 * Decode the position and then switch per container klass
189 v = atts.getValue("column");
191 column = Integer.valueOf(v);
193 v = atts.getValue("line");
195 line = Integer.valueOf(v);
198 switch (fieldValue.found) {
199 case ScilabBoolean: {
200 ScilabBoolean localScilabValue = ((ScilabBoolean) fieldValue.value);
201 boolean[][] data = localScilabValue.getData();
203 v = atts.getValue("value");
205 data[line][column] = Boolean.valueOf(v);
210 ScilabDouble localScilabValue = ((ScilabDouble) fieldValue.value);
211 double[][] realPartData = localScilabValue.getRealPart();
212 double[][] imaginaryPartData = localScilabValue.getImaginaryPart();
214 v = atts.getValue("realPart");
216 realPartData[line][column] = Double.valueOf(v);
219 v = atts.getValue("imaginaryPart");
221 // allocate the imaginary part on demand
222 if (imaginaryPartData == null) {
223 imaginaryPartData = new double[localScilabValue.getHeight()][localScilabValue.getWidth()];
224 localScilabValue.setImaginaryPart(imaginaryPartData);
227 imaginaryPartData[line][column] = Double.valueOf(v);
231 case ScilabInteger: {
232 ScilabInteger localScilabValue = ((ScilabInteger) fieldValue.value);
233 ScilabIntegerTypeEnum precision = localScilabValue.getPrec();
235 v = atts.getValue("value");
240 localScilabValue.getDataAsByte()[line][column] = Byte.valueOf(v);
244 localScilabValue.getDataAsShort()[line][column] = Short.valueOf(v);
248 localScilabValue.getDataAsInt()[line][column] = Integer.valueOf(v);
252 localScilabValue.getDataAsLong()[line][column] = Long.valueOf(v);
259 ScilabString localScilabValue = ((ScilabString) fieldValue.value);
260 String[][] data = localScilabValue.getData();
261 data[line][column] = atts.getValue("value");
270 throw new IllegalArgumentException();
277 * Allocate a {@link ScilabType} datatype accordingly to the decoded descriptors
280 * the decoded element
282 * the attributes of the element
288 * decoded scilabClass
289 * @return the container
291 @SuppressWarnings("fallthrough")
292 private Object allocateDataType(HandledElement found, Attributes atts, int height, int width, String scilabClass) {
294 final Object container;
297 container = new ScilabBoolean(new boolean[height][width]);
300 container = new ScilabDouble(new double[height][width]);
303 v = atts.getValue("intPrecision");
305 boolean unsigned = true;
306 switch (ScilabIntegerTypeEnum.valueOf(v)) {
309 // no break on purpose
311 container = new ScilabInteger(new byte[height][width], unsigned);
315 // no break on purpose
317 container = new ScilabInteger(new short[height][width], unsigned);
321 // no break on purpose
323 container = new ScilabInteger(new int[height][width], unsigned);
327 // no break on purpose
329 container = new ScilabInteger(new long[height][width], unsigned);
332 container = new ScilabInteger(new long[height][width], false);
336 container = new ScilabInteger(new long[height][width], false);
340 container = new ScilabString(new String[height][width]);
342 default: // case Array
343 if ("ScilabMList".equals(scilabClass)) {
344 container = new ScilabMList();
345 } else if ("ScilabTList".equals(scilabClass)) {
346 container = new ScilabTList();
347 } else if ("ScilabList".equals(scilabClass)) {
348 container = new ScilabList();
350 container = new ArrayList<>();
358 public void endElement(HandledElement found) {
361 // no break on purpose
363 // no break on purpose
365 // no break on purpose
367 // no break on purpose
369 // defensive programming
370 if (!(saxHandler.parents.peek() instanceof RawDataDescriptor)) {
373 RawDataDescriptor fieldValue = (RawDataDescriptor) saxHandler.parents.peek();
374 Object parent = saxHandler.parents.peek(1);
376 // when we are decoding data into a list "as" is null
377 if (fieldValue.as == null) {
378 if (!(parent instanceof RawDataDescriptor)) {
382 ArrayList<Object> parentList = (ArrayList<Object>) ((RawDataDescriptor) parent).value;
383 parentList.add(fieldValue.value);
387 switch (fieldValue.as) {
388 case CONTROL_POINTS: {
389 // defensive programming
390 if (!(parent instanceof mxGeometry)) {
393 mxGeometry geom = (mxGeometry) parent;
395 @SuppressWarnings("unchecked")
396 ArrayList<mxPoint> value = (ArrayList<mxPoint>) fieldValue.value;
397 geom.setPoints(value);
400 case DIAGRAM_CONTEXT: {
401 // defensive programming
402 if (!(parent instanceof ScicosObjectOwner)) {
405 ScicosObjectOwner diagram = (ScicosObjectOwner) parent;
407 @SuppressWarnings("unchecked")
408 ArrayList<String> value = (ArrayList<String>) fieldValue.value;
409 VectorOfString ctx = new VectorOfString(value.size());
410 for (int i = 0; i < value.size(); i++) {
411 ctx.set(i, value.get(i));
413 saxHandler.controller.setObjectProperty(diagram.getUID(), diagram.getKind(), ObjectProperties.DIAGRAM_CONTEXT, ctx);
419 // defensive programming
420 if (!(parent instanceof XcosCell)) {
423 XcosCell cell = (XcosCell) parent;
424 if (fieldValue.as == ObjectProperties.RPAR && fieldValue.value instanceof ScilabMList) {
425 // CORNER CASE for partially decoded sub-diagram hierarchy
426 // decode the rpar as a subdiagram using the legacy decoders
428 new DiagramElement(saxHandler.controller).decode((ScilabMList) fieldValue.value, new XcosDiagram(cell.getUID(), cell.getKind()));
429 } catch (ScicosFormatException e) {
435 if (fieldValue.value instanceof ScilabDouble) {
436 // defensive programming against old schema
437 ScilabDouble value = (ScilabDouble) fieldValue.value;
439 vec = new VectorOfDouble(value.getHeight());
440 for (int i = 0; i < value.getHeight(); i++) {
441 vec.set(i, value.getRealElement(i, 0));
444 saxHandler.controller.setObjectProperty(cell.getUID(), cell.getKind(), fieldValue.as, vec);
451 // defensive programming
452 if (!(parent instanceof XcosCell)) {
455 XcosCell cell = (XcosCell) parent;
457 VectorOfInt vec = null;
458 if (fieldValue.value instanceof ScilabDouble) {
459 // defensive programming against old schema
460 ScilabDouble value = (ScilabDouble) fieldValue.value;
462 vec = new VectorOfInt(value.getHeight());
463 for (int i = 0; i < value.getHeight(); i++) {
464 vec.set(i, (int) value.getRealElement(i, 0));
466 } else if (fieldValue.value instanceof ScilabInteger) {
467 // defensive programming against old schema
468 ScilabInteger value = (ScilabInteger) fieldValue.value;
470 vec = new VectorOfInt(value.getHeight());
471 for (int i = 0; i < value.getHeight(); i++) {
472 switch (value.getPrec()) {
475 vec.set(i, value.getByteElement(i, 0));
479 vec.set(i, value.getShortElement(i, 0));
483 vec.set(i, value.getIntElement(i, 0));
487 vec.set(i, (int) value.getLongElement(i, 0));
493 saxHandler.controller.setObjectProperty(cell.getUID(), cell.getKind(), fieldValue.as, vec);
502 // defensive programming
503 if (!(parent instanceof XcosCell)) {
506 XcosCell cell = (XcosCell) parent;
507 ScilabType value = (ScilabType) fieldValue.value;
509 saxHandler.controller.setObjectProperty(cell.getUID(), cell.getKind(), fieldValue.as, new ScilabTypeCoder().var2vec(value));
513 XcosSAXHandler.LOG.warning("RawDataHandler not handled: " + fieldValue.as);
523 throw new IllegalArgumentException();