154f216a3f84280e5410f6680863ec78e7cde64a
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / io / sax / RawDataHandler.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.beans.BeanDescriptor;
16 import java.beans.IntrospectionException;
17 import java.beans.PropertyDescriptor;
18 import java.beans.SimpleBeanInfo;
19 import java.lang.reflect.InvocationTargetException;
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import org.scilab.modules.types.ScilabBoolean;
26 import org.scilab.modules.types.ScilabDouble;
27 import org.scilab.modules.types.ScilabInteger;
28 import org.scilab.modules.types.ScilabIntegerTypeEnum;
29 import org.scilab.modules.types.ScilabList;
30 import org.scilab.modules.types.ScilabMList;
31 import org.scilab.modules.types.ScilabString;
32 import org.scilab.modules.types.ScilabTList;
33 import org.scilab.modules.xcos.ObjectProperties;
34 import org.scilab.modules.xcos.VectorOfString;
35 import org.scilab.modules.xcos.graph.model.ScicosObjectOwner;
36 import org.xml.sax.Attributes;
37
38 import com.mxgraph.model.mxGeometry;
39 import com.mxgraph.util.mxPoint;
40
41 class RawDataHandler implements ScilabHandler {
42
43     static class RawDataDescriptor {
44         final ObjectProperties as;
45         final HandledElement found;
46         final String scilabClass;
47         final Object value;
48
49         public RawDataDescriptor(ObjectProperties as, HandledElement found, String scilabClass, Object container) {
50             // defensive programming
51             if (as == null) {
52                 throw new IllegalAccessError();
53             }
54
55             this.as = as;
56             this.found = found;
57             this.scilabClass = scilabClass;
58             this.value = container;
59         }
60     }
61
62     private final SAXHandler saxHandler;
63     private final Map<String, ObjectProperties> propertyMap;
64
65     /**
66      * Default constructor
67      * @param saxHandler the shared sax handler
68      */
69     RawDataHandler(SAXHandler saxHandler) {
70         this.saxHandler = saxHandler;
71
72         Map<String, ObjectProperties> localPropertyMap = new HashMap<>();
73         localPropertyMap.put("context", ObjectProperties.DIAGRAM_CONTEXT);
74         localPropertyMap.put("equations", ObjectProperties.EQUATIONS);
75         localPropertyMap.put("exprs", ObjectProperties.EXPRS);
76         localPropertyMap.put("integerParameters", ObjectProperties.IPAR);
77         localPropertyMap.put("nbZerosCrossing", ObjectProperties.NZCROSS);
78         localPropertyMap.put("nmode", ObjectProperties.NMODE);
79         localPropertyMap.put("objectsParameters", ObjectProperties.OPAR);
80         localPropertyMap.put("oDState", ObjectProperties.ODSTATE);
81         localPropertyMap.put("points", ObjectProperties.CONTROL_POINTS);
82         localPropertyMap.put("realParameters", ObjectProperties.RPAR);
83         // TODO might be incomplete
84         propertyMap = Collections.unmodifiableMap(localPropertyMap);
85     }
86
87     public Object startElement(HandledElement found, Attributes atts) {
88         String v;
89
90         switch (found) {
91             case ScilabBoolean:
92             // no break on purpose
93             case ScilabDouble:
94             // no break on purpose
95             case ScilabInteger:
96             // no break on purpose
97             case ScilabString:
98             // no break on purpose
99             case Array: {
100                 String as = atts.getValue("as");
101
102                 /*
103                  * first : try to retrieve the already decoded binary data
104                  */
105                 boolean binary = false;
106                 int position = -1;
107
108                 v = atts.getValue("binary");
109                 if (v != null) {
110                     binary = Boolean.valueOf(v);
111                 }
112                 v = atts.getValue("position");
113                 if (v != null) {
114                     position = Integer.valueOf(v);
115                 }
116
117                 if (binary && (0 <= position && position < saxHandler.dictionary.size())) {
118                     return new RawDataDescriptor(propertyMap.get(as), found, null, saxHandler.dictionary.get(position));
119                 }
120
121                 /*
122                  * otherwise : this is not a binary, decode it
123                  */
124                 int height = 0;
125                 int width = 0;
126                 String scilabClass = "ScilabDouble";
127
128                 v = atts.getValue("height");
129                 if (v != null) {
130                     height = Integer.valueOf(v);
131                 }
132                 v = atts.getValue("width");
133                 if (v != null) {
134                     width = Integer.valueOf(v);
135                 }
136                 v = atts.getValue("scilabClass");
137                 if (v != null) {
138                     scilabClass = v;
139                 }
140
141                 // allocate the right class
142                 final Object container;
143                 switch (found) {
144                     case ScilabBoolean:
145                         container = new ScilabBoolean(new boolean[height][width]);
146                         break;
147                     case ScilabDouble:
148                         container = new ScilabDouble(new double[height][width]);
149                         break;
150                     case ScilabInteger:
151                         v = atts.getValue("intPrecision");
152                         if (v != null) {
153                             boolean unsigned = true;
154                             switch (ScilabIntegerTypeEnum.valueOf(v)) {
155                                 case sci_int8:
156                                     unsigned = false;
157                                 // no break on purpose
158                                 case sci_uint8:
159                                     container = new ScilabInteger(new byte[height][width], unsigned);
160                                     break;
161                                 case sci_int16:
162                                     unsigned = false;
163                                 // no break on purpose
164                                 case sci_uint16:
165                                     container = new ScilabInteger(new short[height][width], unsigned);
166                                     break;
167                                 case sci_int32:
168                                     unsigned = false;
169                                 // no break on purpose
170                                 case sci_uint32:
171                                     container = new ScilabInteger(new int[height][width], unsigned);
172                                     break;
173                                 case sci_int64:
174                                     unsigned = false;
175                                 // no break on purpose
176                                 case sci_uint64:
177                                     container = new ScilabInteger(new long[height][width], unsigned);
178                                     break;
179                                 default:
180                                     container = new ScilabInteger(new long[height][width], false);
181                                     break;
182                             }
183                         } else {
184                             container = new ScilabInteger(new long[height][width], false);
185                         }
186                         break;
187                     case ScilabString:
188                         container = new ScilabString(new String[height][width]);
189                         break;
190                     default: // case Array
191                         if (scilabClass.equalsIgnoreCase("ScilabMList")) {
192                             container = new ScilabMList();
193                         } else if (scilabClass.equalsIgnoreCase("ScilabTList")) {
194                             container = new ScilabTList();
195                         } else if (scilabClass.equalsIgnoreCase("ScilabList")) {
196                             container = new ScilabList();
197                         } else {
198                             container = new ArrayList<>();
199                         }
200                         break;
201                 }
202
203                 return new RawDataDescriptor(propertyMap.get(as), found, scilabClass, container);
204             }
205             case add: {
206                 // defensive programming
207                 if (!(saxHandler.parents.peek() instanceof RawDataDescriptor)) {
208                     return null;
209                 }
210                 RawDataDescriptor fieldValue = (RawDataDescriptor) saxHandler.parents.peek();
211
212                 switch (fieldValue.as) {
213                     case DIAGRAM_CONTEXT: {
214                         ArrayList<String> container = ((ArrayList<String>) fieldValue.value);
215                         container.add(atts.getValue("value"));
216                         break;
217                     }
218                     case CONTROL_POINTS: {
219                         // FIXME not implemented yet
220                         break;
221                     }
222                     default:
223                         break;
224                 }
225
226                 break;
227             }
228             case data: {
229                 // defensive programming
230                 if (!(saxHandler.parents.peek() instanceof RawDataDescriptor)) {
231                     return null;
232                 }
233                 RawDataDescriptor fieldValue = (RawDataDescriptor) saxHandler.parents.peek();
234
235                 /*
236                  * Decode the position and then switch per container klass
237                  */
238
239                 int column = 0;
240                 int line = 0;
241
242                 v = atts.getValue("column");
243                 if (v != null) {
244                     column = Integer.valueOf(v);
245                 }
246                 v = atts.getValue("line");
247                 if (v != null) {
248                     line = Integer.valueOf(v);
249                 }
250
251                 switch (fieldValue.found) {
252                     case ScilabBoolean: {
253                         ScilabBoolean localScilabValue = ((ScilabBoolean) fieldValue.value);
254                         boolean[][] data = localScilabValue.getData();
255
256                         v = atts.getValue("value");
257                         if (v != null) {
258                             data[line][column] = Boolean.valueOf(v);
259                         }
260                         break;
261                     }
262                     case ScilabDouble: {
263                         ScilabDouble localScilabValue = ((ScilabDouble) fieldValue.value);
264                         double[][] realPartData = localScilabValue.getRealPart();
265                         double[][] imaginaryPartData = localScilabValue.getImaginaryPart();
266
267                         v = atts.getValue("realPart");
268                         if (v != null) {
269                             realPartData[line][column] = Double.valueOf(v);
270                         }
271
272                         v = atts.getValue("imaginaryPart");
273                         if (v != null) {
274                             // allocate the imaginary part on demand
275                             if (imaginaryPartData == null) {
276                                 imaginaryPartData = new double[localScilabValue.getHeight()][localScilabValue.getWidth()];
277                                 localScilabValue.setImaginaryPart(imaginaryPartData);
278                             }
279
280                             imaginaryPartData[line][column] = Double.valueOf(v);
281                         }
282                         break;
283                     }
284                     case ScilabInteger: {
285                         ScilabInteger localScilabValue = ((ScilabInteger) fieldValue.value);
286                         ScilabIntegerTypeEnum precision = localScilabValue.getPrec();
287
288                         v = atts.getValue("value");
289                         if (v != null) {
290                             switch (precision) {
291                                 case sci_int8:
292                                 case sci_uint8:
293                                     localScilabValue.getDataAsByte()[line][column] = Byte.valueOf(v);
294                                     break;
295                                 case sci_int16:
296                                 case sci_uint16:
297                                     localScilabValue.getDataAsShort()[line][column] = Short.valueOf(v);
298                                     break;
299                                 case sci_int32:
300                                 case sci_uint32:
301                                     localScilabValue.getDataAsInt()[line][column] = Integer.valueOf(v);
302                                     break;
303                                 case sci_int64:
304                                 case sci_uint64:
305                                     localScilabValue.getDataAsLong()[line][column] = Long.valueOf(v);
306                                     break;
307                             }
308                         }
309                         break;
310                     }
311                     case ScilabString: {
312                         ScilabString localScilabValue = ((ScilabString) fieldValue.value);
313                         String[][] data = localScilabValue.getData();
314                         data[line][column] = atts.getValue("value");
315                         break;
316                     }
317                     default:
318                         break;
319                 }
320             }
321             default:
322                 throw new IllegalArgumentException();
323         }
324
325         return null;
326     }
327
328     public void endElement(HandledElement found) {
329         switch (found) {
330             case Array:
331             // no break on purpose
332             case ScilabBoolean:
333             // no break on purpose
334             case ScilabDouble:
335             // no break on purpose
336             case ScilabInteger:
337             // no break on purpose
338             case ScilabString: {
339                 // defensive programming
340                 if (!(saxHandler.parents.peek() instanceof RawDataDescriptor)) {
341                     return;
342                 }
343                 RawDataDescriptor fieldValue = (RawDataDescriptor) saxHandler.parents.peek();
344                 Object parent = saxHandler.parents.peek(1);
345
346                 switch (fieldValue.as) {
347                     case CONTROL_POINTS: {
348                         // defensive programming
349                         if (!(parent instanceof mxGeometry)) {
350                             return;
351                         }
352                         mxGeometry geom = (mxGeometry) parent;
353                         ArrayList<mxPoint> value = (ArrayList<mxPoint>) fieldValue.value;
354                         geom.setPoints(value);
355                         break;
356                     }
357                     case DIAGRAM_CONTEXT: {
358                         // defensive programming
359                         if (!(parent instanceof ScicosObjectOwner)) {
360                             return;
361                         }
362                         ScicosObjectOwner diagram = (ScicosObjectOwner) parent;
363
364                         ArrayList<String> value = (ArrayList<String>) fieldValue.value;
365                         VectorOfString ctx = new VectorOfString(value.size());
366                         for (int i = 0; i < value.size(); i++) {
367                             ctx.set(i, value.get(i));
368                         }
369                         saxHandler.controller.setObjectProperty(diagram.getUID(), diagram.getKind(), ObjectProperties.DIAGRAM_CONTEXT, ctx);
370                         break;
371                     }
372                     default:
373                         System.err.println("RawDataHandler not handled: " + fieldValue.as);
374                         break;
375
376                 }
377                 break;
378             }
379             case add:
380                 break;
381             case data:
382                 break;
383             default:
384                 throw new IllegalArgumentException();
385         }
386     }
387
388 }