001package jmri.jmrit.operations.rollingstock.cars.tools; 002 003import java.io.*; 004 005import jmri.IdTagManager; 006import jmri.InstanceManager; 007import jmri.jmrit.operations.locations.*; 008import jmri.jmrit.operations.locations.divisions.Division; 009import jmri.jmrit.operations.locations.divisions.DivisionManager; 010import jmri.jmrit.operations.rollingstock.ImportRollingStock; 011import jmri.jmrit.operations.rollingstock.RollingStock; 012import jmri.jmrit.operations.rollingstock.cars.*; 013import jmri.jmrit.operations.setup.Control; 014import jmri.jmrit.operations.setup.Setup; 015import jmri.jmrit.operations.trains.*; 016import jmri.util.swing.JmriJOptionPane; 017 018/** 019 * This routine will import cars into the operation database. Each field is 020 * space or comma delimited. Field order: Number Road Type Length Weight Color 021 * Owner Built Location - Track. If a CSV file, the import will accept these 022 * additional fields: Load Kernel Moves Value Comment Miscellaneous Extensions 023 * 024 * @author Dan Boudreau Copyright (C) 2008 2010 2011, 2013, 2016, 2021, 2024 025 */ 026public class ImportCars extends ImportRollingStock { 027 028 CarManager carManager = InstanceManager.getDefault(CarManager.class); 029 030 private int weightResults = JmriJOptionPane.NO_OPTION; 031 private boolean autoCalculate = true; 032 private boolean askAutoCreateTypes = true; 033 private boolean askAutoCreateLocations = true; 034 private boolean askAutoCreateTracks = true; 035 private boolean askAutoLocationType = true; 036 private boolean askAutoIncreaseTrackLength = true; 037 private boolean askAutoForceCar = true; 038 039 private boolean autoCreateTypes = false; 040 private boolean autoCreateLocations = false; 041 private boolean autoCreateTracks = false; 042 private boolean autoAdjustLocationType = false; 043 private boolean autoAdjustTrackLength = false; 044 private boolean autoForceCar = false; 045 046 private final boolean autoCreateRoads = true; 047 private final boolean autoCreateLoads = true; 048 private final boolean autoCreateLengths = true; 049 private final boolean autoCreateColors = true; 050 private final boolean autoCreateOwners = true; 051 052 // see ExportCars for column numbers 053 private static final int CAR_NUMBER = 0; 054 private static final int CAR_ROAD = 1; 055 private static final int CAR_TYPE = 2; 056 private static final int CAR_LENGTH = 3; 057 private static final int CAR_WEIGHT = 4; 058 private static final int CAR_COLOR = 5; 059 private static final int CAR_OWNER = 6; 060 private static final int CAR_BUILT = 7; 061 private static final int CAR_LOCATION = 8; 062 private static final int CAR_LOCATION_TRACK_SEPARATOR = 9; 063 private static final int CAR_TRACK = 10; 064 065 // only for CSV files 066 private static final int CAR_LOAD = 11; 067 private static final int CAR_KERNEL = 12; 068 private static final int CAR_MOVES = 13; 069 private static final int CAR_VALUE = 14; 070 private static final int CAR_COMMENT = 15; 071 private static final int CAR_MISCELLANEOUS = 16; 072 private static final int CAR_EXTENSIONS = 17; 073 074 // private static final int CAR_WAIT = 18; 075 // private static final int CAR_PICKUP_SCH = 19; 076 // private static final int CAR_LAST = 20; 077 078 private static final int CAR_RWE_DESTINATION = 21; 079 private static final int CAR_RWE_TRACK = 23; 080 private static final int CAR_RWE_LOAD = 24; 081 082 private static final int CAR_RWL_DESTINATION = 25; 083 private static final int CAR_RWL_TRACK = 27; 084 private static final int CAR_RWL_LOAD = 28; 085 086 private static final int CAR_DIVISION = 29; 087 private static final int CAR_TRAIN = 30; 088 089 private static final int CAR_DESTINATION = 31; 090 private static final int CAR_DEST_TRACK = 33; 091 092 private static final int CAR_FINAL_DESTINATION = 34; 093 private static final int CAR_FINAL_TRACK = 36; 094 private static final int CAR_SCH_ID = 37; 095 096 private static final int CAR_RFID_TAG = 38; 097 098 // we use a thread so the status frame will work! 099 @Override 100 public void run() { 101 File file = getFile(); 102 if (file == null) { 103 return; 104 } 105 BufferedReader in = getBufferedReader(file); 106 if (in == null) { 107 return; 108 } 109 110 createStatusFrame(Bundle.getMessage("ImportCars")); 111 112 // Now read the input file 113 boolean importOkay = false; 114 boolean comma = false; 115 boolean importKernel = false; 116 int lineNum = 0; 117 int carsAdded = 0; 118 String line = " "; 119 String carNumber; 120 String carRoad; 121 String carType; 122 String carLength; 123 String carWeight; 124 String carColor = ""; 125 String carOwner = ""; 126 String carBuilt = ""; 127 String carLocationName = ""; 128 String carTrackName = ""; 129 String carLoadName = ""; 130 String carKernelName = ""; 131 int carMoves = 0; 132 String carValue = ""; 133 String carComment = ""; 134 String[] inputLine; 135 136 // does the file name end with .csv? 137 if (file.getAbsolutePath().endsWith(".csv")) { // NOI18N 138 log.info("Using comma as delimiter for import cars"); 139 comma = true; 140 } 141 142 while (true) { 143 lineNumber.setText(Bundle.getMessage("LineNumber") + " " + Integer.toString(++lineNum)); 144 try { 145 line = in.readLine(); 146 } catch (IOException e) { 147 break; 148 } 149 150 if (line == null) { 151 importOkay = true; 152 break; 153 } 154 155 // has user canceled import? 156 if (!fstatus.isShowing()) { 157 break; 158 } 159 160 line = line.trim(); 161 log.debug("Import: {}", line); 162 importLine.setText(line); 163 164 if (line.startsWith(Bundle.getMessage("Number"))) { 165 continue; // skip header 166 } 167 if (line.equalsIgnoreCase("kernel")) { // NOI18N 168 log.info("Importing kernel names"); 169 importKernel = true; 170 continue; 171 } 172 if (line.equalsIgnoreCase("comma")) { // NOI18N 173 log.info("Using comma as delimiter for import cars"); 174 comma = true; 175 continue; 176 } 177 // use comma as delimiter if found otherwise use spaces 178 if (comma) { 179 inputLine = parseCommaLine(line); 180 } else { 181 inputLine = line.split("\\s+"); // NOI18N 182 } 183 if (inputLine.length < 1 || line.isEmpty()) { 184 log.debug("Skipping blank line"); 185 continue; 186 } 187 int base = 1; 188 if (comma || !inputLine[0].isEmpty()) { 189 base--; // skip over any spaces at start of line 190 } 191 192 // The minimum import is car number, road, type and length 193 if (inputLine.length > base + 3) { 194 195 carNumber = inputLine[base + CAR_NUMBER].trim(); 196 carRoad = inputLine[base + CAR_ROAD].trim(); 197 carType = inputLine[base + CAR_TYPE].trim(); 198 carLength = inputLine[base + CAR_LENGTH].trim(); 199 carWeight = "0"; 200 carColor = ""; 201 carOwner = ""; 202 carBuilt = ""; 203 carLocationName = ""; 204 carTrackName = ""; 205 carLoadName = InstanceManager.getDefault(CarLoads.class).getDefaultEmptyName(); 206 carKernelName = ""; 207 carMoves = 0; 208 carValue = ""; 209 carComment = ""; 210 211 if (inputLine.length > base + CAR_WEIGHT) { 212 carWeight = inputLine[base + CAR_WEIGHT].trim(); 213 } 214 if (inputLine.length > base + CAR_COLOR) { 215 carColor = inputLine[base + CAR_COLOR].trim(); 216 } 217 218 log.debug("Checking car number ({}) road ({}) type ({}) length ({}) weight ({}) color ({})", carNumber, 219 carRoad, carType, carLength, carWeight, carColor); // NOI18N 220 221 if (carNumber.isEmpty()) { 222 log.info("Import line {} missing car number", lineNum); 223 JmriJOptionPane.showMessageDialog(null, 224 Bundle.getMessage("RoadNumberNotSpecified", lineNum), 225 Bundle.getMessage("RoadNumberMissing"), JmriJOptionPane.ERROR_MESSAGE); 226 break; 227 } 228 if (carRoad.isEmpty()) { 229 log.info("Import line {} missing car road", lineNum); 230 JmriJOptionPane.showMessageDialog(null, 231 Bundle.getMessage("RoadNameNotSpecified", lineNum), 232 Bundle.getMessage("RoadNameMissing"), JmriJOptionPane.ERROR_MESSAGE); 233 break; 234 } 235 if (carType.isEmpty()) { 236 log.info("Import line {} missing car type", lineNum); 237 JmriJOptionPane.showMessageDialog(null, 238 Bundle.getMessage("CarTypeNotSpecified", carRoad, carNumber, lineNum), 239 Bundle.getMessage("CarTypeMissing"), JmriJOptionPane.ERROR_MESSAGE); 240 break; 241 } 242 if (carLength.isEmpty()) { 243 log.info("Import line {} missing car length", lineNum); 244 JmriJOptionPane.showMessageDialog(null, 245 Bundle.getMessage("CarLengthNotSpecified", carRoad, carNumber, lineNum), 246 Bundle.getMessage("CarLengthMissing"), JmriJOptionPane.ERROR_MESSAGE); 247 break; 248 } 249 if (TrainCommon.splitString(carNumber).length() > Control.max_len_string_road_number) { 250 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("CarRoadNumberTooLong", 251 carRoad, carNumber, carNumber), 252 Bundle.getMessage("RoadNumMustBeLess", 253 Control.max_len_string_road_number + 1), 254 JmriJOptionPane.ERROR_MESSAGE); 255 break; 256 } 257 if (TrainCommon.splitString(carRoad).length() > Control.max_len_string_attibute) { 258 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("CarRoadNameTooLong", 259 carRoad, carNumber, carRoad), 260 Bundle.getMessage("carAttribute", 261 Control.max_len_string_attibute), 262 JmriJOptionPane.ERROR_MESSAGE); 263 break; 264 } 265 if (TrainCommon.splitString(carType).length() > Control.max_len_string_attibute) { 266 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("CarTypeNameTooLong", 267 carRoad, carNumber, carType), 268 Bundle.getMessage("carAttribute", 269 Control.max_len_string_attibute), 270 JmriJOptionPane.ERROR_MESSAGE); 271 break; 272 } 273 if (!InstanceManager.getDefault(CarTypes.class).containsName(carType)) { 274 if (autoCreateTypes) { 275 log.debug("Adding car type ({})", carType); 276 InstanceManager.getDefault(CarTypes.class).addName(carType); 277 } else { 278 int results = JmriJOptionPane.showConfirmDialog(null, Bundle.getMessage("Car") + 279 " (" + 280 carRoad + 281 " " + 282 carNumber + 283 ")" + 284 NEW_LINE + 285 Bundle.getMessage("typeNameNotExist", carType), 286 Bundle.getMessage("carAddType"), JmriJOptionPane.YES_NO_CANCEL_OPTION); 287 if (results == JmriJOptionPane.YES_OPTION) { 288 InstanceManager.getDefault(CarTypes.class).addName(carType); 289 if (askAutoCreateTypes) { 290 results = JmriJOptionPane.showConfirmDialog(null, 291 Bundle.getMessage("DoYouWantToAutoAddCarTypes"), 292 Bundle.getMessage("OnlyAskedOnce"), 293 JmriJOptionPane.YES_NO_OPTION); 294 if (results == JmriJOptionPane.YES_OPTION) { 295 autoCreateTypes = true; 296 } 297 } 298 askAutoCreateTypes = false; 299 } else if (results == JmriJOptionPane.CANCEL_OPTION) { 300 break; 301 } 302 } 303 } 304 if (carLength.length() > Control.max_len_string_length_name) { 305 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("CarLengthNameTooLong", 306 carRoad, carNumber, carLength), 307 Bundle.getMessage("carAttribute", 308 Control.max_len_string_length_name), 309 JmriJOptionPane.ERROR_MESSAGE); 310 break; 311 } 312 try { 313 Integer.parseInt(carLength); 314 } catch (NumberFormatException e) { 315 JmriJOptionPane.showMessageDialog( 316 null, Bundle.getMessage("CarLengthNameNotNumber", 317 carRoad, carNumber, carLength), 318 Bundle.getMessage("CarLengthMissing"), JmriJOptionPane.ERROR_MESSAGE); 319 break; 320 } 321 if (carWeight.length() > Control.max_len_string_weight_name) { 322 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("CarWeightNameTooLong", 323 carRoad, carNumber, carWeight), 324 Bundle.getMessage("carAttribute", 325 Control.max_len_string_weight_name), 326 JmriJOptionPane.ERROR_MESSAGE); 327 break; 328 } 329 if (carColor.length() > Control.max_len_string_attibute) { 330 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("CarColorNameTooLong", 331 carRoad, carNumber, carColor), 332 Bundle.getMessage("carAttribute", 333 Control.max_len_string_attibute), 334 JmriJOptionPane.ERROR_MESSAGE); 335 break; 336 } 337 // calculate car weight if "0" 338 if (carWeight.equals("0")) { 339 try { 340 carWeight = CarManager.calculateCarWeight(carLength); // ounces. 341 } catch (NumberFormatException e) { 342 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("carLengthMustBe"), Bundle 343 .getMessage("carWeigthCanNot"), JmriJOptionPane.ERROR_MESSAGE); 344 } 345 } 346 Car existingCar = carManager.getByRoadAndNumber(carRoad, carNumber); 347 if (existingCar != null) { 348 log.info("Can not add, car number ({}) road ({}) already exists!", carNumber, carRoad); // NOI18N 349 continue; 350 } 351 if (inputLine.length > base + CAR_OWNER) { 352 carOwner = inputLine[base + CAR_OWNER].trim(); 353 if (carOwner.length() > Control.max_len_string_attibute) { 354 JmriJOptionPane.showMessageDialog(null, Bundle 355 .getMessage("CarOwnerNameTooLong", 356 carRoad, carNumber, carOwner), 357 Bundle.getMessage("carAttribute", 358 Control.max_len_string_attibute), 359 JmriJOptionPane.ERROR_MESSAGE); 360 break; 361 } 362 } 363 if (inputLine.length > base + CAR_BUILT) { 364 carBuilt = inputLine[base + CAR_BUILT].trim(); 365 if (carBuilt.length() > Control.max_len_string_built_name) { 366 JmriJOptionPane.showMessageDialog( 367 null, Bundle.getMessage("CarBuiltNameTooLong", 368 carRoad, carNumber, carBuilt), 369 Bundle.getMessage("carAttribute", 370 Control.max_len_string_built_name), 371 JmriJOptionPane.ERROR_MESSAGE); 372 break; 373 } 374 } 375 if (inputLine.length > base + CAR_LOCATION) { 376 carLocationName = inputLine[base + CAR_LOCATION].trim(); 377 } 378 if (comma && inputLine.length > base + CAR_TRACK) { 379 carTrackName = inputLine[base + CAR_TRACK].trim(); 380 } 381 // Location and track name can be one or more words in a 382 // space delimited file 383 if (!comma) { 384 int j = 0; 385 StringBuffer name = new StringBuffer(carLocationName); 386 for (int i = base + CAR_LOCATION_TRACK_SEPARATOR; i < inputLine.length; i++) { 387 if (inputLine[i].equals(LOCATION_TRACK_SEPARATOR)) { 388 j = i + 1; 389 break; 390 } else { 391 name.append(" " + inputLine[i]); 392 } 393 } 394 carLocationName = name.toString(); 395 log.debug("Car ({} {}) has location ({})", carRoad, carNumber, carLocationName); 396 // now get the track name 397 name = new StringBuffer(); 398 if (j != 0 && j < inputLine.length) { 399 name.append(inputLine[j]); 400 for (int i = j + 1; i < inputLine.length; i++) { 401 name.append(" " + inputLine[i]); 402 } 403 log.debug("Car ({} {}) has track ({})", carRoad, carNumber, carTrackName); 404 } 405 carTrackName = name.toString(); 406 } 407 408 // is there a load name? 409 if (comma && inputLine.length > CAR_LOAD) { 410 if (!inputLine[CAR_LOAD].isBlank()) { 411 carLoadName = inputLine[CAR_LOAD].trim(); 412 log.debug("Car ({} {}) has load ({})", carRoad, carNumber, carLoadName); 413 } 414 if (carLoadName.length() > Control.max_len_string_attibute) { 415 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("CarLoadNameTooLong", 416 carRoad, carNumber, carLoadName), 417 Bundle.getMessage("carAttribute", 418 Control.max_len_string_attibute), 419 JmriJOptionPane.ERROR_MESSAGE); 420 break; 421 } 422 } 423 // is there a kernel name? 424 if (comma && inputLine.length > CAR_KERNEL) { 425 carKernelName = inputLine[CAR_KERNEL].trim(); 426 log.debug("Car ({} {}) has kernel name ({})", carRoad, carNumber, carKernelName); 427 } 428 // is there a move count? 429 if (comma && inputLine.length > CAR_MOVES) { 430 if (!inputLine[CAR_MOVES].trim().isEmpty()) { 431 try { 432 carMoves = Integer.parseInt(inputLine[CAR_MOVES].trim()); 433 log.debug("Car ({} {}) has move count ({})", carRoad, carNumber, carMoves); 434 } catch (NumberFormatException e) { 435 log.error("Car ({} {}) has move count ({}) not a number", carRoad, carNumber, carMoves); 436 } 437 } 438 } 439 // is there a car value? 440 if (comma && inputLine.length > CAR_VALUE) { 441 carValue = inputLine[CAR_VALUE].trim(); 442 } 443 // is there a car comment? 444 if (comma && inputLine.length > CAR_COMMENT) { 445 carComment = inputLine[CAR_COMMENT]; 446 } 447 448 if (TrainCommon.splitString(carLocationName).length() > Control.max_len_string_location_name) { 449 JmriJOptionPane.showMessageDialog( 450 null, Bundle.getMessage("CarLocationNameTooLong", 451 carRoad, carNumber, carLocationName), 452 Bundle.getMessage("carAttribute", 453 Control.max_len_string_location_name), 454 JmriJOptionPane.ERROR_MESSAGE); 455 break; 456 } 457 if (TrainCommon.splitString(carTrackName).length() > Control.max_len_string_track_name) { 458 JmriJOptionPane.showMessageDialog(null, Bundle 459 .getMessage("CarTrackNameTooLong", 460 carRoad, carNumber, carTrackName), 461 Bundle.getMessage("carAttribute", 462 Control.max_len_string_track_name), 463 JmriJOptionPane.ERROR_MESSAGE); 464 break; 465 } 466 Location location = 467 InstanceManager.getDefault(LocationManager.class).getLocationByName(carLocationName); 468 Track track = null; 469 if (location == null && !carLocationName.isEmpty()) { 470 if (autoCreateLocations) { 471 log.debug("Create location ({})", carLocationName); 472 location = InstanceManager.getDefault(LocationManager.class).newLocation(carLocationName); 473 } else { 474 JmriJOptionPane.showMessageDialog(null, Bundle 475 .getMessage("CarLocationDoesNotExist", 476 carRoad, carNumber, carLocationName), 477 Bundle.getMessage("carLocation"), JmriJOptionPane.ERROR_MESSAGE); 478 int results = JmriJOptionPane.showConfirmDialog(null, Bundle 479 .getMessage("DoYouWantToCreateLoc", carLocationName), 480 Bundle 481 .getMessage("carLocation"), 482 JmriJOptionPane.YES_NO_OPTION); 483 if (results == JmriJOptionPane.YES_OPTION) { 484 log.debug("Create location ({})", carLocationName); 485 location = 486 InstanceManager.getDefault(LocationManager.class).newLocation(carLocationName); 487 if (askAutoCreateLocations) { 488 results = JmriJOptionPane.showConfirmDialog(null, Bundle 489 .getMessage("DoYouWantToAutoCreateLoc"), 490 Bundle.getMessage("OnlyAskedOnce"), JmriJOptionPane.YES_NO_OPTION); 491 if (results == JmriJOptionPane.YES_OPTION) { 492 autoCreateLocations = true; 493 } 494 } 495 askAutoCreateLocations = false; 496 } else { 497 break; 498 } 499 } 500 } 501 if (location != null && !carTrackName.isEmpty()) { 502 track = location.getTrackByName(carTrackName, null); 503 if (track == null) { 504 if (autoCreateTracks) { 505 if (!location.isStaging()) { 506 log.debug("Create 1000 foot yard track ({})", carTrackName); 507 track = location.addTrack(carTrackName, Track.YARD); 508 } else { 509 log.debug("Create 1000 foot staging track ({})", carTrackName); 510 track = location.addTrack(carTrackName, Track.STAGING); 511 } 512 track.setLength(1000); 513 } else { 514 JmriJOptionPane.showMessageDialog( 515 null, Bundle.getMessage("CarTrackDoesNotExist", 516 carRoad, carNumber, carTrackName, carLocationName), 517 Bundle.getMessage("carTrack"), JmriJOptionPane.ERROR_MESSAGE); 518 int results = JmriJOptionPane.showConfirmDialog(null, 519 Bundle.getMessage("DoYouWantToCreateTrack", 520 carTrackName, carLocationName), 521 Bundle.getMessage("carTrack"), JmriJOptionPane.YES_NO_OPTION); 522 if (results == JmriJOptionPane.YES_OPTION) { 523 if (!location.isStaging()) { 524 log.debug("Create 1000 foot yard track ({})", carTrackName); 525 track = location.addTrack(carTrackName, Track.YARD); 526 } else { 527 log.debug("Create 1000 foot staging track ({})", carTrackName); 528 track = location.addTrack(carTrackName, Track.STAGING); 529 } 530 track.setLength(1000); 531 if (askAutoCreateTracks) { 532 results = JmriJOptionPane.showConfirmDialog(null, 533 Bundle.getMessage("DoYouWantToAutoCreateTrack"), 534 Bundle.getMessage("OnlyAskedOnce"), 535 JmriJOptionPane.YES_NO_OPTION); 536 if (results == JmriJOptionPane.YES_OPTION) { 537 autoCreateTracks = true; 538 } 539 askAutoCreateTracks = false; 540 } 541 } else { 542 break; 543 } 544 } 545 } 546 } 547 548 log.debug("Add car ({} {}) owner ({}) built ({}) location ({}, {})", carRoad, carNumber, carOwner, 549 carBuilt, carLocationName, carTrackName); 550 Car car = carManager.newRS(carRoad, carNumber); 551 car.setTypeName(carType); 552 car.setLength(carLength); 553 car.setWeight(carWeight); 554 car.setColor(carColor); 555 car.setOwnerName(carOwner); 556 car.setBuilt(carBuilt); 557 car.setLoadName(carLoadName); 558 car.setKernel(InstanceManager.getDefault(KernelManager.class).newKernel(carKernelName)); 559 car.setMoves(carMoves); 560 car.setValue(carValue); 561 car.setComment(carComment); 562 carsAdded++; 563 564 // if the car's type name is "Caboose" then make it a 565 // caboose 566 car.setCaboose(carType.equals("Caboose")); 567 568 // Out of Service? 569 if (comma && inputLine.length > CAR_MISCELLANEOUS) { 570 car.setOutOfService(inputLine[CAR_MISCELLANEOUS].equals(Bundle.getMessage("OutOfService"))); 571 } 572 573 // determine if there are any car extensions 574 if (comma && inputLine.length > CAR_EXTENSIONS) { 575 String extensions = inputLine[CAR_EXTENSIONS]; 576 log.debug("Car ({}) has extension ({})", car.toString(), extensions); 577 String[] ext = extensions.split(Car.EXTENSION_REGEX); 578 for (int i = 0; i < ext.length; i++) { 579 if (ext[i].equals(Car.CABOOSE_EXTENSION)) { 580 car.setCaboose(true); 581 } 582 if (ext[i].equals(Car.FRED_EXTENSION)) { 583 car.setFred(true); 584 } 585 if (ext[i].equals(Car.PASSENGER_EXTENSION)) { 586 car.setPassenger(true); 587 car.setBlocking(Integer.parseInt(ext[i + 1])); 588 } 589 if (ext[i].equals(Car.UTILITY_EXTENSION)) { 590 car.setUtility(true); 591 } 592 if (ext[i].equals(Car.HAZARDOUS_EXTENSION)) { 593 car.setCarHazardous(true); 594 } 595 } 596 } 597 598 // TODO car wait, pick up schedule, last moved 599 600 // Return When Empty 601 if (comma && inputLine.length > CAR_RWE_DESTINATION) { 602 Location rweDestination = 603 InstanceManager.getDefault(LocationManager.class) 604 .getLocationByName(inputLine[CAR_RWE_DESTINATION]); 605 606 car.setReturnWhenEmptyDestination(rweDestination); 607 if (rweDestination != null && inputLine.length > CAR_RWE_TRACK) { 608 Track rweTrack = rweDestination.getTrackByName(inputLine[CAR_RWE_TRACK], null); 609 car.setReturnWhenEmptyDestTrack(rweTrack); 610 } 611 } 612 if (comma && inputLine.length > CAR_RWE_LOAD && !inputLine[CAR_RWE_LOAD].isBlank()) { 613 car.setReturnWhenEmptyLoadName(inputLine[CAR_RWE_LOAD].trim()); 614 } 615 616 // Return When Loaded 617 if (comma && inputLine.length > CAR_RWL_DESTINATION) { 618 Location rwlDestination = 619 InstanceManager.getDefault(LocationManager.class) 620 .getLocationByName(inputLine[CAR_RWL_DESTINATION]); 621 622 car.setReturnWhenLoadedDestination(rwlDestination); 623 if (rwlDestination != null && inputLine.length > CAR_RWL_TRACK) { 624 Track rweTrack = rwlDestination.getTrackByName(inputLine[CAR_RWL_TRACK], null); 625 car.setReturnWhenLoadedDestTrack(rweTrack); 626 } 627 } 628 if (comma && inputLine.length > CAR_RWL_LOAD && !inputLine[CAR_RWL_LOAD].isBlank()) { 629 car.setReturnWhenLoadedLoadName(inputLine[CAR_RWL_LOAD].trim()); 630 } 631 632 if (comma && inputLine.length > CAR_DIVISION) { 633 Division division = InstanceManager.getDefault(DivisionManager.class) 634 .getDivisionByName(inputLine[CAR_DIVISION].trim()); 635 car.setDivision(division); 636 } 637 638 if (comma && inputLine.length > CAR_TRAIN) { 639 Train train = InstanceManager.getDefault(TrainManager.class) 640 .getTrainByName(inputLine[CAR_TRAIN].trim()); 641 car.setTrain(train); 642 } 643 644 // Destination 645 if (comma && inputLine.length > CAR_DESTINATION) { 646 Location destination = 647 InstanceManager.getDefault(LocationManager.class) 648 .getLocationByName(inputLine[CAR_DESTINATION]); 649 if (destination != null && inputLine.length > CAR_DEST_TRACK) { 650 Track destTrack = destination.getTrackByName(inputLine[CAR_DEST_TRACK], null); 651 car.setDestination(destination, destTrack); 652 } 653 } 654 655 // Final Destination 656 if (comma && inputLine.length > CAR_FINAL_DESTINATION) { 657 Location finalDestination = 658 InstanceManager.getDefault(LocationManager.class) 659 .getLocationByName(inputLine[CAR_FINAL_DESTINATION]); 660 661 car.setFinalDestination(finalDestination); 662 if (finalDestination != null && inputLine.length > CAR_FINAL_TRACK) { 663 Track finalTrack = finalDestination.getTrackByName(inputLine[CAR_FINAL_TRACK], null); 664 car.setFinalDestinationTrack(finalTrack); 665 } 666 } 667 668 // Schedule Id 669 if (comma && inputLine.length > CAR_SCH_ID) { 670 car.setScheduleItemId(inputLine[CAR_SCH_ID]); 671 } 672 673 if (comma && inputLine.length > CAR_RFID_TAG) { 674 String newTag = inputLine[CAR_RFID_TAG]; 675 if (!newTag.trim().isEmpty()) { 676 InstanceManager.getDefault(IdTagManager.class).provideIdTag(newTag); 677 log.debug("New ID tag added - {}", newTag); 678 car.setRfid(newTag); 679 } 680 } 681 682 // add new roads 683 if (!InstanceManager.getDefault(CarRoads.class).containsName(carRoad)) { 684 if (autoCreateRoads) { 685 log.debug("add car road {}", carRoad); 686 InstanceManager.getDefault(CarRoads.class).addName(carRoad); 687 } 688 } 689 690 // add new loads 691 if (!InstanceManager.getDefault(CarLoads.class).containsName(carLoadName)) { 692 if (autoCreateLoads) { 693 log.debug("add car load {}", carLoadName); 694 InstanceManager.getDefault(CarLoads.class).addName(carType, carLoadName); 695 } 696 } 697 698 // add new lengths 699 if (!InstanceManager.getDefault(CarLengths.class).containsName(carLength)) { 700 if (autoCreateLengths) { 701 log.debug("add car length {}", carLength); 702 InstanceManager.getDefault(CarLengths.class).addName(carLength); 703 } 704 } 705 706 // add new colors 707 if (!InstanceManager.getDefault(CarColors.class).containsName(carColor)) { 708 if (autoCreateColors) { 709 log.debug("add car color {}", carColor); 710 InstanceManager.getDefault(CarColors.class).addName(carColor); 711 } 712 } 713 714 // add new owners 715 if (!InstanceManager.getDefault(CarOwners.class).containsName(carOwner)) { 716 if (autoCreateOwners) { 717 log.debug("add car owner {}", carOwner); 718 InstanceManager.getDefault(CarOwners.class).addName(carOwner); 719 } 720 } 721 722 if (car.getWeight().isEmpty()) { 723 log.debug("Car ({}) weight not specified", car.toString()); 724 if (weightResults != JmriJOptionPane.CANCEL_OPTION) { 725 weightResults = JmriJOptionPane.showOptionDialog(null, 726 Bundle.getMessage("CarWeightNotFound", 727 car.toString()), 728 Bundle.getMessage("CarWeightMissing"), 729 JmriJOptionPane.DEFAULT_OPTION, // custom buttons 730 JmriJOptionPane.INFORMATION_MESSAGE, null, 731 new Object[]{ 732 Bundle.getMessage("ButtonYes"), Bundle.getMessage("ButtonNo"), 733 Bundle.getMessage("ButtonDontShow")}, 734 autoCalculate ? Bundle.getMessage("ButtonYes") : Bundle.getMessage("ButtonNo")); 735 } 736 if (weightResults == 1) { // array position 1, ButtonNo 737 autoCalculate = false; 738 } 739 if (weightResults == 0 || // array position 0, ButtonYes 740 autoCalculate == true && weightResults == 2) { // array position 2 ButtonDontShow 741 autoCalculate = true; 742 try { 743 carWeight = CarManager.calculateCarWeight(carLength); 744 car.setWeight(carWeight); 745 int tons = (int) (Double.parseDouble(carWeight) * Setup.getScaleTonRatio()); 746 // adjust weight for caboose 747 if (car.isCaboose() || car.isPassenger()) { 748 tons = (int) (Double.parseDouble(car.getLength()) * .9); 749 } 750 car.setWeightTons(Integer.toString(tons)); 751 } catch (NumberFormatException e) { 752 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("carLengthMustBe"), Bundle 753 .getMessage("carWeigthCanNot"), JmriJOptionPane.ERROR_MESSAGE); 754 } 755 } 756 } 757 758 if (location != null && track != null) { 759 String status = car.setLocation(location, track); 760 if (!status.equals(Track.OKAY)) { 761 log.debug("Can't set car's location because of {}", status); 762 if (status.startsWith(Track.TYPE)) { 763 if (autoAdjustLocationType) { 764 location.addTypeName(carType); 765 track.addTypeName(carType); 766 status = car.setLocation(location, track); 767 } else { 768 JmriJOptionPane.showMessageDialog( 769 null, Bundle.getMessage("CanNotSetCarAtLocation", 770 car.toString(), carType, carLocationName, carTrackName, 771 status), 772 Bundle.getMessage("rsCanNotLoc"), JmriJOptionPane.ERROR_MESSAGE); 773 int results = JmriJOptionPane.showConfirmDialog(null, Bundle 774 .getMessage("DoYouWantToAllowService", 775 carLocationName, carTrackName, car.toString(), carType), 776 Bundle.getMessage("ServiceCarType"), 777 JmriJOptionPane.YES_NO_OPTION); 778 if (results == JmriJOptionPane.YES_OPTION) { 779 location.addTypeName(carType); 780 track.addTypeName(carType); 781 status = car.setLocation(location, track); 782 log.debug("Set car's location status: {}", status); 783 if (askAutoLocationType) { 784 results = JmriJOptionPane.showConfirmDialog(null, 785 Bundle.getMessage("DoYouWantToAutoAdjustLocations"), 786 Bundle.getMessage("OnlyAskedOnce"), JmriJOptionPane.YES_NO_OPTION); 787 if (results == JmriJOptionPane.YES_OPTION) { 788 autoAdjustLocationType = true; 789 } 790 askAutoLocationType = false; 791 } 792 } else { 793 break; 794 } 795 } 796 } 797 if (status.startsWith(Track.LENGTH) || status.startsWith(Track.CAPACITY)) { 798 if (autoAdjustTrackLength) { 799 track.setLength(track.getLength() + 1000); 800 status = car.setLocation(location, track); 801 log.debug("Set track length status: {}", status); 802 } else { 803 JmriJOptionPane.showMessageDialog(null, Bundle 804 .getMessage("CanNotSetCarAtLocation", 805 car.toString(), carType, carLocationName, carTrackName, 806 status), 807 Bundle.getMessage("rsCanNotLoc"), JmriJOptionPane.ERROR_MESSAGE); 808 int results = JmriJOptionPane.showConfirmDialog(null, Bundle 809 .getMessage("DoYouWantIncreaseLength", carTrackName), 810 Bundle 811 .getMessage("TrackLength"), 812 JmriJOptionPane.YES_NO_OPTION); 813 if (results == JmriJOptionPane.YES_OPTION) { 814 track.setLength(track.getLength() + 1000); 815 status = car.setLocation(location, track); 816 log.debug("Set track length status: {}", status); 817 if (askAutoIncreaseTrackLength) { 818 results = JmriJOptionPane.showConfirmDialog(null, Bundle 819 .getMessage("DoYouWantToAutoAdjustTrackLength"), 820 Bundle.getMessage("OnlyAskedOnce"), 821 JmriJOptionPane.YES_NO_OPTION); 822 if (results == JmriJOptionPane.YES_OPTION) { 823 autoAdjustTrackLength = true; 824 } 825 askAutoIncreaseTrackLength = false; 826 } 827 } else { 828 break; 829 } 830 } 831 } 832 if (!status.equals(Track.OKAY)) { 833 if (autoForceCar) { 834 car.setLocation(location, track, RollingStock.FORCE); // force 835 } else { 836 JmriJOptionPane.showMessageDialog(null, Bundle 837 .getMessage("CanNotSetCarAtLocation", 838 car.toString(), carType, carLocationName, carTrackName, 839 status), 840 Bundle.getMessage("rsCanNotLoc"), JmriJOptionPane.ERROR_MESSAGE); 841 int results = JmriJOptionPane.showConfirmDialog(null, Bundle 842 .getMessage("DoYouWantToForceCar", 843 car.toString(), carLocationName, carTrackName), 844 Bundle.getMessage("OverRide"), 845 JmriJOptionPane.YES_NO_OPTION); 846 if (results == JmriJOptionPane.YES_OPTION) { 847 car.setLocation(location, track, RollingStock.FORCE); // force 848 if (askAutoForceCar) { 849 results = JmriJOptionPane.showConfirmDialog(null, Bundle 850 .getMessage("DoYouWantToAutoForceCar"), 851 Bundle.getMessage("OnlyAskedOnce"), 852 JmriJOptionPane.YES_NO_OPTION); 853 if (results == JmriJOptionPane.YES_OPTION) { 854 autoForceCar = true; 855 } 856 askAutoForceCar = false; 857 } 858 } else { 859 break; 860 } 861 } 862 } 863 } 864 } else { 865 // log.debug("No location for car ("+carRoad+" 866 // "+carNumber+")"); 867 } 868 } else if (importKernel && inputLine.length == base + 3) { 869 carNumber = inputLine[base + 0].trim(); 870 carRoad = inputLine[base + 1].trim(); 871 String kernelName = inputLine[base + 2].trim(); 872 Car car = carManager.getByRoadAndNumber(carRoad, carNumber); 873 if (car != null) { 874 Kernel kernel = InstanceManager.getDefault(KernelManager.class).newKernel(kernelName); 875 car.setKernel(kernel); 876 carsAdded++; 877 } else { 878 log.info("Car number ({}) road ({}) does not exist!", carNumber, carRoad); // NOI18N 879 break; 880 } 881 } else if (!line.isEmpty()) { 882 log.info("Car import line {} missing attributes: {}", lineNum, line); 883 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("ImportMissingAttributes", 884 lineNum) + 885 NEW_LINE + 886 line + 887 NEW_LINE + 888 Bundle.getMessage("ImportMissingAttributes2"), 889 Bundle.getMessage("CarAttributeMissing"), 890 JmriJOptionPane.ERROR_MESSAGE); 891 break; 892 } 893 } 894 try { 895 in.close(); 896 } catch (IOException e) { 897 } 898 899 if (importOkay) { 900 JmriJOptionPane 901 .showMessageDialog(null, Bundle.getMessage("ImportCarsAdded", 902 carsAdded), Bundle.getMessage("SuccessfulImport"), 903 JmriJOptionPane.INFORMATION_MESSAGE); 904 } else { 905 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("ImportCarsAdded", 906 carsAdded), Bundle.getMessage("ImportFailed"), JmriJOptionPane.ERROR_MESSAGE); 907 } 908 909 // kill status panel 910 fstatus.dispose(); 911 } 912 913 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ImportCars.class); 914}