001package jmri.jmrix.cmri.serial.networkdriver.configurexml;
002
003import java.util.List;
004import jmri.jmrix.cmri.CMRISystemConnectionMemo;
005import jmri.jmrix.cmri.serial.SerialNode;
006import jmri.jmrix.cmri.serial.SerialTrafficController;
007import jmri.jmrix.cmri.serial.networkdriver.ConnectionConfig;
008import jmri.jmrix.cmri.serial.networkdriver.NetworkDriverAdapter;
009import jmri.jmrix.configurexml.AbstractNetworkConnectionConfigXml;
010import org.jdom2.Element;
011
012/**
013 * Handle XML persistence of layout connections by persisting the
014 * NetworkDriverAdapter (and connections).
015 * <p>
016 * Note this is named as the XML version of a ConnectionConfig object, but it's
017 * actually persisting the NetworkDriverAdapter.
018 * <p>
019 * This class is invoked from jmrix.JmrixConfigPaneXml on write, as that class
020 * is the one actually registered. Reads are brought here directly via the class
021 * attribute in the XML.
022 *
023 * @author Bob Jacobsen Copyright: Copyright (c) 2003, 2015
024 * @author kcameron Copyright (C) 2010 added multiple connections
025 */
026public class ConnectionConfigXml extends AbstractNetworkConnectionConfigXml {
027
028    public ConnectionConfigXml() {
029        super();
030    }
031
032    @Override
033    protected void getInstance() {
034        if(adapter == null) {
035           adapter = new NetworkDriverAdapter();
036        }
037    }
038
039    @Override
040    protected void getInstance(Object object) {
041        adapter = ((ConnectionConfig) object).getAdapter();
042    }
043
044    /**
045     * Write out the SerialNode objects too
046     *
047     * @param e Element being extended
048     */
049    @Override
050    protected void extendElement(Element e) {
051        SerialTrafficController tc = ((CMRISystemConnectionMemo)adapter.getSystemConnectionMemo()).getTrafficController();
052        SerialNode node = (SerialNode) tc.getNode(0);
053        int index = 1;
054        while (node != null) {
055            // add node as an element
056            Element n = new Element("node");
057            n.setAttribute("name", "" + node.getNodeAddress());
058            e.addContent(n);
059            // add parameters to the node as needed
060            n.addContent(makeParameter("nodetype", "" + node.getNodeType()));
061            n.addContent(makeParameter("bitspercard", "" + node.getNumBitsPerCard()));
062            n.addContent(makeParameter("transmissiondelay", "" + node.getTransmissionDelay()));
063            n.addContent(makeParameter("num2lsearchlights", "" + node.getNum2LSearchLights()));
064            n.addContent(makeParameter("pulsewidth", "" + node.getPulseWidth()));
065            StringBuilder value = new StringBuilder("");
066            for (int i = 0; i < node.getLocSearchLightBits().length; i++) {
067                value.append(Integer.toHexString(node.getLocSearchLightBits()[i] & 0xF));
068            }
069            n.addContent(makeParameter("locsearchlightbits", value.toString()));
070            value = new StringBuilder("");
071            for (int i = 0; i < node.getCardTypeLocation().length; i++) {
072                value.append(Integer.toHexString(node.getCardTypeLocation()[i] & 0xF));
073            }
074            n.addContent(makeParameter("cardtypelocation", value.toString()));
075
076            // look for the next node
077            node = (SerialNode) tc.getNode(index);
078            index++;
079        }
080    }
081
082    protected Element makeParameter(String name, String value) {
083        Element p = new Element("parameter");
084        p.setAttribute("name", name);
085        p.addContent(value);
086        return p;
087    }
088
089    @Override
090    protected void unpackElement(Element shared, Element perNode) {
091        List<Element> l = shared.getChildren("node");
092        for (int i = 0; i < l.size(); i++) {
093            Element n = l.get(i);
094            int addr = Integer.parseInt(n.getAttributeValue("name"));
095            int type = Integer.parseInt(findParmValue(n, "nodetype"));
096            int bpc = Integer.parseInt(findParmValue(n, "bitspercard"));
097            int delay = Integer.parseInt(findParmValue(n, "transmissiondelay"));
098            int num2l = Integer.parseInt(findParmValue(n, "num2lsearchlights"));
099            int pulseWidth = 500;
100            if ((findParmValue(n, "pulsewidth")) != null) {
101                pulseWidth = Integer.parseInt(findParmValue(n, "pulsewidth"));
102            }
103
104            String slb = findParmValue(n, "locsearchlightbits");
105            String ctl = findParmValue(n, "cardtypelocation");
106
107            // create node (they register themselves)
108            SerialNode node = new SerialNode(addr, type,((CMRISystemConnectionMemo)adapter.getSystemConnectionMemo()).getTrafficController());
109            node.setNumBitsPerCard(bpc);
110            node.setTransmissionDelay(delay);
111            node.setNum2LSearchLights(num2l);
112            node.setPulseWidth(pulseWidth);
113
114            for (int j = 0; j < slb.length(); j++) {
115                node.setLocSearchLightBits(j, (slb.charAt(j) - '0'));
116            }
117
118            for (int j = 0; j < ctl.length(); j++) {
119                node.setCardTypeLocation(j, (ctl.charAt(j) - '0'));
120            }
121
122            // Trigger initialization of this Node to reflect these parameters
123            ((CMRISystemConnectionMemo)adapter.getSystemConnectionMemo()).getTrafficController().initializeSerialNode(node);
124        }
125    }
126
127    @Override
128    protected void register() {
129        this.register(new ConnectionConfig(adapter));
130    }
131
132}