001package jmri.util.startup.configurexml; 002 003import java.lang.reflect.InvocationTargetException; 004 005import jmri.util.startup.PerformActionModel; 006import jmri.util.startup.StartupActionsManager; 007import jmri.InstanceManager; 008import jmri.SystemConnectionMemo; 009import jmri.jmrix.swing.SystemConnectionAction; 010 011import org.jdom2.Attribute; 012import org.jdom2.Element; 013 014/** 015 * Handle XML persistence of PerformActionModel objects. 016 * 017 * @author Bob Jacobsen Copyright (c) 2003 018 * @see jmri.util.startup.PerformActionModelFactory 019 */ 020public class PerformActionModelXml extends jmri.configurexml.AbstractXmlAdapter { 021 022 public PerformActionModelXml() { 023 // no state to set 024 } 025 026 /** 027 * Default implementation for storing the model contents 028 * 029 * @param o Object to store, of type PerformActonModel 030 * @return Element containing the complete info 031 */ 032 @Override 033 public Element store(Object o) { 034 Element element = new Element("perform"); 035 PerformActionModel g = (PerformActionModel) o; 036 037 element.setAttribute("name", g.getClassName()); 038 element.setAttribute("type", "Action"); 039 element.setAttribute("enabled", g.isEnabled() ? "yes" : "no"); 040 element.setAttribute("class", this.getClass().getName()); 041 Element property = new Element("property"); // NOI18N 042 property.setAttribute("name", "systemPrefix"); // NOI18N 043 property.setAttribute("value", g.getSystemPrefix()); 044 element.addContent(property); 045 return element; 046 } 047 048 /** 049 * Object should be loaded after basic GUI constructed 050 * 051 * @return true to defer loading 052 * @see jmri.configurexml.AbstractXmlAdapter#loadDeferred() 053 * @see jmri.configurexml.XmlAdapter#loadDeferred() 054 */ 055 @Override 056 public boolean loadDeferred() { 057 return true; 058 } 059 060 @Override 061 public boolean load(Element shared, Element perNode) { 062 boolean result = true; 063 String className = shared.getAttribute("name").getValue(); 064 PerformActionModel model = new PerformActionModel(); 065 066 Attribute enabled = shared.getAttribute("enabled"); 067 if (enabled != null) { 068 model.setEnabled("yes".equals(enabled.getValue())); 069 } else { 070 model.setEnabled(true); 071 } 072 073 model.setClassName(className); 074 shared.getChildren("property").forEach(child -> { // NOI18N 075 String value = child.getAttributeValue("value"); // NOI18N 076 if (child.getAttributeValue("name").equals("systemPrefix") // NOI18N 077 && value != null) { 078 // handle the situation where the model expects a system prefix 079 // but was not saved with one in a pre-4.19.7 JMRI instance 080 // TODO: at some point (June 2022 release?) change entire 081 // try/catch block to just "model.setSystemPrefix(value);" 082 try { 083 Class<?> ac = Class.forName(className); 084 if (value.isEmpty() && SystemConnectionAction.class.isAssignableFrom(ac)) { 085 SystemConnectionAction<?> a = (SystemConnectionAction<?>) ac.getConstructor().newInstance(); 086 InstanceManager.getList(SystemConnectionMemo.class) 087 .forEach(memo -> a.getSystemConnectionMemoClasses().stream() 088 .filter(mc -> memo.getClass().isAssignableFrom(mc)) 089 .forEach(mc -> model.setSystemPrefix(memo.getSystemPrefix()))); 090 } else { 091 model.setSystemPrefix(value); 092 } 093 } catch (ClassNotFoundException 094 | InstantiationException 095 | IllegalAccessException 096 | IllegalArgumentException 097 | InvocationTargetException 098 | NoSuchMethodException 099 | SecurityException ex) { 100 // ignore to allow manager to handle later 101 log.warn("While trying to do {}, encountered exception", className, ex); 102 } 103 } 104 }); 105 InstanceManager.getDefault(StartupActionsManager.class).addAction(model); 106 return result; 107 } 108 109 // initialize logging 110 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PerformActionModelXml.class); 111 112}