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