001package jmri.jmrit.operations.routes.tools; 002 003import java.io.BufferedReader; 004import java.io.File; 005 006import jmri.InstanceManager; 007import jmri.jmrit.operations.locations.Location; 008import jmri.jmrit.operations.locations.LocationManager; 009import jmri.jmrit.operations.rollingstock.ImportCommon; 010import jmri.jmrit.operations.routes.*; 011import jmri.jmrit.operations.setup.Setup; 012import jmri.util.ThreadingUtil; 013import jmri.util.swing.JmriJOptionPane; 014 015/** 016 * This routine will import Routes from a CSV file into the operations database. 017 * The field order is as defined below. 018 * 019 * @author Daniel Boudreau Copyright (C) 2025 020 */ 021public class ImportRoutes extends ImportCommon { 022 023 RouteManager routeManager = InstanceManager.getDefault(RouteManager.class); 024 LocationManager locationManager = InstanceManager.getDefault(LocationManager.class); 025 026 int routesAdded = 0; 027 028 // each route starts with name and comment 029 protected static final int FIELD_ROUTE_NAME = 0; 030 protected static final int FIELD_EMPTY = 1; 031 protected static final int FIELD_ROUTE_COMMENT = 2; 032 033 // each route can have one or more route locations 034 protected static final int FIELD_ROUTE_LOCATION_EMPTY = 0; 035 protected static final int FIELD_ROUTE_LOCATION_NAME = 1; 036 protected static final int FIELD_ROUTE_LOCATION_DIRECTION = 2; 037 protected static final int FIELD_ROUTE_LOCATION_MOVES = 3; 038 protected static final int FIELD_ROUTE_LOCATION_RANDOM = 4; 039 protected static final int FIELD_ROUTE_LOCATION_PICKUP_ALLOWED = 5; 040 protected static final int FIELD_ROUTE_LOCATION_DROP_ALLOWED = 6; 041 protected static final int FIELD_ROUTE_LOCATION_TRAVEL = 7; 042 protected static final int FIELD_ROUTE_LOCATION_DEPARTURE_TIME = 8; 043 protected static final int FIELD_ROUTE_LOCATION_TRAIN_LENGTH = 9; 044 protected static final int FIELD_ROUTE_LOCATION_GRADE = 10; 045 protected static final int FIELD_ROUTE_LOCATION_ICON_X = 11; 046 protected static final int FIELD_ROUTE_LOCATION_ICON_Y = 12; 047 protected static final int FIELD_ROUTE_LOCATION_COMMENT = 13; 048 protected static final int FIELD_ROUTE_LOCATION_COMMENT_COLOR = 14; 049 050 @Override 051 public void run() { 052 File file = getFile(); 053 if (file == null) { 054 return; 055 } 056 BufferedReader rdr = getBufferedReader(file); 057 if (rdr == null) { 058 return; 059 } 060 createStatusFrame(Bundle.getMessage("TitleImportRoutes")); 061 062 String[] inputLine; 063 boolean headerFound = false; 064 Route route = null; 065 066 while (true) { 067 inputLine = readNextLine(rdr); 068 if (inputLine == BREAK) { 069 log.debug("Done"); 070 break; 071 } 072 if (inputLine.length < 1) { 073 log.debug("Skipping blank line"); 074 continue; 075 } 076 // header? 077 if (!headerFound && inputLine[FIELD_ROUTE_NAME].equals(Bundle.getMessage("Route"))) { 078 headerFound = true; 079 int elementNum = 0; 080 for (String lineElement : inputLine) { 081 log.debug("Header {} is: {}", elementNum++, lineElement); 082 } 083 continue; // skip header 084 } 085 // add route? 086 if (inputLine.length == 3) { 087 log.debug("Found start of route: {}", inputLine[FIELD_ROUTE_NAME]); 088 route = routeManager.getRouteByName(inputLine[FIELD_ROUTE_NAME]); 089 if (route != null) { 090 log.info("Route: {} already exists, will not import!", inputLine[FIELD_ROUTE_NAME]); 091 route = null; 092 } else { 093 routesAdded++; 094 route = routeManager.newRoute(inputLine[FIELD_ROUTE_NAME]); 095 log.info("Creating route: {}", inputLine[FIELD_ROUTE_NAME]); 096 route.setComment(inputLine[FIELD_ROUTE_COMMENT]); 097 } 098 } 099 // add route location? 100 if (route != null && inputLine.length == 15) { 101 log.debug("Adding route location: {}", inputLine[FIELD_ROUTE_LOCATION_NAME]); 102 Location location = locationManager.getLocationByName(inputLine[FIELD_ROUTE_LOCATION_NAME]); 103 if (location == null) { 104 log.error("Location ({}) in route ({}) does not exist", inputLine[FIELD_ROUTE_LOCATION_NAME], 105 route.getName()); 106 break; 107 } 108 RouteLocation rl = route.addLocation(location); 109 rl.setTrainDirection(Setup.getDirectionInt(inputLine[FIELD_ROUTE_LOCATION_DIRECTION])); 110 rl.setMaxCarMoves(Integer.parseInt(inputLine[FIELD_ROUTE_LOCATION_MOVES])); 111 rl.setRandomControl(inputLine[FIELD_ROUTE_LOCATION_RANDOM]); 112 rl.setPickUpAllowed(inputLine[FIELD_ROUTE_LOCATION_PICKUP_ALLOWED].equals(Bundle.getMessage("yes"))); 113 rl.setDropAllowed(inputLine[FIELD_ROUTE_LOCATION_DROP_ALLOWED].equals(Bundle.getMessage("yes"))); 114 rl.setWait(Integer.parseInt(inputLine[FIELD_ROUTE_LOCATION_TRAVEL]) - Setup.getTravelTime()); 115 rl.setDepartureTime(inputLine[FIELD_ROUTE_LOCATION_DEPARTURE_TIME]); 116 rl.setMaxTrainLength(Integer.parseInt(inputLine[FIELD_ROUTE_LOCATION_TRAIN_LENGTH])); 117 rl.setGrade(Double.parseDouble(inputLine[FIELD_ROUTE_LOCATION_GRADE])); 118 rl.setTrainIconX(Integer.parseInt(inputLine[FIELD_ROUTE_LOCATION_ICON_X])); 119 rl.setTrainIconY(Integer.parseInt(inputLine[FIELD_ROUTE_LOCATION_ICON_Y])); 120 rl.setComment(inputLine[FIELD_ROUTE_LOCATION_COMMENT]); 121 rl.setCommentTextColor(inputLine[FIELD_ROUTE_LOCATION_COMMENT_COLOR]); 122 } 123 } 124 125 ThreadingUtil.runOnGUI(()->{ 126 if (importOkay) { 127 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("ImportRoutesAdded", routesAdded), 128 Bundle.getMessage("SuccessfulImport"), JmriJOptionPane.INFORMATION_MESSAGE); 129 } else { 130 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("ImportRoutesAdded", routesAdded), 131 Bundle.getMessage("ImportFailed"), JmriJOptionPane.ERROR_MESSAGE); 132 } 133 }); 134 fstatus.dispose(); 135 } 136 137 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ImportRoutes.class); 138}