package openadk.library.impl.surrogates; import java.math.BigDecimal; import javax.xml.datatype.Duration; import javax.xml.stream.XMLStreamReader; import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.jxpath.ri.model.NodePointer; import openadk.library.*; import openadk.library.impl.ElementDefAlias; import openadk.library.trans.BusRouteInfo; import openadk.library.trans.DistanceUnit; import openadk.util.XMLWriter; /** * A surrogate for rendering the RouteDuration and RouteStatus elements, which * changed shape between SIF 1.5 and SIF 2.0 * * @author Andrew * */ public class RouteElementSurrogate extends AbstractRenderSurrogate implements RenderSurrogate { public RouteElementSurrogate(ElementDef def) { super(def); } public void renderRaw(XMLWriter writer, SIFVersion version, Element o, SIFFormatter formatter) throws SIFException { String type = "Total"; if (fElementDef.name().endsWith("Loaded")) { type = "Loaded"; } SIFSimpleType typedValue = o.getSIFValue(); String elementName = "RouteDuration"; if (fElementDef != null && fElementDef instanceof ElementDefAlias && ((ElementDefAlias) fElementDef).internalName().startsWith("RouteDistance")) { elementName = "RouteDistance"; SimpleField unit = ((SIFElement) o).getField("Unit"); if (unit != null && unit.getTextValue().equalsIgnoreCase("km")) { // Convert the km value to miles, which is how it is always // represented in SIF 1.x if (typedValue != null) { SIFDecimal kilometers = (SIFDecimal) typedValue; BigDecimal rawValue = kilometers.getValue(); if (rawValue != null) { rawValue = rawValue.multiply(new BigDecimal(0.621371192)); typedValue = new SIFDecimal(rawValue); } } } } String value = ""; if (typedValue != null) { value = typedValue.toString(formatter); } if (type != null && value != null) { writer.tab(); writer.write("<"); writer.write(elementName); writer.write(" Type=\""); writer.write(type); writer.write("\">"); writer.write(value); writer.write("</"); writer.write(elementName); writer.write(">"); writer.write("\r\n"); } } public boolean readRaw(XMLStreamReader reader, SIFVersion version, SIFElement parent, SIFFormatter formatter) throws ADKParsingException { String name = reader.getLocalName(); if (!name.startsWith("RouteD")) { return false; } BusRouteInfo busRoute = (BusRouteInfo) parent; String type = reader.getAttributeValue(null, "Type"); String value = consumeElementTextValue(reader, version); // TODO: Better type conversion if (type != null && value != null) { if (name.equals("RouteDuration")) { Duration duration = formatter.toDuration(value); if ("Total".equals(type)) { busRoute.setRouteDurationTotal(duration); } else if ("Loaded".equals(type)) { busRoute.setRouteDurationLoaded(duration); } } else if ( name.equals("RouteDistance")) { BigDecimal distance = new BigDecimal(value); if ( "Total".equals(type)) { busRoute.setRouteDistanceTotal(DistanceUnit.M, distance ); } else if ( "Loaded".equals(type) ) { busRoute.setRouteDistanceLoaded(DistanceUnit.M, distance ); } } } return true; } public NodePointer createChild(NodePointer parentPointer, SIFFormatter formatter, SIFVersion version, JXPathContext context) { // TODO Auto-generated method stub return null; } public NodePointer createNodePointer(NodePointer parent, Element element, SIFVersion version) { // TODO Auto-generated method stub return null; } public String getPath() { String type = "Total"; if (fElementDef.name().endsWith("Loaded")) { type = "Loaded"; } String elementName = "RouteDuration"; if (fElementDef.name().startsWith("RouteDistance")) { elementName = "RouteDistance"; } return elementName + "[@Type='" + type + "']"; } }