001package jmri.managers.configurexml; 002 003import java.util.List; 004import java.util.SortedSet; 005import jmri.InstanceManager; 006import jmri.Meter; 007import jmri.MeterManager; 008import jmri.configurexml.JmriConfigureXmlException; 009import org.jdom2.Element; 010 011/** 012 * Provides the basic load and store functionality for configuring 013 * MeterManagers, working with AbstractMeterManagers. 014 * <p> 015 * This class cannot create Meters, so the meters must either be already 016 * created, for example by the connections, in which case this class only 017 * updates the data of the meter, for example its user name. 018 * Or this class is overridden by a class that knows how to create the meters. 019 * 020 * @author Bob Jacobsen Copyright (C) 2002, 2008 021 * @author Daniel Bergqvist Copyright (C) 2020 022 */ 023public class AbstractMeterManagerXml extends AbstractNamedBeanManagerConfigXML { 024 025 public AbstractMeterManagerXml() { 026 } 027 028 /** 029 * Default implementation for storing the contents of a MeterManager. 030 * 031 * @param o Object to store, of type MeterManager 032 * @return Element containing the complete info 033 */ 034 @Override 035 public Element store(Object o) { 036 Element meters = new Element("meters"); 037 setStoreElementClass(meters); 038 MeterManager mm = (MeterManager) o; 039 if (mm != null) { 040 SortedSet<Meter> memList = mm.getNamedBeanSet(); 041 // don't return an element if there are no meters to include 042 if (memList.isEmpty()) { 043 return null; 044 } 045 // store the meters 046 for (Meter m : memList) { 047 var elem = storeMeter(m); 048 meters.addContent(elem); 049 } 050 } 051 return meters; 052 } 053 054 /** 055 * Create an element representing a single Meter 056 * @param m The Meter being stored 057 * @return Element containing the Meter info 058 */ 059 protected Element storeMeter(Meter m) { 060 String mName = m.getSystemName(); 061 log.debug("system name is {}", mName); 062 063 Element elem = new Element("meter"); 064 elem.addContent(new Element("systemName").addContent(mName)); 065 066 // store common part 067 storeCommon(m, elem); 068 069 return elem; 070 } 071 072 /** 073 * Subclass provides implementation to create the correct top element, 074 * including the type information. Default implementation is to use the 075 * local class here. 076 * 077 * @param meters The top-level element being created 078 */ 079 public void setStoreElementClass(Element meters) { 080 meters.setAttribute("class", this.getClass().getName()); // NOI18N 081 } 082 083 /** 084 * Create a MeterManager object of the correct class, then register and 085 * fill it. 086 * 087 * @param sharedMeters Shared top level Element to unpack. 088 * @param perNodeMemories Per-node top level Element to unpack. 089 * @return true if successful 090 * @throws jmri.configurexml.JmriConfigureXmlException if error during load. 091 */ 092 @Override 093 public boolean load(Element sharedMeters, Element perNodeMemories) throws JmriConfigureXmlException { 094 loadMeters(sharedMeters); 095 return true; 096 } 097 098 /** 099 * Utility method to load the individual Meter objects. If there's no 100 * additional info needed for a specific Meter type, invoke this with the 101 * parent of the set of Meter elements. 102 * 103 * @param meters Element containing the Meter elements to load. 104 */ 105 public void loadMeters(Element meters) { 106 List<Element> meterList = meters.getChildren("meter"); 107 log.debug("Found {} Meter objects", meterList.size()); 108 MeterManager mm = InstanceManager.getDefault(MeterManager.class); 109 110 for (Element el : meterList) { 111 String sysName = getSystemName(el); 112 if (sysName == null) { 113 log.warn("unexpected null in systemName {}", (el)); 114 break; 115 } 116 117 String userName = getUserName(el); 118 119 checkNameNormalization(sysName, userName, mm); 120 121 loadMeter(sysName, userName, el, mm); 122 } 123 } 124 125 protected void loadMeter(String sysName, String userName, Element el, MeterManager mm) { 126 log.debug("get Meter: ({})({})", sysName, (userName == null ? "<null>" : userName)); 127 Meter m = mm.getBySystemName(sysName); 128 if (m != null) { 129 m.setUserName(userName); 130 // load common parts 131 loadCommon(m, el); 132 } else { 133 log.debug("Meter ({}) does not exists and cannot be created", sysName); 134 } 135 } 136 137 @Override 138 public int loadOrder() { 139 return InstanceManager.getDefault(MeterManager.class).getXMLOrder(); 140 } 141 142 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AbstractMeterManagerXml.class); 143 144}