package developer; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.StringReader; import java.io.StringWriter; import java.util.Vector; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import oculusPrime.Util; /** manage XML file for navigation */ public class NavigationUtilities { public static File navroutesfile = new File(System.getenv("RED5_HOME")+"/conf/navigationroutes.xml"); public static final String ESTIMATED_DISTANCE_TAG = "estimateddistance"; public static final String ESTIMATED_TIME_TAG = "estimatedtime"; public static final String ROUTE_COUNT_TAG = "routecount"; public static final String ROUTE_FAIL_TAG = "routefail"; public static final String WAYPOINT_NAME = "wpname"; public static final String ROUTE_NAME = "rname"; public static final String ACTIVE = "active"; public static synchronized void saveRoute(final String str){ final String current = routesLoad(); if(str.equalsIgnoreCase(current)){ // Util.debug("saveRoute(): skipped, same XML string"); return; } // TODO: COMPARE TWO STRING... RETURN NAME OF ROUTE THAT WAS EDITED... ? or reset states, esitmates? try { FileWriter fw = new FileWriter(navroutesfile); fw.append(str); fw.close(); } catch (Exception e){ Util.printError(e); } } /** */ public static String XMLtoString(Document doc) { String output = null; try { TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); StringWriter writer = new StringWriter(); transformer.transform(new DOMSource(doc), new StreamResult(writer)); output = writer.getBuffer().toString().replaceAll("\n|\r", ""); } catch (Exception e){ Util.printError(e); } return output; } /** */ public static String routesLoad(){ String result = ""; BufferedReader reader; try { reader = new BufferedReader(new FileReader(navroutesfile)); String line = ""; while ((line = reader.readLine()) != null) result += line; reader.close(); } catch (Exception e) { return "<routeslist></routeslist>"; } return result; } /** */ public static Document loadXMLFromString(String xml){ try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder; builder = factory.newDocumentBuilder(); InputSource is = new InputSource(new StringReader(xml)); return builder.parse(is); } catch (Exception e){e.printStackTrace(); } return null; } /** */ public static Vector<String> getRoutes(final String xml){ Vector<String> names = new Vector<String>(); NodeList routes = loadXMLFromString(xml).getDocumentElement().getChildNodes(); for(int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); names.add(rname); } return names; } /** */ public static Vector<String> getRoutes(){ return getRoutes(routesLoad()); } /** */ public static Vector<String> getWaypointsForRoute(final String routename, final String xml){ if(routename == null) return null; Document document = loadXMLFromString(xml); NodeList routes = document.getDocumentElement().getChildNodes(); Vector<String> ans = new Vector<String>(); for(int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); if(routename.equals(rname)){ NodeList wp = ((Element) routes.item(i)).getElementsByTagName(WAYPOINT_NAME); for(int j = 0 ; j < wp.getLength() ; j++){ ans.add(wp.item(j).getTextContent()); // TODO: if( wp.item(j).getTextContent().contains(" ")) Util.log("getWaypointsForRoute(): ... WARNING .... HTML CHARATERS IN NAV XML ...", "NavigationUtilities.getWaypointsForRoute()"); } } } return ans; } /** */ public static Vector<String> getWaypointsForRoute(String rname) { return getWaypointsForRoute(rname, routesLoad()); } /** */ public static String getTag(final String tag, final String xml) throws ParserConfigurationException{ if(tag == null || xml == null) return null; /* <routeslist> <route> <rname>back door</rname> <minbetween>2</minbetween> <starthour>00</starthour> <startmin>00</startmin> <routeduration>24</routeduration> <day>Sun</day> <active>false</active> <waypoint> <wpname>deck</wpname> <duration>10</duration> <action>photo</action> </waypoint> <estimateddistance>5</estimateddistance> <estimatedtime>158</estimatedtime> <day>Mon</day><day>Tue</day><day>Wed</day><day>Thu</day><day>Fri</day><day>Sat</day> <routecount>151</routecount> <routefail>5</routefail> <waypoint> <wpname>coner</wpname> <duration>10</duration> <action>photo</action></waypoint><waypoint><wpname>sink</wpname><duration>10</duration><action>photo</action></waypoint></route> ... </routeslist> neelcant and case worker donna and raven song */ String start = "<" + tag + ">"; String end = "</" + tag + ">"; String sub = xml.substring( xml.indexOf(start) + start.length(), xml.indexOf(end)); return sub; } //---------------- route fails public static int getRouteFails(final String name){ return Integer.parseInt(getRouteFailsString(name)); } public static int getRouteFails(final String name, final String xml){ return Integer.parseInt(getRouteFailsString(name, xml)); } public static String getRouteFailsString(final String name){ return getRouteFailsString(name, routesLoad()); } public static String getRouteFailsString(final String name, final String xml){ if(name == null || xml == null) return "0"; NodeList routes = loadXMLFromString(xml).getDocumentElement().getChildNodes(); for (int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); if (rname.equals(name)){ try { return ((Element) routes.item(i)).getElementsByTagName(ROUTE_FAIL_TAG).item(0).getTextContent(); } catch (Exception e){} break; } } return "0"; } public static void setRouteFails(final String name, final int routefails){ if(name == null) return; Document document = NavigationUtilities.loadXMLFromString(routesLoad()); NodeList routes = document.getDocumentElement().getChildNodes(); Element route = null; for (int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); if (rname.equals(name)){ route = (Element) routes.item(i); try { route.getElementsByTagName(ROUTE_FAIL_TAG).item(0).setTextContent(Integer.toString(routefails)); } catch (Exception e) { // create if not there Node fail = document.createElement(ROUTE_FAIL_TAG); fail.setTextContent(Integer.toString(routefails)); route.appendChild(fail); } saveRoute(XMLtoString(document)); break; } } } //--------------- route count public static void setRouteCount(final String name, final int routecount){ if(name == null) return; Document document = NavigationUtilities.loadXMLFromString(routesLoad()); NodeList routes = document.getDocumentElement().getChildNodes(); Element route = null; for (int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); if (rname.equals(name)){ route = (Element) routes.item(i); try { route.getElementsByTagName(ROUTE_COUNT_TAG).item(0).setTextContent(Integer.toString(routecount)); } catch (Exception e) { // create if not there Node count = document.createElement(ROUTE_COUNT_TAG); count.setTextContent(Integer.toString(routecount)); route.appendChild(count); } saveRoute(XMLtoString(document)); break; } } } public static String getRouteCountString(final String name, final String xml){ if(name == null || xml == null) return "0"; NodeList routes = loadXMLFromString(xml).getDocumentElement().getChildNodes(); for (int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); if (rname.equals(name)){ try { return ((Element) routes.item(i)).getElementsByTagName(ROUTE_COUNT_TAG).item(0).getTextContent(); } catch (Exception e){break;} } } return "0"; } public static String getRouteCountString(final String name){ return getRouteCountString(name, routesLoad()); } public static int getRouteCount(final String name, final String xml){ return Integer.parseInt(getRouteCountString(name, xml)); } public static int getRouteCount(final String name){ return Integer.parseInt(getRouteCountString(name)); } //------------ distance -- units meters ---------// public static void setRouteDistanceEstimate(final String name, final int meters){ if(name == null) return; Document document = NavigationUtilities.loadXMLFromString(routesLoad()); NodeList routes = document.getDocumentElement().getChildNodes(); Element route = null; for (int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); if (rname.equals(name)){ route = (Element) routes.item(i); try { route.getElementsByTagName(ESTIMATED_DISTANCE_TAG).item(0).setTextContent(Util.formatFloat(meters, 0)); } catch (Exception e) { // create if not there Node dist = document.createElement(ESTIMATED_DISTANCE_TAG); dist.setTextContent(Util.formatFloat(meters, 0)); route.appendChild(dist); } saveRoute(XMLtoString(document)); break; } } } public static String getRouteDistanceEstimateString(final String name, final String xml){ if(name == null || xml == null) return "0"; NodeList routes = loadXMLFromString(xml).getDocumentElement().getChildNodes(); for (int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); if (rname.equals(name)){ try { return ((Element) routes.item(i)).getElementsByTagName(ESTIMATED_DISTANCE_TAG).item(0).getTextContent(); } catch (Exception e){return "0";} } } return "0"; } public static String getRouteDistanceEstimateString(final String name){ return getRouteDistanceEstimateString(name, routesLoad()); } public static int getRouteDistanceEstimate(final String name, final String xml){ return Integer.parseInt(getRouteDistanceEstimateString(name, xml)); } public static int getRouteDistanceEstimate(final String name){ return (int) Double.parseDouble(getRouteDistanceEstimateString(name)); } //-------------------- time -- units seconds --------------------// public static void setRouteTimeEstimate(final String name, final int seconds){ if(name == null) return; Document document = NavigationUtilities.loadXMLFromString(routesLoad()); NodeList routes = document.getDocumentElement().getChildNodes(); Element route = null; for (int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); if (rname.equals(name)){ route = (Element) routes.item(i); try { route.getElementsByTagName(ESTIMATED_TIME_TAG).item(0).setTextContent(Integer.toString(seconds)); } catch (Exception e) { // create if not there Node time = document.createElement(ESTIMATED_TIME_TAG); time.setTextContent(Integer.toString(seconds)); route.appendChild(time); } saveRoute(XMLtoString(document)); break; } } } public static String getRouteTimeEstimateString(final String name, final String xml){ if(name == null) return "0"; NodeList routes = loadXMLFromString(xml).getDocumentElement().getChildNodes(); for (int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); if (rname.equals(name)){ try { return ((Element) routes.item(i)).getElementsByTagName(ESTIMATED_TIME_TAG).item(0).getTextContent(); } catch (Exception e){return "0";} } } return "0"; } public static String getRouteTimeEstimateString(final String name){ return getRouteTimeEstimateString(name, routesLoad()); } public static int getRouteTimeEstimate(final String name, final String xml){ return (int) Double.parseDouble(getRouteTimeEstimateString(name, xml)); } public static int getRouteTimeEstimate(final String name){ return Integer.parseInt(getRouteTimeEstimateString(name)); } //-------------- active route public static String getActiveRoute(){ try { Document document = NavigationUtilities.loadXMLFromString(NavigationUtilities.routesLoad()); NodeList routes = document.getDocumentElement().getChildNodes(); for (int i = 0; i < routes.getLength(); i++) { String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); String isactive = ((Element) routes.item(i)).getElementsByTagName(ACTIVE).item(0).getTextContent(); if(isactive.equals("true")) return rname;//Boolean.TRUE.toString())) return rname; //-------------------------------------------------------------------- bpool? } } catch (DOMException e) { Util.printError(e); return null; } return null; } public static void deactivateAllRoutes() { Document document = loadXMLFromString(routesLoad()); NodeList routes = document.getDocumentElement().getChildNodes(); for (int i = 0 ; i < routes.getLength(); i++) ((Element) routes.item(i)).getElementsByTagName(ACTIVE).item(0).setTextContent("false"); String xmlString = XMLtoString(document); saveRoute(xmlString); } public static boolean routeExists(final String name){ Vector<String> routes = getRoutes(); if(routes.contains(name)) return true; return false; } public static void setActiveRoute(final String name){ if(name == null) return; if(name.equals("")) return; try { Document document = loadXMLFromString(routesLoad()); NodeList routes = document.getDocumentElement().getChildNodes(); Element route = null; for (int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); ((Element) routes.item(i)).getElementsByTagName(ACTIVE).item(0).setTextContent("false"); if(rname.equals(name)) route = (Element) routes.item(i); } route.getElementsByTagName(ACTIVE).item(0).setTextContent("true"); saveRoute(XMLtoString(document)); } catch (DOMException e) { Util.printError(e); } } public static Element getRouteElement(final String name){ return getRouteElement(name, routesLoad()); } public static Element getRouteElement(final String name, final String xml ){ try { Document document = loadXMLFromString(xml); NodeList routes = document.getDocumentElement().getChildNodes(); Element route = null; for (int i = 0; i < routes.getLength(); i++){ String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); if(rname.equals(name)) route = (Element) routes.item(i); } return route; } catch (DOMException e) { Util.printError(e); return null; } } public static void routeCompleted(final String name, final int seconds, final int meters){ setRouteCount(name, getRouteCount(name)+1); // Util.log("NavigationUtilies.routeCompleted("+name+", " + seconds + ", " + meters + "): called.. "); if(seconds <= 0 || meters <= 0) { // Util.log("NavigationUtilies.routeCompleted("+name+", " + seconds + ", " + meters + "): faillllll.. "); return; // sanity test } final int estsec = getRouteTimeEstimate(name); if(estsec == 0) setRouteTimeEstimate(name, seconds); else if(estsec != seconds) { setRouteTimeEstimate(name, (seconds+estsec)/2); // average them Util.log("routeCompleted("+name+", " + seconds + ", " + meters + "): average seconds = " + seconds + " updated = "+ (seconds+estsec)/2, "NavigationUtilities, routeCompleted()"); } final int distance = getRouteDistanceEstimate(name); if(distance == 0) setRouteDistanceEstimate(name, meters); else if(distance != meters){ setRouteDistanceEstimate(name, (distance+meters)/2); // average them Util.log("routeCompleted("+name+", " + seconds + ", " + meters + "): average meters = " + meters + " updated = "+ (distance+meters)/2, "NavigationUtilities, routeCompleted()"); } } public static void routeCompleted(String name){ setRouteCount(name, getRouteCount(name)+1); } public static void routeFailed(String name){ setRouteFails(name, getRouteFails(name)+1); } /* */ public static void resetAllRouteStats(){ Document document = NavigationUtilities.loadXMLFromString(routesLoad()); NodeList routes = document.getDocumentElement().getChildNodes(); for (int i = 0; i < routes.getLength(); i++){ Element route = (Element) routes.item(i); try { route.getElementsByTagName(ESTIMATED_TIME_TAG).item(0).setTextContent("0"); } catch (Exception e) { // create if not there Node time = document.createElement(ESTIMATED_TIME_TAG); time.setTextContent("0"); route.appendChild(time); } try { route.getElementsByTagName(ESTIMATED_DISTANCE_TAG).item(0).setTextContent("0"); } catch (Exception e) { // create if not there Node dist = document.createElement(ESTIMATED_DISTANCE_TAG); dist.setTextContent("0"); route.appendChild(dist); } try { route.getElementsByTagName(ROUTE_COUNT_TAG).item(0).setTextContent("0"); } catch (Exception e) { // create if not there Node count = document.createElement(ROUTE_COUNT_TAG); count.setTextContent("0"); route.appendChild(count); } try { route.getElementsByTagName(ROUTE_FAIL_TAG).item(0).setTextContent("0"); } catch (Exception e) { // create if not there Node fail = document.createElement(ROUTE_FAIL_TAG); fail.setTextContent("0"); route.appendChild(fail); } } // screws up junit tests // NavigationLog.newItem(NavigationLog.ALERTSTATUS, "Utilities.resetAllRouteStats"); // Util.log("NavigationUtilies.developer.NavigationUtilities.resetAllRouteStats(): " + XMLtoString(document)); saveRoute(XMLtoString(document)); } /** do in single method, don't call helper methods in loop, too many file operations */ public static String getRouteStatsHTML(){ String info = "<table >\n<tbody><tr><th>Route Name <th>Seconds<th>Meters</font><th>Success<th>Failures</tr>"; Document document = NavigationUtilities.loadXMLFromString(routesLoad()); NodeList routes = document.getDocumentElement().getChildNodes(); for (int i = 0; i < routes.getLength(); i++){ try { Element route = (Element) routes.item(i); String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); // does nada in master branch // info += "<tr><td><a href=\"dashboard?action=resetstats&route=" + rname + "\">" + rname + "</a>"; info += "<tr><td>" + rname; info += "<td>" + route.getElementsByTagName(ESTIMATED_TIME_TAG).item(0).getTextContent(); info += "<td>" + route.getElementsByTagName(ESTIMATED_DISTANCE_TAG).item(0).getTextContent(); info += "<td>" + route.getElementsByTagName(ROUTE_COUNT_TAG).item(0).getTextContent(); info += "<td>" + route.getElementsByTagName(ROUTE_FAIL_TAG).item(0).getTextContent() + "</tr>\n"; } catch (Exception e) {} } info += "</tbody></table>"; return info; } public static String getRouteStats(){ String info = ""; Document document = NavigationUtilities.loadXMLFromString(routesLoad()); NodeList routes = document.getDocumentElement().getChildNodes(); for (int i = 0; i < routes.getLength(); i++){ try { Element route = (Element) routes.item(i); String rname = ((Element) routes.item(i)).getElementsByTagName(ROUTE_NAME).item(0).getTextContent(); info += "route name: " + rname + " time: " + route.getElementsByTagName(ESTIMATED_TIME_TAG).item(0).getTextContent() + " distance: " + route.getElementsByTagName(ESTIMATED_DISTANCE_TAG).item(0).getTextContent() + " count: " + route.getElementsByTagName(ROUTE_COUNT_TAG).item(0).getTextContent() + " fail: " + route.getElementsByTagName(ROUTE_FAIL_TAG).item(0).getTextContent() + "\n"; } catch (Exception e) {} } return info; } }