package tim.prune.save.xml;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import tim.prune.data.DataPoint;
import tim.prune.data.SourceInfo;
/**
* Class to read in a GPX file and cache all the point strings
*/
public class GpxCacher implements TagReceiver
{
private SourceInfo _sourceInfo = null;
private String _headerString = null;
private String[] _strings = null;
private int _pointNum = 0;
/**
* Constructor
* @param inSourceInfo source information
*/
public GpxCacher(SourceInfo inInfo)
{
_sourceInfo = inInfo;
_strings = new String[inInfo.getNumPoints()];
_pointNum = 0;
// Should be a gpx file, but might be raw, zipped or gzipped
File gpxFile = inInfo.getFile();
String fileName = gpxFile.getName().toLowerCase();
if (gpxFile.exists() && gpxFile.canRead())
{
GpxSlicer slicer = new GpxSlicer(this);
InputStream istream = null;
BufferedInputStream bstream = null;
try {
if (fileName.endsWith(".gpx") || fileName.endsWith(".xml")) {
istream = new FileInputStream(inInfo.getFile());
}
else if (fileName.endsWith(".zip")) {
istream = getZipInputStream(inInfo.getFile());
}
else if (fileName.endsWith(".gz")) {
istream = new GZIPInputStream(new FileInputStream(inInfo.getFile()));
}
else {
System.out.println("GpxCacher unrecognised file type: " + inInfo.getFile().getName());
}
if (istream != null) {
bstream = new BufferedInputStream(istream);
slicer.slice(bstream);
bstream.close();
}
} catch (Exception e) {
// TODO: Handle errors here with a list of warnings?
e.printStackTrace();
}
}
}
/**
* Accept a tag from the slicer
*/
public void reportTag(String inTag)
{
if (_headerString == null) {
_headerString = inTag;
}
else if (_strings != null)
{
if (_pointNum < _strings.length)
{
_strings[_pointNum] = inTag;
_pointNum++;
}
else
{
// _pointNum has got too high for the strings array
// This means the cacher has failed, probably by invalid points - need to give up caching here
_strings = null;
}
}
}
/**
* @return the header string from the GPX tag
*/
public String getHeaderString()
{
return _headerString;
}
/**
* Get the source string for the given point
* @param inPoint point to retrieve
* @return string if found, otherwise null
*/
public String getSourceString(DataPoint inPoint)
{
int index = _sourceInfo.getIndex(inPoint);
if (_strings != null && index >= 0 && index < _strings.length) {
return _strings[index];
}
return null;
}
/**
* Get an inputstream of a GPX file inside a zip
* @param inFile File object describing zip file
* @return input stream for Xml parser
*/
private static InputStream getZipInputStream(File inFile)
{
try
{
ZipInputStream zis = new ZipInputStream(new FileInputStream(inFile));
while (zis.available() > 0)
{
ZipEntry entry = zis.getNextEntry();
String entryName = entry.toString();
if (entryName != null && entryName.length() > 4)
{
String suffix = entryName.substring(entryName.length()-4).toLowerCase();
if (suffix.equals(".gpx") || suffix.equals(".xml")) {
// First matching file so must be gpx
return zis;
}
}
}
}
catch (Exception e) {} // ignore errors
// not found - error!
return null;
}
}