Browse Source

Process the long term schedule

TODO: fix TrainSchedule.hashCode() and TrainScheduleLocation.hashCode()
develop
LO Kam Tao Leo 4 years ago
parent
commit
c90b7177a2
  1. 93
      src/org/leolo/rail/AssoicationProcessor.java
  2. 28
      src/org/leolo/rail/BaseProcessor.java
  3. 2
      src/org/leolo/rail/Constants.java
  4. 138
      src/org/leolo/rail/LongTermScheduleJob.java
  5. 316
      src/org/leolo/rail/ScheduleProcessor.java
  6. 67
      src/org/leolo/rail/TiplocProcessor.java
  7. 17
      src/org/leolo/rail/model/LocationRecordType.java
  8. 20
      src/org/leolo/rail/model/ScheduleType.java
  9. 328
      src/org/leolo/rail/model/TrainSchedule.java
  10. 175
      src/org/leolo/rail/model/TrainScheduleLocation.java
  11. 8
      src/org/leolo/rail/model/package-info.java

93
src/org/leolo/rail/AssoicationProcessor.java

@ -0,0 +1,93 @@
package org.leolo.rail;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.zip.GZIPInputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONObject;
import org.leolo.rail.util.TUIDDateFormat;
public class AssoicationProcessor extends BaseProcessor implements Runnable {
private File targetFile;
private Logger log = LogManager.getLogger(AssoicationProcessor.class);
public AssoicationProcessor(File targetFile) {
this.targetFile = targetFile;
}
@Override
public void run() {
log.atInfo().log("Processing {}", targetFile.getName());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
TUIDDateFormat tdf = new TUIDDateFormat();
try(
BufferedReader br = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(targetFile))));
Connection conn = DatabaseManager.getInstance().getConnection();
PreparedStatement pstmt = conn.prepareStatement("REPLACE INTO ltp_assoication VALUES(?,?,?,?,?,?,?,?,?,?,?,?)")
){
while(true) {
String line = br.readLine();
if(line==null) {
break;
}
JSONObject obj = new JSONObject(line);
String mainTrainUID = obj.optString("main_train_uid");
String assocTrainUID = obj.optString("assoc_train_uid");
java.sql.Date startDate, endDate;
try {
startDate = new java.sql.Date(sdf.parse(obj.optString("assoc_start_date")).getTime());
endDate = new java.sql.Date(sdf.parse(obj.optString("assoc_end_date")).getTime());
} catch (ParseException e1) {
log.warn("Unable to parse date! {}", e1.getMessage(), e1);
continue;
}
String assoc_days = obj.optString("assoc_days");
String assoc_type = obj.optString("category");
String location = obj.optString("location");
String base_suffix = obj.optString("base_location_suffix");
String assoc_suffix = obj.optString("assoc_location_suffix");
String stp_ind = obj.optString("CIF_stp_indicator");
String auid = mainTrainUID + assocTrainUID + location + tdf.format(startDate) + tdf.format(endDate)+stp_ind;
int hashCode = (auid+assoc_type+assoc_days).hashCode();
setString(pstmt, 1, auid);
setString(pstmt, 2, mainTrainUID);
setString(pstmt, 3, assocTrainUID);
pstmt.setDate(4, startDate);
pstmt.setDate(5, endDate);
setString(pstmt, 6, assoc_days);
setString(pstmt, 7, assoc_type);
setString(pstmt, 8, location);
setString(pstmt, 9, base_suffix);
setString(pstmt, 10, assoc_suffix);
setString(pstmt, 11, stp_ind);
pstmt.setInt(12, hashCode);
pstmt.addBatch();
}
pstmt.executeBatch();
conn.commit();
} catch (FileNotFoundException e) {
log.error(e.getMessage(), e);
} catch (IOException e) {
log.error(e.getMessage(), e);
} catch (SQLException e) {
log.error(e.getMessage(), e);
}
if(!targetFile.delete()) {
log.warn("Unable to delete {}", targetFile.getName());
}
}
}

28
src/org/leolo/rail/BaseProcessor.java

@ -0,0 +1,28 @@
package org.leolo.rail;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
public abstract class BaseProcessor {
public void setString(PreparedStatement stmt, int col, String val) throws SQLException{
if(val==null || "".equals(val.trim())) {
stmt.setNull(col, Types.CHAR);
}else {
stmt.setString(col, val);
}
}
public void setTime(PreparedStatement stmt, int col, long time) throws SQLException{
if(time==0) {
stmt.setNull(col, Types.TIME);
}else {
int h = (int)(time/3_600_000);
int m = (int)((time/60_000)%60);
int s = (int)((time/1_000)%60);
stmt.setString(col, h+":"+m+":"+s);
}
}
}

2
src/org/leolo/rail/Constants.java

@ -28,4 +28,6 @@ public class Constants {
public static class Metadata{ public static class Metadata{
public static final String LAST_NETOWRK_RAIL_SCHEDULE_UPD = "LNeRSchUpd"; public static final String LAST_NETOWRK_RAIL_SCHEDULE_UPD = "LNeRSchUpd";
} }
public static final int BATCH_SIZE = 5_000;
} }

