Android Open Source - BART Bart Route Parser






From Project

Back to project page BART.

License

The source code is released under:

GNU General Public License

If you think the Android project BART listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 *  Copyright (C) 2012  David Brodsky//from   w w  w .  j  ava 2 s.c o  m
 *  This file is part of Open BART.
 *
 *  Open BART is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Open BART is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Open BART.  If not, see <http://www.gnu.org/licenses/>.
*/


package pro.dbro.bart;

import java.io.ByteArrayInputStream;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import com.crittercism.app.Crittercism;
import com.thebuzzmedia.sjxp.XMLParser;
import com.thebuzzmedia.sjxp.XMLParserException;
import com.thebuzzmedia.sjxp.rule.DefaultRule;
import com.thebuzzmedia.sjxp.rule.IRule;
import com.thebuzzmedia.sjxp.rule.IRule.Type;

import android.content.Intent;
import android.os.AsyncTask;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

public class BartRouteParser extends AsyncTask<String, String, routeResponse> {
  String responseDate;
  String responseTime;
  String routeOriginDate;
  String routeOriginTime;
  String routeDestinationDate;
  String routeDestinationTime;
  String legTime;
  String legDate;
  SimpleDateFormat curFormater;
  Date dateObj;
  TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
  boolean updateUI;
  
  //DEBUGGING
  boolean dateError = false;
  
  BartRouteParser(boolean updateUI) {
        this.updateUI = updateUI;
    }

