001package jmri.jmrix.configurexml; 002 003import jmri.jmrix.NetworkPortAdapter; 004import org.jdom2.Element; 005import org.slf4j.Logger; 006import org.slf4j.LoggerFactory; 007 008import javax.annotation.Nonnull; 009 010/** 011 * Abstract base (and partial implementation) for classes persisting the status 012 * of Network port adapters. 013 * 014 * @author Bob Jacobsen, Copyright (c) 2003 015 */ 016abstract public class AbstractNetworkConnectionConfigXml extends AbstractConnectionConfigXml { 017 018 public AbstractNetworkConnectionConfigXml() { 019 } 020 021 protected NetworkPortAdapter adapter; 022 023 protected void getInstance(Object object) { 024 getInstance(); // over-ridden during migration 025 } 026 027 /** 028 * Default implementation for storing the static contents of the Network 029 * port implementation. 030 * 031 * @param o Object to store, of type PositionableLabel 032 * @return Element containing the complete info 033 */ 034 @Override 035 public Element store(Object o) { 036 getInstance(o); 037 038 Element e = new Element("connection"); 039 // many of the following are required by the DTD; failing to include 040 // them makes the XML file unreadable, but at least the next 041 // invocation of the program can then continue. 042 043 storeCommon(e, adapter); 044 045 if (adapter.getMdnsConfigure()) { 046 // if we are using mDNS for configuration, only save 047 // the hostname if it was specified. 048 if (adapter.getHostName() != null && !adapter.getHostName().equals("")) { 049 e.setAttribute("address", adapter.getHostName()); 050 } 051 052 e.setAttribute("mdnsConfigure", "true"); 053 if (adapter.getAdvertisementName() != null) { 054 e.setAttribute("advertisementName", adapter.getAdvertisementName()); 055 } 056 if (adapter.getServiceType() != null) { 057 e.setAttribute("serviceType", adapter.getServiceType()); 058 } 059 060 } else { 061 e.setAttribute("mdnsConfigure", "false"); 062 063 // require a value for the address if we are not using mDNS. 064 if (adapter.getHostName() != null) { 065 e.setAttribute("address", adapter.getHostName()); 066 } else { 067 e.setAttribute("address", Bundle.getMessage("noneSelected")); 068 } 069 070 // write the port only if we are not using automatic configuration. 071 if (adapter.getPort() != 0) { 072 e.setAttribute("port", "" + adapter.getPort()); 073 } else { 074 e.setAttribute("port", Bundle.getMessage("noneSelected")); 075 } 076 } 077 078 setOutputInterval(adapter, e); 079 080 e.setAttribute("class", this.getClass().getName()); 081 082 extendElement(e); 083 084 return e; 085 } 086 087 /** 088 * Customizable method if you need to add anything more. 089 * 090 * @param e Element being created, update as needed 091 */ 092 @Override 093 protected void extendElement(Element e) { 094 } 095 096 @Override 097 public boolean load(@Nonnull Element shared, Element perNode) { 098 boolean result = true; 099 getInstance(); 100 101 boolean mdnsConfig = false; 102 try { 103 mdnsConfig = (shared.getAttribute("mdnsConfigure").getValue().equals("true")); 104 } catch (NullPointerException ex) { // considered normal if the attributes are not present 105 } 106 adapter.setMdnsConfigure(mdnsConfig); 107 108 if (mdnsConfig) { 109 110 // configure host name 111 try { 112 String hostName = shared.getAttribute("address").getValue(); 113 // the hostname is optional when mDNS is being used. 114 adapter.setHostName(hostName); 115 } catch (NullPointerException ex) { // considered normal if the attributes are not present 116 } 117 118 // configure the Service Type 119 try { 120 String serviceType = shared.getAttribute("serviceType").getValue(); 121 // the Service Type is optional when mDNS is being used. 122 adapter.setServiceType(serviceType); 123 } catch (NullPointerException ex) { // considered normal if the attributes are not present 124 } 125 126 // configure the advertisement name 127 try { 128 String advertisementName = shared.getAttribute("advertisementName").getValue(); 129 // the Advertisement Name is optional when mDNS is being used. 130 adapter.setAdvertisementName(advertisementName); 131 } catch (NullPointerException ex) { // considered normal if the attributes are not present 132 } 133 134 // get the host IP and port number 135 // via mdns 136 adapter.autoConfigure(); 137 138 } else { 139 // get the host name and port number via parameters. 140 141 // configure host name 142 String hostName = null; 143 try { 144 hostName = shared.getAttribute("address").getValue(); 145 } catch (NullPointerException ex) { // considered normal if the attributes are not present 146 } 147 adapter.setHostName(hostName); 148 149 try { 150 int port = shared.getAttribute("port").getIntValue(); 151 adapter.setPort(port); 152 } catch (org.jdom2.DataConversionException ex) { 153 log.warn("Could not parse port attribute: {}", shared.getAttribute("port")); 154 } catch (NullPointerException ex) { // considered normal if the attributes are not present 155 } 156 } 157 158 loadCommon(shared, perNode, adapter); 159 // register, so can be picked up next time 160 register(); 161 162 if (adapter.getDisabled()) { 163 unpackElement(shared, perNode); 164 return result; 165 } 166 try { 167 log.trace("start adapter.connect()"); 168 adapter.connect(); 169 } catch (Exception ex) { 170 log.debug("Caught exception in adapter.connect", ex); 171 handleException(ex.getMessage(), "opening connection", null, null, ex); 172 return false; 173 } 174 175 // if successful so far, go ahead and configure 176 log.trace("start adapter.configure()"); 177 adapter.configure(); 178 179 // once all the configure processing has happened, do any 180 // extra config 181 log.trace("start unpackElement"); 182 183 if (perNode.getAttribute("turnoutInterval") != null) { // migrate existing profile, defaults to 250 ms in memo 184 adapter.getSystemConnectionMemo().setOutputInterval(Integer.parseInt(perNode.getAttribute("turnoutInterval").getValue())); 185 } 186 187 unpackElement(shared, perNode); 188 return result; 189 } 190 191 /** 192 * Update static data from XML file. 193 * 194 * @param element Top level Element to unpack. 195 */ 196 @Override 197 public void load(Element element, Object o) { 198 log.error("method with two args invoked"); 199 } 200 201 @Override 202 protected void dispose() { 203 adapter.dispose(); 204 } 205 206 // initialize logging 207 private final static Logger log = LoggerFactory.getLogger(AbstractNetworkConnectionConfigXml.class); 208 209}