138
src/org/leolo/rail/LongTermScheduleJob.java

@ -1,10 +1,26 @@
package org.leolo.rail; package org.leolo.rail;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Base64;
import java.util.Date; import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipException;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.json.JSONObject;
import org.leolo.rail.dao.MetadataDao; import org.leolo.rail.dao.MetadataDao;
import org.quartz.Job; import org.quartz.Job;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
@ -36,7 +52,127 @@ public class LongTermScheduleJob implements Job{
} catch (SchedulerException e) { } catch (SchedulerException e) {
log.atError().log(e.getMessage(),e); log.atError().log(e.getMessage(),e);
} }
InputStream fis = null;
try {
URL url = new URL(ConfigurationManager.getInstance().getProperty("network.schedule.path"));
URLConnection conn = url.openConnection();
String userpwd = ConfigurationManager.getInstance().getProperty("network.user")+":"+ConfigurationManager.getInstance().getProperty("network.pwd");
conn.addRequestProperty("Authorization", "Basic "+Base64.getEncoder().encodeToString(userpwd.getBytes()));
conn.connect();
fis = conn.getInputStream();
}catch(IOException e) {
log.error(e.getMessage(), e);
System.exit(4);
}
log.info("Connected!");
File tempDir = new File(ConfigurationManager.getInstance().getProperty("file.temp_dir", ".")+"/nrdg");
if(!tempDir.exists()) {
tempDir.mkdirs();
}
int countA=0, countT=0, countS=0;
int batchA=0, batchT=0, batchS=0;
try(
GZIPInputStream gis = new GZIPInputStream(fis);
BufferedReader br = new BufferedReader(new InputStreamReader(gis));
){
PrintWriter ass = new PrintWriter(new GZIPOutputStream(new FileOutputStream(new File(tempDir, "ass_0"))));
PrintWriter tip = new PrintWriter(new GZIPOutputStream(new FileOutputStream(new File(tempDir, "tip_0"))));
PrintWriter sch = new PrintWriter(new GZIPOutputStream(new FileOutputStream(new File(tempDir, "sch_0"))));
int count = 0;
while(true) {
String line = br.readLine();
if(line==null) {
break;
}
count++;
JSONObject obj = new JSONObject(line);
String objectType = obj.keys().next();
if("JsonTimetableV1".equals(objectType)) {
}else if("JsonAssociationV1".equals(objectType)){
ass.println(obj.getJSONObject("JsonAssociationV1"));
countA++;
if(countA%Constants.BATCH_SIZE==0) {
ass.close();
if(batchA%50==0)
log.info("Created batch for assoication");
ass = new PrintWriter(new GZIPOutputStream(new FileOutputStream(new File(tempDir, "ass_"+(++batchA)))));
}
}else if("TiplocV1".equals(objectType)){
tip.println(obj.getJSONObject("TiplocV1"));
countT++;
if(countT%Constants.BATCH_SIZE==0) {
tip.close();
if(batchT%50==0)
log.info("Created batch for TIPLOC");
tip = new PrintWriter(new GZIPOutputStream(new FileOutputStream(new File(tempDir, "tip_"+(++batchT)))));
}
}else if("JsonScheduleV1".equals(objectType)){
sch.println(obj.getJSONObject("JsonScheduleV1"));
countS++;
if(countS%Constants.BATCH_SIZE==0) {
sch.close();
if(batchS%50==0)
log.info("Created batch for schedule");
sch = new PrintWriter(new GZIPOutputStream(new FileOutputStream(new File(tempDir, "sch_"+(++batchS)))));
}
}else if("EOF".equals(objectType)){
//Nothing to do
}else {
log.fatal("Unhandled type {}", objectType);
System.exit(2);
}
}
ass.close();
tip.close();
sch.close();
log.info("Created batch for assoication");
log.info("Created batch for TIPLOC");
log.info("Created batch for schedule");
log.info("Total count : {}", count);
}catch(ZipException e) {
log.error(e.getMessage(), e);
}catch(IOException e) {
log.error(e.getMessage(), e);
System.exit(1);
}
try {
fis.close();
}catch(IOException e) {
log.fatal(e.getMessage(), e);
System.exit(1);
}
log.info("Done reading. Dispatching now. {}/{}/{}[{}/{}/{}]", countA, countT, countS, batchA, batchT, batchS);
ExecutorService threadPool = java.util.concurrent.Executors.newFixedThreadPool(1);
for(int i=0;i<=batchA;i++) {
if(i%50==0)
log.info("Queued Assoication - {}", i);
threadPool.execute(new AssoicationProcessor(new File(tempDir, "ass_"+i)));
}
for(int i=0;i<=batchT;i++) {
if(i%50==0)
log.info("Queued Tiploc - {}", i);
threadPool.execute(new TiplocProcessor(new File(tempDir, "tip_"+i)));
}
for(int i=0;i<=batchS;i++) {
if(i%50==0)
log.info("Queued Schedule - {}", i);
threadPool.execute(new ScheduleProcessor(new File(tempDir, "sch_"+i)));
}
log.info("All entry queued.");
threadPool.shutdown();
try {
threadPool.awaitTermination(3, TimeUnit.HOURS);
} catch (InterruptedException e) {
log.error(e.getMessage(), e);
}
if(!threadPool.isTerminated()) {
log.error("Some job cannot be finished!");
System.exit(50);
}
log.atInfo().log("LTS job done!");
} }
} }