  @Override
  protected routeResponse doInBackground(String... input) {
    final routeResponse response = new routeResponse();
    //convert string into input stream for xml parsing
    ByteArrayInputStream bais = new ByteArrayInputStream( input[0].getBytes());
    
    IRule originStationRule = new DefaultRule(Type.CHARACTER, "/root/origin") {
      @Override
      public void handleParsedCharacters(XMLParser parser, String text, Object userObject) {
        response.originStation = text;
      }
    };
    IRule destinationStationRule = new DefaultRule(Type.CHARACTER, "/root/destination") {
      @Override
      public void handleParsedCharacters(XMLParser parser, String text, Object userObject) {
        response.destinationStation = text;
      }
    };
    IRule timeRule = new DefaultRule(Type.CHARACTER, "/root/schedule/time") {
      @Override
      public void handleParsedCharacters(XMLParser parser, String text, Object userObject) {
        responseTime = text;
      }
    };
    IRule dateRule = new DefaultRule(Type.CHARACTER, "/root/schedule/date") {
      @Override
      public void handleParsedCharacters(XMLParser parser, String text, Object userObject) {
        responseDate = text;
      }
    };
    IRule specialScheduleRule = new DefaultRule(Type.CHARACTER, "/root/message/special_schedule") {
      @Override
      public void handleParsedCharacters(XMLParser parser, String text, Object userObject) {
        //fix for BART returning relative, not absolute, links
        response.specialSchedule = text.replace("href=\"/", "href=\"http://bart.gov/");
      }
    };
    // origin="DBRK" destination="WCRK" fare="3.15" origTimeMin="3:18 PM" origTimeDate="03/16/2012 " destTimeMin="3:44 PM" destTimeDate="03/16/2012"
    IRule tripAttributeRule = new DefaultRule(Type.ATTRIBUTE, "/root/schedule/request/trip", new String[]{"fare", "origTimeMin","origTimeDate","destTimeMin","destTimeDate"}) {
      @Override
      public void handleParsedAttribute(XMLParser parser, int num, String value, Object userObject) {
        
        //("ATTRIBUTE",String.valueOf(num)+ " - "+value);
        if(num == 0){ // fare
          route thisRoute = response.addRoute();
          thisRoute.fare = value;
          //leg thisLeg = thisRoute.addLeg();
          //thisLeg.disembarkStation = TheActivity.STATION_MAP.get(value);
        }
        else if(num == 1){ // origTimeMin
          routeOriginTime = value;
        }
        else if(num == 2){
          routeOriginDate = value;
        }
        else if(num == 3){
          routeDestinationTime = value;
          //("ROUTE_DEST_TIME",value.toString());
        }
        else if(num == 4){
          //Log.v("ROUTE_DEST_DATE",value.toString());
          routeDestinationDate = value;
        }
        //thisRoute.fare
      }
    };
    IRule tripTagRule = new DefaultRule(Type.TAG, "/root/schedule/request/trip") {
      @Override
      public void handleTag(XMLParser parser, boolean isStartTag, Object userObject) {
        if (!isStartTag){
          route thisRoute = response.getLastRoute();
          
          // Determine if bikes are allowed on all legs of this route
          boolean bikes = true;
          for(int x=0;x<thisRoute.legs.size();x++){
            if(!((leg)thisRoute.legs.get(x)).bikes)
              bikes = false;
          }
          thisRoute.bikes = bikes;
          
          String originDateStr = routeOriginDate + " " + routeOriginTime;
          String destinationDateStr = routeDestinationDate + " " + routeDestinationTime;
          // Bart Route responses don't indicate timezone (?), though etd responses do
          // Set SimpleDateFormat TimeZone to America/Los-Angeles
          // This ensures the application can correctly combine etd responses (with timezone) and route (without)
          // Even if the application is run on a device who's locale differs from BARTs (PST)
          curFormater = new SimpleDateFormat("MM/dd/yyyy hh:mm a", Locale.US); 
          curFormater.setTimeZone(tz);
          try {
            Log.d("BartRouteParserEndTrip","originDate: " + originDateStr + " destDate: " + destinationDateStr);
            thisRoute.departureDate = curFormater.parse(originDateStr);//append BART response timezone
            thisRoute.arrivalDate = curFormater.parse(destinationDateStr);//append BART response timezone
          } catch (ParseException e) {
            Log.d("BartRouteParserEndTrip","non-PDT coerced parse failed");
            // TODO Auto-generated catch block
            // 5.15.2012: I've received multiple crashes here. Something's going on related to irregular time format...
            // IF coercing PDT fails, try without at the risk of displaying incorrect time
            /*try{
              Crittercism.leaveBreadcrumb(Log.getStackTraceString(e));
              thisRoute.departureDate = curFormater.parse(originDateStr);
              thisRoute.arrivalDate = curFormater.parse(destinationDateStr);
            }
            catch(ParseException e2){*/
              Log.d("BartRouteParserEndTrip","non-PST coerced parse failed");
              Log.d("BartRouteParserEndTrip_DateString", "origin: " + originDateStr+" , destination: "+destinationDateStr);
              Log.d("BartRouteParserEndTripException",e.getClass().toString() + ": " + e.getMessage());
              Crittercism.leaveBreadcrumb(originDateStr+" , "+destinationDateStr);
              Crittercism.leaveBreadcrumb(Log.getStackTraceString(e));
              Crittercism.logHandledException(e);
              dateError = true;
            //}
          }
          if(!dateError)
            Log.d("RouteParserDate","depart: " + thisRoute.departureDate.toString() + " arrive: " + thisRoute.arrivalDate.toString());
          else{
            // if an improper date is given, remove this route from response
            response.removeLastRoute();
          }
          // reset these variables for use by the next route
          originDateStr = "";
          destinationDateStr = "";
        }

      }
    };
    //
    IRule legAttributeRule = new DefaultRule(Type.ATTRIBUTE, "/root/schedule/request/trip/leg", new String[]{"transfercode", "origin","destination","origTimeMin","origTimeDate","destTimeMin","destTimeDate","trainHeadStation", "bikeflag"}) {
      @Override
      public void handleParsedAttribute(XMLParser parser, int num, String value, Object userObject) {
        // TODO: Fix assumed order of XML attributes
        route thisRoute;
        leg thisLeg;
        String dateStr;
        switch(num){
        case 0:// transfercode
          thisRoute = response.getLastRoute();
          thisLeg = thisRoute.addLeg();
          thisLeg.transferCode = value;
          break;
          //leg thisLeg = thisRoute.addLeg();
          //thisLeg.disembarkStation = TheActivity.STATION_MAP.get(value);
        
        case 1: // orig station
          thisRoute = response.getLastRoute();
          thisLeg = thisRoute.getLastLeg();
          thisLeg.boardStation = value;
          break;
          
        case 2: // dest station
          thisRoute = response.getLastRoute();
          thisLeg = thisRoute.getLastLeg();
          thisLeg.disembarkStation = value;
          break;
        
        case 3: // board time
          legTime = value;
          break;
        
        case 4: // board date
          legDate = value;
          dateStr = legDate + " " + legTime;
          curFormater = new SimpleDateFormat("MM/dd/yyyy hh:mm a", Locale.US); 
          curFormater.setTimeZone(tz);
          thisRoute = response.getLastRoute();
          thisLeg = thisRoute.getLastLeg();
          try {
            thisLeg.boardTime = curFormater.parse(dateStr); 
          } catch (ParseException e) {
            Log.d("BartRouteParser","boardTime unparseable: "+ dateStr);
            e.printStackTrace();
          }
          break;
        
        case 5: // dest time
          legTime = value;
          break;
        
        case 6: // dest date
          legDate = value;
          //assume date always follows time:
          dateStr = legDate + " " + legTime;
          curFormater = new SimpleDateFormat("MM/dd/yyyy hh:mm a", Locale.US); 
          curFormater.setTimeZone(tz);
          thisRoute = response.getLastRoute();
          thisLeg = thisRoute.getLastLeg();
          try {
            thisLeg.disembarkTime = curFormater.parse(dateStr);
          } catch (ParseException e) {
            // TODO Auto-generated catch block
            Log.d("BartRouteParser","disembarkTime unparseable: "+ dateStr);
            e.printStackTrace();
          }
          break;
        
        case 7: // train head station
          thisRoute = response.getLastRoute();
          thisLeg = thisRoute.getLastLeg();
          thisLeg.trainHeadStation = value.toLowerCase();
          break;
        
        case 8:  // bikeFlag
          thisRoute = response.getLastRoute();
          thisLeg = thisRoute.getLastLeg();
          if(value.equals("1"))
            thisLeg.bikes = true;
          else
            thisLeg.bikes = false;
          break;
        }
        
      }
    };
    
    XMLParser parser = new XMLParser(originStationRule, destinationStationRule, timeRule, dateRule, tripAttributeRule, tripTagRule, legAttributeRule, specialScheduleRule);
    try{
      parser.parse(bais);
    }
    catch(XMLParserException e){
      // Send a message to TheActivity to display an error dialog
      // Then cancel this AsyncTask
      sendError("Open BART received a malformed response. Please try again.");
      this.cancel(true);
    }
    //11:15:32 AM PDT
    
    //String[] timesplit = time.split(" ");
    String dateStr = responseDate + " " + responseTime;
    //Log.v("time split", timesplit.toString());
    //Log.v("Time",dateStr);
    curFormater = new SimpleDateFormat("MMM dd, yyyy hh:mm a", Locale.US); 
    curFormater.setTimeZone(tz);
    Date dateObj = new Date();
    try {
      dateObj = curFormater.parse(dateStr);
    } catch (ParseException e) {
      // TODO Auto-generated catch block
      //Log.v("XMLParse", "date formatting error");
      Log.d("BartRouteParser","Response date parse error");
      e.printStackTrace();
    } 
    response.date = dateObj;
    
    return response;
  }
  
