001package jmri.managers.configurexml; 002 003import java.util.List; 004import java.util.SortedSet; 005import jmri.InstanceManager; 006import jmri.StringIO; 007import jmri.StringIOManager; 008import org.jdom2.Element; 009 010/** 011 * Provides the abstract base and store functionality for configuring 012 * StringIOManagers, working with AbstractStringIOManagers. 013 * <p> 014 * Typically, a subclass will just implement the load(Element StringIOs) class, 015 * relying on implementation here to load the individual StringIOs. Note that 016 * these are stored explicitly, so the resolution mechanism doesn't need to see 017 * *Xml classes for each specific StringIO or AbstractStringIO subclass at store 018 * time. 019 * 020 * @author Bob Jacobsen Copyright: Copyright (c) 2002, 2008, 2009, 2024 021 */ 022public abstract class AbstractStringIOManagerConfigXML extends AbstractNamedBeanManagerConfigXML { 023 024 public AbstractStringIOManagerConfigXML() { 025 } 026 027 /** 028 * Default implementation for storing the contents of a StringIOManager 029 * 030 * @param o Object to store, of type StringIOManager 031 * @return Element containing the complete info 032 */ 033 @Override 034 public Element store(Object o) { 035 log.warn("AbstractStringIOManagerConfigXML store with {}",o); 036 Element stringIOs = new Element("stringios"); 037 setStoreElementClass(stringIOs); 038 StringIOManager rm = (StringIOManager) o; 039 if (rm != null) { 040 SortedSet<StringIO> rList = rm.getNamedBeanSet(); 041 // don't return an element if there are no StringIOs to include 042 if (rList.isEmpty()) { 043 return null; 044 } 045 // store the StringIOs 046 for (var r : rList) { 047 String rName = r.getSystemName(); 048 log.debug("system name is {}", rName); 049 Element elem = new Element("stringio"); 050 elem.addContent(new Element("systemName").addContent(rName)); 051 // store common parts 052 storeCommon(r, elem); 053 054 log.debug("store StringIO {}", rName); 055 stringIOs.addContent(elem); 056 } 057 } 058 return stringIOs; 059 } 060 061 /** 062 * Subclass provides an implementation to create the correct top element, 063 * including the type information. Default implementation is to use the 064 * local class here. 065 * 066 * @param stringIOs The top-level element being created 067 */ 068 abstract public void setStoreElementClass(Element stringIOs); 069 070 /** 071 * Utility method to load the individual StringIO objects. If there's no 072 * additional info needed for a specific StringIO type, invoke this with the 073 * parent of the set of StringIO elements. 074 * 075 * @param stringIOs Element containing the StringIO elements to load. 076 * @return true if successful 077 */ 078 public boolean loadStringIOs(Element stringIOs) { 079 boolean result = true; 080 List<Element> stringIOList = stringIOs.getChildren("stringio"); 081 log.debug("Found {} StringIOs", stringIOList.size()); 082 var tm = InstanceManager.getDefault(jmri.StringIOManager.class); 083 tm.setPropertyChangesSilenced("beans", true); 084 085 for (Element e : stringIOList) { 086 String sysName = getSystemName(e); 087 if (sysName == null) { 088 log.warn("unexpected null in systemName {} {}", e, e.getAttributes()); 089 result = false; 090 break; 091 } 092 093 String userName = getUserName(e); 094 095 log.debug("create StringIO: ({})({})", sysName, (userName == null ? "<null>" : userName)); 096 var r = tm.newStringIO(sysName, userName); 097 loadCommon(r, e); 098 } 099 tm.setPropertyChangesSilenced("beans", false); 100 return result; 101 } 102 103 @Override 104 public int loadOrder() { 105 return InstanceManager.getDefault(jmri.StringIOManager.class).getXMLOrder(); 106 } 107 108 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AbstractStringIOManagerConfigXML.class); 109 110}