001package jmri.jmrit; 002 003import java.awt.Component; 004import java.awt.event.ActionEvent; 005import java.io.File; 006 007import javax.swing.JFileChooser; 008import javax.swing.JTextArea; 009 010import jmri.util.swing.JmriPanel; 011import jmri.util.swing.JmriJOptionPane; 012import jmri.util.swing.WindowInterface; 013 014/** 015 * Make sure an XML file is readable, and validates OK against its schema and DTD. 016 * <p> 017 * Can also be run from the command line as apps.jmrit.XmlFileValidationAction 018 * (e.g. ./runtest.csh apps/jmrit/XmlFileValidateAction foo.xml) in which case 019 * if there's a filename argument, it checks that directly, otherwise it pops a 020 * file selection dialog. (The dialog form has to be manually canceled when 021 * done) 022 * 023 * @author Bob Jacobsen Copyright (C) 2005, 2007 024 * @see jmri.jmrit.XmlFile 025 * @see jmri.jmrit.XmlFileCheckAction 026 */ 027public class XmlFileValidateAction extends jmri.util.swing.JmriAbstractAction { 028 029 public XmlFileValidateAction(String s, Component who) { 030 super(s); 031 _who = who; 032 } 033 034 public XmlFileValidateAction(String s, WindowInterface wi) { 035 this(s, wi != null ? wi.getFrame() : null); 036 } 037 038 public XmlFileValidateAction() { 039 super(Bundle.getMessage("XmlFileValidateAction")); // NOI18N 040 } 041 042 private JFileChooser fci; 043 044 private Component _who; 045 046 private final XmlFile xmlfile = new XmlFile() {}; // odd syntax is due to XmlFile being abstract 047 048 @Override 049 public void actionPerformed(ActionEvent e) { 050 if (fci == null) { 051 fci = jmri.jmrit.XmlFile.userFileChooser("XML files", "xml"); 052 } 053 // request the filename from an open dialog 054 fci.rescanCurrentDirectory(); 055 int retVal = fci.showOpenDialog(_who); 056 // handle selection or cancel 057 if (retVal == JFileChooser.APPROVE_OPTION) { 058 processFile(fci.getSelectedFile()); 059 } else { 060 log.debug("XmlFileValidateAction cancelled in open dialog"); 061 } 062 } 063 064 protected void processFile(File file) { 065 log.debug("located file \"{}\" for XML processing", file); 066 // handle the file (TODO should be outside this thread?) 067 try { 068 xmlfile.setValidate(XmlFile.Validate.CheckDtdThenSchema); 069 readFile(file); 070 } catch (Exception ex) { 071 showFailResults(_who, file.getName(), ex.getMessage()); 072 return; 073 } 074 showOkResults(_who, Bundle.getMessage("ValidatedOk", file.getName())); 075 log.debug("parsing xml complete"); 076 } 077 078 protected void showOkResults(Component who, String text) { 079 JmriJOptionPane.showMessageDialog(who, text); 080 } 081 082 protected void showFailResults(Component who, String fileName, String text) { 083 // non-editable line-wrapped JTextArea 30 columns wide so user can copy text 084 JTextArea jta = new JTextArea((int) Math.ceil((double)text.length() / 30),30); 085 jta.setLineWrap(true); 086 jta.setWrapStyleWord(true); 087 jta.setEditable(false); 088 jta.setText(text); 089 JmriJOptionPane.showMessageDialog(who, jta, 090 Bundle.getMessage("ValidationErrorInFile", fileName), JmriJOptionPane.ERROR_MESSAGE); 091 } 092 093 /** 094 * Read and verify a file is schema valid XML. 095 * 096 * @param file the file to read 097 * @throws org.jdom2.JDOMException if file is not schema valid XML 098 * @throws java.io.IOException if unable to read file 099 */ 100 void readFile(File file) throws org.jdom2.JDOMException, java.io.IOException { 101 xmlfile.rootFromFile(file); 102 103 } 104 105 // never invoked, because we overrode actionPerformed above 106 @Override 107 public JmriPanel makePanel() { 108 throw new IllegalArgumentException("Should not be invoked"); 109 } 110 111 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(XmlFileValidateAction.class); 112 113}