001package jmri.jmrit.operations.rollingstock.cars; 002 003import org.jdom2.Element; 004import org.slf4j.Logger; 005import org.slf4j.LoggerFactory; 006 007import jmri.InstanceManager; 008import jmri.InstanceManagerAutoDefault; 009import jmri.jmrit.operations.rollingstock.RollingStockAttribute; 010import jmri.jmrit.operations.setup.Setup; 011 012/** 013 * Represents the types of cars a railroad can have. 014 * 015 * @author Daniel Boudreau Copyright (C) 2008, 2014 016 */ 017public class CarTypes extends RollingStockAttribute implements InstanceManagerAutoDefault { 018 019 private static final String TYPES = Bundle.getMessage("carTypeNames"); 020 private static final String CONVERT_TYPES = Bundle.getMessage("carTypeConvert"); // Used to convert from ARR to 021 // Descriptive 022 private static final String ARR_TYPES = Bundle.getMessage("carTypeARR"); 023 // for property change 024 public static final String CARTYPES_CHANGED_PROPERTY = "CarTypes Length"; // NOI18N 025 public static final String CARTYPES_NAME_CHANGED_PROPERTY = "CarTypes Name"; // NOI18N 026 027 public CarTypes() { 028 } 029 030 @Override 031 protected String getDefaultNames() { 032 if (Setup.getCarTypes().equals(Setup.AAR)) { 033 return ARR_TYPES; 034 } 035 return TYPES; 036 } 037 038 /** 039 * Changes the car types from descriptive to AAR, or the other way. Only 040 * removes the default car type names from the list 041 * @param type Setup.DESCRIPTIVE or Setup.AAR 042 */ 043 public void changeDefaultNames(String type) { 044 String[] convert = CONVERT_TYPES.split(","); // NOI18N 045 String[] types = TYPES.split(","); // NOI18N 046 // this conversion has internationalization problems, so we can't call 047 // this an error. 048 if (convert.length != types.length) { 049 log.warn( 050 "Properties file doesn't have equal length conversion strings, carTypeNames {}, carTypeConvert {}", // NOI18N 051 types.length, convert.length); 052 return; 053 } 054 if (type.equals(Setup.DESCRIPTIVE)) { 055 // first replace the types 056 for (int i = 0; i < convert.length; i++) { 057 replaceName(convert[i], types[i]); 058 } 059 // remove AAR types 060 String[] aarTypes = ARR_TYPES.split(","); // NOI18N 061 for (int i = 0; i < aarTypes.length; i++) { 062 list.remove(aarTypes[i]); 063 } 064 // add descriptive types 065 for (int i = 0; i < types.length; i++) { 066 if (!list.contains(types[i])) { 067 list.add(types[i]); 068 } 069 } 070 } else { 071 // first replace the types 072 for (int i = 0; i < convert.length; i++) { 073 replaceName(types[i], convert[i]); 074 } 075 // remove descriptive types 076 for (int i = 0; i < types.length; i++) { 077 list.remove(types[i]); 078 } 079 // add AAR types 080 types = ARR_TYPES.split(","); // NOI18N 081 for (int i = 0; i < types.length; i++) { 082 if (!list.contains(types[i])) { 083 list.add(types[i]); 084 } 085 } 086 } 087 } 088 089 @Override 090 public void addName(String type) { 091 super.addName(type); 092 setDirtyAndFirePropertyChange(CARTYPES_CHANGED_PROPERTY, null, type); 093 } 094 095 @Override 096 public void deleteName(String type) { 097 super.deleteName(type); 098 setDirtyAndFirePropertyChange(CARTYPES_CHANGED_PROPERTY, type, null); 099 } 100 101 public void replaceName(String oldName, String newName) { 102 super.addName(newName); 103 setDirtyAndFirePropertyChange(CARTYPES_NAME_CHANGED_PROPERTY, oldName, newName); 104 // need to keep old name so location manager can replace properly 105 super.deleteName(oldName); 106 } 107 108 /** 109 * Get the maximum character length of a car type when printing on a 110 * manifest or switch list. Car "subtypes" or characters after the hyphen are 111 * ignored. 112 * 113 * @return the maximum character length of a car type 114 */ 115 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings( value="SLF4J_FORMAT_SHOULD_BE_CONST", 116 justification="I18N of Info Message") 117 @Override 118 public int getMaxNameLength() { 119 if (maxNameSubStringLength == 0) { 120 super.getMaxNameSubStringLength(); 121 log.info(Bundle.getMessage("InfoMaxType", maxName, maxNameSubStringLength)); 122 } 123 return maxNameSubStringLength; 124 } 125 126 /** 127 * Get the maximum character length of a car type including the sub type 128 * characters. 129 * 130 * @return the maximum character length of a car type 131 */ 132 public int getMaxFullNameLength() { 133 return super.getMaxNameLength(); 134 } 135 136 /** 137 * Create an XML element to represent this Entry. This member has to remain 138 * synchronized with the detailed DTD in operations-cars.dtd. 139 * @param root The common Element for operations-cars.dtd. 140 * 141 */ 142 public void store(Element root) { 143 store(root, Xml.TYPES, Xml.TYPE); 144 } 145 146 public void load(Element root) { 147 load(root, Xml.TYPES, Xml.TYPE, Xml.CAR_TYPES); 148 } 149 150 protected void setDirtyAndFirePropertyChange(String p, Object old, Object n) { 151 // Set dirty 152 InstanceManager.getDefault(CarManagerXml.class).setDirty(true); 153 super.firePropertyChange(p, old, n); 154 } 155 156 private final static Logger log = LoggerFactory.getLogger(CarTypes.class); 157 158}