001package jmri.jmrix.acela.serialdriver.configurexml;
002
003import java.util.List;
004import jmri.jmrix.acela.AcelaNode;
005import jmri.jmrix.acela.AcelaSystemConnectionMemo;
006import jmri.jmrix.acela.AcelaTrafficController;
007import jmri.jmrix.acela.serialdriver.ConnectionConfig;
008import jmri.jmrix.acela.serialdriver.SerialDriverAdapter;
009import jmri.jmrix.configurexml.AbstractSerialConnectionConfigXml;
010import org.jdom2.Element;
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014/**
015 * Handle XML persistance of layout connections by persistening the
016 * SerialDriverAdapter (and connections). Note this is named as the XML version
017 * of a ConnectionConfig object, but it's actually persisting the
018 * SerialDriverAdapter.
019 * <p>
020 * This class is invoked from jmrix.JmrixConfigPaneXml on write, as that class
021 * is the one actually registered. Reads are brought here directly via the class
022 * attribute in the XML.
023 *
024 * @author Bob Jacobsen Copyright: Copyright (c) 2003
025 * @author Bob Coleman, Copyright (c) 2007, 2008 Based on CMRI serial example,
026 * modified to establish Acela support.
027 */
028public class ConnectionConfigXml extends AbstractSerialConnectionConfigXml {
029
030    public ConnectionConfigXml() {
031        super();
032    }
033 
034    /**
035     * Write out the SerialNode objects too
036     *
037     * @param e Element being extended
038     */
039    @Override
040    protected void extendElement(Element e) {
041        AcelaTrafficController tc = ((AcelaSystemConnectionMemo) adapter.getSystemConnectionMemo()).getTrafficController();
042        AcelaNode node = (AcelaNode) tc.getNode(0);
043        int index = 1;
044        while (node != null) {
045            // add node as an element
046            Element n = new Element("node");
047            n.setAttribute("name", "" + node.getNodeAddress());
048            e.addContent(n);
049            // add parameters to the node as needed
050            n.addContent(makeParameter("nodetype", "" + node.getNodeTypeString()));
051            if (node.getNodeType() == AcelaNode.TB) {
052                for (int s = 0; s < 4; s++) {
053                    n.addContent(makeParameter("sensortype" + s, "" + node.getSensorTypeString(s)));
054                    n.addContent(makeParameter("sensorpolarity" + s, "" + node.getSensorPolarityString(s)));
055                    n.addContent(makeParameter("sensorthreshold" + s, "" + node.getSensorThreshold(s)));
056                }
057                for (int o = 0; o < 4; o++) {
058                    n.addContent(makeParameter("outputwired" + o, "" + node.getOutputWiredString(o)));
059                    n.addContent(makeParameter("outputinit" + o, "" + node.getOutputInitString(o)));
060                    n.addContent(makeParameter("outputtype" + o, "" + node.getOutputTypeString(o)));
061                    n.addContent(makeParameter("outputlength" + o, "" + node.getOutputLength(o)));
062                }
063            } else if (node.getNodeType() == AcelaNode.D8) {
064                for (int o = 0; o < 8; o++) {
065                    n.addContent(makeParameter("outputwired" + o, "" + node.getOutputWiredString(o)));
066                    n.addContent(makeParameter("outputinit" + o, "" + node.getOutputInitString(o)));
067                    n.addContent(makeParameter("outputtype" + o, "" + node.getOutputTypeString(o)));
068                    n.addContent(makeParameter("outputlength" + o, "" + node.getOutputLength(o)));
069                }
070            } else if (node.getNodeType() == AcelaNode.WM) {
071                for (int s = 0; s < 8; s++) {
072                    n.addContent(makeParameter("sensortype" + s, "" + node.getSensorTypeString(s)));
073                    n.addContent(makeParameter("sensorpolarity" + s, "" + node.getSensorPolarityString(s)));
074                    n.addContent(makeParameter("sensorthreshold" + s, "" + node.getSensorThreshold(s)));
075                }
076            } else if (node.getNodeType() == AcelaNode.SM) {
077                for (int o = 0; o < 16; o++) {
078                    n.addContent(makeParameter("outputwired" + o, "" + node.getOutputWiredString(o)));
079                    n.addContent(makeParameter("outputinit" + o, "" + node.getOutputInitString(o)));
080                    n.addContent(makeParameter("outputtype" + o, "" + node.getOutputTypeString(o)));
081                    n.addContent(makeParameter("outputlength" + o, "" + node.getOutputLength(o)));
082                }
083            } else if (node.getNodeType() == AcelaNode.SW) {
084                for (int o = 0; o < 16; o++) {
085                    n.addContent(makeParameter("outputwired" + o, "" + node.getOutputWiredString(o)));
086                    n.addContent(makeParameter("outputinit" + o, "" + node.getOutputInitString(o)));
087                    n.addContent(makeParameter("outputtype" + o, "" + node.getOutputTypeString(o)));
088                    n.addContent(makeParameter("outputlength" + o, "" + node.getOutputLength(o)));
089                }
090            } else if (node.getNodeType() == AcelaNode.YM) {
091                for (int o = 0; o < 16; o++) {
092                    n.addContent(makeParameter("outputwired" + o, "" + node.getOutputWiredString(o)));
093                    n.addContent(makeParameter("outputinit" + o, "" + node.getOutputInitString(o)));
094                    n.addContent(makeParameter("outputtype" + o, "" + node.getOutputTypeString(o)));
095                    n.addContent(makeParameter("outputlength" + o, "" + node.getOutputLength(o)));
096                }
097            } else if (node.getNodeType() == AcelaNode.SY) {
098                for (int s = 0; s < 16; s++) {
099                    n.addContent(makeParameter("sensortype" + s, "" + node.getSensorTypeString(s)));
100                    n.addContent(makeParameter("sensorpolarity" + s, "" + node.getSensorPolarityString(s)));
101                    n.addContent(makeParameter("sensorthreshold" + s, "" + node.getSensorThreshold(s)));
102                }
103            }
104            // look for the next node
105            node = (AcelaNode) tc.getNode(index);
106            index++;
107        }
108    }
109
110    protected Element makeParameter(String name, String value) {
111        Element p = new Element("parameter");
112        p.setAttribute("name", name);
113        p.addContent(value);
114        return p;
115    }
116
117    @Override
118    protected void unpackElement(Element shared, Element perNode) {
119        List<Element> l = shared.getChildren("node");
120        for (int i = 0; i < l.size(); i++) {
121            Element n = l.get(i);
122            int addr = Integer.parseInt(n.getAttributeValue("name"));
123            String nodetypestring = findParmValue(n, "nodetype");
124            int type = AcelaNode.moduleTypes.lastIndexOf(nodetypestring) / 2;
125
126            // create node (they register themselves)
127            AcelaNode node = new AcelaNode(addr, type, ((jmri.jmrix.acela.serialdriver.SerialDriverAdapter) adapter).getSystemConnectionMemo().getTrafficController());
128            log.info("Created a new Acela Node [{}] as a result of a configuration file of type: {}", addr, type);
129
130            if (type == AcelaNode.TB) {
131                for (int s = 0; s < 4; s++) {
132                    String sensortype = findParmValue(n, "sensortype" + s);
133                    String sensorpolarity = findParmValue(n, "sensorpolarity" + s);
134                    int sensorthreshold = Integer.parseInt(findParmValue(n, "sensorthreshold" + s));
135                    node.setSensorTypeString(s, sensortype);
136                    node.setSensorPolarityString(s, sensorpolarity);
137
138                    if (sensorthreshold < 0) {
139                        sensorthreshold = 0;
140                    }
141                    if (sensorthreshold > 31) {
142                        sensorthreshold = 31;
143                    }
144                    node.setSensorThreshold(s, sensorthreshold);
145
146                }
147                for (int o = 0; o < 4; o++) {
148                    String outputwired = findParmValue(n, "outputwired" + o);
149                    String outputinit = findParmValue(n, "outputinit" + o);
150                    String outputtype = findParmValue(n, "outputtype" + o);
151                    String outputlengths = findParmValue(n, "outputlength" + o);
152                    // This can be removed in June 2010:
153                    if (outputlengths == null) {
154                        outputlengths = AcelaNode.outputLEN0;
155                    }
156                    int outputlength = Integer.parseInt(outputlengths);
157                    node.setOutputWiredString(o, outputwired);
158                    node.setOutputInitString(o, outputinit);
159                    // This can be removed in June 2010:
160                    if (outputtype == null) {
161                        outputtype = AcelaNode.outputONOFF;
162                    }
163                    node.setOutputTypeString(o, outputtype);
164                    if (outputlength < 0) {
165                        outputlength = 0;
166                    }
167                    if (outputlength > 255) {
168                        outputlength = 255;
169                    }
170                    node.setOutputLength(o, outputlength);
171                }
172            } else if (type == AcelaNode.D8) {
173                for (int o = 0; o < 8; o++) {
174                    String outputwired = findParmValue(n, "outputwired" + o);
175                    String outputinit = findParmValue(n, "outputinit" + o);
176                    String outputtype = findParmValue(n, "outputtype" + o);
177                    String outputlengths = findParmValue(n, "outputlength" + o);
178                    // This can be removed in June 2010:
179                    if (outputlengths == null) {
180                        outputlengths = AcelaNode.outputLEN0;
181                    }
182                    int outputlength = Integer.parseInt(outputlengths);
183                    node.setOutputWiredString(o, outputwired);
184                    node.setOutputInitString(o, outputinit);
185                    // This can be removed in June 2010:
186                    if (outputtype == null) {
187                        outputtype = AcelaNode.outputONOFF;
188                    }
189                    node.setOutputTypeString(o, outputtype);
190                    if (outputlength < 0) {
191                        outputlength = 0;
192                    }
193                    if (outputlength > 255) {
194                        outputlength = 255;
195                    }
196                    node.setOutputLength(o, outputlength);
197                }
198            } else if (type == AcelaNode.WM) {
199                for (int s = 0; s < 8; s++) {
200                    String sensortype = findParmValue(n, "sensortype" + s);
201                    String sensorpolarity = findParmValue(n, "sensorpolarity" + s);
202                    int sensorthreshold = Integer.parseInt(findParmValue(n, "sensorthreshold" + s));
203                    node.setSensorTypeString(s, sensortype);
204                    node.setSensorPolarityString(s, sensorpolarity);
205
206                    if (sensorthreshold < 0) {
207                        sensorthreshold = 0;
208                    }
209                    if (sensorthreshold > 31) {
210                        sensorthreshold = 31;
211                    }
212                    node.setSensorThreshold(s, sensorthreshold);
213
214                }
215            } else if (type == AcelaNode.SM) {
216                for (int o = 0; o < 16; o++) {
217                    String outputwired = findParmValue(n, "outputwired" + o);
218                    // This can be removed in June 2010:
219                    if (outputwired == null) {
220                        outputwired = AcelaNode.outputNO;
221                    }
222                    String outputinit = findParmValue(n, "outputinit" + o);
223                    String outputtype = findParmValue(n, "outputtype" + o);
224                    String outputlengths = findParmValue(n, "outputlength" + o);
225                    // This can be removed in June 2010:
226                    if (outputlengths == null) {
227                        outputlengths = AcelaNode.outputLEN0;
228                    }
229                    int outputlength = Integer.parseInt(outputlengths);
230                    node.setOutputInitString(o, outputinit);
231                    // This can be removed in June 2010:
232                    if (outputtype == null) {
233                        outputtype = AcelaNode.outputONOFF;
234                    }
235                    node.setOutputTypeString(o, outputtype);
236                    if (outputlength < 0) {
237                        outputlength = 0;
238                    }
239                    if (outputlength > 255) {
240                        outputlength = 255;
241                    }
242                    node.setOutputLength(o, outputlength);
243                }
244            } else if (type == AcelaNode.SW) {
245                for (int o = 0; o < 16; o++) {
246                    String outputwired = findParmValue(n, "outputwired" + o);
247                    // This can be removed in June 2010:
248                    if (outputwired == null) {
249                        outputwired = AcelaNode.outputNO;
250                    }
251                    String outputinit = findParmValue(n, "outputinit" + o);
252                    String outputtype = findParmValue(n, "outputtype" + o);
253                    String outputlengths = findParmValue(n, "outputlength" + o);
254                    // This can be removed in June 2010:
255                    if (outputlengths == null) {
256                        outputlengths = AcelaNode.outputLEN0;
257                    }
258                    int outputlength = Integer.parseInt(outputlengths);
259                    node.setOutputInitString(o, outputinit);
260                    // This can be removed in June 2010:
261                    if (outputtype == null) {
262                        outputtype = AcelaNode.outputONOFF;
263                    }
264                    node.setOutputTypeString(o, outputtype);
265                    if (outputlength < 0) {
266                        outputlength = 0;
267                    }
268                    if (outputlength > 255) {
269                        outputlength = 255;
270                    }
271                    node.setOutputLength(o, outputlength);
272                }
273            } else if (type == AcelaNode.YM) {
274                for (int o = 0; o < 16; o++) {
275                    String outputwired = findParmValue(n, "outputwired" + o);
276                    // This can be removed in June 2010:
277                    if (outputwired == null) {
278                        outputwired = AcelaNode.outputNO;
279                    }
280                    String outputinit = findParmValue(n, "outputinit" + o);
281                    String outputtype = findParmValue(n, "outputtype" + o);
282                    String outputlengths = findParmValue(n, "outputlength" + o);
283                    // This can be removed in June 2010:
284                    if (outputlengths == null) {
285                        outputlengths = AcelaNode.outputLEN0;
286                    }
287                    int outputlength = Integer.parseInt(outputlengths);
288                    node.setOutputInitString(o, outputinit);
289                    // This can be removed in June 2010:
290                    if (outputtype == null) {
291                        outputtype = AcelaNode.outputONOFF;
292                    }
293                    node.setOutputTypeString(o, outputtype);
294                    if (outputlength < 0) {
295                        outputlength = 0;
296                    }
297                    if (outputlength > 255) {
298                        outputlength = 255;
299                    }
300                    node.setOutputLength(o, outputlength);
301                }
302            } else if (type == AcelaNode.SY) {
303                for (int s = 0; s < 16; s++) {
304                    String sensortype = findParmValue(n, "sensortype" + s);
305                    String sensorpolarity = findParmValue(n, "sensorpolarity" + s);
306                    int sensorthreshold = Integer.parseInt(findParmValue(n, "sensorthreshold" + s));
307                    node.setSensorTypeString(s, sensortype);
308                    node.setSensorPolarityString(s, sensorpolarity);
309
310                    if (sensorthreshold < 0) {
311                        sensorthreshold = 0;
312                    }
313                    if (sensorthreshold > 31) {
314                        sensorthreshold = 31;
315                    }
316                    node.setSensorThreshold(s, sensorthreshold);
317
318                }
319            }
320
321            AcelaTrafficController tc = ((AcelaSystemConnectionMemo) adapter.getSystemConnectionMemo()).getTrafficController();
322            // Do not poll for Acela network nodes
323            tc.setNeedToPollNodes(false);
324
325            // Trigger initialization of this Node to reflect these parameters
326            tc.initializeAcelaNode(node);
327        }
328        // Do not let the Acela network poll until we are really ready
329        ((AcelaSystemConnectionMemo) adapter.getSystemConnectionMemo()).getTrafficController().setReallyReadyToPoll(true);
330    }
331
332    @Override
333    protected void getInstance() {
334        if (adapter == null) {
335            adapter = new SerialDriverAdapter();
336        }
337    }
338
339    @Override
340    protected void getInstance(Object object) {
341        adapter = ((ConnectionConfig) object).getAdapter();
342    }
343
344    @Override
345    protected void register() {
346        this.register(new ConnectionConfig(adapter));
347    }
348
349    // initialize logging
350    private final static Logger log = LoggerFactory.getLogger(ConnectionConfigXml.class);
351
352}