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