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