001package jmri.configurexml.turnoutoperations;
002
003import jmri.TurnoutOperation;
004import org.jdom2.Element;
005import org.slf4j.Logger;
006import org.slf4j.LoggerFactory;
007
008/**
009 * Superclass for save/restore of TurnoutOperation subclasses in XML.
010 *
011 * @author John Harper Copyright 2005
012 *
013 */
014public abstract class TurnoutOperationXml extends jmri.configurexml.AbstractXmlAdapter {
015
016    @Override
017    public boolean load(Element shared, Element perNode) {
018        loadOne(shared);
019        return true;
020    }
021
022    public abstract TurnoutOperation loadOne(Element e);
023
024    /**
025     * Load one operation, using the appropriate adapter
026     *
027     * @param e element for operation
028     * @return the loaded TurnoutOperation or null if unable to load from e
029     */
030    public static TurnoutOperation loadOperation(Element e) {
031        TurnoutOperation result = null;
032        String className = e.getAttributeValue("class");
033        if (className == null) {
034            log.error("class name missing in turnout operation \"{}\"", e);
035        } else {
036            log.debug("loadOperation for class {}", className);
037            try {
038                Class<?> adapterClass = Class.forName(className);
039                TurnoutOperationXml adapter = (TurnoutOperationXml) adapterClass.getDeclaredConstructor().newInstance();
040                result = adapter.loadOne(e);
041                if (result.getName().charAt(0) == '*') {
042                    result.setNonce(true);
043                }
044            } catch (ClassNotFoundException | InstantiationException | NoSuchMethodException | java.lang.reflect.InvocationTargetException e1) {
045                log.error("while creating TurnoutOperation", e1);
046                return null;
047            } catch (IllegalAccessException e2) {
048                log.error("while creating CommonTurnoutOperation", e2);
049                return null;
050            }
051        }
052        return result;
053    }
054
055    /**
056     * common part of store - create the element and store the name and the
057     * class
058     *
059     * @param o TurnoutOperation object
060     * @return partially filled element
061     */
062    @Override
063    public Element store(Object o) {
064        TurnoutOperation myOp = (TurnoutOperation) o;
065        Element elem = new Element("operation");
066        elem.setAttribute("name", myOp.getName());
067        elem.setAttribute("class", this.getClass().getName());
068        return elem;
069    }
070
071    /**
072     * Given an instance of a concrete subclass of the TurnoutOperation class,
073     * looks for a corresponding ...Xml class and creates an instance of it. If
074     * anything goes wrong (no such class, wrong constructors, instantiation
075     * error, ....) just return null
076     *
077     * @param op operation for which configurator is required
078     * @return the configurator
079     */
080    static public TurnoutOperationXml getAdapter(TurnoutOperation op) {
081        TurnoutOperationXml adapter = null;
082        String[] fullOpNameComponents = op.getClass().getName().split("\\.");
083        log.debug("getAdapter found class name {}", op.getClass().getName());
084        String[] myNameComponents
085                = new String[]{"jmri", "configurexml", "turnoutoperations", "TurnoutOperationXml"};
086        myNameComponents[myNameComponents.length - 1]
087                = fullOpNameComponents[fullOpNameComponents.length - 1];
088        String fullConfigName = String.join(".", myNameComponents) + "Xml";
089        log.debug("getAdapter looks for {}", fullConfigName);
090        try {
091            Class<?> configClass = Class.forName(fullConfigName);
092            adapter = (TurnoutOperationXml) configClass.getDeclaredConstructor().newInstance();
093        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | NoSuchMethodException | java.lang.reflect.InvocationTargetException e) {
094            log.error("exception in getAdapter", e);
095        }
096        if (adapter == null) {
097            log.warn("could not create adapter class {}", fullConfigName);
098        }
099        return adapter;
100    }
101
102    private final static Logger log = LoggerFactory.getLogger(TurnoutOperationXml.class);
103}