1 package tim.prune.save;
4 import java.io.FileInputStream;
5 import java.io.InputStream;
6 import java.util.zip.GZIPInputStream;
7 import java.util.zip.ZipEntry;
8 import java.util.zip.ZipInputStream;
10 import javax.xml.parsers.SAXParser;
11 import javax.xml.parsers.SAXParserFactory;
13 import org.xml.sax.Attributes;
14 import org.xml.sax.SAXException;
15 import org.xml.sax.helpers.DefaultHandler;
17 import tim.prune.data.DataPoint;
18 import tim.prune.data.SourceInfo;
21 * Class to read in a GPX file and cache all the point strings
23 public class GpxCacher extends DefaultHandler
25 private SourceInfo _sourceInfo = null;
26 private String _headerString = null;
27 private String[] _strings = null;
28 private int _pointNum = 0;
29 private boolean _insidePoint = false;
30 private StringBuilder _builder = null;
35 * @param inSourceInfo source information
37 public GpxCacher(SourceInfo inInfo)
40 _strings = new String[inInfo.getNumPoints()];
42 // Should be a gpx file, but might be raw, zipped or gzipped
43 File gpxFile = inInfo.getFile();
44 String fileName = gpxFile.getName().toLowerCase();
45 if (gpxFile.exists() && gpxFile.canRead())
48 SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
49 if (fileName.endsWith(".gpx") || fileName.endsWith(".xml")) {
50 saxParser.parse(inInfo.getFile(), this);
52 else if (fileName.endsWith(".zip")) {
53 saxParser.parse(getZipInputStream(inInfo.getFile()), this);
55 else if (fileName.endsWith(".gz")) {
56 saxParser.parse(new GZIPInputStream(new FileInputStream(inInfo.getFile())), this);
59 System.out.println("GpxCacher unrecognised file type: " + inInfo.getFile().getName());
61 } catch (Exception e) {
62 // TODO: Handle errors here with a list of warnings?
71 * Receive the start of a tag
73 public void startElement(String inUri, String inLocalName, String inTagName,
74 Attributes inAttributes) throws SAXException
76 if (inTagName.equalsIgnoreCase("gpx"))
78 // store initial gpx tag
79 _builder = new StringBuilder(60);
80 appendTag(_builder, inTagName, inAttributes);
81 _headerString = _builder.toString();
85 if (inTagName.equalsIgnoreCase("wpt") || inTagName.equalsIgnoreCase("trkpt")
86 || inTagName.equalsIgnoreCase("rtept"))
89 _builder = new StringBuilder(60);
92 appendTag(_builder, inTagName, inAttributes);
95 super.startElement(inUri, inLocalName, inTagName, inAttributes);
99 * Receive characters between tags (inside or outside)
101 public void characters(char[] inChars, int inStart, int inLength)
105 _builder.append(new String(inChars, inStart, inLength));
107 super.characters(inChars, inStart, inLength);
111 * Receive end of xml tag
113 public void endElement(String inUri, String inLocalName, String inTagName)
117 _builder.append("</").append(inTagName).append('>');
119 if (inTagName.equalsIgnoreCase("wpt") || inTagName.equalsIgnoreCase("trkpt")
120 || inTagName.equalsIgnoreCase("rtept"))
122 _strings[_pointNum] = _builder.toString();
124 _insidePoint = false;
126 super.endElement(inUri, inLocalName, inTagName);
131 * Append the current tag to the supplied StringBuilder
132 * @param inBuilder Stringbuilder object to append tag to
133 * @param inTagName name of tag
134 * @param inAttributes attributes of tag
136 private static void appendTag(StringBuilder inBuilder, String inTagName, Attributes inAttributes)
138 inBuilder.append('<').append(inTagName);
139 int numAtts = inAttributes.getLength();
140 for (int i=0; i<numAtts; i++) {
141 inBuilder.append(' ').append(inAttributes.getQName(i)).append("=\"")
142 .append(inAttributes.getValue(i)).append('"');
144 inBuilder.append('>');
149 * @return the header string from the GPX tag
151 public String getHeaderString()
153 return _headerString;
157 * Get the source string for the given point
158 * @param inPoint point to retrieve
159 * @return string if found, otherwise null
161 public String getSourceString(DataPoint inPoint)
163 int index = _sourceInfo.getIndex(inPoint);
165 return _strings[index];
171 * Get an inputstream of a GPX file inside a zip
172 * @param inFile File object describing zip file
173 * @return input stream for Xml parser
175 private static InputStream getZipInputStream(File inFile)
179 ZipInputStream zis = new ZipInputStream(new FileInputStream(inFile));
180 while (zis.available() > 0)
182 ZipEntry entry = zis.getNextEntry();
183 String entryName = entry.toString();
184 if (entryName != null && entryName.length() > 4)
186 String suffix = entryName.substring(entryName.length()-4).toLowerCase();
187 if (suffix.equals(".gpx") || suffix.equals(".xml")) {
188 // First matching file so must be gpx
194 catch (Exception e) {} // ignore errors
195 // not found - error!