316
src/org/leolo/rail/ScheduleProcessor.java

@ -0,0 +1,316 @@
package org.leolo.rail;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
import java.util.zip.GZIPInputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.leolo.rail.model.LocationRecordType;
import org.leolo.rail.model.ScheduleType;
import org.leolo.rail.model.TrainSchedule;
import org.leolo.rail.model.TrainScheduleLocation;
public class ScheduleProcessor extends BaseProcessor implements Runnable {
private Logger log = LogManager.getLogger(ScheduleProcessor.class);
private File targetFile;
public ScheduleProcessor(File targetFile) {
this.targetFile = targetFile;
}
@Override
public void run() {
Vector<TrainSchedule> newSchedule = new Vector<>();
Vector<TrainSchedule> updatedSchedule = new Vector<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try(
BufferedReader br = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(targetFile))));
Connection conn = DatabaseManager.getInstance().getConnection();
PreparedStatement pstmt = conn.prepareStatement("SELECT hash_code FROM ltp_schedule WHERE suid = ?")//For checking duplication
){
while(true) {
String line = br.readLine();
if(line==null) {
break;
}
JSONObject obj = new JSONObject(line);
TrainSchedule ts = new TrainSchedule();
ts.setTrainUId(obj.optString("CIF_train_uid"));
String stpInd = obj.optString("CIF_stp_indicator");
if("C".equals(stpInd))
ts.setScheduleType(ScheduleType.CAN);
else if("N".equals(stpInd))
ts.setScheduleType(ScheduleType.WTT);
else if("O".equals(stpInd))
ts.setScheduleType(ScheduleType.OVL);
else if("P".equals(stpInd))
ts.setScheduleType(ScheduleType.WTT);
else
log.atWarn().log("Unknow schedule type {} for train UID {}",stpInd,obj.optString("CIF_train_uid"));
try {
ts.setStartDate(sdf.parse(obj.optString("schedule_start_date")));
ts.setEndDate(sdf.parse(obj.optString("schedule_end_date")));
}catch(ParseException e) {
log.atError().log(e.getMessage(), e);
}
ts.setDays(obj.optString("schedule_days_runs"));
ts.setBankHolidayInd(obj.optString("CIF_bank_holiday_running"));
ts.setSignalId(obj.getJSONObject("schedule_segment").optString("signalling_id"));
ts.setRsid(obj.getJSONObject("schedule_segment").optString("CIF_headcode"));
ts.setTrainStatus(obj.optString("train_status"));
ts.setTrainCategory(obj.getJSONObject("schedule_segment").optString("CIF_train_category"));
ts.setSection(obj.getJSONObject("schedule_segment").optString("CIF_business_sector"));
ts.setPowerType(obj.getJSONObject("schedule_segment").optString("CIF_power_type"));
ts.setTimingLoad(obj.getJSONObject("schedule_segment").optString("CIF_timing_load"));
ts.setPlannedSpeed(obj.getJSONObject("schedule_segment").optString("CIF_speed"));
ts.setOperatingCharacter(obj.getJSONObject("schedule_segment").optString("CIF_operating_characteristics"));
ts.setClassAvailable(obj.getJSONObject("schedule_segment").optString("CIF_train_class"));
ts.setSleeper(obj.getJSONObject("schedule_segment").optString("CIF_sleepers"));
ts.setReservation(obj.getJSONObject("schedule_segment").optString("CIF_reservations"));
ts.setCatering(obj.getJSONObject("schedule_segment").optString("CIF_catering_code"));
// if()
// ts.setUicCode(obj.getJSONObject("new_schedule_segment").optString("uic_code"));
ts.setAtocCode(obj.optString("atoc_code"));
JSONArray locs = obj.getJSONObject("schedule_segment").optJSONArray("schedule_location");
if(locs==null && !"C".equals(stpInd)) {
log.atWarn().log("No segments for {}",ts.getSUID());
continue;
}
if(locs!=null) {
for(int i=0;i<locs.length();i++) {
JSONObject loc = locs.getJSONObject(i);
TrainScheduleLocation tsl = new TrainScheduleLocation();
tsl.setTiplocCode(loc.optString("tiploc_code"));
tsl.setTiplocInstance(loc.optInt("tiploc_instance"));
tsl.setArrival(getScheduleTime(loc.optString("arrival")));
tsl.setDeparture(getScheduleTime(loc.optString("departure")));
tsl.setPass(getScheduleTime(loc.optString("pass")));
tsl.setPubArrival(getScheduleTime(loc.optString("public_arrival")));
tsl.setPubDeparture(getScheduleTime(loc.optString("public_departure")));
tsl.setPlatform(loc.optString("platform"));
tsl.setLine(loc.optString("line"));
tsl.setPath(loc.optString("path"));
tsl.setEngineeringAllowance(getAllowanceTime(loc.optString("engineering_allowance")));
tsl.setPathingAllowance(getAllowanceTime(loc.optString("pathing_allowance")));
tsl.setPerformanceAllowance(getAllowanceTime(loc.optString("performance_allowance")));
String locType = loc.optString("location_type");
if("LO".equals(locType)) {
tsl.setRecordType(LocationRecordType.ORIGIN);
}else if("LI".equals(locType)) {
tsl.setRecordType(LocationRecordType.INTERMEDIATE);
}else if("LT".equals(locType)) {
tsl.setRecordType(LocationRecordType.TERMINATE);
}
ts.getLocations().add(tsl);
}//loop for location
}
pstmt.setString(1, ts.getSUID());
try(ResultSet rs = pstmt.executeQuery()){
if(rs.next()) {
log.atDebug().log("SUID: {}, old hash: {}, new hash: {}", ts.getSUID(), Integer.toHexString(rs.getInt(1)), Integer.toHexString(ts.hashCode()));
System.exit(1000);
if(rs.getInt(1)!=ts.hashCode()) {
updatedSchedule.add(ts);
}
}else {
newSchedule.add(ts);
}
}
}//main loop
log.atInfo().log("New: {}; Updated:{}", newSchedule.size(), updatedSchedule.size());
} catch (FileNotFoundException e) {
log.error(e.getMessage(), e);
} catch (IOException e) {
log.error(e.getMessage(), e);
} catch (SQLException e) {
log.error(e.getMessage(), e);
}
//TODO: Insert/update the record
try(Connection conn = DatabaseManager.getInstance().getConnection()){
//New records
try(
PreparedStatement psSch = conn.prepareStatement("INSERT INTO ltp_schedule VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
PreparedStatement psLoc = conn.prepareStatement("INSERT INTO ltp_location VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
){
for(TrainSchedule ts:newSchedule) {
setString(psSch, 1, ts.getSUID());
setString(psSch, 2, ts.getTrainUId());
setString(psSch, 3, ts.getScheduleType().name());
setString(psSch, 4, sdf.format(ts.getStartDate()));
setString(psSch, 5, sdf.format(ts.getEndDate()));
setString(psSch, 6, ts.getDays());
setString(psSch, 7, ts.getBankHolidayInd());
setString(psSch, 8, ts.getSignalId());
setString(psSch, 9, ts.getRsid());
setString(psSch,10, ts.getTrainStatus());
setString(psSch,11, ts.getTrainCategory());
setString(psSch,12, ts.getSection());
setString(psSch,13, ts.getPowerType());
setString(psSch,14, ts.getTimingLoad());
setString(psSch,15, ts.getPlannedSpeed());
setString(psSch,16, ts.getOperatingCharacter());
setString(psSch,17, ts.getClassAvailable());
setString(psSch,18, ts.getSleeper());
setString(psSch,19, ts.getReservation());
setString(psSch,20, ts.getCatering());
setString(psSch,21, ts.getUicCode());
setString(psSch,22, ts.getAtocCode());
if(ts.getLocations().size()>1) {
setString(psSch,23, ts.getLocations().get(0).getTiplocCode());
setTime(psSch,24, ts.getLocations().get(0).getDeparture());
setString(psSch,25, ts.getLocations().get(ts.getLocations().size()-1).getTiplocCode());
setTime(psSch,26, ts.getLocations().get(ts.getLocations().size()-1).getArrival());
}else {
psSch.setNull(23, Types.CHAR);
psSch.setNull(24, Types.TIME);
psSch.setNull(25, Types.CHAR);
psSch.setNull(26, Types.TIME);
}
psSch.setInt(27, ts.hashCode());
int seq = 1;
for(TrainScheduleLocation tsl:ts.getLocations()) {
setString(psLoc, 1, ts.getSUID());
psLoc.setInt(2, seq++);
setString(psLoc, 3, tsl.getTiplocCode());
psLoc.setInt(4, tsl.getTiplocInstance());
setTime(psLoc, 5, tsl.getArrival());
setTime(psLoc, 6, tsl.getDeparture());
setTime(psLoc, 7, tsl.getPass());
setTime(psLoc, 8, tsl.getPubArrival());
setTime(psLoc, 9, tsl.getPubDeparture());
setString(psLoc,10, tsl.getPlatform());
setString(psLoc,11, tsl.getLine());
setString(psLoc,12, tsl.getPath());
setTime(psLoc,13, tsl.getEngineeringAllowance());
setTime(psLoc,14, tsl.getPathingAllowance());
setTime(psLoc,15, tsl.getPerformanceAllowance());
setString(psLoc,16, tsl.getRecordType().getRecordCode());
psLoc.addBatch();
}
psSch.executeUpdate();
psLoc.executeBatch();
conn.commit();
}
}//New Records
//Update records
try(
PreparedStatement psSch = conn.prepareStatement("REPLACE INTO ltp_schedule VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
PreparedStatement psDel = conn.prepareStatement("DELETE FROM ltp_location WHERE suid = ?");
PreparedStatement psLoc = conn.prepareStatement("INSERT INTO ltp_location VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
){
for(TrainSchedule ts:updatedSchedule) {
setString(psSch, 1, ts.getSUID());
setString(psSch, 2, ts.getTrainUId());
setString(psSch, 3, ts.getScheduleType().name());
setString(psSch, 4, sdf.format(ts.getStartDate()));
setString(psSch, 5, sdf.format(ts.getEndDate()));
setString(psSch, 6, ts.getDays());
setString(psSch, 7, ts.getBankHolidayInd());
setString(psSch, 8, ts.getSignalId());
setString(psSch, 9, ts.getRsid());
setString(psSch,10, ts.getTrainStatus());
setString(psSch,11, ts.getTrainCategory());
setString(psSch,12, ts.getSection());
setString(psSch,13, ts.getPowerType());
setString(psSch,14, ts.getTimingLoad());
setString(psSch,15, ts.getPlannedSpeed());
setString(psSch,16, ts.getOperatingCharacter());
setString(psSch,17, ts.getClassAvailable());
setString(psSch,18, ts.getSleeper());
setString(psSch,19, ts.getReservation());
setString(psSch,20, ts.getCatering());
setString(psSch,21, ts.getUicCode());
setString(psSch,22, ts.getAtocCode());
if(ts.getLocations().size()>1) {
setString(psSch,23, ts.getLocations().get(0).getTiplocCode());
setTime(psSch,24, ts.getLocations().get(0).getDeparture());
setString(psSch,25, ts.getLocations().get(ts.getLocations().size()-1).getTiplocCode());
setTime(psSch,26, ts.getLocations().get(ts.getLocations().size()-1).getArrival());
}else {
psSch.setNull(23, Types.CHAR);
psSch.setNull(24, Types.TIME);
psSch.setNull(25, Types.CHAR);
psSch.setNull(26, Types.TIME);
}
psSch.setInt(27, ts.hashCode());
psDel.setString(1, ts.getSUID());
psDel.executeUpdate();
int seq = 1;
for(TrainScheduleLocation tsl:ts.getLocations()) {
setString(psLoc, 1, ts.getSUID());
psLoc.setInt(2, seq++);
setString(psLoc, 3, tsl.getTiplocCode());
psLoc.setInt(4, tsl.getTiplocInstance());
setTime(psLoc, 5, tsl.getArrival());
setTime(psLoc, 6, tsl.getDeparture());
setTime(psLoc, 7, tsl.getPass());
setTime(psLoc, 8, tsl.getPubArrival());
setTime(psLoc, 9, tsl.getPubDeparture());
setString(psLoc,10, tsl.getPlatform());
setString(psLoc,11, tsl.getLine());
setString(psLoc,12, tsl.getPath());
setTime(psLoc,13, tsl.getEngineeringAllowance());
setTime(psLoc,14, tsl.getPathingAllowance());
setTime(psLoc,15, tsl.getPerformanceAllowance());
setString(psLoc,16, tsl.getRecordType().getRecordCode());
psLoc.addBatch();
}
psSch.executeUpdate();
psLoc.executeBatch();
conn.commit();
}
}//New Records
log.atInfo().log("Inserted new {} record(s).",newSchedule.size());
} catch (SQLException e) {
log.error(e.getMessage(), e);
}
if(!targetFile.delete()) {
log.warn("Unable to delete {}", targetFile.getName());
}
}
private long getScheduleTime(String t) {
//HHMM'H'
if("".equals(t.trim())) {
return 0;
}
int hour = Integer.parseInt(t.substring(0, 2));
int min = Integer.parseInt(t.substring(2, 4));
boolean half = t.length()>=5 && t.substring(4, 5).equals("H");
return hour*3_600_000+min*60_000+(half?30_000:0);
}
private long getAllowanceTime(String t) {
if("".equals(t.trim())) {
return 0;
}
if("H".equals(t.trim()))
return 30_000;
if(t.endsWith("H")) {
//nH
return Integer.parseInt(t.substring(0,1))*60_000+30_000;
}else {
//nn
return Integer.parseInt(t)*60_000;
}
}
}

67
src/org/leolo/rail/TiplocProcessor.java

@ -0,0 +1,67 @@
package org.leolo.rail;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.zip.GZIPInputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONObject;
import org.leolo.rail.util.TUIDDateFormat;
public class TiplocProcessor extends BaseProcessor implements Runnable {
private Logger log = LogManager.getLogger(TiplocProcessor.class);
private File file;
public TiplocProcessor(File f) {
file = f;
}
@Override
public void run() {
log.atInfo().log("Processing {}", file.getName());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
TUIDDateFormat tdf = new TUIDDateFormat();
try(
BufferedReader br = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(file))));
Connection conn = DatabaseManager.getInstance().getConnection();
PreparedStatement pstmt = conn.prepareStatement("REPLACE INTO tiploc VALUES(?,?,?,?,?,?)")
){
while(true) {
String line = br.readLine();
if(line==null) {
break;
}
JSONObject obj = new JSONObject(line);
setString(pstmt, 1, obj.optString("tiploc_code"));
setString(pstmt, 2, obj.optString("nalco"));
setString(pstmt, 3, obj.optString("stanox"));
setString(pstmt, 4, obj.optString("crs_code"));
setString(pstmt, 5, obj.optString("description"));
setString(pstmt, 6, obj.optString("tps_description"));
pstmt.addBatch();
}
pstmt.executeBatch();
conn.commit();
} catch (FileNotFoundException e) {
log.error(e.getMessage(), e);
} catch (IOException e) {
log.error(e.getMessage(), e);
} catch (SQLException e) {
log.error(e.getMessage(), e);
}
if(!file.delete()) {
log.warn("Unable to delete {}", file.getName());
}
}
}

