* Bug #15284 fixed: Port names are not set to the corresponding I/O block labels.
[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-2018 - 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 com.mxgraph.util.mxUtils;
28
29 import java.nio.DoubleBuffer;
30 import java.nio.LongBuffer;
31 import java.util.ArrayList;
32 import org.scilab.modules.xcos.VectorOfDouble;
33 import org.scilab.modules.xcos.VectorOfScicosID;
34
35 class JGraphXHandler implements ScilabHandler {
36
37     private final XcosSAXHandler saxHandler;
38
39     JGraphXHandler(XcosSAXHandler saxHandler) {
40         this.saxHandler = saxHandler;
41     }
42
43
44
45     @Override
46     public Object startElement(HandledElement found, Attributes atts) {
47         String v;
48
49         switch (found) {
50             case mxCell: {
51                 v = atts.getValue("parent");
52                 if (v != null) {
53                     long parentUID = saxHandler.allChildren.peek().getOrDefault(v, 0l);
54                     if (parentUID != 0) {
55                         return decodeCellAnnotation(parentUID, saxHandler.controller.getKind(parentUID), atts);
56                     }
57                 } else {
58                     Object parent = saxHandler.parents.peek();
59                     if (parent instanceof XcosCell) {
60                         XcosCell cell = ((XcosCell) parent);
61                         if (cell.getUID() != 0) {
62                             return decodeCellAnnotation(cell.getUID(), cell.getKind(), atts);
63                         }
64                     }
65                 }
66                 return null;
67             }
68             case mxGeometry: {
69                 mxGeometry g = new mxGeometry();
70
71                 v = atts.getValue("x");
72                 if (v != null) {
73                     g.setX(Double.valueOf(v));
74                 }
75                 v = atts.getValue("y");
76                 if (v != null) {
77                     g.setY(Double.valueOf(v));
78                 }
79                 v = atts.getValue("width");
80                 if (v != null) {
81                     g.setWidth(Double.valueOf(v));
82                 }
83                 v = atts.getValue("height");
84                 if (v != null) {
85                     g.setHeight(Double.valueOf(v));
86                 }
87
88                 /*
89                  * the MVC only store absolute values, resolve the "relative" geometry flag for Scilab 5.5.2 annotation
90                  */
91                 v = atts.getValue("relative");
92                 if (v != null && v.charAt(0) == '1') {
93                     Object parent = saxHandler.parents.peek();
94                     if (parent instanceof XcosCell) {
95                         XcosCell cell = (XcosCell) parent;
96                         long[] parentUID = {0};
97                         saxHandler.controller.getObjectProperty(cell.getUID(), cell.getKind(), ObjectProperties.RELATED_TO, parentUID);
98
99                         VectorOfDouble parentGeom = new VectorOfDouble(4);
100                         saxHandler.controller.getObjectProperty(parentUID[0], saxHandler.controller.getKind(parentUID[0]), ObjectProperties.GEOMETRY, parentGeom);
101                         g.setX(g.getX() * parentGeom.get(2));
102                         g.setY(g.getY() * parentGeom.get(3));
103                     }
104                 }
105
106                 return g;
107             }
108             case mxPoint: {
109                 mxPoint p = new mxPoint();
110
111                 v = atts.getValue("x");
112                 if (v != null) {
113                     p.setX(Double.valueOf(v));
114                 }
115                 v = atts.getValue("y");
116                 if (v != null) {
117                     p.setY(Double.valueOf(v));
118                 }
119
120                 Object localParent = saxHandler.parents.peek();
121                 if (localParent instanceof mxGeometry) {
122                     mxGeometry parent = (mxGeometry) localParent;
123                     v = atts.getValue("as");
124                     if ("sourcePoint".equals(v)) {
125                         parent.setSourcePoint(p);
126                     } else if ("targetPoint".equals(v)) {
127                         parent.setTargetPoint(p);
128                     }
129                 } else if (localParent instanceof RawDataHandler.RawDataDescriptor) {
130                     RawDataHandler.RawDataDescriptor parent = (RawDataHandler.RawDataDescriptor) localParent;
131                     ((ArrayList) parent.value).add(p);
132                 } else if (localParent instanceof XcosCell) {
133                     // Diagram origin, translate each children
134                     XcosCell parent = (XcosCell) localParent;
135
136                     VectorOfScicosID children = new VectorOfScicosID();
137                     saxHandler.controller.getObjectProperty(parent.getUID(), parent.getKind(), ObjectProperties.CHILDREN, children);
138
139                     VectorOfDouble geometry = new VectorOfDouble(4);
140                     DoubleBuffer geom = geometry.asByteBuffer(0, 4).asDoubleBuffer();
141
142                     LongBuffer childrenUIDs = children.asByteBuffer(0, children.size()).asLongBuffer();
143                     while (childrenUIDs.hasRemaining()) {
144                         long uid = childrenUIDs.get();
145                         Kind kind = saxHandler.controller.getKind(uid);
146
147                         saxHandler.controller.getObjectProperty(uid, kind, ObjectProperties.GEOMETRY, geometry);
148                         geom.put(0, geom.get(0) + p.getX());
149                         geom.put(1, geom.get(1) + p.getY());
150                         saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.GEOMETRY, geometry);
151
152                         // translate the annotation
153                         long[] annotation = { 0 };
154                         saxHandler.controller.getObjectProperty(uid, kind, ObjectProperties.LABEL, annotation);
155                         if (annotation[0] != 0) {
156                             saxHandler.controller.getObjectProperty(annotation[0], Kind.ANNOTATION, ObjectProperties.GEOMETRY, geometry);
157                             geom.put(0, geom.get(0) + p.getX());
158                             geom.put(1, geom.get(1) + p.getY());
159                             saxHandler.controller.setObjectProperty(annotation[0], Kind.ANNOTATION, ObjectProperties.GEOMETRY, geometry);
160                         }
161
162                         // translate control-points
163                         if (kind == Kind.LINK) {
164                             VectorOfDouble controlPoints = new VectorOfDouble();
165                             saxHandler.controller.getObjectProperty(uid, kind, ObjectProperties.CONTROL_POINTS, controlPoints);
166
167                             DoubleBuffer points = controlPoints.asByteBuffer(0, controlPoints.size()).asDoubleBuffer();
168                             for (int i = 0; i < controlPoints.size(); i += 2) {
169                                 points.put(i, points.get(i) + p.getX());
170                                 points.put(i + 1, points.get(i + 1) + p.getY());
171                             }
172                             saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.CONTROL_POINTS, controlPoints);
173                         }
174                     }
175
176                 }
177                 return p;
178             }
179             default:
180                 throw new IllegalArgumentException();
181         }
182     }
183
184     private XcosCell decodeCellAnnotation(long parentUID, Kind parentKind, Attributes atts) {
185         Kind kind = Kind.ANNOTATION;
186         final long uid = saxHandler.controller.createObject(kind);
187         String value = atts.getValue("value");
188         if (value != null) {
189             saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.DESCRIPTION, mxUtils.getBodyMarkup(value, false));
190         }
191         String style = atts.getValue("style");
192         if (style != null) {
193             saxHandler.controller.setObjectProperty(uid, kind, ObjectProperties.STYLE, style);
194         }
195         String id = atts.getValue("id");
196         if (id != null) {
197             saxHandler.allChildren.peek().put(id, uid);
198         }
199
200         XcosCell label = new XcosCell(saxHandler.controller, uid, kind, value, null, style, id);
201         saxHandler.controller.setObjectProperty(parentUID, parentKind, ObjectProperties.LABEL, label.getUID());
202         saxHandler.controller.setObjectProperty(label.getUID(), label.getKind(), ObjectProperties.RELATED_TO, parentUID);
203
204         return label;
205     }
206
207     @Override
208     public void endElement(HandledElement found) {
209         switch (found) {
210             case mxCell:
211                 break;
212             case mxGeometry: {
213                 // defensive programming
214                 if (!(saxHandler.parents.peek() instanceof mxGeometry)) {
215                     return;
216                 }
217                 mxGeometry g = (mxGeometry) saxHandler.parents.peek();
218                 if (!(saxHandler.parents.peek(1) instanceof XcosCell)) {
219                     return;
220                 }
221                 XcosCell cell = (XcosCell) saxHandler.parents.peek(1);
222
223                 cell.setGeometry(saxHandler.controller, g);
224             }
225             break;
226             case mxPoint:
227                 break;
228             default:
229                 throw new IllegalArgumentException();
230         }
231     }
232 }