Xcos load: use a valid port type value
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / io / sax / PortHandler.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
16 package org.scilab.modules.xcos.io.sax;
17
18 import java.util.ArrayList;
19
20 import org.scilab.modules.xcos.Kind;
21 import org.scilab.modules.xcos.ObjectProperties;
22 import org.scilab.modules.xcos.VectorOfInt;
23 import org.scilab.modules.xcos.VectorOfScicosID;
24 import org.scilab.modules.xcos.graph.model.ScicosObjectOwner;
25 import org.scilab.modules.xcos.graph.model.XcosCell;
26 import org.scilab.modules.xcos.io.HandledElement;
27 import org.scilab.modules.xcos.io.sax.XcosSAXHandler.UnresolvedReference;
28 import org.scilab.modules.xcos.port.BasicPort;
29 import org.scilab.modules.xcos.port.command.CommandPort;
30 import org.scilab.modules.xcos.port.control.ControlPort;
31 import org.scilab.modules.xcos.port.input.ExplicitInputPort;
32 import org.scilab.modules.xcos.port.input.ImplicitInputPort;
33 import org.scilab.modules.xcos.port.output.ExplicitOutputPort;
34 import org.scilab.modules.xcos.port.output.ImplicitOutputPort;
35 import org.xml.sax.Attributes;
36
37 class PortHandler implements ScilabHandler {
38
39     private final XcosSAXHandler shared;
40
41     /**
42      * Default constructor
43      * @param saxHandler the shared sax handler
44      */
45     PortHandler(XcosSAXHandler saxHandler) {
46         this.shared = saxHandler;
47     }
48
49     @Override
50     public BasicPort startElement(HandledElement found, Attributes atts) {
51         String v;
52         BasicPort port;
53         ObjectProperties relatedProperty;
54         boolean isImplicit;
55
56         /*
57          * First, check if the port has already been defined. Otherwise, create the object in the model
58          */
59         String strUID = atts.getValue("id");
60         long uid = 0;
61         if (strUID != null) {
62             if (shared.allChildren.peek().containsKey(strUID)) {
63                 uid = shared.allChildren.peek().get(strUID);
64             } else {
65                 uid = shared.controller.createObject(Kind.PORT);
66                 shared.allChildren.peek().put(strUID, uid);
67             }
68         }
69
70         String style = atts.getValue("style");
71         if (style != null) {
72             shared.controller.setObjectProperty(uid, Kind.PORT, ObjectProperties.STYLE, style);
73         }
74
75         String value = atts.getValue("value");
76         if (value != null &&  shared.validCIdentifier.matcher(value).matches()) {
77             shared.controller.setObjectProperty(uid, Kind.PORT, ObjectProperties.LABEL, value);
78         }
79
80         /*
81          * Allocate the port with the right class to set default properties
82          */
83
84         switch (found) {
85             case CommandPort:
86                 port = new CommandPort(shared.controller, uid, Kind.PORT, value, style, strUID);
87                 relatedProperty = ObjectProperties.EVENT_OUTPUTS;
88                 isImplicit = false;
89                 break;
90             case ControlPort:
91                 port = new ControlPort(shared.controller, uid, Kind.PORT, value, style, strUID);
92                 relatedProperty = ObjectProperties.EVENT_INPUTS;
93                 isImplicit = false;
94                 break;
95             case ExplicitInputPort:
96                 port = new ExplicitInputPort(shared.controller, uid, Kind.PORT, value, style, strUID);
97                 relatedProperty = ObjectProperties.INPUTS;
98                 isImplicit = false;
99                 break;
100             case ExplicitOutputPort:
101                 port = new ExplicitOutputPort(shared.controller, uid, Kind.PORT, value, style, strUID);
102                 relatedProperty = ObjectProperties.OUTPUTS;
103                 isImplicit = false;
104                 break;
105             case ImplicitInputPort:
106                 port = new ImplicitInputPort(shared.controller, uid, Kind.PORT, value, style, strUID);
107                 relatedProperty = ObjectProperties.INPUTS;
108                 isImplicit = true;
109                 break;
110             case ImplicitOutputPort:
111                 port = new ImplicitOutputPort(shared.controller, uid, Kind.PORT, value, style, strUID);
112                 relatedProperty = ObjectProperties.OUTPUTS;
113                 isImplicit = true;
114                 break;
115             default:
116                 throw new IllegalArgumentException();
117         }
118
119         /*
120          * Setup the properties
121          */
122         VectorOfInt datatype = new VectorOfInt();
123         shared.controller.getObjectProperty(uid, Kind.PORT, ObjectProperties.DATATYPE, datatype);
124
125         v = atts.getValue("dataType");
126         int intValue = BasicPort.DataType.REAL_MATRIX.asScilabValue();  // Magic default value, used in Scilab 5.x
127         if (v != null) {
128             intValue = BasicPort.DataType.valueOf(v).asScilabValue();
129         }
130         datatype.set(2, intValue);
131         intValue = -2; // Magic default value, used in Scilab 5.x
132         v = atts.getValue("dataColumns");
133         if (v != null) {
134             intValue = Integer.parseInt(v);
135         }
136         datatype.set(1, intValue);
137         intValue = -1; // Magic default value, used in Scilab 5.x
138         v = atts.getValue("dataLines");
139         if (v != null) {
140             intValue = Integer.parseInt(v);
141         }
142         datatype.set(0, intValue);
143
144         shared.controller.setObjectProperty(uid, Kind.PORT, ObjectProperties.DATATYPE, datatype);
145
146         v = atts.getValue("initialState");
147         if (v != null) {
148             shared.controller.setObjectProperty(uid, Kind.PORT, ObjectProperties.FIRING, Double.valueOf(v));
149         } else {
150             shared.controller.setObjectProperty(uid, Kind.PORT, ObjectProperties.FIRING, -1.0);
151         }
152
153         /*
154          * Associate to the parent block : now or later
155          */
156
157         int ordering = 0;
158         Long parent = 0l;
159
160         v = atts.getValue("ordering");
161         if (v != null) {
162             ordering = Integer.parseInt(v) - 1;
163         }
164
165         v = atts.getValue("parent");
166         if (v != null) {
167             parent = shared.allChildren.peek().get(v);
168
169             // if we can resolve the parent, then connect it directly
170             if (parent != null) {
171                 VectorOfScicosID associatedPorts = new VectorOfScicosID();
172                 shared.controller.getObjectProperty(parent, Kind.BLOCK, relatedProperty, associatedPorts);
173
174                 associatedPorts.resize(Math.max(associatedPorts.size(), ordering + 1));
175                 associatedPorts.set(ordering, uid);
176                 shared.controller.referenceObject(uid);
177
178                 shared.controller.setObjectProperty(uid, Kind.PORT, ObjectProperties.SOURCE_BLOCK, parent);
179                 shared.controller.setObjectProperty(parent, Kind.BLOCK, relatedProperty, associatedPorts);
180             } else {
181                 // resolve the parent later
182                 ArrayList<UnresolvedReference> refList = shared.unresolvedReferences.get(v);
183                 if (refList == null) {
184                     refList = new ArrayList<>();
185                     shared.unresolvedReferences.put(v, refList);
186                 }
187                 refList.add(new UnresolvedReference(new ScicosObjectOwner(uid, Kind.PORT), ObjectProperties.SOURCE_BLOCK, relatedProperty, ordering));
188             }
189         }
190
191         /*
192          * Associate to the link if possible (reverse linking)
193          */
194         v = atts.getValue("as");
195         if (v != null) {
196             ObjectProperties opposite = null;
197             if ("source".equals(v)) {
198                 opposite = ObjectProperties.SOURCE_PORT;
199             } else if ("target".equals(v)) {
200                 opposite = ObjectProperties.DESTINATION_PORT;
201             }
202
203             XcosCell cell = shared.lookupForParentXcosCellElement();
204             if (cell.getKind() == Kind.LINK) {
205                 shared.controller.setObjectProperty(cell.getUID(), cell.getKind(), opposite, port.getUID());
206                 shared.controller.setObjectProperty(port.getUID(), port.getKind(), ObjectProperties.CONNECTED_SIGNALS, cell.getUID());
207             }
208         }
209
210         return port;
211     }
212
213     @Override
214     public void endElement(HandledElement found) {
215     }
216 }