X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=src%2Ftim%2Fprune%2Fload%2Fxml%2FXmlFileLoader.java;fp=src%2Ftim%2Fprune%2Fload%2Fxml%2FXmlFileLoader.java;h=c907d373ded1a80a3f8b30783bc5298673302dcf;hp=0000000000000000000000000000000000000000;hb=ce6f2161b8596f7018d6a76bff79bc9e571f35fd;hpb=2d8cb72e84d5cc1089ce77baf1e34ea3ea2f8465 diff --git a/src/tim/prune/load/xml/XmlFileLoader.java b/src/tim/prune/load/xml/XmlFileLoader.java new file mode 100644 index 0000000..c907d37 --- /dev/null +++ b/src/tim/prune/load/xml/XmlFileLoader.java @@ -0,0 +1,211 @@ +package tim.prune.load.xml; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.helpers.XMLReaderFactory; + +import tim.prune.App; +import tim.prune.I18nManager; +import tim.prune.data.SourceInfo; +import tim.prune.load.MediaLinkInfo; + +/** + * Class for handling loading of Xml files, and passing the + * loaded data back to the App object + */ +public class XmlFileLoader extends DefaultHandler implements Runnable +{ + private File _file = null; + private App _app = null; + private XmlHandler _handler = null; + private String _unknownType = null; + + + /** + * Constructor + * @param inApp Application object to inform of track load + */ + public XmlFileLoader(App inApp) + { + _app = inApp; + } + + /** + * Reset the handler to ensure data cleared + */ + public void reset() + { + _handler = null; + _unknownType = null; + } + + /** + * Open the selected file + * @param inFile File to open + */ + public void openFile(File inFile) + { + _file = inFile; + reset(); + // start new thread in case xml parsing is time-consuming + new Thread(this).start(); + } + + + /** + * Run method, to parse the file + * @see java.lang.Runnable#run() + */ + public void run() + { + FileInputStream inStream = null; + boolean success = false; + try + { + inStream = new FileInputStream(_file); + success = parseXmlStream(inStream); + } + catch (FileNotFoundException fnfe) {} + + // Clean up the stream, don't need it any more + try {inStream.close();} catch (IOException e2) {} + + if (success) + { + // Check whether handler was properly instantiated + if (_handler == null) + { + // Wasn't either kml or gpx + _app.showErrorMessageNoLookup("error.load.dialogtitle", + I18nManager.getText("error.load.unknownxml") + " " + _unknownType); + } + else + { + SourceInfo.FILE_TYPE sourceType = (_handler instanceof GpxHandler ? SourceInfo.FILE_TYPE.GPX : SourceInfo.FILE_TYPE.KML); + SourceInfo sourceInfo = new SourceInfo(_file, sourceType); + sourceInfo.setFileTitle(_handler.getFileTitle()); + + // Pass information back to app + _app.informDataLoaded(_handler.getFieldArray(), _handler.getDataArray(), + null, sourceInfo, _handler.getTrackNameList(), + new MediaLinkInfo(_handler.getLinkArray())); + } + } + } + + + /** + * Try both Xerces and the built-in java classes to parse the given xml stream + * @param inStream input stream from file / zip / gzip + * @return true on success, false if both xerces and built-in parser failed + */ + public boolean parseXmlStream(InputStream inStream) + { + boolean success = false; + // Firstly, try to use xerces to parse the xml (will throw an exception if not available) + try + { + XMLReader xmlReader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); + xmlReader.setContentHandler(this); + xmlReader.parse(new InputSource(inStream)); + success = true; // worked + } + catch (Exception e) {} // don't care too much if it didn't work, there's a backup + + // If that didn't work, try the built-in classes (which work for xml1.0 but handling for 1.1 contains bugs) + if (!success) + { + try + { + // Construct a SAXParser and use this as a default handler + SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); + saxParser.parse(inStream, this); + success = true; + } + catch (Exception e) + { + // Show error dialog + _app.showErrorMessageNoLookup("error.load.dialogtitle", + I18nManager.getText("error.load.othererror") + " " + e.getMessage()); + } + } + return success; + } + + /** + * Receive a tag + * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) + */ + public void startElement(String uri, String localName, String qName, + Attributes attributes) throws SAXException + { + // Check for "kml" or "gpx" tags + if (_handler == null) + { + if (qName.equals("kml")) {_handler = new KmlHandler();} + else if (qName.equals("gpx")) {_handler = new GpxHandler();} + else if (_unknownType == null && !qName.equals("")) + { + _unknownType = qName; + } + } + else + { + // Handler instantiated so pass tags on to it + _handler.startElement(uri, localName, qName, attributes); + } + super.startElement(uri, localName, qName, attributes); + } + + + /** + * Receive characters, either between or inside tags + * @see org.xml.sax.ContentHandler#characters(char[], int, int) + */ + public void characters(char[] ch, int start, int length) + throws SAXException + { + if (_handler != null) + { + // Handler instantiated so pass tags on to it + _handler.characters(ch, start, length); + } + super.characters(ch, start, length); + } + + + /** + * Receive end of element + * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String) + */ + public void endElement(String uri, String localName, String qName) + throws SAXException + { + if (_handler != null) + { + // Handler instantiated so pass tags on to it + _handler.endElement(uri, localName, qName); + } + super.endElement(uri, localName, qName); + } + + /** + * @return The Xml handler used for the parsing + */ + public XmlHandler getHandler() + { + return _handler; + } +}