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