package com.bluevia.android.location.parser.xml; import java.io.IOException; import java.io.InputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.util.Log; import android.util.Xml; import com.bluevia.android.commons.Entity; import com.bluevia.android.commons.parser.IParser; import com.bluevia.android.commons.parser.ParseException; import com.bluevia.android.commons.parser.xml.XmlConstants; import com.bluevia.android.commons.parser.xml.XmlParserSerializerUtils; import com.bluevia.android.location.data.CoordinatesType; import com.bluevia.android.location.data.LocationDataType; import com.bluevia.android.location.data.LocationDataType.ReportStatus; import com.bluevia.android.location.data.LocationInfoType; /** * XML implementation of {@link com.bluevia.android.commons.parser.IParser IParser} * Class that represents the parser object for any Location entity. * Using this class you will be able to parse XML documents containing * a representation of any Location entity into an instance * object of this entity * * @author Telefonica R&D * */ public class XmlLocationParser implements IParser { private static final String TAG = "XmlLocationParser"; private XmlPullParser mParser; public Entity parse(InputStream is) throws ParseException { if (is == null) throw new ParseException("Input stream is null"); LocationDataType locationData = null; mParser = Xml.newPullParser(); try { mParser.setInput(is,null); } catch(XmlPullParserException e){ Log.e(TAG, "Exception occureed while reading the XML Document", e); throw new ParseException("Could not create XmlLocationParser", e); } int eventType; try { eventType = mParser.getEventType(); Log.d(TAG, "EventType: " + eventType); } catch (XmlPullParserException e) { throw new ParseException("Could not parse LocationDataType entity.", e); } if (eventType != XmlPullParser.START_DOCUMENT) { Log.e(TAG, "Attempting to initialize parsing beyond " + "the start of the document."); throw new ParseException("",new XmlPullParserException("Attempting to initialize parsing beyond " + "the start of the document.")); } String text = ""; String tagName = ""; while (eventType != XmlPullParser.END_DOCUMENT){ try { eventType = mParser.next(); Log.d(TAG, "Event type:" + eventType); } catch (XmlPullParserException e) { throw new ParseException("Ill-formed xml"); } catch (IOException e) { throw new ParseException(e); } tagName = mParser.getName(); if (tagName!=null){ Log.d(TAG, "name = " + tagName); } text = mParser.getText(); if (text!=null){ Log.d(TAG, "text = " + text); } if (eventType == XmlPullParser.START_TAG){ if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_LOCATION)){ Entity entity; try { entity = parseLocationEntity(eventType); } catch (IOException e) { throw new ParseException(e); } if (entity instanceof LocationDataType){ locationData = (LocationDataType) entity; } else throw new ParseException("Invalid received entity"); } else throw new ParseException("Unrecognized tag: "+tagName); } } return locationData; } private LocationDataType parseLocationEntity(int eventType) throws ParseException, IOException { LocationDataType locationDataType = new LocationDataType(); while (eventType != XmlPullParser.END_DOCUMENT){ try { eventType = mParser.next(); Log.d(TAG, "Event type:" + eventType); } catch (XmlPullParserException e) { throw new ParseException("Ill-formed xml"); } String tagName = mParser.getName(); if (tagName!=null){ Log.d(TAG, "name = " + tagName); } String text = mParser.getText(); if (text!=null){ Log.d(TAG, "text = " + text); } switch (eventType) { case XmlPullParser.END_TAG: if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_LOCATION)) { return locationDataType; } break; case XmlPullParser.START_TAG: if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_LOCATEDPARTY)){ try { locationDataType.setLocationParty( XmlParserSerializerUtils.parseUserId(mParser, eventType, XmlConstants.XSD_TERMINALLOCATION_LOCATEDPARTY)); } catch (XmlPullParserException e) { Log.e(TAG, "Error in XmlLocationParser " + e.getMessage(), e); throw new ParseException("Ill-formed xml"); } } else if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_CURRENTLOCATION)){ try { locationDataType.setCurrentLocation(parseCurrentLocation(eventType)); } catch (NumberFormatException e) { Log.e(TAG, "Error in XmlLocationParser " + e.getMessage(), e); throw new ParseException("Altitude number not valid"); } catch (XmlPullParserException e) { Log.e(TAG, "Error in XmlLocationParser " + e.getMessage(), e); throw new ParseException("Acurracy number not valid"); } catch (java.text.ParseException e) { Log.e(TAG, "Error in XmlLocationParser " + e.getMessage(), e); throw new ParseException("Timestamp not valid"); } Log.d(TAG, XmlConstants.XSD_TERMINALLOCATION_CURRENTLOCATION); } else if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_REPORTSTATUS)){ try{ ReportStatus status = stringToRetrievalStatus(XmlParserSerializerUtils.getChildText(mParser)); locationDataType.setReportStatus(status); } catch (XmlPullParserException e) { throw new ParseException("Ill-formed xml"); } } else if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_ERRORINFORMATION)){ Log.d(TAG, XmlConstants.XSD_TERMINALLOCATION_ERRORINFORMATION); //TODO parseError } default: break; } } return null; } private LocationInfoType parseCurrentLocation(int eventType) throws ParseException, IOException, NumberFormatException, XmlPullParserException, java.text.ParseException { LocationInfoType locationInfo = new LocationInfoType(); while (eventType != XmlPullParser.END_DOCUMENT){ try { eventType = mParser.next(); Log.d(TAG, "Event type:" + eventType); } catch (XmlPullParserException e) { throw new ParseException("Ill-formed xml"); } String tagName = mParser.getName(); if (tagName!=null){ Log.d(TAG, "name = " + tagName); } String text = mParser.getText(); if (text!=null){ Log.d(TAG, "text = " + text); } switch (eventType) { case XmlPullParser.END_TAG: if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_CURRENTLOCATION)) { return locationInfo; } break; case XmlPullParser.START_TAG: if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_COORDINATES)){ locationInfo.setCoordinates(parseCoordinates(eventType)); } else if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_ALTITUDE)){ locationInfo.setAltitude(Float.valueOf(XmlParserSerializerUtils.getChildText(mParser))); } else if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_ACCURACY)){ locationInfo.setAccuracy(Integer.valueOf(XmlParserSerializerUtils.getChildText(mParser))); } else if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_TIMESTAMP)){ DateFormat formatter = new SimpleDateFormat("yyyy-mm-dd'T'HH:mm:ss"); locationInfo.setTimestamp((Date)formatter.parse(XmlParserSerializerUtils.getChildText(mParser))); } else { throw new ParseException("Unrecognized tag: "+tagName); } default: break; } } return null; } private CoordinatesType parseCoordinates(int eventType) throws ParseException, IOException, NumberFormatException, XmlPullParserException { float latitude = 0, longitude = 0; while (eventType != XmlPullParser.END_DOCUMENT){ try { eventType = mParser.next(); Log.d(TAG, "Event type:" + eventType); } catch (XmlPullParserException e) { throw new ParseException("Ill-formed xml"); } String tagName = mParser.getName(); if (tagName!=null){ Log.d(TAG, "name = " + tagName); } String text = mParser.getText(); if (text!=null){ Log.d(TAG, "text = " + text); } switch (eventType) { case XmlPullParser.END_TAG: if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_COORDINATES)) { return new CoordinatesType(longitude, latitude); } break; case XmlPullParser.START_TAG: if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_LATITUDE)){ latitude = Float.valueOf(XmlParserSerializerUtils.getChildText(mParser)); } else if (tagName.equals(XmlConstants.XSD_TERMINALLOCATION_LONGITUDE)){ longitude = Float.valueOf(XmlParserSerializerUtils.getChildText(mParser)); } else { throw new ParseException("Unrecognized tag: "+tagName); } default: break; } } return null; } private ReportStatus stringToRetrievalStatus(String typeStr) { if (typeStr == null) return null; typeStr = typeStr.trim(); if (typeStr.equals(XmlConstants.XSD_TERMINALLOCATION_REPORTSTATUS_ATTR_RETRIEVED_VALUE)) { return ReportStatus.RETRIEVED; } else if (typeStr.equals(XmlConstants.XSD_TERMINALLOCATION_REPORTSTATUS_ATTR_NONRETRIEVED_VALUE)) { return ReportStatus.NON_RETRIEVED; } else if (typeStr.equals(XmlConstants.XSD_TERMINALLOCATION_REPORTSTATUS_ATTR_ERROR_VALUE)) { return ReportStatus.ERROR; } else return null; } }