  @Override
    protected void onPostExecute(routeResponse result) {
    //((TheActivity) caller).handleResponse(result, updateUI);
    sendMessage(result);
        super.onPostExecute(result);
    }
  
  private void sendMessage(routeResponse result) { // 0 = service stopped , 1 = service started, 2 = refresh view with call to bartApiRequest(), 3 = 
      int status = 4; // hardcode status for calling TheActivity.handleResponse
      Log.d("sender", "Sending AsyncTask message");
        Intent intent = new Intent("service_status_change");
        // You can also include some extra data.
        intent.putExtra("status", status);
        intent.putExtra("result", (Serializable) result);
        //intent.putExtra("result",(CharSequence)result);
        intent.putExtra("updateUI", updateUI);
        LocalBroadcastManager.getInstance(TheActivity.c).sendBroadcast(intent);
  }
  
  // Send a LocalBroadCast message to TheActivity indicating an error
  private void sendError(String message){
    int status = 13;
    Intent intent = new Intent("service_status_change");
    intent.putExtra("status", status);
    intent.putExtra("message", message);
    LocalBroadcastManager.getInstance(TheActivity.c).sendBroadcast(intent);
  }

}




Java Source Code List

pro.dbro.bart.BART.java
pro.dbro.bart.BartLinearLayout.java
pro.dbro.bart.BartRouteParser.java
pro.dbro.bart.BartStationEtdParser.java
pro.dbro.bart.DeviceLocation.java
pro.dbro.bart.LocalPersistence.java
pro.dbro.bart.MapActivity.java
pro.dbro.bart.RequestTask.java
pro.dbro.bart.StationSuggestion.java
pro.dbro.bart.TextPlusIconArrayAdapter.java
pro.dbro.bart.TheActivity.java
pro.dbro.bart.UsherService.java
pro.dbro.bart.ViewCountDownTimer.java
pro.dbro.bart.etdResponse.java
pro.dbro.bart.etd.java
pro.dbro.bart.leg.java
pro.dbro.bart.routeResponse.java
pro.dbro.bart.route.java