Xcos save/load: manage dep_ut values
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / io / writer / BlockWriter.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 import java.util.EnumSet;
19
20 import javax.xml.stream.XMLStreamException;
21
22 import org.scilab.modules.xcos.Kind;
23 import org.scilab.modules.xcos.ObjectProperties;
24 import org.scilab.modules.xcos.VectorOfInt;
25 import org.scilab.modules.xcos.VectorOfScicosID;
26 import org.scilab.modules.xcos.block.BasicBlock;
27 import org.scilab.modules.xcos.block.BasicBlock.SimulationFunctionType;
28 import org.scilab.modules.xcos.graph.model.BlockInterFunction;
29 import org.scilab.modules.xcos.graph.model.XcosCellFactory;
30
31 public class BlockWriter extends ScilabWriter {
32
33     public BlockWriter(XcosWriter writer) {
34         super(writer);
35     }
36
37     @Override
38     public void write(long uid, Kind kind) throws XMLStreamException {
39         // Lookup for the element name
40         String[] interfaceFunction = new String[1];
41         BlockInterFunction interFunction;
42         if (kind == Kind.BLOCK) {
43             shared.controller.getObjectProperty(uid, kind, ObjectProperties.INTERFACE_FUNCTION, interfaceFunction);
44             interFunction = XcosCellFactory.lookForInterfunction(interfaceFunction[0]);
45         } else {
46             interfaceFunction[0] = BlockInterFunction.TEXT_f.name();
47             interFunction = BlockInterFunction.TEXT_f;
48         }
49
50         shared.stream.writeStartElement(interFunction.getKlass().getSimpleName());
51
52         String[] v = new String[1];
53
54         shared.controller.getObjectProperty(uid, kind, ObjectProperties.UID, v);
55         while (isInvalidUID(v[0])) {
56             v[0] = new UID().toString();
57         }
58         shared.controller.setObjectProperty(uid, kind, ObjectProperties.UID, v[0]);
59         shared.stream.writeAttribute("id", v[0]);
60         shared.stream.writeAttribute("parent", shared.layers.peek());
61         shared.layers.push(v[0]);
62
63         shared.stream.writeAttribute("interfaceFunctionName", interfaceFunction[0]);
64
65         if (kind == Kind.BLOCK) {
66             shared.controller.getObjectProperty(uid, kind, ObjectProperties.SIM_BLOCKTYPE, v);
67             shared.stream.writeAttribute("blockType", v[0]);
68
69             VectorOfInt vecOfInt = new VectorOfInt(2);
70             shared.controller.getObjectProperty(uid, kind, ObjectProperties.SIM_DEP_UT, vecOfInt);
71             shared.stream.writeAttribute("dependsOnU", Integer.toString(vecOfInt.get(0)));
72             shared.stream.writeAttribute("dependsOnT", Integer.toString(vecOfInt.get(1)));
73
74             shared.controller.getObjectProperty(uid, kind, ObjectProperties.SIM_FUNCTION_NAME, v);
75             shared.stream.writeAttribute("simulationFunctionName", v[0]);
76
77             int[] functionAPI = new int[1];
78             shared.controller.getObjectProperty(uid, kind, ObjectProperties.SIM_FUNCTION_API, functionAPI);
79             SimulationFunctionType type = BasicBlock.SimulationFunctionType.convertScilabValue(functionAPI[0]);
80             shared.stream.writeAttribute("simulationFunctionType", type.name());
81         }
82
83         shared.controller.getObjectProperty(uid, kind, ObjectProperties.STYLE, v);
84         shared.stream.writeAttribute("style", v[0]);
85
86         shared.controller.getObjectProperty(uid, kind, ObjectProperties.DESCRIPTION, v);
87         if (!v[0].isEmpty()) {
88             // remove any '\n' character that will not be preserved by the XML Handlers on re-load
89             String escaped = v[0].replace('\n', ' ');
90             shared.stream.writeAttribute("value", escaped);
91         }
92
93         // delegate the sub-elements to their writers
94         shared.rawDataWriter.write(uid, kind);
95         new JGraphXWriter(shared).write(uid, kind);
96         new CustomWriter(shared).write(uid, kind);
97
98         shared.stream.writeEndElement(); // Block name
99
100         /*
101          * We serialize the ports on the inner layer but close it before to
102          * have a flat object view per diagram, this is Scilab 5 compatible.
103          */
104
105         // serialize the ports after the block
106         VectorOfScicosID ports = new VectorOfScicosID();
107         final EnumSet<ObjectProperties> portKind = EnumSet.of(ObjectProperties.INPUTS, ObjectProperties.OUTPUTS,
108                 ObjectProperties.EVENT_INPUTS, ObjectProperties.EVENT_OUTPUTS);
109         for (ObjectProperties p : portKind) {
110             shared.controller.getObjectProperty(uid, kind, p, ports);
111             PortWriter portWriter = new PortWriter(shared, p);
112
113             final int length = ports.size();
114             for (int i = 0; i < length; i++) {
115                 portWriter.write(ports.get(i), Kind.PORT);
116             }
117         }
118
119         shared.layers.pop();
120     }
121
122     private boolean isInvalidUID(String uid) {
123         if (uid.isEmpty()) {
124             return true;
125         }
126         if (shared.uniqueUIDs.contains(uid)) {
127             return true;
128         }
129
130         // more advanced check to remove non-generated UID without loosing performance
131         // a valid one is in the form : "-5151d0b0:12dcdfdd360:-7fff"
132         if (3 < uid.length() && uid.length() < 28) {
133             // more costly operations there but there is no allocation
134             int firstSep = uid.indexOf(':', 0);
135             if (firstSep <= 0) {
136                 return true;
137             }
138
139             int secondSep = uid.indexOf(':', firstSep + 1);
140             if (secondSep <= firstSep + 1) {
141                 return true;
142             }
143
144             return false;
145         } else {
146             return true;
147         }
148     }
149
150
151
152
153 }