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_LOCAL_MOVES_ALLOWED = 7; 042 protected static final int FIELD_ROUTE_LOCATION_TRAVEL = 8; 043 protected static final int FIELD_ROUTE_LOCATION_DEPARTURE_TIME = 9; 044 protected static final int FIELD_ROUTE_LOCATION_TRAIN_LENGTH = 10; 045 protected static final int FIELD_ROUTE_LOCATION_GRADE = 11; 046 protected static final int FIELD_ROUTE_LOCATION_ICON_X = 12; 047 protected static final int FIELD_ROUTE_LOCATION_ICON_Y = 13; 048 protected static final int FIELD_ROUTE_LOCATION_COMMENT = 14; 049 protected static final int FIELD_ROUTE_LOCATION_COMMENT_COLOR = 15; 050 051 @Override 052 public void run() { 053 File file = getFile(); 054 if (file == null) { 055 return; 056 } 057 BufferedReader rdr = getBufferedReader(file); 058 if (rdr == null) { 059 return; 060 } 061 createStatusFrame(Bundle.getMessage("TitleImportRoutes")); 062 063 String[] inputLine; 064 boolean headerFound = false; 065 Route route = null; 066 067 while (true) { 068 inputLine = readNextLine(rdr); 069 if (inputLine == BREAK) { 070 log.debug("Done"); 071 break; 072 } 073 if (inputLine.length < 1) { 074 log.debug("Skipping blank line"); 075 continue; 076 } 077 // header? 078 if (!headerFound && inputLine[FIELD_ROUTE_NAME].equals(Bundle.getMessage("Route"))) { 079 headerFound = true; 080 int elementNum = 0; 081 for (String lineElement : inputLine) { 082 log.debug("Header {} is: {}", elementNum++, lineElement); 083 } 084 continue; // skip header 085 } 086 // add route? 087 if (inputLine.length == 3) { 088 log.debug("Found start of route: {}", inputLine[FIELD_ROUTE_NAME]); 089 route = routeManager.getRouteByName(inputLine[FIELD_ROUTE_NAME]); 090 if (route != null) { 091 log.info("Route: {} already exists, will not import!", inputLine[FIELD_ROUTE_NAME]); 092 route = null; 093 } else { 094 routesAdded++; 095 route = routeManager.newRoute(inputLine[FIELD_ROUTE_NAME]); 096 log.info("Creating route: {}", inputLine[FIELD_ROUTE_NAME]); 097 route.setComment(inputLine[FIELD_ROUTE_COMMENT]); 098 } 099 } 100 // add route location? 101 if (route != null && inputLine.length == 16) { 102 log.debug("Adding route location: {}", inputLine[FIELD_ROUTE_LOCATION_NAME]); 103 Location location = locationManager.getLocationByName(inputLine[FIELD_ROUTE_LOCATION_NAME]); 104 if (location == null) { 105 log.error("Location ({}) in route ({}) does not exist", inputLine[FIELD_ROUTE_LOCATION_NAME], 106 route.getName()); 107 break; 108 } 109 RouteLocation rl = route.addLocation(location); 110 rl.setTrainDirection(Setup.getDirectionInt(inputLine[FIELD_ROUTE_LOCATION_DIRECTION])); 111 rl.setMaxCarMoves(Integer.parseInt(inputLine[FIELD_ROUTE_LOCATION_MOVES])); 112 rl.setRandomControl(inputLine[FIELD_ROUTE_LOCATION_RANDOM]); 113 rl.setPickUpAllowed(inputLine[FIELD_ROUTE_LOCATION_PICKUP_ALLOWED].equals(Bundle.getMessage("yes"))); 114 rl.setDropAllowed(inputLine[FIELD_ROUTE_LOCATION_DROP_ALLOWED].equals(Bundle.getMessage("yes"))); 115 rl.setLocalMovesAllowed( 116 inputLine[FIELD_ROUTE_LOCATION_LOCAL_MOVES_ALLOWED].equals(Bundle.getMessage("yes"))); 117 rl.setWait(Integer.parseInt(inputLine[FIELD_ROUTE_LOCATION_TRAVEL]) - Setup.getTravelTime()); 118 rl.setDepartureTime(inputLine[FIELD_ROUTE_LOCATION_DEPARTURE_TIME]); 119 rl.setMaxTrainLength(Integer.parseInt(inputLine[FIELD_ROUTE_LOCATION_TRAIN_LENGTH])); 120 rl.setGrade(Double.parseDouble(inputLine[FIELD_ROUTE_LOCATION_GRADE])); 121 rl.setTrainIconX(Integer.parseInt(inputLine[FIELD_ROUTE_LOCATION_ICON_X])); 122 rl.setTrainIconY(Integer.parseInt(inputLine[FIELD_ROUTE_LOCATION_ICON_Y])); 123 rl.setComment(inputLine[FIELD_ROUTE_LOCATION_COMMENT]); 124 rl.setCommentTextColor(inputLine[FIELD_ROUTE_LOCATION_COMMENT_COLOR]); 125 } 126 } 127 128 ThreadingUtil.runOnGUI(()->{ 129 if (importOkay) { 130 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("ImportRoutesAdded", routesAdded), 131 Bundle.getMessage("SuccessfulImport"), JmriJOptionPane.INFORMATION_MESSAGE); 132 } else { 133 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("ImportRoutesAdded", routesAdded), 134 Bundle.getMessage("ImportFailed"), JmriJOptionPane.ERROR_MESSAGE); 135 } 136 }); 137 fstatus.dispose(); 138 } 139 140 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ImportRoutes.class); 141}