001package apps.startup.configurexml;
002
003import apps.startup.ScriptButtonModel;
004
005import java.io.FileNotFoundException;
006import java.util.Locale;
007
008import jmri.InstanceManager;
009import jmri.configurexml.AbstractXmlAdapter;
010import jmri.util.FileUtil;
011import jmri.util.prefs.InitializationException;
012import jmri.util.startup.StartupActionsManager;
013import jmri.util.startup.StartupModel;
014
015import org.jdom2.Attribute;
016import org.jdom2.Element;
017
018/**
019 * Handle XML persistence for {@link apps.startup.ScriptButtonModel} objects and
020 * set the defined {@link jmri.Route} during application start.
021 *
022 * @author Bob Jacobsen Copyright: Copyright (c) 2003
023 * @author Ken Cameron Copyright: 2014(c)
024 * @author Randall Wood (c) 2016
025 * @see apps.startup.TriggerRouteModelFactory
026 */
027public class ScriptButtonModelXml extends AbstractXmlAdapter {
028
029    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ScriptButtonModelXml.class);
030
031    public ScriptButtonModelXml() {
032    }
033
034    /**
035     * Default implementation for storing the model contents
036     *
037     * @param o Object to store, of type PerformActonModel
038     * @return Element containing the complete info
039     */
040    @Override
041    public Element store(Object o) {
042        Element element = new Element("perform"); // NOI18N
043        element.setAttribute("name", ((StartupModel) o).getName()); // NOI18N
044        element.setAttribute("type", "Button"); // NOI18N
045        element.setAttribute("enabled", ((StartupModel) o).isEnabled() ? "yes" : "no");
046        element.setAttribute("class", this.getClass().getName()); // NOI18N
047        Element property = new Element("property"); // NOI18N
048        property.setAttribute("name", "script"); // NOI18N
049        property.setAttribute("value", FileUtil.getPortableFilename(((ScriptButtonModel) o).getScript()));
050        element.addContent(property);
051        return element;
052    }
053
054    /**
055     * Object should be loaded after basic GUI constructed
056     *
057     * @return true to defer loading
058     * @see jmri.configurexml.AbstractXmlAdapter#loadDeferred()
059     * @see jmri.configurexml.XmlAdapter#loadDeferred()
060     */
061    @Override
062    public boolean loadDeferred() {
063        return true;
064    }
065
066    @Override
067    public boolean load(Element shared, Element perNode) {
068        // Should the script engines be pre-loaded here?
069        boolean result = false;
070        ScriptButtonModel model = new ScriptButtonModel();
071        model.setName(shared.getAttribute("name").getValue()); // NOI18N
072
073        Attribute enabled = shared.getAttribute("enabled");
074        if (enabled != null) {
075            model.setEnabled("yes".equals(enabled.getValue()));
076        } else {
077            model.setEnabled(true);
078        }
079
080        for (Element child : shared.getChildren("property")) { // NOI18N
081            if (child.getAttributeValue("name").equals("script") // NOI18N
082                    && child.getAttributeValue("value") != null) { // NOI18N
083                String script = child.getAttributeValue("value"); // NOI18N
084                try {
085                    model.setScript(FileUtil.getFile(script));
086                    result = true;
087                } catch (FileNotFoundException ex) {
088                    model.addException(new InitializationException(
089                            Bundle.getMessage(Locale.ENGLISH, "ScriptButtonModel.ScriptNotFound", script),
090                            Bundle.getMessage("ScriptButtonModel.ScriptNotFound", script),
091                            ex));
092                    log.error("Unable to create button for script {}", script);
093                }
094            }
095        }
096
097        // store the model
098        InstanceManager.getDefault(StartupActionsManager.class).addAction(model);
099        return result;
100    }
101
102    /**
103     * Update static data from XML file
104     *
105     * @param element Top level Element to unpack.
106     * @param o       ignored
107     */
108    @Override
109    public void load(Element element, Object o) {
110        log.error("Unexpected call of load(Element, Object)");
111    }
112}