2ccc5d80876de1d306f912d8a65a8f3e0f4e9ffe
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / io / sax / JGraphXHandler.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2015-2017 - Scilab Enterprises - Clement DAVID
4  * Copyright (C) 2017 - ESI Group - Clement DAVID
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17 package org.scilab.modules.xcos.io.sax;
18
19 import org.scilab.modules.xcos.Kind;
20 import org.scilab.modules.xcos.ObjectProperties;
21 import org.scilab.modules.xcos.graph.model.XcosCell;
22 import org.scilab.modules.xcos.io.HandledElement;
23 import org.xml.sax.Attributes;
24
25 import com.mxgraph.model.mxGeometry;
26 import com.mxgraph.util.mxPoint;
27 import java.nio.DoubleBuffer;
28 import java.nio.LongBuffer;
29 import java.util.ArrayList;
30 import org.scilab.modules.xcos.VectorOfDouble;
31 import org.scilab.modules.xcos.VectorOfScicosID;
32
33 class JGraphXHandler implements ScilabHandler {
34
35     private final XcosSAXHandler saxHandler;
36
37     JGraphXHandler(XcosSAXHandler saxHandler) {
38         this.saxHandler = saxHandler;
39     }
40
41
42
43     @Override
44     public Object startElement(HandledElement found, Attributes atts) {
45         String v;
46
47         switch (found) {
48             case mxCell: {
49                 v = atts.getValue("parent");
50                 if (v != null) {
51                     long parentUID = saxHandler.allChildren.peek().getOrDefault(v, 0l);
52                     if (parentUID != 0) {
53                         return decodeCellAnnotation(parentUID, saxHandler.controller.getKind(parentUID), atts);
54                     }
55                 } else {
56                     Object parent = saxHandler.parents.peek();
57                     if (parent instanceof XcosCell) {
58                         XcosCell cell = ((XcosCell) parent);
59                         if (cell.getUID() != 0) {
60                             return decodeCellAnnotation(cell.getUID(), cell.getKind(), atts);
61                         }
62                     }
63                 }
64                 return null;
65             }
66             case mxGeometry: {
67                 mxGeometry g = new mxGeometry();
68
69                 v = atts.getValue("x");
70                 if (v != null) {
71                     g.setX(Double.valueOf(v));
72                 }
73                 v = atts.getValue("y");
74                 if (v != null) {
75                     g.setY(Double.valueOf(v));
76                 }
77                 v = atts.getValue("width");
78                 if (v != null) {
79                     g.setWidth(Double.valueOf(v));
80                 }
81                 v = atts.getValue("height");
82                 if (v != null) {
83                     g.setHeight(Double.valueOf(v));
84                 }
85
86                 /*
87                  * the MVC only store absolute values, resolve the "relative" geometry flag for Scilab 5.5.2 annotation
88                  */
89                 v = atts.getValue("relative");
90                 if (v != null && v.charAt(0) == '1') {
91                     Object parent = saxHandler.parents.peek();
92                     if (parent instanceof XcosCell) {
93                         XcosCell cell = (XcosCell) parent;
94                         long[] parentUID = {0};
95                         saxHandler.controller.getObjectProperty(cell.getUID(), cell.getKind(), ObjectProperties.RELATED_TO, parentUID);
96
97                         VectorOfDouble parentGeom = new VectorOfDouble(4);
98                         saxHandler.controller.getObjectProperty(parentUID[0], saxHandler.controller.getKind(parentUID[0]), ObjectProperties.GEOMETRY, parentGeom);
99                         g.setX(parentGeom.get(0) + g.getX() * parentGeom.get(2));
100                         g.setY(parentGeom.get(1) + g.getY() * parentGeom.get(3));
101                     }
102                 }
103
104                 return g;
105             }
106             case mxPoint: {
107                 mxPoint p = new mxPoint();
108
109                 v = atts.getValue("x");
110                 if (v != null) {
111                     p.setX(Double.valueOf(v));
112                 }
113                 v = atts.getValue("y");
114                 if (v != null) {
115                     p.setY(Double.valueOf(v));
116                 }
117
118                 Object localParent = saxHandler.parents.peek();
119                 if (localParent instanceof mxGeometry) {
120                     mxGeometry parent = (mxGeometry) localParent;
121                     v = atts.getValue("as");
122                     if ("sourcePoint".equals(v)) {
123                         parent.setSourcePoint(p);
124                     } else if ("targetPoint".equals(v)) {
125                         parent.setTargetPoint(p);
126                     }
127                 } else if (localParent instanceof RawDataHandler.RawDataDescriptor) {
128                     RawDataHandler.RawDataDescriptor parent = (RawDataHandler.RawDataDescriptor) localParent;
129                     ((ArrayList) parent.value).add(p);
130                 } else if (localParent instanceof XcosCell) {
131                     // Diagram origin, translate each children
132                     XcosCell parent = (XcosCell) localParent;
133
134                     VectorOfScicosID children = new VectorOfScicosID();
135                     saxHandler.controller.getObjectProperty(parent.getUID(), parent.getKind(), ObjectProperties.CHILDREN, children);
136
137                     VectorOfDouble geometry = new VectorOfDouble(4);
138                     DoubleBuffer geom = geometry.asByteBuffer(0, 4).asDoubleBuffer();
139
140                     LongBuffer childrenUIDs = children.asByteBuffer(0, children.size()).asLongBuffer();
141                     while (childrenUIDs.hasRemaining()) {
142                         long uid = childrenUIDs.get();
143                         Kind kind = saxHandler.controller.getKind(uid);
144
145                         saxHandler.controller.getObjectProperty(uid, kind, ObjectProperties.GEOMETRY, geometry);
146                         geom.put(0, geom.get(0) + p.getX());
147                         geom.put(1, geom.get(1) + p.getY());
148                         saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.GEOMETRY, geometry);
149
150                         // translate the annotation
151                         long[] annotation = { 0 };
152                         saxHandler.controller.getObjectProperty(uid, kind, ObjectProperties.LABEL, annotation);
153                         if (annotation[0] != 0) {
154                             saxHandler.controller.getObjectProperty(annotation[0], Kind.ANNOTATION, ObjectProperties.GEOMETRY, geometry);
155                             geom.put(0, geom.get(0) + p.getX());
156                             geom.put(1, geom.get(1) + p.getY());
157                             saxHandler.controller.setObjectProperty(annotation[0], Kind.ANNOTATION, ObjectProperties.GEOMETRY, geometry);
158                         }
159                     }
160
161                 }
162                 return p;
163             }
164             default:
165                 throw new IllegalArgumentException();
166         }
167     }
168
169     private XcosCell decodeCellAnnotation(long parentUID, Kind parentKind, Attributes atts) {
170         Kind kind = Kind.ANNOTATION;
171         final long uid = saxHandler.controller.createObject(kind);
172         String value = atts.getValue("value");
173         if (value != null) {
174             saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.DESCRIPTION, value);
175         }
176         String style = atts.getValue("style");
177         if (style != null) {
178             saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.STYLE, style);
179         }
180         String id = atts.getValue("id");
181         if (id != null) {
182             saxHandler.allChildren.peek().put(id, uid);
183         }
184
185         XcosCell label = new XcosCell(saxHandler.controller, uid, kind, value, null, style, id);
186         saxHandler.controller.setObjectProperty(parentUID, parentKind, ObjectProperties.LABEL, label.getUID());
187         saxHandler.controller.setObjectProperty(label.getUID(), label.getKind(), ObjectProperties.RELATED_TO, parentUID);
188
189         return label;
190     }
191
192     @Override
193     public void endElement(HandledElement found) {
194         switch (found) {
195             case mxCell:
196                 break;
197             case mxGeometry: {
198                 // defensive programming
199                 if (!(saxHandler.parents.peek() instanceof mxGeometry)) {
200                     return;
201                 }
202                 mxGeometry g = (mxGeometry) saxHandler.parents.peek();
203                 if (!(saxHandler.parents.peek(1) instanceof XcosCell)) {
204                     return;
205                 }
206                 XcosCell cell = (XcosCell) saxHandler.parents.peek(1);
207
208                 cell.setGeometry(saxHandler.controller, g);
209             }
210             break;
211             case mxPoint:
212                 break;
213             default:
214                 throw new IllegalArgumentException();
215         }
216     }
217 }