// Created by plusminus on 18:06:19 - 07.11.2008
package org.androad.sys.ors.ds.openrouteservice;
import java.util.ArrayList;
import org.osmdroid.util.GeoPoint;
import org.androad.sys.ors.adt.Error;
import org.androad.sys.ors.adt.ds.ORSPOI;
import org.androad.sys.ors.adt.ds.POIType;
import org.androad.sys.ors.exceptions.ORSException;
import org.androad.util.constants.Constants;
import org.androad.util.constants.TimeConstants;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
/**
* Parses XML-Data like:
* <pre><?xml version="1.0" encoding="UTF-8"?>
* <xls:XLS xmlns:xls="http://www.opengis.net/xls" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" version="1.1" xsi:schemaLocation="http://www.opengis.net/xls http://schemas.opengis.net/ols/1.1.0/DirectoryService.xsd">
* <xls:ResponseHeader xsi:type="xls:ResponseHeaderType"/>
* <xls:Response xsi:type="xls:ResponseType" requestID="123456789" version="1.1" numberOfResponses="13">
* <xls:DirectoryResponse xsi:type="xls:DirectoryResponseType">
* <xls:POIContext>
* <xls:POI POIName="Kocaman" description="bakery" ID="293710580">
* <gml:Point>
* <gml:pos srsName="EPSG:4326">7.0866882 50.7335413</gml:pos>
* </gml:Point>
* </xls:POI>
* <xls:Distance uom="M" value="625"/>
* </xls:POIContext>
* ...
* <xls:POIContext>
* <xls:POI POIName="Domgorgen" description="bakery" ID="270495053">
* <gml:Point>
* <gml:pos srsName="EPSG:4326">7.0922473 50.7741497</gml:pos>
* </gml:Point>
* </xls:POI>
* <xls:Distance uom="KM" value="5"/>
* </xls:POIContext>
* </xls:DirectoryResponse>
* </xls:Response>
* </xls:XLS></pre>
*
* @author Nicolas Gramlich
*
*/
public class OpenRouteServiceDSParser extends DefaultHandler implements TimeConstants, Constants{
// ====================================
// Constants
// ====================================
// ====================================
// Fields
// ====================================
private final ArrayList<Error> mErrors = new ArrayList<Error>();
private ArrayList<ORSPOI> mPOIs;
private ORSPOI mCurPOI;
private boolean inXLS = false;
private boolean inRepsonseHeader = false;
private boolean inRepsonse = false;
private boolean inDirectoryResponse = false;
private boolean inPOIContext = false;
private boolean inPOI = false;
private boolean inPoint = false;
private boolean inPos = false;
private boolean inDistance = false;
// ===========================================================
// Getter & Setter
// ===========================================================
public ArrayList<Error> getErrors(){
return this.mErrors;
}
public ArrayList<ORSPOI> getDSResponse() throws ORSException{
if(this.mErrors != null && this.mErrors.size() > 0) {
throw new ORSException(this.mErrors);
}
return this.mPOIs;
}
// ====================================
// Methods from Superclasses
// ====================================
@Override
public void startDocument() throws SAXException {
super.startDocument();
this.mPOIs = new ArrayList<ORSPOI>();
}
@Override
public void startElement(final String uri, final String localName, final String name, final Attributes attributes) throws SAXException {
if(localName.equals("Error") || name.equals("Error")){
final String errorCode = attributes.getValue("", "errorCode");
final String severity = attributes.getValue("", "severity");
final String locationPath = attributes.getValue("", "locationPath");
final String message = attributes.getValue("", "message");
this.mErrors.add(new Error(errorCode, severity, locationPath, message));
}
this.sb.setLength(0);
if(localName.equals("XLS")){
this.inXLS = true;
} else if(localName.equals("ResponseHeader")){
this.inRepsonseHeader = true;
} else if(localName.equals("Response")){
this.inRepsonse = true;
} else if(localName.equals("DirectoryResponse")){
this.inDirectoryResponse = true;
} else if(localName.equals("POIContext")){
this.inPOIContext = true;
} else if(localName.equals("POI")){
this.inPOI = true;
this.mCurPOI = new ORSPOI();
final String poiname = attributes.getValue("", "POIName");
final String poitype = attributes.getValue("", "description");
this.mCurPOI.setName(poiname);
this.mCurPOI.setPOIType(POIType.fromRawName(poitype));
this.mPOIs.add(this.mCurPOI);
} else if(localName.equals("Point")){
this.inPoint = true;
} else if(localName.equals("pos")){
this.inPos = true;
} else if(localName.equals("Distance")){
this.inDistance = true;
final String uom = attributes.getValue("", "uom");
float factor = 0;
if(uom != null){
if(uom.equals("M")){
factor = 1;
}else if(uom.equals("KM")){
factor = 1000;
}
}
this.mCurPOI.setDistance((int)(factor * Float.parseFloat(attributes.getValue("", "value"))));
} else {
Log.w(DEBUGTAG, "Unexpected tag: '" + name + "'");
}
super.startElement(uri, localName, name, attributes);
}
private final StringBuilder sb = new StringBuilder();
@Override
public void characters(final char[] chars, final int start, final int length) throws SAXException {
this.sb.append(chars, start, length);
super.characters(chars, start, length);
}
@Override
public void endElement(final String uri, final String localName, final String name) throws SAXException {
if(localName.equals("XLS")){
this.inXLS = false;
} else if(localName.equals("ResponseHeader")){
this.inRepsonseHeader = false;
} else if(localName.equals("Response")){
this.inRepsonse = false;
} else if(localName.equals("DirectoryResponse")){
this.inDirectoryResponse = false;
} else if(localName.equals("POIContext")){
this.inPOIContext = false;
} else if(localName.equals("POI")){
this.inPOI = false;
} else if(localName.equals("Point")){
this.inPoint = false;
} else if(localName.equals("pos")){
this.inPos = false;
this.mCurPOI.setGeoPoint(GeoPoint.fromInvertedDoubleString(this.sb.toString(), ' '));
} else if(localName.equals("Distance")){
this.inDistance = false;
} else {
Log.w(DEBUGTAG, "Unexpected end-tag: '" + name + "'");
}
// Reset the stringbuffer
this.sb.setLength(0);
super.endElement(uri, localName, name);
}
@Override
public void endDocument() throws SAXException {
if(this.mErrors == null || this.mErrors.size() == 0){
// Maybe do some finalization or similar...
}
super.endDocument();
}
// ====================================
// Helper-Methods
// ====================================
}