Compare commits
No commits in common. 'develop' and 'master' have entirely different histories.
31 changed files with 25 additions and 3870 deletions
@ -1,93 +0,0 @@ |
|||||||
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()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,57 +0,0 @@ |
|||||||
package org.leolo.rail; |
|
||||||
|
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
import org.apache.activemq.transport.stomp.StompConnection; |
|
||||||
|
|
||||||
public abstract class BaseProcessingThread extends Thread implements AutoCloseable{ |
|
||||||
|
|
||||||
private boolean isInit = false; |
|
||||||
protected StompConnection connection; |
|
||||||
private String configPrefix; |
|
||||||
|
|
||||||
public BaseProcessingThread(String configPrefix) throws Exception { |
|
||||||
this.configPrefix = configPrefix; |
|
||||||
this.connection = getConnection(); |
|
||||||
} |
|
||||||
|
|
||||||
protected abstract void _init(); |
|
||||||
|
|
||||||
@Override |
|
||||||
public abstract void run(); |
|
||||||
|
|
||||||
public void init() { |
|
||||||
_init(); |
|
||||||
isInit = true; |
|
||||||
} |
|
||||||
|
|
||||||
private StompConnection getConnection() throws Exception { |
|
||||||
StompConnection conn = new StompConnection(); |
|
||||||
conn.open( |
|
||||||
ConfigurationManager.getInstance().getProperty(configPrefix+".host"), |
|
||||||
ConfigurationManager.getInstance().getInt(configPrefix+".port") |
|
||||||
); |
|
||||||
conn.connect( |
|
||||||
ConfigurationManager.getInstance().getProperty(configPrefix+".user"), |
|
||||||
ConfigurationManager.getInstance().getProperty(configPrefix+".pwd") |
|
||||||
); |
|
||||||
return conn; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public synchronized void start() { |
|
||||||
if(isInit) { |
|
||||||
super.start(); |
|
||||||
}else { |
|
||||||
throw new RuntimeException("Thread not init yet"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void close() throws IOException { |
|
||||||
connection.close(); |
|
||||||
connection = null; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
@ -1,28 +0,0 @@ |
|||||||
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); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
@ -1,28 +0,0 @@ |
|||||||
package org.leolo.rail; |
|
||||||
|
|
||||||
public enum CurrentTrainStatus { |
|
||||||
|
|
||||||
ACTIVATED("A"), |
|
||||||
CANCELLED("C"), |
|
||||||
TERMINATED("T"); |
|
||||||
|
|
||||||
private String code; |
|
||||||
|
|
||||||
private CurrentTrainStatus(String code) { |
|
||||||
this.code = code; |
|
||||||
} |
|
||||||
|
|
||||||
public String getCode() { |
|
||||||
return code; |
|
||||||
} |
|
||||||
|
|
||||||
public static CurrentTrainStatus getCurrentTrainStatus(String code) { |
|
||||||
for(CurrentTrainStatus cts:values()) { |
|
||||||
if(cts.code.equals(code)) { |
|
||||||
return cts; |
|
||||||
} |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,82 +0,0 @@ |
|||||||
package org.leolo.rail; |
|
||||||
|
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
import org.apache.activemq.command.Endpoint; |
|
||||||
import org.apache.activemq.transport.stomp.StompFrame; |
|
||||||
import org.apache.logging.log4j.LogManager; |
|
||||||
import org.apache.logging.log4j.Logger; |
|
||||||
|
|
||||||
public class NetowrkRailProcessingThread extends BaseProcessingThread { |
|
||||||
|
|
||||||
private static Logger log = LogManager.getLogger(NetowrkRailProcessingThread.class); |
|
||||||
private TrainMovementProcessor procTrainMvt = new TrainMovementProcessor(); |
|
||||||
private VTSPProcessor procVTSP = new VTSPProcessor(); |
|
||||||
private boolean stopThread = false; |
|
||||||
|
|
||||||
public NetowrkRailProcessingThread() throws Exception { |
|
||||||
super("network"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected void _init() { |
|
||||||
try { |
|
||||||
connection.subscribe(Constants.NetworkRail.TOPIC_NAME_MVT); |
|
||||||
connection.subscribe(Constants.NetworkRail.TOPIC_NAME_VTSP); |
|
||||||
} catch (Exception e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
|
|
||||||
procTrainMvt.start(); |
|
||||||
procVTSP.start(); |
|
||||||
} |
|
||||||
|
|
||||||
private volatile long sleepTime = Constants.Generic.DEFAULT_SLEEP_TIME; |
|
||||||
|
|
||||||
private void sleep() { |
|
||||||
try { |
|
||||||
sleep(sleepTime); |
|
||||||
} catch (InterruptedException e1) { |
|
||||||
log.error(e1.getMessage(), e1); |
|
||||||
} |
|
||||||
sleepTime*=Constants.Generic.INCRESE_RATIO; |
|
||||||
if(sleepTime>128000) { |
|
||||||
log.atError().log("Failed too many times. Restart thread."); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void run() { |
|
||||||
while(true) { |
|
||||||
try { |
|
||||||
if(stopThread) { |
|
||||||
break; |
|
||||||
} |
|
||||||
StompFrame frm = connection.receive(); |
|
||||||
if("ERROR".equals(frm.getAction())) { |
|
||||||
log.error("Error message received. {}", frm.getBody()); |
|
||||||
sleep(); |
|
||||||
continue; |
|
||||||
} |
|
||||||
log.info("HDRs: {}", frm.getHeaders()); |
|
||||||
String topic = frm.getHeaders().get("destination"); |
|
||||||
if(Constants.NetworkRail.TOPIC_NAME_MVT.equals(topic)) { |
|
||||||
procTrainMvt.process(frm); |
|
||||||
}else if(Constants.NetworkRail.TOPIC_NAME_VTSP.equals(topic)) { |
|
||||||
procVTSP.process(frm); |
|
||||||
} |
|
||||||
sleepTime = Constants.Generic.DEFAULT_SLEEP_TIME; |
|
||||||
} catch (Exception e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
sleep(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void close() throws IOException { |
|
||||||
procTrainMvt.terminate(); |
|
||||||
super.close(); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,317 +0,0 @@ |
|||||||
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(); |
|
||||||
} |
|
||||||
}//Updated 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()); |
|
||||||
} |
|
||||||
log.atInfo().log("Done processing {}", 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; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,113 +0,0 @@ |
|||||||
package org.leolo.rail; |
|
||||||
|
|
||||||
import java.util.Collection; |
|
||||||
import java.util.List; |
|
||||||
import java.util.TreeMap; |
|
||||||
import java.util.concurrent.Callable; |
|
||||||
import java.util.concurrent.ExecutionException; |
|
||||||
import java.util.concurrent.ExecutorService; |
|
||||||
import java.util.concurrent.Executors; |
|
||||||
import java.util.concurrent.Future; |
|
||||||
import java.util.concurrent.TimeUnit; |
|
||||||
import java.util.concurrent.TimeoutException; |
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager; |
|
||||||
import org.apache.logging.log4j.Logger; |
|
||||||
|
|
||||||
public class ThreadPoolManager { |
|
||||||
private static Logger log = LogManager.getLogger(ThreadPoolManager.class); |
|
||||||
|
|
||||||
private static ThreadPoolManager instance; |
|
||||||
|
|
||||||
private final Object SYNC_TOKEN = new Object(); |
|
||||||
|
|
||||||
public static synchronized ThreadPoolManager getInstance() { |
|
||||||
if(instance==null) { |
|
||||||
instance = new ThreadPoolManager(); |
|
||||||
} |
|
||||||
return instance; |
|
||||||
} |
|
||||||
|
|
||||||
private ExecutorService pool = Executors.newFixedThreadPool( |
|
||||||
ConfigurationManager.getInstance().getInt("pool.size", 30)); |
|
||||||
private TreeMap<Long, Runnable> pendingJob = new TreeMap<>(); |
|
||||||
private ThreadPoolManager() { |
|
||||||
new Thread(()-> { |
|
||||||
while(true) { |
|
||||||
if(pendingJob.isEmpty()) { |
|
||||||
try { |
|
||||||
synchronized(SYNC_TOKEN) { |
|
||||||
SYNC_TOKEN.wait(100); |
|
||||||
} |
|
||||||
}catch(InterruptedException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
continue; |
|
||||||
} |
|
||||||
Long key = pendingJob.firstKey(); |
|
||||||
if(key==null || System.currentTimeMillis() < key) { |
|
||||||
try { |
|
||||||
synchronized(SYNC_TOKEN) { |
|
||||||
SYNC_TOKEN.wait(100); |
|
||||||
} |
|
||||||
}catch(InterruptedException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
continue; |
|
||||||
} |
|
||||||
log.info("Running job#{}", key); |
|
||||||
Runnable r = pendingJob.get(key); |
|
||||||
pendingJob.remove(key); |
|
||||||
pool.execute(r); |
|
||||||
} |
|
||||||
}).start(); |
|
||||||
} |
|
||||||
|
|
||||||
public void execute(Runnable arg0) { |
|
||||||
pool.execute(arg0); |
|
||||||
} |
|
||||||
|
|
||||||
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) |
|
||||||
throws InterruptedException { |
|
||||||
return pool.invokeAll(tasks, timeout, unit); |
|
||||||
} |
|
||||||
|
|
||||||
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException { |
|
||||||
return pool.invokeAll(tasks); |
|
||||||
} |
|
||||||
|
|
||||||
public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) |
|
||||||
throws InterruptedException, ExecutionException, TimeoutException { |
|
||||||
return pool.invokeAny(tasks, timeout, unit); |
|
||||||
} |
|
||||||
|
|
||||||
public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException { |
|
||||||
return pool.invokeAny(tasks); |
|
||||||
} |
|
||||||
|
|
||||||
public boolean isShutdown() { |
|
||||||
return pool.isShutdown(); |
|
||||||
} |
|
||||||
|
|
||||||
public boolean isTerminated() { |
|
||||||
return pool.isTerminated(); |
|
||||||
} |
|
||||||
|
|
||||||
public Future<?> submit(Runnable task) { |
|
||||||
return pool.submit(task); |
|
||||||
} |
|
||||||
|
|
||||||
public synchronized void schedule(Runnable task, long notBefore) { |
|
||||||
while(true) { |
|
||||||
if(!pendingJob.containsKey(notBefore)) { |
|
||||||
break; |
|
||||||
} |
|
||||||
notBefore++; |
|
||||||
} |
|
||||||
pendingJob.put(notBefore, task); |
|
||||||
synchronized(SYNC_TOKEN) { |
|
||||||
SYNC_TOKEN.notifyAll(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,67 +0,0 @@ |
|||||||
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()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,371 +0,0 @@ |
|||||||
package org.leolo.rail; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.io.FileNotFoundException; |
|
||||||
import java.io.PrintWriter; |
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.PreparedStatement; |
|
||||||
import java.sql.ResultSet; |
|
||||||
import java.sql.SQLException; |
|
||||||
import java.sql.Timestamp; |
|
||||||
import java.sql.Types; |
|
||||||
import java.text.ParseException; |
|
||||||
import java.text.SimpleDateFormat; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Date; |
|
||||||
import java.util.HashMap; |
|
||||||
import java.util.LinkedList; |
|
||||||
import java.util.Queue; |
|
||||||
import java.util.Vector; |
|
||||||
|
|
||||||
import org.apache.activemq.transport.stomp.StompFrame; |
|
||||||
import org.apache.logging.log4j.LogManager; |
|
||||||
import org.apache.logging.log4j.Logger; |
|
||||||
import org.json.JSONArray; |
|
||||||
import org.json.JSONException; |
|
||||||
import org.json.JSONObject; |
|
||||||
import org.leolo.rail.util.TUIDDateFormat; |
|
||||||
|
|
||||||
public class TrainMovementProcessor extends Thread{ |
|
||||||
|
|
||||||
private Logger log = LogManager.getLogger(TrainMovementProcessor.class); |
|
||||||
private Logger logRI = LogManager.getLogger("org.leolo.RI"); |
|
||||||
|
|
||||||
private final Object SYNC_TOKEN = new Object(); |
|
||||||
|
|
||||||
private Queue<StompFrame> procQueue = new LinkedList<>(); |
|
||||||
private boolean terminated = false; |
|
||||||
|
|
||||||
public void terminate() { |
|
||||||
terminated = true; |
|
||||||
synchronized(SYNC_TOKEN) { |
|
||||||
SYNC_TOKEN.notifyAll(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void process(StompFrame data) { |
|
||||||
procQueue.add(data); |
|
||||||
synchronized(SYNC_TOKEN) { |
|
||||||
SYNC_TOKEN.notifyAll(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void run() { |
|
||||||
logRI.debug("Started."); |
|
||||||
while(true) { |
|
||||||
if(terminated) { |
|
||||||
return; |
|
||||||
} |
|
||||||
StompFrame data = procQueue.poll(); |
|
||||||
if(data==null) { |
|
||||||
synchronized(SYNC_TOKEN) { |
|
||||||
try { |
|
||||||
// log.debug("No more data. Sleep.");
|
|
||||||
SYNC_TOKEN.wait(1000); |
|
||||||
} catch (InterruptedException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
} |
|
||||||
continue; |
|
||||||
} |
|
||||||
//Actually handle the data
|
|
||||||
String msgId = data.getHeaders().get("message-id"); |
|
||||||
log.info("Processing message {}", msgId); |
|
||||||
if(Constants.Generic.DEBUG_MODE) { |
|
||||||
new File("tmpd").mkdirs(); |
|
||||||
try(PrintWriter out = new PrintWriter("tmpd/msg_"+msgId.replace(":", "-")+".json")){ |
|
||||||
out.println(data.getBody()); |
|
||||||
} catch (FileNotFoundException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
} |
|
||||||
HashMap<String, ArrayList<JSONObject>> procMap = new HashMap<>(); |
|
||||||
JSONArray procData = new JSONArray(data.getBody()); |
|
||||||
log.info("{} entries expected", procData.length()); |
|
||||||
for(int i=0;i<procData.length();i++) { |
|
||||||
JSONObject obj = procData.getJSONObject(i); |
|
||||||
String type = obj.getJSONObject("header").getString("msg_type"); |
|
||||||
if(!procMap.containsKey(type)) { |
|
||||||
procMap.put(type, new ArrayList<>()); |
|
||||||
} |
|
||||||
procMap.get(type).add(obj); |
|
||||||
} |
|
||||||
//[TA]0001: Train Activation
|
|
||||||
if(procMap.containsKey("0001")) { |
|
||||||
ThreadPoolManager.getInstance().execute(()->{ |
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
|
||||||
TUIDDateFormat tdf = new TUIDDateFormat(); |
|
||||||
int batchSize = 0; |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmtTA = conn.prepareStatement("REPLACE INTO current_train VALUES (?,?,?,?,?,?)"); |
|
||||||
PreparedStatement pstmtQsid = conn.prepareStatement("SELECT suid FROM all_schedule " |
|
||||||
+ "WHERE train_uid = ? AND ? BETWEEN start_date AND end_date AND days LIKE get_wd_str(?) " |
|
||||||
+ "ORDER BY CASE sch_type WHEN 'CAN' THEN 1 WHEN 'VAR' THEN 2 WHEN 'OVL' THEN 3 ELSE 4 END ASC LIMIT 1") |
|
||||||
){ |
|
||||||
for(JSONObject obj:procMap.get("0001")) { |
|
||||||
String trainId = obj.getJSONObject("body").optString("train_id"); |
|
||||||
String trainUid = obj.getJSONObject("body").optString("train_uid"); |
|
||||||
Date startDate; |
|
||||||
Date endDate; |
|
||||||
Date opDate; |
|
||||||
try { |
|
||||||
startDate = sdf.parse(obj.getJSONObject("body").optString("schedule_start_date")); |
|
||||||
endDate = sdf.parse(obj.getJSONObject("body").optString("schedule_end_date")); |
|
||||||
opDate = sdf.parse(obj.getJSONObject("body").optString("tp_origin_timestamp")); |
|
||||||
}catch(ParseException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
continue; |
|
||||||
} |
|
||||||
String serviceCode = obj.getJSONObject("body").optString("train_service_code"); |
|
||||||
long activationTime = obj.getJSONObject("body").optLong("creation_timestamp"); |
|
||||||
String suid; |
|
||||||
pstmtQsid.setString(1, trainUid); |
|
||||||
pstmtQsid.setDate(2, new java.sql.Date(opDate.getTime())); |
|
||||||
pstmtQsid.setDate(3, new java.sql.Date(opDate.getTime())); |
|
||||||
try(ResultSet rs = pstmtQsid.executeQuery()){ |
|
||||||
if(rs.next()) { |
|
||||||
suid = rs.getString(1); |
|
||||||
}else { |
|
||||||
suid = trainUid + tdf.format(startDate) + tdf.format(endDate) + "V"; |
|
||||||
} |
|
||||||
} |
|
||||||
log.debug("[TA] {}({}) TSC:{}", trainId, suid, serviceCode); |
|
||||||
pstmtTA.setString(1, trainId); |
|
||||||
pstmtTA.setString(2, suid); |
|
||||||
pstmtTA.setDate(3, new java.sql.Date(opDate.getTime())); |
|
||||||
pstmtTA.setString(4, serviceCode); |
|
||||||
pstmtTA.setTimestamp(5, new Timestamp(activationTime)); |
|
||||||
pstmtTA.setString(6, CurrentTrainStatus.ACTIVATED.getCode()); |
|
||||||
pstmtTA.addBatch(); |
|
||||||
batchSize++; |
|
||||||
} |
|
||||||
pstmtTA.executeBatch(); |
|
||||||
conn.commit(); |
|
||||||
log.info("[TA] Record Count : {}", batchSize); |
|
||||||
}catch(SQLException e){ |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
}); |
|
||||||
}//TA
|
|
||||||
//[TC]0002: Train Cancellation
|
|
||||||
if(procMap.containsKey("0002")) { |
|
||||||
ThreadPoolManager.getInstance().execute(()->{ |
|
||||||
int batchSize = 0; |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmtTC = conn.prepareStatement("REPLACE current_train_cancellation VALUES (?,?,?,?,?,?,?)"); |
|
||||||
PreparedStatement pstmtUTA = conn.prepareStatement("UPDATE current_train SET `status` = ? WHERE train_id = ?"); |
|
||||||
){ |
|
||||||
pstmtUTA.setString(1, CurrentTrainStatus.CANCELLED.getCode()); |
|
||||||
for(JSONObject obj:procMap.get("0002")) { |
|
||||||
String train_id = obj.getJSONObject("body").optString("train_id"); |
|
||||||
String canx_loc = obj.getJSONObject("body").optString("loc_stanox"); |
|
||||||
String canx_reason = obj.getJSONObject("body").optString("canx_reason_code"); |
|
||||||
String canx_type = obj.getJSONObject("body").optString("canx_type"); |
|
||||||
String canx_dev = obj.getJSONObject("header").optString("source_dev_id"); |
|
||||||
String canx_usr = obj.getJSONObject("header").optString("user_id"); |
|
||||||
long canx_time = obj.getJSONObject("body").optLong("canx_timestamp"); |
|
||||||
// log.debug("[TC] {}@{} because {} by {}@{}", train_id, canx_loc, canx_reason, canx_usr, canx_dev);
|
|
||||||
pstmtTC.setString(1, train_id); |
|
||||||
pstmtTC.setString(2, canx_loc); |
|
||||||
pstmtTC.setTimestamp(3, new Timestamp(canx_time)); |
|
||||||
pstmtTC.setString(4, canx_reason); |
|
||||||
pstmtTC.setString(5, canx_type); |
|
||||||
setString(pstmtTC,6, canx_dev); |
|
||||||
setString(pstmtTC,7, canx_usr); |
|
||||||
pstmtTC.addBatch(); |
|
||||||
pstmtUTA.setString(2, train_id); |
|
||||||
int rowCount = pstmtUTA.executeUpdate(); |
|
||||||
Runnable r = new Runnable() { |
|
||||||
|
|
||||||
int runCount = 0; |
|
||||||
|
|
||||||
@Override |
|
||||||
public void run() { |
|
||||||
runCount++; |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmtUTA = conn.prepareStatement("UPDATE current_train SET `status` = ? WHERE train_id = ?"); |
|
||||||
){ |
|
||||||
pstmtUTA.setString(1, CurrentTrainStatus.CANCELLED.getCode()); |
|
||||||
pstmtUTA.setString(2, train_id); |
|
||||||
int rowCount = pstmtUTA.executeUpdate(); |
|
||||||
if(rowCount==0) { |
|
||||||
if(runCount > 5) { |
|
||||||
log.warn("[TC] Cannot update {} [LAST]", train_id); |
|
||||||
return; |
|
||||||
} |
|
||||||
log.warn("[TC] Cannot update {} (ROUND {})", train_id, runCount); |
|
||||||
ThreadPoolManager.getInstance().schedule(this, System.currentTimeMillis()+(long)(1000*Math.pow(2, runCount))); |
|
||||||
}else { |
|
||||||
log.info("[TC] Successfully update {} (ROUND {})", train_id, runCount); |
|
||||||
} |
|
||||||
conn.commit(); |
|
||||||
}catch(SQLException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
}; |
|
||||||
if(rowCount==0) { |
|
||||||
log.warn("[TC] Cannot update {}", train_id); |
|
||||||
ThreadPoolManager.getInstance().schedule(r, System.currentTimeMillis()+1000); |
|
||||||
} |
|
||||||
batchSize++; |
|
||||||
} |
|
||||||
pstmtTC.executeBatch(); |
|
||||||
conn.commit(); |
|
||||||
log.info("[TC] Record Count : {}", batchSize); |
|
||||||
}catch(SQLException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
|
|
||||||
}); |
|
||||||
}//TC
|
|
||||||
//[TM]0003: Train Movement
|
|
||||||
if(procMap.containsKey("0003")) { |
|
||||||
ThreadPoolManager.getInstance().execute(()->{ |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmtTM = conn.prepareStatement("REPLACE INTO current_train_movement VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"); |
|
||||||
PreparedStatement pstmtUTA = conn.prepareStatement("UPDATE current_train SET `status` = ? WHERE train_id = ?"); |
|
||||||
){ |
|
||||||
int batchSize = 0; |
|
||||||
for(JSONObject obj:procMap.get("0003")) { |
|
||||||
String trainId = obj.getJSONObject("body" ).optString ("train_id"); |
|
||||||
long movtTime = obj.getJSONObject("body" ).optLong ("actual_timestamp"); |
|
||||||
long gbttTime = obj.getJSONObject("body" ).optLong ("gbtt_timestamp", -1); |
|
||||||
long planTime = obj.getJSONObject("body" ).optLong ("planned_timestamp", -1); |
|
||||||
String stanox = obj.getJSONObject("body" ).optString ("loc_stanox"); |
|
||||||
String eventType = obj.getJSONObject("body" ).optString ("event_type"); |
|
||||||
boolean correction= obj.getJSONObject("body" ).optBoolean("correction_ind"); |
|
||||||
String platform = obj.getJSONObject("body" ).optString ("platform"); |
|
||||||
String line = obj.getJSONObject("body" ).optString ("line_ind"); |
|
||||||
String route = obj.getJSONObject("body" ).optString ("route"); |
|
||||||
String dev = obj.getJSONObject("header").optString ("source_dev_id"); |
|
||||||
String usr = obj.getJSONObject("header").optString ("user_id"); |
|
||||||
boolean termInd = obj.getJSONObject("body" ).optBoolean("train_terminated", false); |
|
||||||
// log.debug("[TM] {}@{} PLAT {}/{}{} by {}@{}{}", trainId, stanox, platform, line, route, usr, dev,termInd?"[T]":"");
|
|
||||||
pstmtTM.setString(1, trainId); |
|
||||||
pstmtTM.setTimestamp(2, new Timestamp(movtTime)); |
|
||||||
if(gbttTime==-1) { |
|
||||||
pstmtTM.setNull(3, Types.TIMESTAMP); |
|
||||||
}else { |
|
||||||
pstmtTM.setTimestamp(3, new Timestamp(gbttTime)); |
|
||||||
} |
|
||||||
if(planTime==-1) { |
|
||||||
pstmtTM.setNull(4, Types.TIMESTAMP); |
|
||||||
}else { |
|
||||||
pstmtTM.setTimestamp(4, new Timestamp(planTime)); |
|
||||||
} |
|
||||||
pstmtTM.setString(5, stanox); |
|
||||||
pstmtTM.setString(6, eventType); |
|
||||||
pstmtTM.setString(7, correction?"Y":"N"); |
|
||||||
setString(pstmtTM,8, platform); |
|
||||||
setString(pstmtTM,9, line); |
|
||||||
setString(pstmtTM,10, route); |
|
||||||
setString(pstmtTM,11, dev); |
|
||||||
setString(pstmtTM,12, usr); |
|
||||||
pstmtTM.addBatch(); |
|
||||||
if(termInd) { |
|
||||||
pstmtUTA.setString(1, CurrentTrainStatus.TERMINATED.getCode()); |
|
||||||
pstmtUTA.setString(2, trainId); |
|
||||||
pstmtUTA.addBatch(); |
|
||||||
} |
|
||||||
batchSize++; |
|
||||||
} |
|
||||||
pstmtTM.executeBatch(); |
|
||||||
pstmtUTA.executeBatch(); |
|
||||||
conn.commit(); |
|
||||||
log.info("[TM] Record Count : {}", batchSize); |
|
||||||
}catch(SQLException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
}); |
|
||||||
}//TM
|
|
||||||
//[RI]0005: Train re-instatement
|
|
||||||
if(procMap.containsKey("0005")) { |
|
||||||
ThreadPoolManager.getInstance().execute(()->{ |
|
||||||
int batchSize = 0; |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmtTC = conn.prepareStatement("REPLACE current_train_reinstatement VALUES (?,?,?,?,?)"); |
|
||||||
PreparedStatement pstmtUTA = conn.prepareStatement("UPDATE current_train SET `status` = ? WHERE train_id = ?"); |
|
||||||
){ |
|
||||||
pstmtUTA.setString(1, CurrentTrainStatus.ACTIVATED.getCode()); |
|
||||||
for(JSONObject obj:procMap.get("0005")) { |
|
||||||
String train_id = obj.getJSONObject("body").optString("train_id"); |
|
||||||
String canx_loc = obj.getJSONObject("body").optString("loc_stanox"); |
|
||||||
String canx_dev = obj.getJSONObject("header").optString("source_dev_id"); |
|
||||||
String canx_usr = obj.getJSONObject("header").optString("user_id"); |
|
||||||
long canx_time = obj.getJSONObject("body").optLong("reinstatement_timestamp"); |
|
||||||
logRI.atInfo().log("TS: {}", canx_time); |
|
||||||
logRI.atInfo().log(obj.getJSONObject("body").toString()); |
|
||||||
// log.debug("[TC] {}@{} because {} by {}@{}", train_id, canx_loc, canx_reason, canx_usr, canx_dev);
|
|
||||||
pstmtTC.setString(1, train_id); |
|
||||||
pstmtTC.setString(2, canx_loc); |
|
||||||
pstmtTC.setTimestamp(3, new Timestamp(canx_time)); |
|
||||||
setString(pstmtTC,4, canx_dev); |
|
||||||
setString(pstmtTC,5, canx_usr); |
|
||||||
pstmtTC.addBatch(); |
|
||||||
pstmtUTA.setString(2, train_id); |
|
||||||
int rowCount = pstmtUTA.executeUpdate(); |
|
||||||
Runnable r = new Runnable() { |
|
||||||
|
|
||||||
int runCount = 0; |
|
||||||
|
|
||||||
@Override |
|
||||||
public void run() { |
|
||||||
runCount++; |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmtUTA = conn.prepareStatement("UPDATE current_train SET `status` = ? WHERE train_id = ?"); |
|
||||||
){ |
|
||||||
pstmtUTA.setString(1, CurrentTrainStatus.ACTIVATED.getCode()); |
|
||||||
pstmtUTA.setString(2, train_id); |
|
||||||
int rowCount = pstmtUTA.executeUpdate(); |
|
||||||
if(rowCount==0) { |
|
||||||
if(runCount > 5) { |
|
||||||
log.warn("[RI] Cannot update {} [LAST]", train_id); |
|
||||||
return; |
|
||||||
} |
|
||||||
log.warn("[RI] Cannot update {} (ROUND {})", train_id, runCount); |
|
||||||
ThreadPoolManager.getInstance().schedule(this, System.currentTimeMillis()+(long)(1000*Math.pow(2, runCount))); |
|
||||||
}else { |
|
||||||
log.info("[RI] Successfully update {} (ROUND {})", train_id, runCount); |
|
||||||
} |
|
||||||
conn.commit(); |
|
||||||
}catch(SQLException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
}; |
|
||||||
if(rowCount==0) { |
|
||||||
log.warn("[RI] Cannot update {}", train_id); |
|
||||||
ThreadPoolManager.getInstance().schedule(r, System.currentTimeMillis()+1000); |
|
||||||
} |
|
||||||
batchSize++; |
|
||||||
} |
|
||||||
pstmtTC.executeBatch(); |
|
||||||
conn.commit(); |
|
||||||
log.info("[RI] Record Count : {}", batchSize); |
|
||||||
}catch(SQLException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected void setString(PreparedStatement stmt, int col, String val) throws SQLException{ |
|
||||||
if(val==null||"".equals(val)) { |
|
||||||
stmt.setNull(col, Types.CHAR); |
|
||||||
}else { |
|
||||||
stmt.setString(col, val); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,275 +0,0 @@ |
|||||||
package org.leolo.rail; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.io.FileNotFoundException; |
|
||||||
import java.io.PrintWriter; |
|
||||||
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.LinkedList; |
|
||||||
import java.util.Queue; |
|
||||||
|
|
||||||
import org.apache.activemq.transport.stomp.StompFrame; |
|
||||||
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 VTSPProcessor extends Thread { |
|
||||||
private Logger log = LogManager.getLogger(VTSPProcessor.class); |
|
||||||
private Logger logRI = LogManager.getLogger("org.leolo.RI"); |
|
||||||
|
|
||||||
private final Object SYNC_TOKEN = new Object(); |
|
||||||
|
|
||||||
private Queue<StompFrame> procQueue = new LinkedList<>(); |
|
||||||
private boolean terminated = false; |
|
||||||
|
|
||||||
public void terminate() { |
|
||||||
terminated = true; |
|
||||||
synchronized(SYNC_TOKEN) { |
|
||||||
SYNC_TOKEN.notifyAll(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void process(StompFrame data) { |
|
||||||
procQueue.add(data); |
|
||||||
synchronized(SYNC_TOKEN) { |
|
||||||
SYNC_TOKEN.notifyAll(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void run() { |
|
||||||
logRI.debug("Started."); |
|
||||||
while(true) { |
|
||||||
if(terminated) { |
|
||||||
return; |
|
||||||
} |
|
||||||
StompFrame data = procQueue.poll(); |
|
||||||
if(data==null) { |
|
||||||
synchronized(SYNC_TOKEN) { |
|
||||||
try { |
|
||||||
// log.debug("No more data. Sleep.");
|
|
||||||
SYNC_TOKEN.wait(1000); |
|
||||||
} catch (InterruptedException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
} |
|
||||||
continue; |
|
||||||
} |
|
||||||
//Actually handle the data
|
|
||||||
String msgId = data.getHeaders().get("message-id"); |
|
||||||
log.info("Processing message {}", msgId); |
|
||||||
if(true||Constants.Generic.DEBUG_MODE) { |
|
||||||
new File("tmpd").mkdirs(); |
|
||||||
try(PrintWriter out = new PrintWriter("tmpd/VTSP-msg_"+msgId.replace(":", "-")+".json")){ |
|
||||||
out.println(data.getBody()); |
|
||||||
} catch (FileNotFoundException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
} |
|
||||||
JSONObject obj = new JSONObject(data.getBody()).getJSONObject("VSTPCIFMsgV1").optJSONObject("schedule"); |
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
|
||||||
String txType = obj.optString("transaction_type"); |
|
||||||
if("Delete".equalsIgnoreCase(txType)) { |
|
||||||
//Remove the schedule
|
|
||||||
TrainSchedule ts = new TrainSchedule(); |
|
||||||
ts.setTrainUId(obj.optString("CIF_train_uid")); |
|
||||||
ts.setScheduleType(ScheduleType.STP); |
|
||||||
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); |
|
||||||
} |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement psLoc = conn.prepareStatement("DELETE FROM stp_location WHERE suid = ?"); |
|
||||||
PreparedStatement psSch = conn.prepareStatement("DELETE FROM stp_schedule WHERE suid = ?"); |
|
||||||
){ |
|
||||||
psLoc.setString(1, ts.getSUID()); |
|
||||||
psSch.setString(1, ts.getSUID()); |
|
||||||
psLoc.executeUpdate(); |
|
||||||
psSch.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
}catch(SQLException e) { |
|
||||||
log.error(e.getMessage(), e); |
|
||||||
} |
|
||||||
return; |
|
||||||
} |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement psSch = conn.prepareStatement("INSERT INTO stp_schedule VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); |
|
||||||
PreparedStatement psLoc = conn.prepareStatement("INSERT INTO stp_location VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") |
|
||||||
){ |
|
||||||
|
|
||||||
TrainSchedule ts = new TrainSchedule(); |
|
||||||
ts.setTrainUId(obj.optString("CIF_train_uid")); |
|
||||||
ts.setScheduleType(ScheduleType.STP); |
|
||||||
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.getJSONArray("schedule_segment").getJSONObject(0).optString("signalling_id")); |
|
||||||
ts.setRsid(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_headcode")); |
|
||||||
ts.setTrainStatus(obj.optString("train_status")); |
|
||||||
ts.setTrainCategory(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_train_category")); |
|
||||||
ts.setSection(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_business_sector")); |
|
||||||
ts.setPowerType(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_power_type")); |
|
||||||
ts.setTimingLoad(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_timing_load")); |
|
||||||
ts.setPlannedSpeed(Integer.toString((int) (obj.getJSONArray("schedule_segment").getJSONObject(0).optInt("CIF_speed")/2.24))); |
|
||||||
ts.setOperatingCharacter(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_operating_characteristics")); |
|
||||||
ts.setClassAvailable(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_train_class")); |
|
||||||
ts.setSleeper(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_sleepers")); |
|
||||||
ts.setReservation(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_reservations")); |
|
||||||
ts.setCatering(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("CIF_catering_code")); |
|
||||||
ts.setAtocCode(obj.getJSONArray("schedule_segment").getJSONObject(0).optString("atoc_code")); |
|
||||||
JSONArray locs = obj.getJSONArray("schedule_segment").getJSONObject(0).getJSONArray("schedule_location"); |
|
||||||
for(int i=0;i<locs.length();i++) { |
|
||||||
JSONObject loc = locs.getJSONObject(i); |
|
||||||
TrainScheduleLocation tsl = new TrainScheduleLocation(); |
|
||||||
tsl.setTiplocCode(loc.getJSONObject("location").getJSONObject("tiploc").optString("tiploc_id")); |
|
||||||
tsl.setTiplocInstance(0); |
|
||||||
tsl.setArrival(getScheduleTime(loc.optString("scheduled_arrival_time"))); |
|
||||||
tsl.setDeparture(getScheduleTime(loc.optString("scheduled_departure_time"))); |
|
||||||
tsl.setPass(getScheduleTime(loc.optString("scheduled_pass_time"))); |
|
||||||
tsl.setPubArrival(getScheduleTime(loc.optString("public_arrival"))); |
|
||||||
tsl.setPubDeparture(getScheduleTime(loc.optString("public_departure"))); |
|
||||||
tsl.setPlatform(loc.optString("CIF_platform")); |
|
||||||
tsl.setLine(loc.optString("CIF_line")); |
|
||||||
tsl.setPath(loc.optString("CIF_path")); |
|
||||||
tsl.setEngineeringAllowance(getAllowanceTime(loc.optString("CIF_engineering_allowance"))); |
|
||||||
tsl.setPathingAllowance(getAllowanceTime(loc.optString("CIF_pathing_allowance"))); |
|
||||||
tsl.setPerformanceAllowance(getAllowanceTime(loc.optString("CIF_performance_allowance"))); |
|
||||||
// String locType = loc.optString("location_type");
|
|
||||||
if(i==0) { |
|
||||||
tsl.setRecordType(LocationRecordType.ORIGIN); |
|
||||||
}else if((i+1)==locs.length()) { |
|
||||||
tsl.setRecordType(LocationRecordType.TERMINATE); |
|
||||||
}else{ |
|
||||||
tsl.setRecordType(LocationRecordType.INTERMEDIATE); |
|
||||||
} |
|
||||||
ts.getLocations().add(tsl); |
|
||||||
} |
|
||||||
|
|
||||||
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(); |
|
||||||
}catch(SQLException e) { |
|
||||||
log.atError().log(e.getMessage(),e); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected void setString(PreparedStatement stmt, int col, String val) throws SQLException{ |
|
||||||
if(val==null||"".equals(val)) { |
|
||||||
stmt.setNull(col, Types.CHAR); |
|
||||||
}else { |
|
||||||
stmt.setString(col, val); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private long getScheduleTime(String t) { |
|
||||||
//HHMMSS
|
|
||||||
t = t.trim(); |
|
||||||
if("".equals(t)) { |
|
||||||
return 0; |
|
||||||
} |
|
||||||
int hour = Integer.parseInt(t.substring(0, 2)); |
|
||||||
int min = Integer.parseInt(t.substring(2, 4)); |
|
||||||
int sec = Integer.parseInt(t.substring(4, 6)); |
|
||||||
return hour*3_600_000+min*60_000+sec; |
|
||||||
} |
|
||||||
|
|
||||||
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; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
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); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,123 +0,0 @@ |
|||||||
package org.leolo.rail.dao; |
|
||||||
|
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.PreparedStatement; |
|
||||||
import java.sql.ResultSet; |
|
||||||
import java.sql.SQLException; |
|
||||||
import java.util.Date; |
|
||||||
|
|
||||||
import org.leolo.rail.DatabaseManager; |
|
||||||
|
|
||||||
public class MetadataDao { |
|
||||||
|
|
||||||
|
|
||||||
public String getString(String key) throws SQLException{ |
|
||||||
return getString(key, null); |
|
||||||
} |
|
||||||
|
|
||||||
public String getString(String key, String defaultValue) throws SQLException{ |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmt = conn.prepareStatement("SELECT metadata_value FROM metadata WHERE metadata_name = ?"); |
|
||||||
){ |
|
||||||
pstmt.setString(1, key); |
|
||||||
try(ResultSet rs = pstmt.executeQuery()){ |
|
||||||
if(rs.next()) { |
|
||||||
return rs.getString("metadata_value"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return defaultValue; |
|
||||||
} |
|
||||||
|
|
||||||
public long getLong(String key) throws SQLException{ |
|
||||||
return getLong(key, 0); |
|
||||||
} |
|
||||||
|
|
||||||
public long getLong(String key, long defaultValue) throws SQLException{ |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmt = conn.prepareStatement("SELECT metadata_value FROM metadata WHERE metadata_name = ?"); |
|
||||||
){ |
|
||||||
pstmt.setString(1, key); |
|
||||||
try(ResultSet rs = pstmt.executeQuery()){ |
|
||||||
if(rs.next()) { |
|
||||||
return rs.getLong("metadata_value"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return defaultValue; |
|
||||||
} |
|
||||||
|
|
||||||
public Date getDate(String key) throws SQLException{ |
|
||||||
return getDate(key, null); |
|
||||||
} |
|
||||||
|
|
||||||
public Date getDate(String key, Date defaultValue) throws SQLException{ |
|
||||||
long val = getLong(key, Long.MIN_VALUE); |
|
||||||
if(val==Long.MIN_VALUE) { |
|
||||||
return defaultValue; |
|
||||||
} |
|
||||||
return new Date(val); |
|
||||||
} |
|
||||||
|
|
||||||
public void setString(String key, String value) throws SQLException{ |
|
||||||
if(value!=null) { |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmt = conn.prepareStatement("REPLACE INTO metadata (metadata_name, metadata_value) VALUES (?,?)"); |
|
||||||
){ |
|
||||||
pstmt.setString(1, key); |
|
||||||
pstmt.setString(2, value); |
|
||||||
pstmt.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
} |
|
||||||
}else { |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmt = conn.prepareStatement("DELETE FROM metadata WHERE metadata_name=?"); |
|
||||||
){ |
|
||||||
pstmt.setString(1, key); |
|
||||||
pstmt.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void setLong(String key, long value) throws SQLException{ |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmt = conn.prepareStatement("REPLACE INTO metadata (metadata_name, metadata_value) VALUES (?,?)"); |
|
||||||
){ |
|
||||||
pstmt.setString(1, key); |
|
||||||
pstmt.setLong(2, value); |
|
||||||
pstmt.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public void setDate(String key, Date value) throws SQLException{ |
|
||||||
if(value!=null) { |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmt = conn.prepareStatement("REPLACE INTO metadata (metadata_name, metadata_value) VALUES (?,?)"); |
|
||||||
){ |
|
||||||
pstmt.setString(1, key); |
|
||||||
pstmt.setLong(2, value.getTime()); |
|
||||||
pstmt.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
} |
|
||||||
}else { |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmt = conn.prepareStatement("DELETE FROM metadata WHERE metadata_name=?"); |
|
||||||
){ |
|
||||||
pstmt.setString(1, key); |
|
||||||
pstmt.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,193 +0,0 @@ |
|||||||
package org.leolo.rail.job; |
|
||||||
|
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.PreparedStatement; |
|
||||||
import java.sql.ResultSet; |
|
||||||
import java.sql.SQLException; |
|
||||||
import java.sql.Statement; |
|
||||||
import java.text.SimpleDateFormat; |
|
||||||
import java.util.Calendar; |
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager; |
|
||||||
import org.apache.logging.log4j.Logger; |
|
||||||
import org.leolo.rail.Constants; |
|
||||||
import org.leolo.rail.DatabaseManager; |
|
||||||
import org.quartz.Job; |
|
||||||
import org.quartz.JobExecutionContext; |
|
||||||
import org.quartz.JobExecutionException; |
|
||||||
|
|
||||||
public class DayEndJob implements Job { |
|
||||||
private Logger log = LogManager.getLogger(DayEndJob.class); |
|
||||||
|
|
||||||
@Override |
|
||||||
public void execute(JobExecutionContext context) throws JobExecutionException { |
|
||||||
// TODO Auto-generated method stub
|
|
||||||
log.atInfo().log("Start day-end job"); |
|
||||||
try(Connection conn = DatabaseManager.getInstance().getConnection()){ |
|
||||||
Calendar c = Calendar.getInstance(); |
|
||||||
c.add(Calendar.DAY_OF_MONTH, -1*Constants.Generic.DATA_RETAINTION_PERIOD); |
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
|
||||||
log.atInfo().log("Removing data on or before {}", sdf.format(c.getTime())); |
|
||||||
String cutoffDate = sdf.format(c.getTime()); |
|
||||||
//Delete LTP main records
|
|
||||||
try( |
|
||||||
PreparedStatement psQuery = conn.prepareStatement("SELECT suid FROM ltp_schedule WHERE end_date < ?"); |
|
||||||
){ |
|
||||||
psQuery.setString(1, cutoffDate); |
|
||||||
try( |
|
||||||
ResultSet rs = psQuery.executeQuery(); |
|
||||||
PreparedStatement psLoc = conn.prepareStatement("DELETE FROM ltp_location WHERE suid = ?"); |
|
||||||
PreparedStatement psSch = conn.prepareStatement("DELETE FROM ltp_schedule WHERE suid = ?"); |
|
||||||
){ |
|
||||||
int schCount = 0; |
|
||||||
while(rs.next()) { |
|
||||||
psLoc.setString(1, rs.getString(1)); |
|
||||||
psSch.setString(1, rs.getString(1)); |
|
||||||
psLoc.executeUpdate(); |
|
||||||
psSch.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
schCount++; |
|
||||||
} |
|
||||||
log.atInfo().log("Deleted {} LTP schedules.", schCount); |
|
||||||
} |
|
||||||
} catch (SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
}//Delete LTP main records
|
|
||||||
try( |
|
||||||
PreparedStatement psQuery = conn.prepareStatement("SELECT suid FROM stp_schedule WHERE end_date < ?"); |
|
||||||
){ |
|
||||||
psQuery.setString(1, cutoffDate); |
|
||||||
try( |
|
||||||
ResultSet rs = psQuery.executeQuery(); |
|
||||||
PreparedStatement psLoc = conn.prepareStatement("DELETE FROM stp_location WHERE suid = ?"); |
|
||||||
PreparedStatement psSch = conn.prepareStatement("DELETE FROM stp_schedule WHERE suid = ?"); |
|
||||||
){ |
|
||||||
int schCount = 0; |
|
||||||
while(rs.next()) { |
|
||||||
psLoc.setString(1, rs.getString(1)); |
|
||||||
psSch.setString(1, rs.getString(1)); |
|
||||||
psLoc.executeUpdate(); |
|
||||||
psSch.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
schCount++; |
|
||||||
} |
|
||||||
log.atInfo().log("Deleted {} STP schedules.", schCount); |
|
||||||
} |
|
||||||
} catch (SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
//Delete LTP association records
|
|
||||||
try( |
|
||||||
PreparedStatement psQuery = conn.prepareStatement("SELECT auid FROM ltp_assoication WHERE end_date < ?"); |
|
||||||
){ |
|
||||||
psQuery.setString(1, cutoffDate); |
|
||||||
try( |
|
||||||
ResultSet rs = psQuery.executeQuery(); |
|
||||||
PreparedStatement psSch = conn.prepareStatement("DELETE FROM ltp_assoication WHERE auid = ?"); |
|
||||||
){ |
|
||||||
int assoCount = 0; |
|
||||||
while(rs.next()) { |
|
||||||
psSch.setString(1, rs.getString(1)); |
|
||||||
psSch.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
assoCount++; |
|
||||||
} |
|
||||||
log.atInfo().log("Deleted {} assocication.", assoCount); |
|
||||||
} |
|
||||||
} catch (SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
//Delete Movements
|
|
||||||
try( |
|
||||||
PreparedStatement psQuery = conn.prepareStatement("SELECT DISTINCT train_id FROM current_train_movement WHERE movt_time < ?"); |
|
||||||
){ |
|
||||||
psQuery.setString(1, cutoffDate); |
|
||||||
int movtCount = 0; |
|
||||||
try( |
|
||||||
ResultSet rs = psQuery.executeQuery(); |
|
||||||
PreparedStatement psDel = conn.prepareStatement("DELETE FROM current_train_movement WHERE train_id = ? "); |
|
||||||
){ |
|
||||||
while(rs.next()) { |
|
||||||
psDel.setString(1, rs.getString(1)); |
|
||||||
psDel.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
movtCount++; |
|
||||||
} |
|
||||||
log.atInfo().log("Deleted movement records for {} trains.", movtCount); |
|
||||||
|
|
||||||
} |
|
||||||
}catch (SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
//Delete cancellation
|
|
||||||
try( |
|
||||||
PreparedStatement psQuery = conn.prepareStatement("SELECT DISTINCT train_id FROM current_train_cancellation WHERE canx_time < ?"); |
|
||||||
){ |
|
||||||
psQuery.setString(1, cutoffDate); |
|
||||||
int movtCount = 0; |
|
||||||
try( |
|
||||||
ResultSet rs = psQuery.executeQuery(); |
|
||||||
PreparedStatement psDel = conn.prepareStatement("DELETE FROM current_train_cancellation WHERE train_id = ? "); |
|
||||||
){ |
|
||||||
while(rs.next()) { |
|
||||||
psDel.setString(1, rs.getString(1)); |
|
||||||
psDel.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
movtCount++; |
|
||||||
} |
|
||||||
log.atInfo().log("Deleted cancellation records for {} trains.", movtCount); |
|
||||||
|
|
||||||
} |
|
||||||
}catch (SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
//Delete Movements
|
|
||||||
try( |
|
||||||
PreparedStatement psQuery = conn.prepareStatement("SELECT DISTINCT train_id FROM current_train_reinstatement WHERE rein_time < ?"); |
|
||||||
){ |
|
||||||
psQuery.setString(1, cutoffDate); |
|
||||||
int movtCount = 0; |
|
||||||
try( |
|
||||||
ResultSet rs = psQuery.executeQuery(); |
|
||||||
PreparedStatement psDel = conn.prepareStatement("DELETE FROM current_train_reinstatement WHERE train_id = ? "); |
|
||||||
){ |
|
||||||
while(rs.next()) { |
|
||||||
psDel.setString(1, rs.getString(1)); |
|
||||||
psDel.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
movtCount++; |
|
||||||
} |
|
||||||
log.atInfo().log("Deleted reinstatement records for {} trains.", movtCount); |
|
||||||
|
|
||||||
} |
|
||||||
}catch (SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
//Delete activation
|
|
||||||
try( |
|
||||||
PreparedStatement psQuery = conn.prepareStatement("SELECT DISTINCT train_id FROM current_train WHERE op_date < ?"); |
|
||||||
){ |
|
||||||
psQuery.setString(1, cutoffDate); |
|
||||||
int movtCount = 0; |
|
||||||
try( |
|
||||||
ResultSet rs = psQuery.executeQuery(); |
|
||||||
PreparedStatement psDel = conn.prepareStatement("DELETE FROM current_train WHERE train_id = ? "); |
|
||||||
){ |
|
||||||
while(rs.next()) { |
|
||||||
psDel.setString(1, rs.getString(1)); |
|
||||||
psDel.executeUpdate(); |
|
||||||
conn.commit(); |
|
||||||
movtCount++; |
|
||||||
} |
|
||||||
log.atInfo().log("Deleted activation records for {} trains.", movtCount); |
|
||||||
|
|
||||||
} |
|
||||||
}catch (SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
} catch (SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,190 +0,0 @@ |
|||||||
package org.leolo.rail.job; |
|
||||||
|
|
||||||
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.util.Base64; |
|
||||||
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.Logger; |
|
||||||
import org.json.JSONObject; |
|
||||||
import org.leolo.rail.AssoicationProcessor; |
|
||||||
import org.leolo.rail.ConfigurationManager; |
|
||||||
import org.leolo.rail.Constants; |
|
||||||
import org.leolo.rail.ScheduleProcessor; |
|
||||||
import org.leolo.rail.TiplocProcessor; |
|
||||||
import org.leolo.rail.Constants.Metadata; |
|
||||||
import org.leolo.rail.Constants.Scheduler; |
|
||||||
import org.leolo.rail.dao.MetadataDao; |
|
||||||
import org.quartz.Job; |
|
||||||
import org.quartz.JobExecutionContext; |
|
||||||
import org.quartz.JobExecutionException; |
|
||||||
import org.quartz.SchedulerException; |
|
||||||
import org.quartz.Trigger; |
|
||||||
import org.quartz.TriggerKey; |
|
||||||
import org.quartz.impl.matchers.GroupMatcher; |
|
||||||
|
|
||||||
public class LongTermScheduleJob implements Job{ |
|
||||||
|
|
||||||
private Logger log = LogManager.getLogger(LongTermScheduleJob.class); |
|
||||||
|
|
||||||
@Override |
|
||||||
public void execute(JobExecutionContext context) throws JobExecutionException { |
|
||||||
MetadataDao mDao = new MetadataDao(); |
|
||||||
log.atInfo().log("LongTermScheduleJob started."); |
|
||||||
|
|
||||||
try { |
|
||||||
TriggerKey triggerKey = TriggerKey.triggerKey(Constants.Scheduler.LTSJ_CRON_TRIGGER, Constants.Scheduler.DEFAULT_GROUP_NAME); |
|
||||||
Trigger trigger = context.getScheduler().getTrigger(triggerKey); |
|
||||||
Date nextFireTime = trigger.getNextFireTime(); |
|
||||||
log.info("Next fire at "+nextFireTime); |
|
||||||
long timeToNextFire = nextFireTime.getTime() - System.currentTimeMillis(); |
|
||||||
if(timeToNextFire > Constants.Scheduler.LTR_SKIP_THRESHOLD && !ConfigurationManager.getInstance().getBoolean("general.debug", false)) { |
|
||||||
log.always().log("Too close to next fire time. Skipping"); |
|
||||||
return; |
|
||||||
} |
|
||||||
} catch (SchedulerException 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); |
|
||||||
} |
|
||||||
try { |
|
||||||
mDao.setDate(Constants.Metadata.LAST_NETOWRK_RAIL_SCHEDULE_UPD, new Date()); |
|
||||||
} catch (SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
log.atInfo().log("LTS job done!"); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,17 +0,0 @@ |
|||||||
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; |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,20 +0,0 @@ |
|||||||
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; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,328 +0,0 @@ |
|||||||
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.name().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; |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,175 +0,0 @@ |
|||||||
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.getRecordCode().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; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,8 +0,0 @@ |
|||||||
/** |
|
||||||
* |
|
||||||
*/ |
|
||||||
/** |
|
||||||
* @author user |
|
||||||
* |
|
||||||
*/ |
|
||||||
package org.leolo.rail.model; |
|
||||||
@ -1,234 +0,0 @@ |
|||||||
package org.leolo.rail.report; |
|
||||||
|
|
||||||
import java.util.HashSet; |
|
||||||
|
|
||||||
import org.leolo.rail.model.ScheduleType; |
|
||||||
|
|
||||||
public class BasicTrainScheduleEntry { |
|
||||||
private String suid; |
|
||||||
private String trainUid; |
|
||||||
private ScheduleType scheduleType; |
|
||||||
private String signalId; |
|
||||||
private String toc; |
|
||||||
private String trainClass; |
|
||||||
private String origin; |
|
||||||
private long originTime; |
|
||||||
private String destination; |
|
||||||
private long destinationTime; |
|
||||||
private long departTime; |
|
||||||
private String departPlatform; |
|
||||||
private long arriveTime; |
|
||||||
private String arrivePlatform; |
|
||||||
|
|
||||||
private HashSet<BasicTrainScheduleEntry> assoicatedEntry = new HashSet<>(); |
|
||||||
|
|
||||||
@Override |
|
||||||
public int hashCode() { |
|
||||||
final int prime = 31; |
|
||||||
int result = 1; |
|
||||||
result = prime * result + ((arrivePlatform == null) ? 0 : arrivePlatform.hashCode()); |
|
||||||
result = prime * result + (int) (arriveTime ^ (arriveTime >>> 32)); |
|
||||||
result = prime * result + ((assoicatedEntry == null) ? 0 : assoicatedEntry.hashCode()); |
|
||||||
result = prime * result + ((departPlatform == null) ? 0 : departPlatform.hashCode()); |
|
||||||
result = prime * result + (int) (departTime ^ (departTime >>> 32)); |
|
||||||
result = prime * result + ((destination == null) ? 0 : destination.hashCode()); |
|
||||||
result = prime * result + (int) (destinationTime ^ (destinationTime >>> 32)); |
|
||||||
result = prime * result + ((origin == null) ? 0 : origin.hashCode()); |
|
||||||
result = prime * result + (int) (originTime ^ (originTime >>> 32)); |
|
||||||
result = prime * result + ((scheduleType == null) ? 0 : scheduleType.name().hashCode()); |
|
||||||
result = prime * result + ((signalId == null) ? 0 : signalId.hashCode()); |
|
||||||
result = prime * result + ((suid == null) ? 0 : suid.hashCode()); |
|
||||||
result = prime * result + ((toc == null) ? 0 : toc.hashCode()); |
|
||||||
result = prime * result + ((trainClass == null) ? 0 : trainClass.hashCode()); |
|
||||||
result = prime * result + ((trainUid == null) ? 0 : trainUid.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; |
|
||||||
BasicTrainScheduleEntry other = (BasicTrainScheduleEntry) obj; |
|
||||||
if (arrivePlatform == null) { |
|
||||||
if (other.arrivePlatform != null) |
|
||||||
return false; |
|
||||||
} else if (!arrivePlatform.equals(other.arrivePlatform)) |
|
||||||
return false; |
|
||||||
if (arriveTime != other.arriveTime) |
|
||||||
return false; |
|
||||||
if (assoicatedEntry == null) { |
|
||||||
if (other.assoicatedEntry != null) |
|
||||||
return false; |
|
||||||
} else if (!assoicatedEntry.equals(other.assoicatedEntry)) |
|
||||||
return false; |
|
||||||
if (departPlatform == null) { |
|
||||||
if (other.departPlatform != null) |
|
||||||
return false; |
|
||||||
} else if (!departPlatform.equals(other.departPlatform)) |
|
||||||
return false; |
|
||||||
if (departTime != other.departTime) |
|
||||||
return false; |
|
||||||
if (destination == null) { |
|
||||||
if (other.destination != null) |
|
||||||
return false; |
|
||||||
} else if (!destination.equals(other.destination)) |
|
||||||
return false; |
|
||||||
if (destinationTime != other.destinationTime) |
|
||||||
return false; |
|
||||||
if (origin == null) { |
|
||||||
if (other.origin != null) |
|
||||||
return false; |
|
||||||
} else if (!origin.equals(other.origin)) |
|
||||||
return false; |
|
||||||
if (originTime != other.originTime) |
|
||||||
return false; |
|
||||||
if (scheduleType != other.scheduleType) |
|
||||||
return false; |
|
||||||
if (signalId == null) { |
|
||||||
if (other.signalId != null) |
|
||||||
return false; |
|
||||||
} else if (!signalId.equals(other.signalId)) |
|
||||||
return false; |
|
||||||
if (suid == null) { |
|
||||||
if (other.suid != null) |
|
||||||
return false; |
|
||||||
} else if (!suid.equals(other.suid)) |
|
||||||
return false; |
|
||||||
if (toc == null) { |
|
||||||
if (other.toc != null) |
|
||||||
return false; |
|
||||||
} else if (!toc.equals(other.toc)) |
|
||||||
return false; |
|
||||||
if (trainClass == null) { |
|
||||||
if (other.trainClass != null) |
|
||||||
return false; |
|
||||||
} else if (!trainClass.equals(other.trainClass)) |
|
||||||
return false; |
|
||||||
if (trainUid == null) { |
|
||||||
if (other.trainUid != null) |
|
||||||
return false; |
|
||||||
} else if (!trainUid.equals(other.trainUid)) |
|
||||||
return false; |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
public String getSuid() { |
|
||||||
return suid; |
|
||||||
} |
|
||||||
|
|
||||||
public ScheduleType getScheduleType() { |
|
||||||
return scheduleType; |
|
||||||
} |
|
||||||
|
|
||||||
public String getSignalId() { |
|
||||||
return signalId; |
|
||||||
} |
|
||||||
|
|
||||||
public String getToc() { |
|
||||||
return toc; |
|
||||||
} |
|
||||||
|
|
||||||
public String getTrainClass() { |
|
||||||
return trainClass; |
|
||||||
} |
|
||||||
|
|
||||||
public String getOrigin() { |
|
||||||
return origin; |
|
||||||
} |
|
||||||
|
|
||||||
public long getOriginTime() { |
|
||||||
return originTime; |
|
||||||
} |
|
||||||
|
|
||||||
public String getDestination() { |
|
||||||
return destination; |
|
||||||
} |
|
||||||
|
|
||||||
public long getDestinationTime() { |
|
||||||
return destinationTime; |
|
||||||
} |
|
||||||
|
|
||||||
public HashSet<BasicTrainScheduleEntry> getAssoicatedEntry() { |
|
||||||
return assoicatedEntry; |
|
||||||
} |
|
||||||
|
|
||||||
public void setSuid(String suid) { |
|
||||||
this.suid = suid; |
|
||||||
} |
|
||||||
|
|
||||||
public void setScheduleType(ScheduleType scheduleType) { |
|
||||||
this.scheduleType = scheduleType; |
|
||||||
} |
|
||||||
|
|
||||||
public void setSignalId(String signalId) { |
|
||||||
this.signalId = signalId; |
|
||||||
} |
|
||||||
|
|
||||||
public void setToc(String toc) { |
|
||||||
this.toc = toc; |
|
||||||
} |
|
||||||
|
|
||||||
public void setTrainClass(String trainClass) { |
|
||||||
this.trainClass = trainClass; |
|
||||||
} |
|
||||||
|
|
||||||
public void setOrigin(String origin) { |
|
||||||
this.origin = origin; |
|
||||||
} |
|
||||||
|
|
||||||
public void setOriginTime(long originTime) { |
|
||||||
this.originTime = originTime; |
|
||||||
} |
|
||||||
|
|
||||||
public void setDestination(String destination) { |
|
||||||
this.destination = destination; |
|
||||||
} |
|
||||||
|
|
||||||
public void setDestinationTime(long destinationTime) { |
|
||||||
this.destinationTime = destinationTime; |
|
||||||
} |
|
||||||
|
|
||||||
public String getTrainUid() { |
|
||||||
return trainUid; |
|
||||||
} |
|
||||||
|
|
||||||
public void setTrainUid(String trainUid) { |
|
||||||
this.trainUid = trainUid; |
|
||||||
} |
|
||||||
|
|
||||||
public long getDepartTime() { |
|
||||||
return departTime; |
|
||||||
} |
|
||||||
|
|
||||||
public String getDepartPlatform() { |
|
||||||
return departPlatform; |
|
||||||
} |
|
||||||
|
|
||||||
public long getArriveTime() { |
|
||||||
return arriveTime; |
|
||||||
} |
|
||||||
|
|
||||||
public String getArrivePlatform() { |
|
||||||
return arrivePlatform; |
|
||||||
} |
|
||||||
|
|
||||||
public void setDepartTime(long departTime) { |
|
||||||
this.departTime = departTime; |
|
||||||
} |
|
||||||
|
|
||||||
public void setDepartPlatform(String departPlatform) { |
|
||||||
this.departPlatform = departPlatform; |
|
||||||
} |
|
||||||
|
|
||||||
public void setArriveTime(long arriveTime) { |
|
||||||
this.arriveTime = arriveTime; |
|
||||||
} |
|
||||||
|
|
||||||
public void setArrivePlatform(String arrivePlatform) { |
|
||||||
this.arrivePlatform = arrivePlatform; |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,740 +0,0 @@ |
|||||||
package org.leolo.rail.report; |
|
||||||
|
|
||||||
import java.io.File; |
|
||||||
import java.io.IOException; |
|
||||||
import java.io.PrintWriter; |
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.Date; |
|
||||||
import java.sql.PreparedStatement; |
|
||||||
import java.sql.ResultSet; |
|
||||||
import java.sql.SQLException; |
|
||||||
import java.text.ParseException; |
|
||||||
import java.util.Comparator; |
|
||||||
import java.util.HashMap; |
|
||||||
import java.util.HashSet; |
|
||||||
import java.util.TreeMap; |
|
||||||
import java.util.TreeSet; |
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager; |
|
||||||
import org.apache.logging.log4j.Logger; |
|
||||||
import org.leolo.rail.DatabaseManager; |
|
||||||
import org.leolo.rail.model.ScheduleType; |
|
||||||
|
|
||||||
public class ReportGenerator { |
|
||||||
public static Logger log = LogManager.getLogger(ReportGenerator.class); |
|
||||||
|
|
||||||
public static final String SQL_1 = "SELECT \r\n" + |
|
||||||
" lts.suid suid, lts.train_uid uid, lts.sch_type sch_type, lts.signal_id signal_id, lts.atoc_code toc,\r\n" + |
|
||||||
" lts.train_category train_category, \r\n" + |
|
||||||
" tiploc_to_crs(lts.origin) origin, TIME_TO_SEC(lts.origin_time) origin_time,\r\n" + |
|
||||||
" tiploc_to_crs(lts.destination) destination, TIME_TO_SEC(lts.destination_time) destination_time,\r\n" + |
|
||||||
" TIME_TO_SEC(al1.pub_departure) pub_departure, al1.platform dPlat,\r\n"+ |
|
||||||
" TIME_TO_SEC(al3.pub_arrival) pub_arrival, al3.platform aPlat\r\n"+ |
|
||||||
" FROM\r\n" + |
|
||||||
" ltp_location al1\r\n" + |
|
||||||
" LEFT JOIN ltp_location al3 ON al1.suid = al3.suid AND al1.seq < al3.seq\r\n" + |
|
||||||
" LEFT JOIN ltp_schedule lts ON al1.suid = lts.suid\r\n" + |
|
||||||
" LEFT JOIN tiploc tipo ON lts.origin = tipo.tiploc_code\r\n" + |
|
||||||
" LEFT JOIN tiploc tipd ON lts.destination = tipd.tiploc_code \r\n" + |
|
||||||
" WHERE\r\n" + |
|
||||||
" 1=1\r\n" + |
|
||||||
" AND al1.tiploc_code IN (SELECT tiploc_code FROM tiploc WHERE stanox IN (SELECT stanox FROM tiploc WHERE crs = ?))\r\n" + |
|
||||||
" AND al3.tiploc_code IN (SELECT tiploc_code FROM tiploc WHERE stanox IN (SELECT stanox FROM tiploc WHERE crs = ?))\r\n" + |
|
||||||
" AND ? BETWEEN lts.start_date AND lts.end_date\r\n" + |
|
||||||
" AND lts.days LIKE get_wd_str(?)\r\n" + |
|
||||||
" AND al1.pub_departure IS NOT null\r\n" + |
|
||||||
" AND al3.pub_arrival IS NOT NULL"; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static final String LATEX_PREMBLE_1 = "\\documentclass[a4paper]{article}\r\n" + |
|
||||||
"\\usepackage{tocloft}\r\n" + |
|
||||||
"\\usepackage[utf8]{inputenc}\r\n" + |
|
||||||
"\\usepackage[margin=0.675in]{geometry}\r\n" + |
|
||||||
"\\usepackage[colorlinks = true]{hyperref}\r\n" + |
|
||||||
"\\usepackage{color}\r\n" + |
|
||||||
"\\usepackage{colortbl}\r\n" + |
|
||||||
"\\usepackage[british]{babel}\r\n" + |
|
||||||
"\\usepackage{longtable}\r\n" + |
|
||||||
"\\usepackage{textcomp}\r\n" + |
|
||||||
"\\usepackage{fancyhdr}\r\n" + |
|
||||||
"\\usepackage{ulem}\r\n" + |
|
||||||
"\\usepackage{array}\r\n" + |
|
||||||
"\r\n" + |
|
||||||
"\\pagestyle{fancy}\r\n" + |
|
||||||
"\r\n" + |
|
||||||
"\\newcommand{\\hr}{\\noindent\\hrulefill}\r\n" + |
|
||||||
"\\newcommand{\\dfa}{\\cftdotfill{2}}\r\n" + |
|
||||||
"\\newcommand{\\dfb}{\\cftdotfill{4}}\r\n" + |
|
||||||
"\\newcommand{\\pa}{\\textit{(PASS)}}\r\n" + |
|
||||||
"\\renewcommand\\cftsecleader{\\cftdotfill{\\cftdotsep}}\r\n" + |
|
||||||
"\r\n" + |
|
||||||
"\\setcounter{secnumdepth}{1}\r\n" + |
|
||||||
"\\setcounter{tocdepth}{1}\r\n" + |
|
||||||
"\r\n" + |
|
||||||
"\\definecolor{hl1}{gray}{0.9}\r\n" + |
|
||||||
"\\definecolor{hl2}{gray}{0.8}\r\n" + |
|
||||||
"\r\n" + |
|
||||||
"\\definecolor{e1}{rgb}{0,0,1}\r\n" + |
|
||||||
"\\definecolor{ot}{rgb}{0,0,0}\r\n" + |
|
||||||
"\\definecolor{l1}{rgb}{1.0,0.33,0.33}\r\n" + |
|
||||||
"\\definecolor{l2}{rgb}{1.0,0,0}\r\n" + |
|
||||||
"\\definecolor{l3}{rgb}{0.67,0,0}"; |
|
||||||
|
|
||||||
public static void main(String [] args) throws ParseException, IOException { |
|
||||||
final String ORIGIN = "RDG"; |
|
||||||
final String DESTINATION = "PAD"; |
|
||||||
final java.util.Date RPT_DATE = new java.text.SimpleDateFormat("yyyy-MM-dd").parse("2022-03-16"); |
|
||||||
generateLaTeX(ORIGIN, DESTINATION, RPT_DATE); |
|
||||||
} |
|
||||||
|
|
||||||
public static File generateLaTeX(String origin, String destination, java.util.Date rptDate) throws IOException{ |
|
||||||
log.atInfo().log("{} -> {} on {}", origin, destination, rptDate); |
|
||||||
TreeSet<String> tocList = new TreeSet<>(); |
|
||||||
TreeSet<String> tcList = new TreeSet<>(); |
|
||||||
TreeSet<String> locList = new TreeSet<>(); |
|
||||||
HashMap<String, String> tocCache = new HashMap<>(); |
|
||||||
HashMap<String, String> tcCache = new HashMap<>(); |
|
||||||
HashMap<String, String> locCache = new HashMap<>(); |
|
||||||
TreeSet<BasicTrainScheduleEntry> trains = new TreeSet<>(new Comparator<BasicTrainScheduleEntry>() { |
|
||||||
|
|
||||||
@Override |
|
||||||
public int compare(BasicTrainScheduleEntry arg0, BasicTrainScheduleEntry arg1) { |
|
||||||
int val = Long.compare(arg0.getDepartTime(), arg1.getDepartTime()); |
|
||||||
if(val!=0) return val; |
|
||||||
val = Long.compare(arg0.getArriveTime(), arg1.getArriveTime()); |
|
||||||
if(val!=0) return val; |
|
||||||
return Integer.compare(arg0.getScheduleType().ordinal(), arg1.getScheduleType().ordinal()); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
}); |
|
||||||
TreeSet<TrainScheduleEntry> trainGroup = new TreeSet<>(new Comparator<TrainScheduleEntry>() { |
|
||||||
|
|
||||||
@Override |
|
||||||
public int compare(TrainScheduleEntry arg0, TrainScheduleEntry arg1) { |
|
||||||
int val = Long.compare(arg0.getDepartTime(), arg1.getDepartTime()); |
|
||||||
if(val!=0) return val; |
|
||||||
val = Long.compare(arg0.getArriveTime(), arg1.getArriveTime()); |
|
||||||
if(val!=0) return val; |
|
||||||
return Integer.compare(arg0.getScheduleType().ordinal(), arg1.getScheduleType().ordinal()); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
}); |
|
||||||
HashMap<String, TrainScheduleEntry> trainGroups = new HashMap<>(); |
|
||||||
java.sql.Date sqlDate = new java.sql.Date(rptDate.getTime()); |
|
||||||
locList.add(origin); |
|
||||||
locList.add(destination); |
|
||||||
//Stage 1: get the basic train information for trains
|
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmt = conn.prepareStatement(SQL_1) |
|
||||||
){ |
|
||||||
pstmt.setString(1, origin); |
|
||||||
pstmt.setString(2, destination); |
|
||||||
pstmt.setDate(3, sqlDate); |
|
||||||
pstmt.setDate(4, sqlDate); |
|
||||||
try(ResultSet rs = pstmt.executeQuery()){ |
|
||||||
int rowCount = 0; |
|
||||||
while(rs.next()) { |
|
||||||
rowCount++; |
|
||||||
BasicTrainScheduleEntry btse = new BasicTrainScheduleEntry(); |
|
||||||
btse.setSuid(rs.getString(1)); |
|
||||||
btse.setTrainUid(rs.getString(2)); |
|
||||||
btse.setScheduleType(ScheduleType.valueOf(rs.getString(3))); |
|
||||||
btse.setSignalId(rs.getString(4)); |
|
||||||
btse.setToc(rs.getString(5)); |
|
||||||
btse.setTrainClass(rs.getString(6)); |
|
||||||
btse.setOrigin(rs.getString(7)); |
|
||||||
btse.setOriginTime(rs.getLong(8)); |
|
||||||
btse.setDestination(rs.getString(9)); |
|
||||||
btse.setDestinationTime(rs.getLong(10)); |
|
||||||
btse.setDepartTime(rs.getLong(11)); |
|
||||||
btse.setDepartPlatform(rs.getString(12)); |
|
||||||
btse.setArriveTime(rs.getLong(13)); |
|
||||||
btse.setArrivePlatform(rs.getString(14)); |
|
||||||
trains.add(btse); |
|
||||||
tocList.add(btse.getToc()); |
|
||||||
tcList.add(btse.getTrainClass()); |
|
||||||
locList.add(btse.getOrigin()); |
|
||||||
locList.add(btse.getDestination()); |
|
||||||
if(!trainGroups.containsKey(btse.getTrainUid())) { |
|
||||||
trainGroups.put(btse.getTrainUid(), new TrainScheduleEntry()); |
|
||||||
} |
|
||||||
trainGroups.get(btse.getTrainUid()).addEntry(btse); |
|
||||||
} |
|
||||||
log.atInfo().log("{} train schedule found.", rowCount); |
|
||||||
log.atInfo().log("{} train group formed.", trainGroups.size()); |
|
||||||
} |
|
||||||
}catch(SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
for(TrainScheduleEntry tse:trainGroups.values()) { |
|
||||||
trainGroup.add(tse); |
|
||||||
} |
|
||||||
//Scan for earlier train arrives later
|
|
||||||
for(TrainScheduleEntry tse:trainGroup) { |
|
||||||
for(TrainScheduleEntry otse:trainGroup) { |
|
||||||
if(tse.getTrainUid().equals(otse.getTrainUid())) { |
|
||||||
continue;//No need to check with self
|
|
||||||
} |
|
||||||
if(tse.getDepartTime() <= otse.getDepartTime() && tse.getArriveTime() >= otse.getArriveTime() && otse.getArriveTime() > otse.getDepartTime()) { |
|
||||||
tse.setNote("A"); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement stmt = conn.prepareStatement("SELECT tps_desc FROM tiploc WHERE crs = ?"); |
|
||||||
){ |
|
||||||
for(String crs:locList) { |
|
||||||
stmt.setString(1, crs); |
|
||||||
try(ResultSet rs = stmt.executeQuery()){ |
|
||||||
if(rs.next()) { |
|
||||||
locCache.put(crs, rs.getString(1)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
}catch(SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
|
|
||||||
//Generate output
|
|
||||||
try(PrintWriter pw = new PrintWriter(new File("Z:\\output.tex"))){ |
|
||||||
pw.print(LATEX_PREMBLE_1); |
|
||||||
pw.println("\\begin{document}"); |
|
||||||
pw.println("\\begin{center}\\begin{LARGE}"); |
|
||||||
pw.println("Train running record from \\\\"+locCache.get(origin)+"\\\\to\\\\"+locCache.get(destination)+"\\\\on\\\\"+new java.text.SimpleDateFormat("dd-MM-yyyy").format(rptDate)); |
|
||||||
pw.println("\\end{LARGE}\\end{center}"); |
|
||||||
pw.println(); |
|
||||||
pw.println("\\hr\r\n" + |
|
||||||
" \r\n" + |
|
||||||
" The information in this report is generated from data feed provided by Network Rail Infrastructure Limited.\r\n" + |
|
||||||
" \r\n" + |
|
||||||
" \\hr\r\n" + |
|
||||||
" \\tableofcontents"); |
|
||||||
//Part 1: Definations
|
|
||||||
pw.println("\\section{Definations}"); |
|
||||||
pw.println("\\subsection{TOC}"); |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement stmt = conn.prepareStatement("SELECT name FROM toc WHERE atoc_code = ? LIMIT 1"); |
|
||||||
){ |
|
||||||
int count = 0; |
|
||||||
for(String toc:tocList) { |
|
||||||
stmt.setString(1, toc); |
|
||||||
try(ResultSet rs = stmt.executeQuery()){ |
|
||||||
if(rs.next()) { |
|
||||||
pw.print(rs.getString(1)); |
|
||||||
if(++count%2==0) |
|
||||||
pw.print("\\dfa "); |
|
||||||
else |
|
||||||
pw.print("\\dfb "); |
|
||||||
pw.print(toc); |
|
||||||
pw.println("\\\\"); |
|
||||||
tocCache.put(toc, rs.getString(1)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
}catch(SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
pw.println("\\subsection{Train Class}"); |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement stmt = conn.prepareStatement("SELECT category_name FROM train_category WHERE category = ? LIMIT 1"); |
|
||||||
){ |
|
||||||
int count = 0; |
|
||||||
for(String tc:tcList) { |
|
||||||
stmt.setString(1, tc); |
|
||||||
try(ResultSet rs = stmt.executeQuery()){ |
|
||||||
if(rs.next()) { |
|
||||||
pw.print(rs.getString(1)); |
|
||||||
if(++count%2==0) |
|
||||||
pw.print("\\dfa "); |
|
||||||
else |
|
||||||
pw.print("\\dfb "); |
|
||||||
pw.print(tc); |
|
||||||
pw.println("\\\\"); |
|
||||||
tcCache.put(tc, rs.getString(1)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
}catch(SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
pw.println("\\subsection{Location}"); |
|
||||||
int locCount = 0; |
|
||||||
for(String loc:locList) { |
|
||||||
pw.print(locCache.get(loc).replace("&", "\\&")); |
|
||||||
if(++locCount%2==0) |
|
||||||
pw.print("\\dfa "); |
|
||||||
else |
|
||||||
pw.print("\\dfb "); |
|
||||||
pw.print(loc); |
|
||||||
pw.print("\\\\"); |
|
||||||
} |
|
||||||
//Part 2: Print the train List
|
|
||||||
pw.println("\\section{Train Schedule}"); |
|
||||||
pw.println("\\begin{longtable}[l]{|c|c|c||cc|cc|cc|cc||c|c|}"); |
|
||||||
pw.println("\\hline\r\n" + |
|
||||||
" UID & TOC & Train class & " |
|
||||||
+ "\\multicolumn{2}{c|}{Origin}& \\multicolumn{2}{c|}{"+origin+"} & " |
|
||||||
+ "\\multicolumn{2}{c|}{"+destination+"} &\\multicolumn{2}{c||}{Destination} & Detail Page &Note\\\\\\hline\\endhead"); |
|
||||||
int recCount = 0; |
|
||||||
TrainScheduleEntry ltse = null; |
|
||||||
for(TrainScheduleEntry tse:trainGroup) { |
|
||||||
if(ltse!=null) { |
|
||||||
if(getHour(ltse.getDepartTime())!=getHour(tse.getDepartTime())) { |
|
||||||
pw.println("\\\\\\hline"); |
|
||||||
}else { |
|
||||||
pw.println("\\\\"); |
|
||||||
} |
|
||||||
} |
|
||||||
if(tse.getSubentryCount()==1) { |
|
||||||
//Basic layout
|
|
||||||
pw.print(tse.getSignalId()); |
|
||||||
pw.print("&"); |
|
||||||
pw.print(tse.getToc()); |
|
||||||
pw.print("&"); |
|
||||||
pw.print(tse.getTrainClass()); |
|
||||||
pw.print("&"); |
|
||||||
pw.print(tse.getOrigin()); |
|
||||||
pw.print("&"); |
|
||||||
pw.print(getTime(tse.getOriginTime())); |
|
||||||
pw.print("&"); |
|
||||||
pw.print(getTime(tse.getDepartTime())); |
|
||||||
pw.print("&\\small{"); |
|
||||||
pw.print(tse.getDepartPlatform()); |
|
||||||
pw.print("}&"); |
|
||||||
pw.print(getTime(tse.getArriveTime())); |
|
||||||
pw.print("&\\small{"); |
|
||||||
pw.print(tse.getArrivePlatform()); |
|
||||||
pw.print("}&"); |
|
||||||
pw.print(tse.getDestination()); |
|
||||||
pw.print("&"); |
|
||||||
pw.print(getTime(tse.getDestinationTime())); |
|
||||||
pw.print("&\\pageref{td:"); |
|
||||||
pw.print(tse.getTrainUid()); |
|
||||||
pw.print("}&"); |
|
||||||
pw.print(tse.getNote()); |
|
||||||
if(tse.getScheduleType()==ScheduleType.CAN) |
|
||||||
pw.print("C"); |
|
||||||
}else { |
|
||||||
//Advance layout
|
|
||||||
recCount++; |
|
||||||
BasicTrainScheduleEntry assoc = tse.getAssocEntry(); |
|
||||||
boolean hasChange = false; |
|
||||||
//Print main record
|
|
||||||
if(recCount%2==0) |
|
||||||
pw.print("\\rowcolor{hl1}"); |
|
||||||
else |
|
||||||
pw.print("\\rowcolor{hl2}"); |
|
||||||
if(!tse.getSignalId().equals(assoc.getSignalId())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\textcolor{red}{"); |
|
||||||
} |
|
||||||
pw.print(tse.getSignalId()); |
|
||||||
if(!tse.getSignalId().equals(assoc.getSignalId())) { |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getToc().equals(assoc.getToc())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\textcolor{red}{"); |
|
||||||
} |
|
||||||
pw.print(tse.getToc()); |
|
||||||
if(!tse.getToc().equals(assoc.getToc())) { |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getTrainClass().equals(assoc.getTrainClass())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\textcolor{red}{"); |
|
||||||
} |
|
||||||
pw.print(tse.getTrainClass()); |
|
||||||
if(!tse.getTrainClass().equals(assoc.getTrainClass())) { |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getOrigin().equals(assoc.getOrigin())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\textcolor{red}{"); |
|
||||||
} |
|
||||||
pw.print(tse.getOrigin()); |
|
||||||
if(!tse.getOrigin().equals(assoc.getOrigin())) { |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(tse.getOriginTime()!=assoc.getOriginTime()) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\textcolor{red}{"); |
|
||||||
} |
|
||||||
pw.print(getTime(tse.getOriginTime())); |
|
||||||
if(tse.getOriginTime()!=assoc.getOriginTime()) { |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(tse.getDepartTime()!=assoc.getDepartTime()) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\textcolor{red}{"); |
|
||||||
} |
|
||||||
pw.print(getTime(tse.getDepartTime())); |
|
||||||
if(tse.getDepartTime()!=assoc.getDepartTime()) { |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getDepartPlatform().equals(assoc.getDepartPlatform())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\textcolor{red}{"); |
|
||||||
} |
|
||||||
pw.print("\\small{"); |
|
||||||
pw.print(tse.getDepartPlatform()); |
|
||||||
pw.print("}"); |
|
||||||
if(!tse.getDepartPlatform().equals(assoc.getDepartPlatform())) { |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(tse.getArriveTime()!=assoc.getArriveTime()) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\textcolor{red}{"); |
|
||||||
} |
|
||||||
pw.print(getTime(tse.getArriveTime())); |
|
||||||
if(tse.getArriveTime()!=assoc.getArriveTime()) { |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getArrivePlatform().equals(assoc.getArrivePlatform())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\textcolor{red}{"); |
|
||||||
} |
|
||||||
pw.print("\\small{"); |
|
||||||
pw.print(tse.getArrivePlatform()); |
|
||||||
pw.print("}"); |
|
||||||
if(!tse.getArrivePlatform().equals(assoc.getArrivePlatform())) { |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getDestination().equals(assoc.getDestination())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\textcolor{red}{"); |
|
||||||
} |
|
||||||
pw.print(tse.getDestination()); |
|
||||||
if(!tse.getDestination().equals(assoc.getDestination())) { |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(tse.getDestinationTime()!=assoc.getDestinationTime()) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\textcolor{red}{"); |
|
||||||
} |
|
||||||
pw.print(getTime(tse.getDestinationTime())); |
|
||||||
if(tse.getDestinationTime()!=assoc.getDestinationTime()) { |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&\\pageref{td:"); |
|
||||||
pw.print(tse.getTrainUid()); |
|
||||||
pw.print("}&"); |
|
||||||
pw.print(tse.getNote()); |
|
||||||
pw.print("B"); |
|
||||||
if(tse.getScheduleType()==ScheduleType.CAN) |
|
||||||
pw.print("C"); |
|
||||||
if(hasChange) { |
|
||||||
pw.print("\\\\*"); |
|
||||||
//Print ORIGINAL record
|
|
||||||
if(recCount%2==0) |
|
||||||
pw.print("\\rowcolor{hl1}"); |
|
||||||
else |
|
||||||
pw.print("\\rowcolor{hl2}"); |
|
||||||
if(!tse.getSignalId().equals(assoc.getSignalId())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\sout{"); |
|
||||||
pw.print(assoc.getSignalId()); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getToc().equals(assoc.getToc())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\sout{"); |
|
||||||
pw.print(assoc.getToc()); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getTrainClass().equals(assoc.getTrainClass())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\sout{"); |
|
||||||
pw.print(assoc.getTrainClass()); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getOrigin().equals(assoc.getOrigin())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\sout{"); |
|
||||||
pw.print(assoc.getOrigin()); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(tse.getOriginTime()!=assoc.getOriginTime()) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\sout{"); |
|
||||||
pw.print(getTime(assoc.getOriginTime())); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(tse.getDepartTime()!=assoc.getDepartTime()) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\sout{"); |
|
||||||
pw.print(getTime(assoc.getDepartTime())); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getDepartPlatform().equals(assoc.getDepartPlatform())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\sout{"); |
|
||||||
pw.print("\\small{"); |
|
||||||
pw.print(assoc.getDepartPlatform()); |
|
||||||
pw.print("}"); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(tse.getArriveTime()!=assoc.getArriveTime()) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\sout{"); |
|
||||||
pw.print(getTime(assoc.getArriveTime())); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getArrivePlatform().equals(assoc.getArrivePlatform())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\sout{"); |
|
||||||
pw.print("\\small{"); |
|
||||||
pw.print(assoc.getArrivePlatform()); |
|
||||||
pw.print("}"); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(!tse.getDestination().equals(assoc.getDestination())) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\sout{"); |
|
||||||
pw.print(assoc.getDestination()); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(tse.getDestinationTime()!=assoc.getDestinationTime()) { |
|
||||||
hasChange = true; |
|
||||||
pw.print("\\sout{"); |
|
||||||
pw.print(getTime(assoc.getDestinationTime())); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.print("&&"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
ltse = tse; |
|
||||||
} |
|
||||||
pw.println("\\\\\\hline\\end{longtable}"); |
|
||||||
pw.println("Note:\\\\"); |
|
||||||
pw.println("A\\dfa Faster train available\\\\"); |
|
||||||
pw.println("B\\dfb Changes to timetable applies\\\\"); |
|
||||||
pw.println("C\\dfa Scheduled cancellation\\\\"); |
|
||||||
pw.println("\\pageref{xx:ukn}\\dfb No train details found\\\\"); |
|
||||||
|
|
||||||
//Details
|
|
||||||
pw.println("\\section{Schedule Details}"); |
|
||||||
for(TrainScheduleEntry tse:trainGroup) { |
|
||||||
TrainRunningRecord trr = getRunningRecord(tse.getMainSUID(), rptDate); |
|
||||||
if(trr==null) { |
|
||||||
log.atWarn().log("No record for {}", tse.getMainSUID()); |
|
||||||
continue; |
|
||||||
} |
|
||||||
pw.println("\\subsection{"+tse.getSignalId()+" "+getTime(tse.getOriginTime())+" to "+locCache.get(tse.getDestination()).replace("&", "\\&")+"}\\label{td:"+tse.getTrainUid()+"}"); |
|
||||||
pw.println(); |
|
||||||
pw.println("Basic infomation\\\\"); |
|
||||||
pw.println("From "+locCache.get(tse.getOrigin()).replace("&", "\\&")+" to "+locCache.get(tse.getDestination()).replace("&", "\\&")+"\\\\"); |
|
||||||
pw.println("Operated by "+tocCache.get(tse.getToc())+"\\\\"); |
|
||||||
pw.println(tcCache.get(tse.getTrainClass())+"\\\\"); |
|
||||||
pw.println("Train UID: "+tse.getTrainUid()+"\\\\"); |
|
||||||
try( |
|
||||||
Connection conn = DatabaseManager.getInstance().getConnection(); |
|
||||||
PreparedStatement pstmt = conn.prepareStatement("SELECT power_type, planned_speed, class, sleeper, reservation, catering, atoc_code, rsid FROM ltp_schedule WHERE suid = ?") |
|
||||||
){ |
|
||||||
pstmt.setString(1, tse.getMainSUID()); |
|
||||||
try(ResultSet rs = pstmt.executeQuery()){ |
|
||||||
if(rs.next()) { |
|
||||||
pw.println("Train ID: "+trr.getTrainId()+"\\\\"); |
|
||||||
pw.println("Activated on: "+new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date(trr.getActivate()))+"\\\\"); |
|
||||||
pw.println("Power type: "+rs.getString(1)+"\\\\"); |
|
||||||
pw.println("Planned speed "+rs.getString(2)+"mph\\\\"); |
|
||||||
if("".equals(rs.getString(3))||"B".equals(rs.getString(3))) { |
|
||||||
pw.println("First class available\\\\"); |
|
||||||
}else { |
|
||||||
pw.println("Only ordinary class available\\\\"); |
|
||||||
} |
|
||||||
if(rs.getString(8)!=null) { |
|
||||||
pw.println("National Reservation System headcode : "+rs.getString(7)+rs.getString(8)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
}catch(SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
pw.println(); |
|
||||||
pw.println("\\begin{longtable}[l]{|p{5.5cm}r|ccc|ccc|lr|}"); |
|
||||||
pw.println("\\hline\r\n" + |
|
||||||
" \\multicolumn{2}{|c|}{Station} & \\multicolumn{3}{c|}{Arrival}& \\multicolumn{3}{c|}{Departure}&\r\n" + |
|
||||||
" Plat. & Diff.\\\\\r\n" + |
|
||||||
" & & GBTT & WTT & Actual & GBTT & WTT & Actual & &\\\\\\hline\\endhead"); |
|
||||||
for(TrainRunningRecordEntry trre:trr.getEntries()) { |
|
||||||
if(trre.getLocationName()==null) |
|
||||||
continue; |
|
||||||
boolean pass = false; |
|
||||||
if(origin.equals(trre.getCrs())) |
|
||||||
pw.print("\\rowcolor{hl1}"); |
|
||||||
if(destination.equals(trre.getCrs())) |
|
||||||
pw.print("\\rowcolor{hl2}"); |
|
||||||
pw.print(trre.getLocationName().replace("&", "\\&")); |
|
||||||
pw.print("&"); |
|
||||||
if(trre.getCrs()!=null) |
|
||||||
pw.print(trre.getCrs()); |
|
||||||
pw.print("&"); |
|
||||||
//ARRIVAL
|
|
||||||
if(trre.getAgbtt()!=0) |
|
||||||
pw.print(getTime(trre.getAgbtt())); |
|
||||||
pw.print("&"); |
|
||||||
if(trre.getAwtt()!=0) |
|
||||||
pw.print(getTime(trre.getAwtt())); |
|
||||||
pw.print("&"); |
|
||||||
if(trre.getAact()!=0) |
|
||||||
pw.print(getTime(trre.getAact())); |
|
||||||
pw.print("&"); |
|
||||||
//ARRIVAL
|
|
||||||
if(trre.getDgbtt()!=0) |
|
||||||
pw.print(getTime(trre.getDgbtt())); |
|
||||||
else if(trre.getDwtt()!=0) { |
|
||||||
pw.print("\\pa"); |
|
||||||
pass = true; |
|
||||||
} |
|
||||||
pw.print("&"); |
|
||||||
if(trre.getDwtt()!=0) |
|
||||||
pw.print(getTime(trre.getDwtt())); |
|
||||||
pw.print("&"); |
|
||||||
if(trre.getDact()!=0) |
|
||||||
pw.print(getTime(trre.getDact())); |
|
||||||
pw.print("&"); |
|
||||||
if(trre.getPlatform()!=null) |
|
||||||
pw.print(trre.getPlatform()); |
|
||||||
pw.print("&"); |
|
||||||
long sch, act; |
|
||||||
if(pass||(trre.getAgbtt()==0&&trre.getAwtt()==0&&trre.getAact()==0)) { |
|
||||||
sch = trre.getDgbtt()!=0?trre.getDgbtt():trre.getDwtt(); |
|
||||||
act = trre.getDact(); |
|
||||||
}else { |
|
||||||
sch = trre.getAgbtt()!=0?trre.getAgbtt():trre.getAwtt(); |
|
||||||
act = trre.getAact(); |
|
||||||
} |
|
||||||
if(sch!=0 && !tse.getOrigin().equals(trre.getCrs())) { |
|
||||||
int diffMin = (int)(act-sch)/60; |
|
||||||
if(diffMin < -240) diffMin+=1440; |
|
||||||
if(diffMin < 0) pw.print("\\textcolor{e1}{"); |
|
||||||
else if(diffMin > 30) pw.print("\\textcolor{l3}{"); |
|
||||||
else if(diffMin > 15) pw.print("\\textcolor{l2}{"); |
|
||||||
else if(diffMin > 0) pw.print("\\textcolor{l1}{"); |
|
||||||
else pw.print("\\textcolor{ot}{"); |
|
||||||
pw.print(diffMin); |
|
||||||
pw.print("}"); |
|
||||||
} |
|
||||||
pw.println("\\\\"); |
|
||||||
|
|
||||||
} |
|
||||||
pw.println("\\hline\\end{longtable}"); |
|
||||||
pw.println(); |
|
||||||
|
|
||||||
} |
|
||||||
pw.println("This is the end of the report"); |
|
||||||
pw.println("\\end{document}"); |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
private static TrainRunningRecord getRunningRecord(String suid, java.util.Date opDate) { |
|
||||||
TrainRunningRecord trr = new TrainRunningRecord(); |
|
||||||
try(Connection conn = DatabaseManager.getInstance().getConnection()){ |
|
||||||
//Step 1: Find the activation record
|
|
||||||
try(PreparedStatement stmt = conn.prepareStatement("SELECT train_id, activate_time FROM current_train WHERE suid=? AND op_date=?")){ |
|
||||||
stmt.setString(1, suid); |
|
||||||
stmt.setDate(2, new java.sql.Date(opDate.getTime())); |
|
||||||
try(ResultSet rs = stmt.executeQuery()){ |
|
||||||
if(rs.next()) { |
|
||||||
trr.setTrainId(rs.getString(1)); |
|
||||||
trr.setActivate(rs.getTimestamp(2).getTime()); |
|
||||||
}else { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
//Step 2: get the actual record
|
|
||||||
try(PreparedStatement stmt = conn.prepareStatement("SELECT get_stanox_name(loc_stanox) loc, stanox_to_crs(loc_stanox) crs,\r\n" + |
|
||||||
" TIME_TO_SEC(gbtt_time) ttt, TIME_TO_SEC(plan_time) plt, TIME_TO_SEC(movt_time) act,\r\n" + |
|
||||||
" platform plat, CASE evnt_type WHEN 'DEPARTURE' THEN 'D' WHEN 'ARRIVAL' THEN 'A' ELSE '?' END, loc_stanox t\r\n" + |
|
||||||
" FROM current_train_movement WHERE train_id = ? ORDER BY movt_time, evnt_type;")){ |
|
||||||
stmt.setString(1, trr.getTrainId()); |
|
||||||
try(ResultSet rs = stmt.executeQuery()){ |
|
||||||
TrainRunningRecordEntry trre = new TrainRunningRecordEntry(); |
|
||||||
while(rs.next()) { |
|
||||||
if(!rs.getString(8).equals(trre.getStanox())) { |
|
||||||
//Changed
|
|
||||||
trr.getEntries().add(trre); |
|
||||||
trre = new TrainRunningRecordEntry(); |
|
||||||
} |
|
||||||
trre.setCrs(rs.getString(2)); |
|
||||||
String locName = rs.getString(1); |
|
||||||
if(locName.length()>20) { |
|
||||||
locName=locName |
|
||||||
.replace("JUNCTION", "JN") |
|
||||||
.replace("INTERNATIONAL", "INTL") |
|
||||||
.replace("THAMESLINK", "TL"); |
|
||||||
} |
|
||||||
trre.setLocationName(locName); |
|
||||||
trre.setPlatform(rs.getString(6)); |
|
||||||
trre.setStanox(rs.getString(8)); |
|
||||||
if("A".equals(rs.getString(7))) { |
|
||||||
//Arrival
|
|
||||||
trre.setAgbtt(rs.getLong(3)); |
|
||||||
trre.setAwtt(rs.getLong(4)); |
|
||||||
trre.setAact(rs.getLong(5)); |
|
||||||
}else { |
|
||||||
//Departure
|
|
||||||
trre.setDgbtt(rs.getLong(3)); |
|
||||||
trre.setDwtt(rs.getLong(4)); |
|
||||||
trre.setDact(rs.getLong(5)); |
|
||||||
} |
|
||||||
} |
|
||||||
trr.getEntries().add(trre); |
|
||||||
} |
|
||||||
} |
|
||||||
}catch(SQLException e) { |
|
||||||
log.atError().log(e.getMessage(), e); |
|
||||||
} |
|
||||||
return trr; |
|
||||||
} |
|
||||||
|
|
||||||
private static String getTime(long sec) { |
|
||||||
long h = sec/3600; |
|
||||||
long m = (sec/60)%60; |
|
||||||
StringBuilder sb = new StringBuilder(); |
|
||||||
if(h<10) sb.append("0"); |
|
||||||
sb.append(h).append(":"); |
|
||||||
if(m<10) sb.append("0"); |
|
||||||
sb.append(m); |
|
||||||
return sb.toString(); |
|
||||||
} |
|
||||||
|
|
||||||
private static int getHour(long sec) { |
|
||||||
return (int) sec/3600; |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,35 +0,0 @@ |
|||||||
package org.leolo.rail.report; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Vector; |
|
||||||
|
|
||||||
public class TrainRunningRecord { |
|
||||||
private String trainId; |
|
||||||
private long activate; |
|
||||||
|
|
||||||
private Vector<TrainRunningRecordEntry> entries = new Vector<>(); |
|
||||||
|
|
||||||
public String getTrainId() { |
|
||||||
return trainId; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public Vector<TrainRunningRecordEntry> getEntries() { |
|
||||||
return entries; |
|
||||||
} |
|
||||||
|
|
||||||
public void setTrainId(String trainId) { |
|
||||||
this.trainId = trainId; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public long getActivate() { |
|
||||||
return activate; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public void setActivate(long activate) { |
|
||||||
this.activate = activate; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,76 +0,0 @@ |
|||||||
package org.leolo.rail.report; |
|
||||||
|
|
||||||
public class TrainRunningRecordEntry { |
|
||||||
private String locationName; |
|
||||||
private String crs; |
|
||||||
private String stanox; |
|
||||||
private String platform; |
|
||||||
|
|
||||||
private long agbtt; |
|
||||||
private long awtt; |
|
||||||
private long aact; |
|
||||||
private long dgbtt; |
|
||||||
private long dwtt; |
|
||||||
private long dact; |
|
||||||
public String getLocationName() { |
|
||||||
return locationName; |
|
||||||
} |
|
||||||
public String getCrs() { |
|
||||||
return crs; |
|
||||||
} |
|
||||||
public long getAgbtt() { |
|
||||||
return agbtt; |
|
||||||
} |
|
||||||
public long getAwtt() { |
|
||||||
return awtt; |
|
||||||
} |
|
||||||
public long getAact() { |
|
||||||
return aact; |
|
||||||
} |
|
||||||
public long getDgbtt() { |
|
||||||
return dgbtt; |
|
||||||
} |
|
||||||
public long getDwtt() { |
|
||||||
return dwtt; |
|
||||||
} |
|
||||||
public long getDact() { |
|
||||||
return dact; |
|
||||||
} |
|
||||||
public void setLocationName(String locationName) { |
|
||||||
this.locationName = locationName; |
|
||||||
} |
|
||||||
public void setCrs(String crs) { |
|
||||||
this.crs = crs; |
|
||||||
} |
|
||||||
public void setAgbtt(long agbtt) { |
|
||||||
this.agbtt = agbtt; |
|
||||||
} |
|
||||||
public void setAwtt(long awtt) { |
|
||||||
this.awtt = awtt; |
|
||||||
} |
|
||||||
public void setAact(long aact) { |
|
||||||
this.aact = aact; |
|
||||||
} |
|
||||||
public void setDgbtt(long dgbtt) { |
|
||||||
this.dgbtt = dgbtt; |
|
||||||
} |
|
||||||
public void setDwtt(long dwtt) { |
|
||||||
this.dwtt = dwtt; |
|
||||||
} |
|
||||||
public void setDact(long dact) { |
|
||||||
this.dact = dact; |
|
||||||
} |
|
||||||
public String getPlatform() { |
|
||||||
return platform; |
|
||||||
} |
|
||||||
public void setPlatform(String platform) { |
|
||||||
this.platform = platform; |
|
||||||
} |
|
||||||
public String getStanox() { |
|
||||||
return stanox; |
|
||||||
} |
|
||||||
public void setStanox(String stanox) { |
|
||||||
this.stanox = stanox; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,105 +0,0 @@ |
|||||||
package org.leolo.rail.report; |
|
||||||
|
|
||||||
import java.util.HashSet; |
|
||||||
|
|
||||||
import org.leolo.rail.model.ScheduleType; |
|
||||||
|
|
||||||
public class TrainScheduleEntry { |
|
||||||
|
|
||||||
private HashSet<BasicTrainScheduleEntry> subEntry = new HashSet<>(); |
|
||||||
private BasicTrainScheduleEntry mainEntry = null; |
|
||||||
private String note = ""; |
|
||||||
|
|
||||||
public void addEntry(BasicTrainScheduleEntry entry) { |
|
||||||
subEntry.add(entry); |
|
||||||
if(mainEntry==null) { |
|
||||||
mainEntry = entry; |
|
||||||
}else if(entry.getScheduleType() == ScheduleType.OVL) { |
|
||||||
mainEntry = entry; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public int getSubentryCount() { |
|
||||||
return subEntry.size(); |
|
||||||
} |
|
||||||
|
|
||||||
public BasicTrainScheduleEntry getAssocEntry() { |
|
||||||
for(BasicTrainScheduleEntry btse:subEntry) { |
|
||||||
if(btse!=mainEntry) { |
|
||||||
return btse; |
|
||||||
} |
|
||||||
} |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
public String getMainSUID() { |
|
||||||
return mainEntry.getSuid(); |
|
||||||
} |
|
||||||
|
|
||||||
public ScheduleType getScheduleType() { |
|
||||||
return mainEntry.getScheduleType(); |
|
||||||
} |
|
||||||
|
|
||||||
public String getSignalId() { |
|
||||||
return mainEntry.getSignalId(); |
|
||||||
} |
|
||||||
|
|
||||||
public String getToc() { |
|
||||||
return mainEntry.getToc(); |
|
||||||
} |
|
||||||
|
|
||||||
public String getTrainClass() { |
|
||||||
return mainEntry.getTrainClass(); |
|
||||||
} |
|
||||||
|
|
||||||
public String getOrigin() { |
|
||||||
return mainEntry.getOrigin(); |
|
||||||
} |
|
||||||
|
|
||||||
public long getOriginTime() { |
|
||||||
return mainEntry.getOriginTime(); |
|
||||||
} |
|
||||||
|
|
||||||
public String getDestination() { |
|
||||||
return mainEntry.getDestination(); |
|
||||||
} |
|
||||||
|
|
||||||
public long getDestinationTime() { |
|
||||||
return mainEntry.getDestinationTime(); |
|
||||||
} |
|
||||||
|
|
||||||
public HashSet<BasicTrainScheduleEntry> getAssoicatedEntry() { |
|
||||||
return mainEntry.getAssoicatedEntry(); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public String getTrainUid() { |
|
||||||
return mainEntry.getTrainUid(); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public long getDepartTime() { |
|
||||||
return mainEntry.getDepartTime(); |
|
||||||
} |
|
||||||
|
|
||||||
public String getDepartPlatform() { |
|
||||||
return mainEntry.getDepartPlatform(); |
|
||||||
} |
|
||||||
|
|
||||||
public long getArriveTime() { |
|
||||||
return mainEntry.getArriveTime(); |
|
||||||
} |
|
||||||
|
|
||||||
public String getArrivePlatform() { |
|
||||||
return mainEntry.getArrivePlatform(); |
|
||||||
} |
|
||||||
|
|
||||||
public String getNote() { |
|
||||||
return note; |
|
||||||
} |
|
||||||
|
|
||||||
public void setNote(String note) { |
|
||||||
this.note = note; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,32 +0,0 @@ |
|||||||
package org.leolo.rail.util; |
|
||||||
|
|
||||||
import java.text.DateFormat; |
|
||||||
import java.text.FieldPosition; |
|
||||||
import java.text.ParsePosition; |
|
||||||
import java.util.Date; |
|
||||||
|
|
||||||
public class TUIDDateFormat extends DateFormat{ |
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
*/ |
|
||||||
private static final long serialVersionUID = 7274736087586430881L; |
|
||||||
|
|
||||||
public static final String MONTH_ID = "MBTQPHSONDUE"; |
|
||||||
public static final String DAY_ID = "0123456789ABCDEFGHJKLMNPRSTUVWX"; |
|
||||||
|
|
||||||
|
|
||||||
@Override |
|
||||||
public StringBuffer format(Date arg0, StringBuffer arg1, FieldPosition arg2) { |
|
||||||
// TODO Auto-generated method stub
|
|
||||||
arg1.append(MONTH_ID.charAt(arg0.getMonth())); |
|
||||||
arg1.append(DAY_ID.charAt(arg0.getDate()-1)); |
|
||||||
return arg1; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Date parse(String arg0, ParsePosition arg1) { |
|
||||||
throw new UnsupportedOperationException(); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
Loading…
Reference in new issue