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