@SuppressWarnings("unchecked") @ApiMethod(name = "insertRecords", path = "findmytrain/v1/insertRecords") public void insertRecords(Record record) { // this method is used to add the timestamp of the server to the record // object // and then the object is persisted // duplicate testing is not done here since there is no way of having // duplicate entries here // changed code: record timestamp from string to long // Date date = new Date(); // String timeStamp = Long.toString(date.getTime()); record.setTimeStamp(new Date().getTime()); PersistenceManager pm = PMF.get().getPersistenceManager(); try { pm.makePersistent(record); } finally { pm.close(); } }
@SuppressWarnings("unchecked") @ApiMethod(name = "checkTrainAndStationStatus", path = "findmytrain/v1/checkStatus") public List<String> checkTrainAndStationStatus( @Named("Train id") String id, @Named("Currnet Station") String station) { // this method returns the list of stations for a selected train and // whether that train has passed each station final int STATION_GAP = 5; // five station from the current station to // both directions are considered for the // calculation final int RECORD_THRESHOLD = 10; final double PROBABILITY_THRESHOLD_LEFT = 0.65; final double PROBABILITY_THRESHOLD_NOT_LEFT = 0.35; final double TRANSITION_THRESHOLD = 0.2; final int RECORD_CONSIDERATION_LIMIT_NUMBER = 50; final int RECORD_CONSIDERATION_LIMIT_MINUTES = 30; // this value can be // reduced when the // number of users // become // higher.(since // there will be // more data to // analyze with in // the given time // period) final long ONE_MINUTE_IN_MILLIS = 60000; List<String> result = new ArrayList<String>(); List<Train> trains = new ArrayList<Train>(); List<Record> records = new ArrayList<Record>(); PersistenceManager pm = PMF.get().getPersistenceManager(); Query queryTrain = pm.newQuery(Train.class); queryTrain.setFilter("trainid == argTrainId"); queryTrain.declareParameters("String argTrainId"); Query queryRecord = pm.newQuery(Record.class); queryTrain.setFilter("trainid == argTrainId"); queryTrain.declareParameters("String argTrainId"); trains = (List<Train>) queryTrain.execute(id); records = (List<Record>) queryRecord.execute(id); List<Stop> stops = new ArrayList<Stop>(); List<Record> tempRecords; int stationIndex = 0; int initialOneCount; int initialZeroCount; double probabilityInitial; double probabilityTransition; int[] centralDifference; int transitionCount; Date atRequest = new Date(); SimpleDateFormat parser = new SimpleDateFormat("HH:mm"); String serverTime = parser.format(atRequest); Date serverDate = null; Date lowerLimit = null; try { serverDate = parser.parse(serverTime); lowerLimit = new Date( serverDate.getTime() - (RECORD_CONSIDERATION_LIMIT_MINUTES * ONE_MINUTE_IN_MILLIS)); } catch (ParseException e) { e.printStackTrace(); } stops = trains.get(0).getStops(); for (int i = 0; i < stops.size(); i++) { if (stops.get(i).getStation().equals(station)) stationIndex = i; } int loopStart = stationIndex >= STATION_GAP ? stationIndex - STATION_GAP : 0; int loopEnd = stationIndex + STATION_GAP < stops.size() ? stationIndex + STATION_GAP : stops.size(); for (int i = loopStart; i < loopEnd; i++) { Stop tempStop = stops.get(i); String tempStatus = "not sure"; // for the situation where there are // not enough data present tempRecords = new ArrayList<Record>(); // these are the records used // to process the data for // each selected station initialOneCount = 0; initialZeroCount = 0; for (Record r : records) { if (r.getStation().equals(tempStop.getStation())) { tempRecords.add(r); } } // case where there is no data if (tempRecords.size() < RECORD_THRESHOLD) { result.add(tempStop.getStation() + ":" + tempStatus); continue; } // when there is enough data sortRecords(tempRecords); // selecting a set of record to perform the analysis based on their // recentness and the number of records int k = 0; for (int j = 0; j < tempRecords.size(); j++) { Date tempDate = new Date(tempRecords.get(j).getTimeStamp()); String tempTime = parser.format(tempDate); try { Date recordDate = parser.parse(tempTime); if (recordDate.after(lowerLimit)) { k = j; break; } } catch (ParseException e) { e.printStackTrace(); } } if (tempRecords.size() - k < RECORD_CONSIDERATION_LIMIT_NUMBER) { if (tempRecords.size() < RECORD_CONSIDERATION_LIMIT_NUMBER) { k = 0; } else k = tempRecords.size() - RECORD_CONSIDERATION_LIMIT_NUMBER; } for (int j = k; j < tempRecords.size(); j++) { // counting the initial ones and zeros System.out.print(j + " "); if (tempRecords.get(j).getStatus() == 1) initialOneCount++; else initialZeroCount++; } System.out.println(); probabilityInitial = (double) initialOneCount / (tempRecords.size()); if (probabilityInitial > PROBABILITY_THRESHOLD_LEFT) { tempStatus = "left"; } else if (probabilityInitial < PROBABILITY_THRESHOLD_NOT_LEFT) { tempStatus = "not left"; } else { // using the first central difference formula centralDifference = new int[tempRecords.size() - 1]; for (int j = 1; j < tempRecords.size(); j++) { centralDifference[j - 1] = tempRecords.get(j).getStatus() - tempRecords.get(j - 1).getStatus(); } transitionCount = 0; for (int j : centralDifference) { if (j == 1) transitionCount++; } probabilityTransition = (double) transitionCount / centralDifference.length; if (probabilityTransition < TRANSITION_THRESHOLD) { tempStatus = "left"; } else { tempStatus = "not sure"; } } // at this point data can be further checked to refine the results result.add(tempStop.getStation() + ":" + tempStatus); } return result; }