001package jmri.jmrit.decoderdefn;
002
003import java.awt.HeadlessException;
004import java.awt.event.ActionEvent;
005import java.io.File;
006import java.io.IOException;
007import java.util.Iterator;
008
009import javax.swing.AbstractAction;
010import javax.swing.JFileChooser;
011import javax.swing.JPanel;
012
013import jmri.InstanceManager;
014import jmri.jmrit.XmlFile;
015import jmri.jmrit.symbolicprog.NameFile;
016import jmri.util.swing.JmriJOptionPane;
017
018import org.jdom2.Attribute;
019import org.jdom2.Element;
020import org.jdom2.JDOMException;
021import org.jdom2.filter.ElementFilter;
022
023/**
024 * Check the names in an XML decoder file against the names.xml definitions
025 *
026 * @author Bob Jacobsen Copyright (C) 2001, 2007
027 * @see jmri.jmrit.XmlFile
028 */
029public class NameCheckAction extends AbstractAction {
030
031    public NameCheckAction(String s, JPanel who) {
032        super(s);
033        _who = who;
034    }
035
036    JFileChooser fci;
037
038    JPanel _who;
039
040    @Override
041    public void actionPerformed(ActionEvent e) {
042        if (fci == null) {
043            fci = jmri.jmrit.XmlFile.userFileChooser("XML files", "xml");
044        }
045        // request the filename from an open dialog
046        fci.rescanCurrentDirectory();
047        int retVal = fci.showOpenDialog(_who);
048        // handle selection or cancel
049        if (retVal == JFileChooser.APPROVE_OPTION) {
050            File file = fci.getSelectedFile();
051            log.debug("located file {} for XML processing", file); // NOI18N
052            // handle the file (later should be outside this thread?)
053            try {
054                Element root = readFile(file);
055                log.debug("parsing complete"); // NOI18N
056
057                // check to see if there's a decoder element
058                if (root.getChild("decoder") == null) {
059                    log.warn("Does not appear to be a decoder file"); // NOI18N
060                    return;
061                }
062
063                Iterator<Element> iter = root.getChild("decoder").getChild("variables")
064                        .getDescendants(new ElementFilter("variable"));
065
066                NameFile nfile = InstanceManager.getDefault(NameFile.class);
067
068                StringBuffer warnings = new StringBuffer();
069
070                while (iter.hasNext()) {
071                    Element varElement = iter.next();
072
073                    // for each variable, see if can find in names file
074                    Attribute labelAttr = varElement.getAttribute("label");
075                    String label = null;
076                    if (labelAttr != null) {
077                        label = labelAttr.getValue();
078                    }
079                    Attribute itemAttr = varElement.getAttribute("item");
080                    String item = null;
081                    if (itemAttr != null) {
082                        item = itemAttr.getValue();
083                    }
084                    if (log.isDebugEnabled()) {
085                        log.debug("Variable called \"{}\" \"{}", (label != null) ? label : "<none>", (item != null) ? item : "<none>"); // NOI18N
086                    }
087                    if (!(label == null ? false : nfile.checkName(label))
088                            && !(item == null ? false : nfile.checkName(item))) {
089                        log.warn("Variable not found: label=\"{}\" item=\"{}\"", (label != null) ? label : "<none>", (item != null) ? label : "<none>"); // NOI18N
090                        warnings.append("Variable not found: label=\"")
091                                .append(((label != null) ? label : "<none>")).append("\" item=\"")
092                                .append(((item != null) ? item : "<none>")).append("\"\n"); // TODO I18N
093                    }
094                }
095
096                if (warnings.length()!=0) {
097                    JmriJOptionPane.showMessageDialog(_who, warnings);
098                } else {
099                    JmriJOptionPane.showMessageDialog(_who, "No mismatched items found"); // TODO I18N
100                }
101
102            } catch (HeadlessException | IOException | JDOMException ex) {
103                JmriJOptionPane.showMessageDialog(_who, "Error parsing decoder file: " + ex); // TODO I18N
104            }
105
106        } else {
107            log.debug("XmlFileCheckAction cancelled in open dialog"); // NOI18N
108        }
109    }
110
111    /**
112     * Read and verify an XML file.
113     *
114     * @param file the file to read
115     * @return the root element in the file
116     * @throws org.jdom2.JDOMException if the file cannot be parsed
117     * @throws java.io.IOException     if the file cannot be read
118     */
119    Element readFile(File file) throws org.jdom2.JDOMException, java.io.IOException {
120        XmlFile xf = new XmlFile() {
121        };   // odd syntax is due to XmlFile being abstract
122
123        return xf.rootFromFile(file);
124
125    }
126
127    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NameCheckAction.class);
128
129}