17
src/org/leolo/rail/model/LocationRecordType.java

@ -0,0 +1,17 @@
package org.leolo.rail.model;
public enum LocationRecordType {
ORIGIN("LO"),
INTERMEDIATE("LI"),
TERMINATE("LT");
private String recordCode;
private LocationRecordType(String recordCode) {
this.recordCode = recordCode;
}
public String getRecordCode() {
return recordCode;
}
}

20
src/org/leolo/rail/model/ScheduleType.java

@ -0,0 +1,20 @@
package org.leolo.rail.model;
public enum ScheduleType {
WTT("P"),
OVL("O"),
VAR("V"),
STP("S"),
CAN("C");
private String scheduleCode;
private ScheduleType(String scheduleCode) {
this.scheduleCode = scheduleCode;
}
public String getScheduleCode() {
return scheduleCode;
}
}

328
src/org/leolo/rail/model/TrainSchedule.java

@ -0,0 +1,328 @@
package org.leolo.rail.model;
import java.util.Date;
import java.util.Vector;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.leolo.rail.util.TUIDDateFormat;
public class TrainSchedule {
private static Logger log = LogManager.getLogger(TrainSchedule.class);
private String trainUId;
private ScheduleType scheduleType = ScheduleType.WTT;
private Date startDate;
private Date endDate;
private String days;
private String bankHolidayInd;
private String signalId;
private String rsid;
private String trainStatus;
private String trainCategory;
private String section;
private String powerType;
private String timingLoad;
private String plannedSpeed;
private String operatingCharacter;
private String classAvailable;
private String sleeper;
private String reservation;
private String catering;
private String uicCode;
private String atocCode;
private Vector<TrainScheduleLocation> locations = new Vector<>();
public String getTrainUId() {
return trainUId;
}
public void setTrainUId(String trainUId) {
this.trainUId = trainUId;
}
public ScheduleType getScheduleType() {
return scheduleType;
}
public void setScheduleType(ScheduleType scheduleType) {
this.scheduleType = scheduleType;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public String getDays() {
return days;
}
public void setDays(String days) {
this.days = days;
}
public String getBankHolidayInd() {
return bankHolidayInd;
}
public void setBankHolidayInd(String bankHolidayInd) {
this.bankHolidayInd = bankHolidayInd;
}
public String getSignalId() {
return signalId;
}
public void setSignalId(String signalId) {
this.signalId = signalId;
}
public String getRsid() {
return rsid;
}
public void setRsid(String rsid) {
this.rsid = rsid;
}
public String getTrainStatus() {
return trainStatus;
}
public void setTrainStatus(String trainStatus) {
this.trainStatus = trainStatus;
}
public String getTrainCategory() {
return trainCategory;
}
public void setTrainCategory(String trainCategory) {
this.trainCategory = trainCategory;
}
public String getSection() {
return section;
}
public void setSection(String section) {
this.section = section;
}
public String getPowerType() {
return powerType;
}
public void setPowerType(String powerType) {
this.powerType = powerType;
}
public String getTimingLoad() {
return timingLoad;
}
public void setTimingLoad(String timingLoad) {
this.timingLoad = timingLoad;
}
public String getPlannedSpeed() {
return plannedSpeed;
}
public void setPlannedSpeed(String plannedSpeed) {
this.plannedSpeed = plannedSpeed;
}
public String getOperatingCharacter() {
return operatingCharacter;
}
public void setOperatingCharacter(String operatingCharacter) {
this.operatingCharacter = operatingCharacter;
}
public String getClassAvailable() {
return classAvailable;
}
public void setClassAvailable(String classAvailable) {
if(" ".equals(classAvailable))
this.classAvailable = "B";
else
this.classAvailable = classAvailable;
}
public String getSleeper() {
return sleeper;
}
public void setSleeper(String sleeper) {
this.sleeper = sleeper;
}
public String getReservation() {
return reservation;
}
public void setReservation(String reservation) {
this.reservation = reservation;
}
public String getCatering() {
return catering;
}
public void setCatering(String catering) {
StringBuilder sb = new StringBuilder();
char chars[] = catering.toCharArray();
for(int i=0;i<chars.length;i++) {
if(i!=0) sb.append(",");
sb.append(chars[i]);
}
this.catering = sb.toString();
}
public String getUicCode() {
return uicCode;
}
public void setUicCode(String uicCode) {
this.uicCode = uicCode;
}
public String getAtocCode() {
return atocCode;
}
public void setAtocCode(String atocCode) {
this.atocCode = atocCode;
}
public Vector<TrainScheduleLocation> getLocations() {
return locations;
}
public String getSUID() {
TUIDDateFormat tdf = new TUIDDateFormat();
return trainUId + tdf.format(startDate) + tdf.format(endDate) + scheduleType.getScheduleCode();
}
@Override
public int hashCode() {
log.info("startdate:{}", startDate.getTime());
final int prime = 31;
int result = 1;
result = prime * result + ((atocCode == null) ? 0 : atocCode.hashCode());
result = prime * result + ((bankHolidayInd == null) ? 0 : bankHolidayInd.hashCode());
result = prime * result + ((catering == null) ? 0 : catering.hashCode());
result = prime * result + ((classAvailable == null) ? 0 : classAvailable.hashCode());
result = prime * result + ((days == null) ? 0 : days.hashCode());
result = prime * result + ((endDate == null) ? 0 : endDate.hashCode());
result = prime * result + ((operatingCharacter == null) ? 0 : operatingCharacter.hashCode());
result = prime * result + ((plannedSpeed == null) ? 0 : plannedSpeed.hashCode());
result = prime * result + ((powerType == null) ? 0 : powerType.hashCode());
result = prime * result + ((reservation == null) ? 0 : reservation.hashCode());
result = prime * result + ((rsid == null) ? 0 : rsid.hashCode());
result = prime * result + ((scheduleType == null) ? 0 : scheduleType.hashCode());
result = prime * result + ((section == null) ? 0 : section.hashCode());
result = prime * result + ((signalId == null) ? 0 : signalId.hashCode());
result = prime * result + ((sleeper == null) ? 0 : sleeper.hashCode());
result = prime * result + ((startDate == null) ? 0 : startDate.hashCode());
result = prime * result + ((timingLoad == null) ? 0 : timingLoad.hashCode());
result = prime * result + ((trainCategory == null) ? 0 : trainCategory.hashCode());
result = prime * result + ((trainStatus == null) ? 0 : trainStatus.hashCode());
result = prime * result + ((trainUId == null) ? 0 : trainUId.hashCode());
result = prime * result + ((uicCode == null) ? 0 : uicCode.hashCode());
for(TrainScheduleLocation tsl:locations) {
log.atDebug().log("TIPLOC: {}, hash: {}//{}", tsl.getTiplocCode(), Integer.toHexString(tsl.hashCode()), Integer.toHexString(tsl.getTiplocCode().hashCode()));
result = prime * result + tsl.hashCode();
}
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TrainSchedule other = (TrainSchedule) obj;
if (atocCode == null) {
if (other.atocCode != null)
return false;
} else if (!atocCode.equals(other.atocCode))
return false;
if (bankHolidayInd == null) {
if (other.bankHolidayInd != null)
return false;
} else if (!bankHolidayInd.equals(other.bankHolidayInd))
return false;
if (catering == null) {
if (other.catering != null)
return false;
} else if (!catering.equals(other.catering))
return false;
if (classAvailable == null) {
if (other.classAvailable != null)
return false;
} else if (!classAvailable.equals(other.classAvailable))
return false;
if (days == null) {
if (other.days != null)
return false;
} else if (!days.equals(other.days))
return false;
if (endDate == null) {
if (other.endDate != null)
return false;
} else if (!endDate.equals(other.endDate))
return false;
if (locations == null) {
if (other.locations != null)
return false;
} else if (!locations.equals(other.locations))
return false;
if (operatingCharacter == null) {
if (other.operatingCharacter != null)
return false;
} else if (!operatingCharacter.equals(other.operatingCharacter))
return false;
if (plannedSpeed == null) {
if (other.plannedSpeed != null)
return false;
} else if (!plannedSpeed.equals(other.plannedSpeed))
return false;
if (powerType == null) {
if (other.powerType != null)
return false;
} else if (!powerType.equals(other.powerType))
return false;
if (reservation == null) {
if (other.reservation != null)
return false;
} else if (!reservation.equals(other.reservation))
return false;
if (rsid == null) {
if (other.rsid != null)
return false;
} else if (!rsid.equals(other.rsid))
return false;
if (scheduleType != other.scheduleType)
return false;
if (section == null) {
if (other.section != null)
return false;
} else if (!section.equals(other.section))
return false;
if (signalId == null) {
if (other.signalId != null)
return false;
} else if (!signalId.equals(other.signalId))
return false;
if (sleeper == null) {
if (other.sleeper != null)
return false;
} else if (!sleeper.equals(other.sleeper))
return false;
if (startDate == null) {
if (other.startDate != null)
return false;
} else if (!startDate.equals(other.startDate))
return false;
if (timingLoad == null) {
if (other.timingLoad != null)
return false;
} else if (!timingLoad.equals(other.timingLoad))
return false;
if (trainCategory == null) {
if (other.trainCategory != null)
return false;
} else if (!trainCategory.equals(other.trainCategory))
return false;
if (trainStatus == null) {
if (other.trainStatus != null)
return false;
} else if (!trainStatus.equals(other.trainStatus))
return false;
if (trainUId == null) {
if (other.trainUId != null)
return false;
} else if (!trainUId.equals(other.trainUId))
return false;
if (uicCode == null) {
if (other.uicCode != null)
return false;
} else if (!uicCode.equals(other.uicCode))
return false;
return true;
}
}

175
src/org/leolo/rail/model/TrainScheduleLocation.java

@ -0,0 +1,175 @@
package org.leolo.rail.model;
public class TrainScheduleLocation {
private String tiplocCode;
private int tiplocInstance = 1;
private long arrival;
private long departure;
private long pass;
private long pubArrival;
private long pubDeparture;
private String platform;
private String line;
private String path;
private long engineeringAllowance;
private long pathingAllowance;
private long performanceAllowance;
private LocationRecordType recordType;
public String getTiplocCode() {
return tiplocCode;
}
public void setTiplocCode(String tiplocCode) {
this.tiplocCode = tiplocCode;
}
public int getTiplocInstance() {
return tiplocInstance;
}
public void setTiplocInstance(int tiplocInstance) {
this.tiplocInstance = tiplocInstance;
}
public long getArrival() {
return arrival;
}
public void setArrival(long arrival) {
this.arrival = arrival;
}
public long getDeparture() {
return departure;
}
public void setDeparture(long departure) {
this.departure = departure;
}
public long getPass() {
return pass;
}
public void setPass(long pass) {
this.pass = pass;
}
public long getPubArrival() {
return pubArrival;
}
public void setPubArrival(long pubArrival) {
this.pubArrival = pubArrival;
}
public long getPubDeparture() {
return pubDeparture;
}
public void setPubDeparture(long pubDeparture) {
this.pubDeparture = pubDeparture;
}
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getLine() {
return line;
}
public void setLine(String line) {
this.line = line;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public long getEngineeringAllowance() {
return engineeringAllowance;
}
public void setEngineeringAllowance(long engineeringAllowance) {
this.engineeringAllowance = engineeringAllowance;
}
public long getPathingAllowance() {
return pathingAllowance;
}
public void setPathingAllowance(long pathingAllowance) {
this.pathingAllowance = pathingAllowance;
}
public long getPerformanceAllowance() {
return performanceAllowance;
}
public void setPerformanceAllowance(long performanceAllowance) {
this.performanceAllowance = performanceAllowance;
}
public LocationRecordType getRecordType() {
return recordType;
}
public void setRecordType(LocationRecordType recordType) {
this.recordType = recordType;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (arrival ^ (arrival >>> 32));
result = prime * result + (int) (departure ^ (departure >>> 32));
result = prime * result + (int) (engineeringAllowance ^ (engineeringAllowance >>> 32));
result = prime * result + ((line == null) ? 0 : line.hashCode());
result = prime * result + (int) (pass ^ (pass >>> 32));
result = prime * result + ((path == null) ? 0 : path.hashCode());
result = prime * result + (int) (pathingAllowance ^ (pathingAllowance >>> 32));
result = prime * result + (int) (performanceAllowance ^ (performanceAllowance >>> 32));
result = prime * result + ((platform == null) ? 0 : platform.hashCode());
result = prime * result + (int) (pubArrival ^ (pubArrival >>> 32));
result = prime * result + (int) (pubDeparture ^ (pubDeparture >>> 32));
result = prime * result + ((recordType == null) ? 0 : recordType.hashCode());
result = prime * result + ((tiplocCode == null) ? 0 : tiplocCode.hashCode());
result = prime * result + tiplocInstance;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TrainScheduleLocation other = (TrainScheduleLocation) obj;
if (arrival != other.arrival)
return false;
if (departure != other.departure)
return false;
if (engineeringAllowance != other.engineeringAllowance)
return false;
if (line == null) {
if (other.line != null)
return false;
} else if (!line.equals(other.line))
return false;
if (pass != other.pass)
return false;
if (path == null) {
if (other.path != null)
return false;
} else if (!path.equals(other.path))
return false;
if (pathingAllowance != other.pathingAllowance)
return false;
if (performanceAllowance != other.performanceAllowance)
return false;
if (platform == null) {
if (other.platform != null)
return false;
} else if (!platform.equals(other.platform))
return false;
if (pubArrival != other.pubArrival)
return false;
if (pubDeparture != other.pubDeparture)
return false;
if (recordType != other.recordType)
return false;
if (tiplocCode == null) {
if (other.tiplocCode != null)
return false;
} else if (!tiplocCode.equals(other.tiplocCode))
return false;
if (tiplocInstance != other.tiplocInstance)
return false;
return true;
}
}

8
src/org/leolo/rail/model/package-info.java

@ -0,0 +1,8 @@
/**
*
*/
/**
* @author user
*
*/
package org.leolo.rail.model;
Loading…
Cancel
Save