Xcos: be compatible with Scilab 5.5.2 zcos files
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / io / writer / CustomWriter.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  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15 package org.scilab.modules.xcos.io.writer;
16
17 import java.rmi.server.UID;
18
19 import javax.xml.stream.XMLStreamException;
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.VectorOfScicosID;
26 import org.scilab.modules.xcos.Xcos;
27 import org.scilab.modules.xcos.graph.ScicosParameters;
28 import org.scilab.modules.xcos.io.HandledElement;
29
30 public class CustomWriter extends ScilabWriter {
31     private static final String SEP = " - ";
32
33     public CustomWriter(XcosWriter writer) {
34         super(writer);
35     }
36
37     @Override
38     public void write(long uid, Kind kind) throws XMLStreamException {
39         String[] str = new String[1];
40         int[] integer = new int[1];
41         VectorOfDouble vDouble = new VectorOfDouble();
42         VectorOfScicosID children = new VectorOfScicosID();
43
44         switch (kind) {
45             case DIAGRAM:
46                 shared.stream.writeStartDocument();
47                 shared.stream.writeStartElement(HandledElement.XcosDiagram.name());
48
49                 /*
50                  * Write diagram content
51                  */
52                 shared.controller.getObjectProperty(uid, kind, ObjectProperties.DEBUG_LEVEL, integer);
53                 shared.stream.writeAttribute("debugLevel", Integer.toString(integer[0]));
54
55                 // write simulation properties
56                 shared.controller.getObjectProperty(uid, kind, ObjectProperties.PROPERTIES, vDouble);
57                 String prop;
58
59                 prop = Double.toString(vDouble.get(ScicosParameters.FINAL_INTEGRATION_TIME));
60                 shared.stream.writeAttribute("finalIntegrationTime", prop);
61                 prop = Double.toString(vDouble.get(ScicosParameters.INTEGRATOR_ABSOLUTE_TOLERANCE));
62                 shared.stream.writeAttribute("integratorAbsoluteTolerance", prop);
63                 prop = Double.toString(vDouble.get(ScicosParameters.INTEGRATOR_RELATIVE_TOLERANCE));
64                 shared.stream.writeAttribute("integratorRelativeTolerance", prop);
65                 prop = Double.toString(vDouble.get(ScicosParameters.TOLERANCE_ON_TIME));
66                 shared.stream.writeAttribute("toleranceOnTime", prop);
67                 prop = Double.toString(vDouble.get(ScicosParameters.MAX_INTEGRATION_TIME_INTERVAL));
68                 shared.stream.writeAttribute("maxIntegrationTimeInterval", prop);
69                 prop = Double.toString(vDouble.get(ScicosParameters.MAXIMUM_STEP_SIZE));
70                 shared.stream.writeAttribute("maximumStepSize", prop);
71                 prop = Double.toString(vDouble.get(ScicosParameters.REAL_TIME_SCALING));
72                 shared.stream.writeAttribute("realTimeScaling", prop);
73                 prop = Double.toString(vDouble.get(ScicosParameters.SOLVER));
74                 shared.stream.writeAttribute("solver", prop);
75
76                 // write the graphical part and children
77                 shared.controller.getObjectProperty(uid, kind, ObjectProperties.CHILDREN, children);
78                 String zeroUID = new UID((short) 0).toString();
79                 shared.uniqueUIDs.add(zeroUID);
80                 writeDiagramAndSuperDiagramContent(uid, kind, children, zeroUID);
81
82                 shared.stream.writeEndElement();
83                 shared.stream.writeEndDocument();
84
85                 // post processing for binary data handling
86                 shared.rawDataWriter.fillSharedDictionary();
87                 break;
88             case BLOCK:
89                 shared.controller.getObjectProperty(uid, kind, ObjectProperties.CHILDREN, children);
90                 if (children.size() > 0) {
91                     shared.stream.writeStartElement(HandledElement.SuperBlockDiagram.name());
92                     shared.stream.writeAttribute("as", "child");
93                     writeDiagramAndSuperDiagramContent(uid, kind, children, shared.layers.peek());
94                     shared.stream.writeEndElement(); // SuperBlockDiagram
95                 }
96                 break;
97             case PORT:
98                 // the orientation is not encoded on the model but propagated inside the style
99                 break;
100             default:
101                 break;
102         }
103     }
104
105     private void writeDiagramAndSuperDiagramContent(long uid, Kind kind, VectorOfScicosID children, String parentUID) throws XMLStreamException {
106         VectorOfInt colors = new VectorOfInt();
107         shared.controller.getObjectProperty(uid, kind, ObjectProperties.COLOR, colors);
108         shared.stream.writeAttribute("background", Integer.toString(colors.get(0)));
109         shared.stream.writeAttribute("gridEnabled", Integer.toString(colors.get(1)));
110
111         String[] str = new String[1];
112         shared.controller.getObjectProperty(uid, kind, ObjectProperties.TITLE, str);
113         shared.stream.writeAttribute("title", str[0]);
114
115         /*
116          * Add a version comment at the top layer
117          */
118         if (kind == Kind.DIAGRAM) {
119             final Package p = Package.getPackage("org.scilab.modules.xcos");
120             String comment = new StringBuilder().append(Xcos.TRADENAME).append(SEP).append(Xcos.VERSION).append(SEP)
121             .append(p.getSpecificationVersion()).append(SEP).append(p.getImplementationVersion()).toString();
122             shared.stream.writeComment(comment);
123         }
124
125         /*
126          * encode some content then the children
127          */
128         shared.rawDataWriter.write(uid, kind);
129
130         /*
131          * Generate uniques but predictables UIDs
132          */
133         String[] parent = parentUID.split(":");
134         long uidCounter = 1;
135         String rootUID = parent[0] + ":" + Long.toString(Long.parseLong(parent[1], 16) + uidCounter, 16) + ":" + parent[2];
136         for (; shared.uniqueUIDs.contains(rootUID); uidCounter++) {
137             rootUID = parent[0] + ":" + Long.toString(Long.parseLong(parent[1], 16) + uidCounter, 16) + ":" + parent[2];
138         }
139         shared.uniqueUIDs.add(rootUID);
140         String layerUID = parent[0] + ":" + Long.toString(Long.parseLong(parent[1], 16) + uidCounter, 16) + ":" + parent[2];
141         for (; shared.uniqueUIDs.contains(layerUID); uidCounter++) {
142             layerUID = parent[0] + ":" + Long.toString(Long.parseLong(parent[1], 16) + uidCounter, 16) + ":" + parent[2];
143         }
144         shared.uniqueUIDs.add(layerUID);
145         shared.layers.push(layerUID);
146
147         // children header
148         shared.stream.writeStartElement("mxGraphModel");
149         shared.stream.writeAttribute("as", "model");
150         shared.stream.writeStartElement("root");
151         shared.stream.writeEmptyElement("mxCell");
152         shared.stream.writeAttribute("id", rootUID);
153         shared.stream.writeEmptyElement("mxCell");
154         shared.stream.writeAttribute("id", layerUID);
155         shared.stream.writeAttribute("parent", rootUID);
156
157         // loop on all children, encode the blocks and ports then the links
158         VectorOfInt kinds = new VectorOfInt();
159         shared.controller.sortAndFillKind(children, kinds);
160
161         final int len = children.size();
162         for (int i = 0; i < len; i++) {
163             long child = children.get(i);
164             Kind childKind = Kind.values()[kinds.get(i)];
165             shared.write(child, childKind);
166         }
167
168         shared.layers.pop();
169         shared.stream.writeEndElement(); // root
170         shared.stream.writeEndElement(); // mxGraphModel
171         shared.stream.writeEmptyElement("mxCell");
172         shared.stream.writeAttribute("as", "defaultParent");
173         shared.stream.writeAttribute("id", layerUID);
174         shared.stream.writeAttribute("parent", rootUID);
175     }
176 }