001package jmri.jmrit.logixng.implementation.configurexml; 002 003import java.lang.reflect.Constructor; 004import java.lang.reflect.InvocationTargetException; 005import java.util.HashMap; 006import java.util.List; 007import java.util.Map; 008 009import jmri.configurexml.ConfigXmlManager; 010import jmri.jmrit.logixng.*; 011import jmri.jmrit.logixng.configurexml.MaleSocketXml; 012 013import org.jdom2.Element; 014 015 016/** 017 * Provides the functionality for configuring ActionManagers 018 * 019 * @author Dave Duchamp Copyright (c) 2007 020 * @author Daniel Bergqvist Copyright (c) 2018 021 */ 022public abstract class AbstractManagerXml extends jmri.managers.configurexml.AbstractNamedBeanManagerConfigXML { 023 024 private final Map<String, Class<?>> xmlClasses = new HashMap<>(); 025 026 027 /** 028 * Store data for a MaleSocket 029 * 030 * @param maleSocket the socket to store 031 * @return Element containing the complete info 032 */ 033 public Element storeMaleSocket(MaleSocket maleSocket) { 034 Element element = new Element("MaleSocket"); 035 036 Base m = maleSocket; 037 while (m instanceof MaleSocket) { 038 MaleSocket ms = (MaleSocket) m; 039 040 try { 041 Element e = ConfigXmlManager.elementFromObject(ms); 042 if (e != null) { 043 element.addContent(e); 044 } else { 045 throw new RuntimeException("Cannot load xml configurator for " + ms.getClass().getName()); 046 } 047 } catch (RuntimeException e) { 048 log.error("Error storing maleSocket: {}", e, e); 049 } 050 051 m = ms.getObject(); 052 } 053 054 return (element); 055 } 056 057 /** 058 * Utility method to load the individual DigitalActionBean objects. If 059 * there's no additional info needed for a specific action type, invoke 060 * this with the parent of the set of DigitalActionBean elements. 061 * 062 * @param element Element containing the MaleSocket element to load. 063 * @param maleSocket the socket to load 064 */ 065 public void loadMaleSocket(Element element, MaleSocket maleSocket) { 066 067 Map<String, Map.Entry<MaleSocketXml, Element>> maleSocketXmlClasses = new HashMap<>(); 068 069 Element elementMaleSocket = element.getChild("MaleSocket"); 070 if (elementMaleSocket == null) { 071 throw new IllegalArgumentException("maleSocket is null"); 072 } 073 074 List<Element> children = elementMaleSocket.getChildren(); 075 log.debug("Found {} male sockets", children.size() ); // NOI18N 076 077 for (Element e : children) { 078 079 String className = e.getAttribute("class").getValue(); 080// log.error("className: " + className); 081 082 Class<?> clazz = xmlClasses.get(className); 083 084 if (clazz == null) { 085 try { 086 clazz = Class.forName(className); 087 xmlClasses.put(className, clazz); 088 } catch (ClassNotFoundException ex) { 089 log.error("cannot load class {}", className, ex); 090 } 091 } 092 093 if (clazz != null) { 094 Constructor<?> c = null; 095 try { 096 c = clazz.getConstructor(); 097 } catch (NoSuchMethodException | SecurityException ex) { 098 log.error("cannot create constructor", ex); 099 } 100 101 if (c != null) { 102 try { 103 MaleSocketXml o = (MaleSocketXml)c.newInstance(); 104 105 Map.Entry<MaleSocketXml, Element> entry = 106 new HashMap.SimpleEntry<>(o, e); 107 maleSocketXmlClasses.put(className, entry); 108 } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { 109 log.error("cannot create object", ex); 110 } 111 } 112 } 113 } 114 115 Base m = maleSocket; 116 while (m instanceof MaleSocket) { 117 MaleSocket ms = (MaleSocket) m; 118 119 String cName = ConfigXmlManager.adapterName(ms); 120 Map.Entry<MaleSocketXml, Element> entry = maleSocketXmlClasses.get(cName); 121 122 try { 123 entry.getKey().load(entry.getValue(), ms); 124 } catch (RuntimeException ex) { 125 log.error("Error loading maleSocket: {}", ex, ex); 126 } 127 128 m = ms.getObject(); 129 } 130 131 } 132 133 134 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AbstractManagerXml.class); 135}