diff --git a/src/org/leolo/rail/AssoicationProcessor.java b/src/org/leolo/rail/AssoicationProcessor.java new file mode 100644 index 0000000..436a882 --- /dev/null +++ b/src/org/leolo/rail/AssoicationProcessor.java @@ -0,0 +1,93 @@ +package org.leolo.rail; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Types; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.zip.GZIPInputStream; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.json.JSONObject; +import org.leolo.rail.util.TUIDDateFormat; + +public class AssoicationProcessor extends BaseProcessor implements Runnable { + + private File targetFile; + private Logger log = LogManager.getLogger(AssoicationProcessor.class); + + public AssoicationProcessor(File targetFile) { + this.targetFile = targetFile; + } + + @Override + public void run() { + log.atInfo().log("Processing {}", targetFile.getName()); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + TUIDDateFormat tdf = new TUIDDateFormat(); + try( + BufferedReader br = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(targetFile)))); + Connection conn = DatabaseManager.getInstance().getConnection(); + PreparedStatement pstmt = conn.prepareStatement("REPLACE INTO ltp_assoication VALUES(?,?,?,?,?,?,?,?,?,?,?,?)") + ){ + while(true) { + String line = br.readLine(); + if(line==null) { + break; + } + JSONObject obj = new JSONObject(line); + String mainTrainUID = obj.optString("main_train_uid"); + String assocTrainUID = obj.optString("assoc_train_uid"); + java.sql.Date startDate, endDate; + try { + startDate = new java.sql.Date(sdf.parse(obj.optString("assoc_start_date")).getTime()); + endDate = new java.sql.Date(sdf.parse(obj.optString("assoc_end_date")).getTime()); + } catch (ParseException e1) { + log.warn("Unable to parse date! {}", e1.getMessage(), e1); + continue; + } + String assoc_days = obj.optString("assoc_days"); + String assoc_type = obj.optString("category"); + String location = obj.optString("location"); + String base_suffix = obj.optString("base_location_suffix"); + String assoc_suffix = obj.optString("assoc_location_suffix"); + String stp_ind = obj.optString("CIF_stp_indicator"); + String auid = mainTrainUID + assocTrainUID + location + tdf.format(startDate) + tdf.format(endDate)+stp_ind; + int hashCode = (auid+assoc_type+assoc_days).hashCode(); + setString(pstmt, 1, auid); + setString(pstmt, 2, mainTrainUID); + setString(pstmt, 3, assocTrainUID); + pstmt.setDate(4, startDate); + pstmt.setDate(5, endDate); + setString(pstmt, 6, assoc_days); + setString(pstmt, 7, assoc_type); + setString(pstmt, 8, location); + setString(pstmt, 9, base_suffix); + setString(pstmt, 10, assoc_suffix); + setString(pstmt, 11, stp_ind); + pstmt.setInt(12, hashCode); + pstmt.addBatch(); + } + pstmt.executeBatch(); + conn.commit(); + } catch (FileNotFoundException e) { + log.error(e.getMessage(), e); + } catch (IOException e) { + log.error(e.getMessage(), e); + } catch (SQLException e) { + log.error(e.getMessage(), e); + } + if(!targetFile.delete()) { + log.warn("Unable to delete {}", targetFile.getName()); + } + } + +} diff --git a/src/org/leolo/rail/BaseProcessor.java b/src/org/leolo/rail/BaseProcessor.java new file mode 100644 index 0000000..e742b2f --- /dev/null +++ b/src/org/leolo/rail/BaseProcessor.java @@ -0,0 +1,28 @@ +package org.leolo.rail; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Types; + +public abstract class BaseProcessor { + public void setString(PreparedStatement stmt, int col, String val) throws SQLException{ + if(val==null || "".equals(val.trim())) { + stmt.setNull(col, Types.CHAR); + }else { + stmt.setString(col, val); + } + } + + public void setTime(PreparedStatement stmt, int col, long time) throws SQLException{ + if(time==0) { + stmt.setNull(col, Types.TIME); + }else { + int h = (int)(time/3_600_000); + int m = (int)((time/60_000)%60); + int s = (int)((time/1_000)%60); + stmt.setString(col, h+":"+m+":"+s); + } + } + + +} diff --git a/src/org/leolo/rail/Constants.java b/src/org/leolo/rail/Constants.java index cc562a7..1b033b2 100644 --- a/src/org/leolo/rail/Constants.java +++ b/src/org/leolo/rail/Constants.java @@ -28,4 +28,6 @@ public class Constants { public static class Metadata{ public static final String LAST_NETOWRK_RAIL_SCHEDULE_UPD = "LNeRSchUpd"; } + + public static final int BATCH_SIZE = 5_000; } diff --git a/src/org/leolo/rail/LongTermScheduleJob.java b/src/org/leolo/rail/LongTermScheduleJob.java index c3b1dbd..259ed51 100644 --- a/src/org/leolo/rail/LongTermScheduleJob.java +++ b/src/org/leolo/rail/LongTermScheduleJob.java @@ -1,10 +1,26 @@ package org.leolo.rail; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.URL; +import java.net.URLConnection; import java.sql.SQLException; +import java.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.dao.MetadataDao; import org.quartz.Job; import org.quartz.JobExecutionContext; @@ -36,7 +52,127 @@ public class LongTermScheduleJob implements Job{ } 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); + } + log.atInfo().log("LTS job done!"); } } diff --git a/src/org/leolo/rail/ScheduleProcessor.java b/src/org/leolo/rail/ScheduleProcessor.java new file mode 100644 index 0000000..caa9726 --- /dev/null +++ b/src/org/leolo/rail/ScheduleProcessor.java @@ -0,0 +1,316 @@ +package org.leolo.rail; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Vector; +import java.util.zip.GZIPInputStream; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.json.JSONArray; +import org.json.JSONObject; +import org.leolo.rail.model.LocationRecordType; +import org.leolo.rail.model.ScheduleType; +import org.leolo.rail.model.TrainSchedule; +import org.leolo.rail.model.TrainScheduleLocation; + +public class ScheduleProcessor extends BaseProcessor implements Runnable { + + private Logger log = LogManager.getLogger(ScheduleProcessor.class); + private File targetFile; + + public ScheduleProcessor(File targetFile) { + this.targetFile = targetFile; + } + + @Override + public void run() { + Vector newSchedule = new Vector<>(); + Vector 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;i1) { + setString(psSch,23, ts.getLocations().get(0).getTiplocCode()); + setTime(psSch,24, ts.getLocations().get(0).getDeparture()); + setString(psSch,25, ts.getLocations().get(ts.getLocations().size()-1).getTiplocCode()); + setTime(psSch,26, ts.getLocations().get(ts.getLocations().size()-1).getArrival()); + }else { + psSch.setNull(23, Types.CHAR); + psSch.setNull(24, Types.TIME); + psSch.setNull(25, Types.CHAR); + psSch.setNull(26, Types.TIME); + } + psSch.setInt(27, ts.hashCode()); + int seq = 1; + for(TrainScheduleLocation tsl:ts.getLocations()) { + setString(psLoc, 1, ts.getSUID()); + psLoc.setInt(2, seq++); + setString(psLoc, 3, tsl.getTiplocCode()); + psLoc.setInt(4, tsl.getTiplocInstance()); + setTime(psLoc, 5, tsl.getArrival()); + setTime(psLoc, 6, tsl.getDeparture()); + setTime(psLoc, 7, tsl.getPass()); + setTime(psLoc, 8, tsl.getPubArrival()); + setTime(psLoc, 9, tsl.getPubDeparture()); + setString(psLoc,10, tsl.getPlatform()); + setString(psLoc,11, tsl.getLine()); + setString(psLoc,12, tsl.getPath()); + setTime(psLoc,13, tsl.getEngineeringAllowance()); + setTime(psLoc,14, tsl.getPathingAllowance()); + setTime(psLoc,15, tsl.getPerformanceAllowance()); + setString(psLoc,16, tsl.getRecordType().getRecordCode()); + psLoc.addBatch(); + } + psSch.executeUpdate(); + psLoc.executeBatch(); + conn.commit(); + } + }//New Records + //Update records + try( + PreparedStatement psSch = conn.prepareStatement("REPLACE INTO ltp_schedule VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); + PreparedStatement psDel = conn.prepareStatement("DELETE FROM ltp_location WHERE suid = ?"); + PreparedStatement psLoc = conn.prepareStatement("INSERT INTO ltp_location VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + ){ + for(TrainSchedule ts:updatedSchedule) { + setString(psSch, 1, ts.getSUID()); + setString(psSch, 2, ts.getTrainUId()); + setString(psSch, 3, ts.getScheduleType().name()); + setString(psSch, 4, sdf.format(ts.getStartDate())); + setString(psSch, 5, sdf.format(ts.getEndDate())); + setString(psSch, 6, ts.getDays()); + setString(psSch, 7, ts.getBankHolidayInd()); + setString(psSch, 8, ts.getSignalId()); + setString(psSch, 9, ts.getRsid()); + setString(psSch,10, ts.getTrainStatus()); + setString(psSch,11, ts.getTrainCategory()); + setString(psSch,12, ts.getSection()); + setString(psSch,13, ts.getPowerType()); + setString(psSch,14, ts.getTimingLoad()); + setString(psSch,15, ts.getPlannedSpeed()); + setString(psSch,16, ts.getOperatingCharacter()); + setString(psSch,17, ts.getClassAvailable()); + setString(psSch,18, ts.getSleeper()); + setString(psSch,19, ts.getReservation()); + setString(psSch,20, ts.getCatering()); + setString(psSch,21, ts.getUicCode()); + setString(psSch,22, ts.getAtocCode()); + if(ts.getLocations().size()>1) { + setString(psSch,23, ts.getLocations().get(0).getTiplocCode()); + setTime(psSch,24, ts.getLocations().get(0).getDeparture()); + setString(psSch,25, ts.getLocations().get(ts.getLocations().size()-1).getTiplocCode()); + setTime(psSch,26, ts.getLocations().get(ts.getLocations().size()-1).getArrival()); + }else { + psSch.setNull(23, Types.CHAR); + psSch.setNull(24, Types.TIME); + psSch.setNull(25, Types.CHAR); + psSch.setNull(26, Types.TIME); + } + psSch.setInt(27, ts.hashCode()); + psDel.setString(1, ts.getSUID()); + psDel.executeUpdate(); + int seq = 1; + for(TrainScheduleLocation tsl:ts.getLocations()) { + setString(psLoc, 1, ts.getSUID()); + psLoc.setInt(2, seq++); + setString(psLoc, 3, tsl.getTiplocCode()); + psLoc.setInt(4, tsl.getTiplocInstance()); + setTime(psLoc, 5, tsl.getArrival()); + setTime(psLoc, 6, tsl.getDeparture()); + setTime(psLoc, 7, tsl.getPass()); + setTime(psLoc, 8, tsl.getPubArrival()); + setTime(psLoc, 9, tsl.getPubDeparture()); + setString(psLoc,10, tsl.getPlatform()); + setString(psLoc,11, tsl.getLine()); + setString(psLoc,12, tsl.getPath()); + setTime(psLoc,13, tsl.getEngineeringAllowance()); + setTime(psLoc,14, tsl.getPathingAllowance()); + setTime(psLoc,15, tsl.getPerformanceAllowance()); + setString(psLoc,16, tsl.getRecordType().getRecordCode()); + psLoc.addBatch(); + } + psSch.executeUpdate(); + psLoc.executeBatch(); + conn.commit(); + } + }//New Records + + log.atInfo().log("Inserted new {} record(s).",newSchedule.size()); + } catch (SQLException e) { + log.error(e.getMessage(), e); + } + if(!targetFile.delete()) { + log.warn("Unable to delete {}", targetFile.getName()); + } + } + + private long getScheduleTime(String t) { + //HHMM'H' + if("".equals(t.trim())) { + return 0; + } + int hour = Integer.parseInt(t.substring(0, 2)); + int min = Integer.parseInt(t.substring(2, 4)); + boolean half = t.length()>=5 && t.substring(4, 5).equals("H"); + return hour*3_600_000+min*60_000+(half?30_000:0); + } + + private long getAllowanceTime(String t) { + if("".equals(t.trim())) { + return 0; + } + if("H".equals(t.trim())) + return 30_000; + if(t.endsWith("H")) { + //nH + return Integer.parseInt(t.substring(0,1))*60_000+30_000; + }else { + //nn + return Integer.parseInt(t)*60_000; + } + } + +} diff --git a/src/org/leolo/rail/TiplocProcessor.java b/src/org/leolo/rail/TiplocProcessor.java new file mode 100644 index 0000000..b055b16 --- /dev/null +++ b/src/org/leolo/rail/TiplocProcessor.java @@ -0,0 +1,67 @@ +package org.leolo.rail; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.zip.GZIPInputStream; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.json.JSONObject; +import org.leolo.rail.util.TUIDDateFormat; + +public class TiplocProcessor extends BaseProcessor implements Runnable { + + private Logger log = LogManager.getLogger(TiplocProcessor.class); + private File file; + + public TiplocProcessor(File f) { + file = f; + } + + @Override + public void run() { + log.atInfo().log("Processing {}", file.getName()); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + TUIDDateFormat tdf = new TUIDDateFormat(); + try( + BufferedReader br = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(file)))); + Connection conn = DatabaseManager.getInstance().getConnection(); + PreparedStatement pstmt = conn.prepareStatement("REPLACE INTO tiploc VALUES(?,?,?,?,?,?)") + ){ + while(true) { + String line = br.readLine(); + if(line==null) { + break; + } + JSONObject obj = new JSONObject(line); + setString(pstmt, 1, obj.optString("tiploc_code")); + setString(pstmt, 2, obj.optString("nalco")); + setString(pstmt, 3, obj.optString("stanox")); + setString(pstmt, 4, obj.optString("crs_code")); + setString(pstmt, 5, obj.optString("description")); + setString(pstmt, 6, obj.optString("tps_description")); + pstmt.addBatch(); + } + pstmt.executeBatch(); + conn.commit(); + } catch (FileNotFoundException e) { + log.error(e.getMessage(), e); + } catch (IOException e) { + log.error(e.getMessage(), e); + } catch (SQLException e) { + log.error(e.getMessage(), e); + } + if(!file.delete()) { + log.warn("Unable to delete {}", file.getName()); + } + } + +} diff --git a/src/org/leolo/rail/model/LocationRecordType.java b/src/org/leolo/rail/model/LocationRecordType.java new file mode 100644 index 0000000..8290b9e --- /dev/null +++ b/src/org/leolo/rail/model/LocationRecordType.java @@ -0,0 +1,17 @@ +package org.leolo.rail.model; + +public enum LocationRecordType { + ORIGIN("LO"), + INTERMEDIATE("LI"), + TERMINATE("LT"); + + private String recordCode; + + private LocationRecordType(String recordCode) { + this.recordCode = recordCode; + } + + public String getRecordCode() { + return recordCode; + } +} diff --git a/src/org/leolo/rail/model/ScheduleType.java b/src/org/leolo/rail/model/ScheduleType.java new file mode 100644 index 0000000..d058842 --- /dev/null +++ b/src/org/leolo/rail/model/ScheduleType.java @@ -0,0 +1,20 @@ +package org.leolo.rail.model; + +public enum ScheduleType { + WTT("P"), + OVL("O"), + VAR("V"), + STP("S"), + CAN("C"); + + private String scheduleCode; + + private ScheduleType(String scheduleCode) { + this.scheduleCode = scheduleCode; + } + + public String getScheduleCode() { + return scheduleCode; + } + +} diff --git a/src/org/leolo/rail/model/TrainSchedule.java b/src/org/leolo/rail/model/TrainSchedule.java new file mode 100644 index 0000000..4936473 --- /dev/null +++ b/src/org/leolo/rail/model/TrainSchedule.java @@ -0,0 +1,328 @@ +package org.leolo.rail.model; + +import java.util.Date; +import java.util.Vector; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.leolo.rail.util.TUIDDateFormat; + +public class TrainSchedule { + + private static Logger log = LogManager.getLogger(TrainSchedule.class); + + private String trainUId; + private ScheduleType scheduleType = ScheduleType.WTT; + private Date startDate; + private Date endDate; + private String days; + private String bankHolidayInd; + private String signalId; + private String rsid; + private String trainStatus; + private String trainCategory; + private String section; + private String powerType; + private String timingLoad; + private String plannedSpeed; + private String operatingCharacter; + private String classAvailable; + private String sleeper; + private String reservation; + private String catering; + private String uicCode; + private String atocCode; + private Vector 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 getLocations() { + return locations; + } + public String getSUID() { + TUIDDateFormat tdf = new TUIDDateFormat(); + return trainUId + tdf.format(startDate) + tdf.format(endDate) + scheduleType.getScheduleCode(); + } + @Override + public int hashCode() { + log.info("startdate:{}", startDate.getTime()); + final int prime = 31; + int result = 1; + result = prime * result + ((atocCode == null) ? 0 : atocCode.hashCode()); + result = prime * result + ((bankHolidayInd == null) ? 0 : bankHolidayInd.hashCode()); + result = prime * result + ((catering == null) ? 0 : catering.hashCode()); + result = prime * result + ((classAvailable == null) ? 0 : classAvailable.hashCode()); + result = prime * result + ((days == null) ? 0 : days.hashCode()); + result = prime * result + ((endDate == null) ? 0 : endDate.hashCode()); + result = prime * result + ((operatingCharacter == null) ? 0 : operatingCharacter.hashCode()); + result = prime * result + ((plannedSpeed == null) ? 0 : plannedSpeed.hashCode()); + result = prime * result + ((powerType == null) ? 0 : powerType.hashCode()); + result = prime * result + ((reservation == null) ? 0 : reservation.hashCode()); + result = prime * result + ((rsid == null) ? 0 : rsid.hashCode()); + result = prime * result + ((scheduleType == null) ? 0 : scheduleType.hashCode()); + result = prime * result + ((section == null) ? 0 : section.hashCode()); + result = prime * result + ((signalId == null) ? 0 : signalId.hashCode()); + result = prime * result + ((sleeper == null) ? 0 : sleeper.hashCode()); + result = prime * result + ((startDate == null) ? 0 : startDate.hashCode()); + result = prime * result + ((timingLoad == null) ? 0 : timingLoad.hashCode()); + result = prime * result + ((trainCategory == null) ? 0 : trainCategory.hashCode()); + result = prime * result + ((trainStatus == null) ? 0 : trainStatus.hashCode()); + result = prime * result + ((trainUId == null) ? 0 : trainUId.hashCode()); + result = prime * result + ((uicCode == null) ? 0 : uicCode.hashCode()); + for(TrainScheduleLocation tsl:locations) { + log.atDebug().log("TIPLOC: {}, hash: {}//{}", tsl.getTiplocCode(), Integer.toHexString(tsl.hashCode()), Integer.toHexString(tsl.getTiplocCode().hashCode())); + result = prime * result + tsl.hashCode(); + } + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TrainSchedule other = (TrainSchedule) obj; + if (atocCode == null) { + if (other.atocCode != null) + return false; + } else if (!atocCode.equals(other.atocCode)) + return false; + if (bankHolidayInd == null) { + if (other.bankHolidayInd != null) + return false; + } else if (!bankHolidayInd.equals(other.bankHolidayInd)) + return false; + if (catering == null) { + if (other.catering != null) + return false; + } else if (!catering.equals(other.catering)) + return false; + if (classAvailable == null) { + if (other.classAvailable != null) + return false; + } else if (!classAvailable.equals(other.classAvailable)) + return false; + if (days == null) { + if (other.days != null) + return false; + } else if (!days.equals(other.days)) + return false; + if (endDate == null) { + if (other.endDate != null) + return false; + } else if (!endDate.equals(other.endDate)) + return false; + if (locations == null) { + if (other.locations != null) + return false; + } else if (!locations.equals(other.locations)) + return false; + if (operatingCharacter == null) { + if (other.operatingCharacter != null) + return false; + } else if (!operatingCharacter.equals(other.operatingCharacter)) + return false; + if (plannedSpeed == null) { + if (other.plannedSpeed != null) + return false; + } else if (!plannedSpeed.equals(other.plannedSpeed)) + return false; + if (powerType == null) { + if (other.powerType != null) + return false; + } else if (!powerType.equals(other.powerType)) + return false; + if (reservation == null) { + if (other.reservation != null) + return false; + } else if (!reservation.equals(other.reservation)) + return false; + if (rsid == null) { + if (other.rsid != null) + return false; + } else if (!rsid.equals(other.rsid)) + return false; + if (scheduleType != other.scheduleType) + return false; + if (section == null) { + if (other.section != null) + return false; + } else if (!section.equals(other.section)) + return false; + if (signalId == null) { + if (other.signalId != null) + return false; + } else if (!signalId.equals(other.signalId)) + return false; + if (sleeper == null) { + if (other.sleeper != null) + return false; + } else if (!sleeper.equals(other.sleeper)) + return false; + if (startDate == null) { + if (other.startDate != null) + return false; + } else if (!startDate.equals(other.startDate)) + return false; + if (timingLoad == null) { + if (other.timingLoad != null) + return false; + } else if (!timingLoad.equals(other.timingLoad)) + return false; + if (trainCategory == null) { + if (other.trainCategory != null) + return false; + } else if (!trainCategory.equals(other.trainCategory)) + return false; + if (trainStatus == null) { + if (other.trainStatus != null) + return false; + } else if (!trainStatus.equals(other.trainStatus)) + return false; + if (trainUId == null) { + if (other.trainUId != null) + return false; + } else if (!trainUId.equals(other.trainUId)) + return false; + if (uicCode == null) { + if (other.uicCode != null) + return false; + } else if (!uicCode.equals(other.uicCode)) + return false; + return true; + } +} diff --git a/src/org/leolo/rail/model/TrainScheduleLocation.java b/src/org/leolo/rail/model/TrainScheduleLocation.java new file mode 100644 index 0000000..6ad479f --- /dev/null +++ b/src/org/leolo/rail/model/TrainScheduleLocation.java @@ -0,0 +1,175 @@ +package org.leolo.rail.model; + +public class TrainScheduleLocation { + + private String tiplocCode; + private int tiplocInstance = 1; + private long arrival; + private long departure; + private long pass; + private long pubArrival; + private long pubDeparture; + private String platform; + private String line; + private String path; + private long engineeringAllowance; + private long pathingAllowance; + private long performanceAllowance; + private LocationRecordType recordType; + public String getTiplocCode() { + return tiplocCode; + } + public void setTiplocCode(String tiplocCode) { + this.tiplocCode = tiplocCode; + } + public int getTiplocInstance() { + return tiplocInstance; + } + public void setTiplocInstance(int tiplocInstance) { + this.tiplocInstance = tiplocInstance; + } + public long getArrival() { + return arrival; + } + public void setArrival(long arrival) { + this.arrival = arrival; + } + public long getDeparture() { + return departure; + } + public void setDeparture(long departure) { + this.departure = departure; + } + public long getPass() { + return pass; + } + public void setPass(long pass) { + this.pass = pass; + } + public long getPubArrival() { + return pubArrival; + } + public void setPubArrival(long pubArrival) { + this.pubArrival = pubArrival; + } + public long getPubDeparture() { + return pubDeparture; + } + public void setPubDeparture(long pubDeparture) { + this.pubDeparture = pubDeparture; + } + public String getPlatform() { + return platform; + } + public void setPlatform(String platform) { + this.platform = platform; + } + public String getLine() { + return line; + } + public void setLine(String line) { + this.line = line; + } + public String getPath() { + return path; + } + public void setPath(String path) { + this.path = path; + } + public long getEngineeringAllowance() { + return engineeringAllowance; + } + public void setEngineeringAllowance(long engineeringAllowance) { + this.engineeringAllowance = engineeringAllowance; + } + public long getPathingAllowance() { + return pathingAllowance; + } + public void setPathingAllowance(long pathingAllowance) { + this.pathingAllowance = pathingAllowance; + } + public long getPerformanceAllowance() { + return performanceAllowance; + } + public void setPerformanceAllowance(long performanceAllowance) { + this.performanceAllowance = performanceAllowance; + } + public LocationRecordType getRecordType() { + return recordType; + } + public void setRecordType(LocationRecordType recordType) { + this.recordType = recordType; + } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (arrival ^ (arrival >>> 32)); + result = prime * result + (int) (departure ^ (departure >>> 32)); + result = prime * result + (int) (engineeringAllowance ^ (engineeringAllowance >>> 32)); + result = prime * result + ((line == null) ? 0 : line.hashCode()); + result = prime * result + (int) (pass ^ (pass >>> 32)); + result = prime * result + ((path == null) ? 0 : path.hashCode()); + result = prime * result + (int) (pathingAllowance ^ (pathingAllowance >>> 32)); + result = prime * result + (int) (performanceAllowance ^ (performanceAllowance >>> 32)); + result = prime * result + ((platform == null) ? 0 : platform.hashCode()); + result = prime * result + (int) (pubArrival ^ (pubArrival >>> 32)); + result = prime * result + (int) (pubDeparture ^ (pubDeparture >>> 32)); + result = prime * result + ((recordType == null) ? 0 : recordType.hashCode()); + result = prime * result + ((tiplocCode == null) ? 0 : tiplocCode.hashCode()); + result = prime * result + tiplocInstance; + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TrainScheduleLocation other = (TrainScheduleLocation) obj; + if (arrival != other.arrival) + return false; + if (departure != other.departure) + return false; + if (engineeringAllowance != other.engineeringAllowance) + return false; + if (line == null) { + if (other.line != null) + return false; + } else if (!line.equals(other.line)) + return false; + if (pass != other.pass) + return false; + if (path == null) { + if (other.path != null) + return false; + } else if (!path.equals(other.path)) + return false; + if (pathingAllowance != other.pathingAllowance) + return false; + if (performanceAllowance != other.performanceAllowance) + return false; + if (platform == null) { + if (other.platform != null) + return false; + } else if (!platform.equals(other.platform)) + return false; + if (pubArrival != other.pubArrival) + return false; + if (pubDeparture != other.pubDeparture) + return false; + if (recordType != other.recordType) + return false; + if (tiplocCode == null) { + if (other.tiplocCode != null) + return false; + } else if (!tiplocCode.equals(other.tiplocCode)) + return false; + if (tiplocInstance != other.tiplocInstance) + return false; + return true; + } + +} diff --git a/src/org/leolo/rail/model/package-info.java b/src/org/leolo/rail/model/package-info.java new file mode 100644 index 0000000..677c706 --- /dev/null +++ b/src/org/leolo/rail/model/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author user + * + */ +package org.leolo.rail.model; \ No newline at end of file