001package jmri.jmrit.operations.locations.divisions; 002 003import java.util.*; 004 005import javax.swing.JComboBox; 006 007import org.jdom2.Element; 008import org.slf4j.Logger; 009import org.slf4j.LoggerFactory; 010 011import jmri.*; 012import jmri.beans.PropertyChangeSupport; 013import jmri.jmrit.operations.OperationsPanel; 014import jmri.jmrit.operations.locations.LocationManagerXml; 015import jmri.jmrit.operations.trains.TrainManifestHeaderText; 016 017/** 018 * Manages divisions. 019 * 020 * @author Bob Jacobsen Copyright (C) 2003 021 * @author Daniel Boudreau Copyright (C) 2021 022 */ 023public class DivisionManager extends PropertyChangeSupport implements InstanceManagerAutoDefault, InstanceManagerAutoInitialize { 024 025 public static final String LISTLENGTH_CHANGED_PROPERTY = "divisionsListLength"; // NOI18N 026 027 public DivisionManager() { 028 } 029 030 private int _id = 0; 031 032 public void dispose() { 033 _divisionHashTable.clear(); 034 _id = 0; 035 } 036 037 protected Hashtable<String, Division> _divisionHashTable = new Hashtable<String, Division>(); 038 039 /** 040 * @return Number of divisions 041 */ 042 public int getNumberOfdivisions() { 043 return _divisionHashTable.size(); 044 } 045 046 /** 047 * @param name The string name of the Division to get. 048 * @return requested Division object or null if none exists 049 */ 050 public Division getDivisionByName(String name) { 051 Division Division; 052 Enumeration<Division> en = _divisionHashTable.elements(); 053 while (en.hasMoreElements()) { 054 Division = en.nextElement(); 055 if (Division.getName().equals(name)) { 056 return Division; 057 } 058 } 059 return null; 060 } 061 062 public Division getDivisionById(String id) { 063 return _divisionHashTable.get(id); 064 } 065 066 /** 067 * Finds an existing Division or creates a new Division if needed requires 068 * Division's name creates a unique id for this Division 069 * 070 * @param name The string name for a new Division. 071 * 072 * 073 * @return new Division or existing Division 074 */ 075 public Division newDivision(String name) { 076 Division division = getDivisionByName(name); 077 if (division == null) { 078 _id++; 079 division = new Division(Integer.toString(_id), name); 080 Integer oldSize = Integer.valueOf(_divisionHashTable.size()); 081 _divisionHashTable.put(division.getId(), division); 082 setDirtyAndFirePropertyChange(LISTLENGTH_CHANGED_PROPERTY, oldSize, 083 Integer.valueOf(_divisionHashTable.size())); 084 } 085 return division; 086 } 087 088 /** 089 * Remember a NamedBean Object created outside the manager. 090 * 091 * @param division The Division to add. 092 */ 093 public void register(Division division) { 094 Integer oldSize = Integer.valueOf(_divisionHashTable.size()); 095 _divisionHashTable.put(division.getId(), division); 096 // find last id created 097 int id = Integer.parseInt(division.getId()); 098 if (id > _id) { 099 _id = id; 100 } 101 setDirtyAndFirePropertyChange(LISTLENGTH_CHANGED_PROPERTY, oldSize, Integer.valueOf(_divisionHashTable.size())); 102 } 103 104 /** 105 * Forget a NamedBean Object created outside the manager. 106 * 107 * @param division The Division to delete. 108 */ 109 public void deregister(Division division) { 110 if (division == null) { 111 return; 112 } 113 Integer oldSize = Integer.valueOf(_divisionHashTable.size()); 114 _divisionHashTable.remove(division.getId()); 115 setDirtyAndFirePropertyChange(LISTLENGTH_CHANGED_PROPERTY, oldSize, Integer.valueOf(_divisionHashTable.size())); 116 } 117 118 /** 119 * Sort by Division name 120 * 121 * @return list of divisions ordered by name 122 */ 123 public List<Division> getDivisionsByNameList() { 124 // first get id list 125 List<Division> sortList = getList(); 126 // now re-sort 127 List<Division> out = new ArrayList<Division>(); 128 for (Division division : sortList) { 129 for (int j = 0; j < out.size(); j++) { 130 if (division.getName().compareToIgnoreCase(out.get(j).getName()) < 0) { 131 out.add(j, division); 132 break; 133 } 134 } 135 if (!out.contains(division)) { 136 out.add(division); 137 } 138 } 139 return out; 140 141 } 142 143 /** 144 * Sort by Division id 145 * 146 * @return list of divisions ordered by id numbers 147 */ 148 public List<Division> getDivisionsByIdList() { 149 List<Division> sortList = getList(); 150 // now re-sort 151 List<Division> out = new ArrayList<Division>(); 152 for (Division Division : sortList) { 153 for (int j = 0; j < out.size(); j++) { 154 try { 155 if (Integer.parseInt(Division.getId()) < Integer.parseInt(out.get(j).getId())) { 156 out.add(j, Division); 157 break; 158 } 159 } catch (NumberFormatException e) { 160 log.debug("list id number isn't a number"); 161 } 162 } 163 if (!out.contains(Division)) { 164 out.add(Division); 165 } 166 } 167 return out; 168 } 169 170 /** 171 * Gets an unsorted list of all divisions. 172 * 173 * @return All divisions. 174 */ 175 public List<Division> getList() { 176 List<Division> out = new ArrayList<Division>(); 177 Enumeration<Division> en = _divisionHashTable.elements(); 178 while (en.hasMoreElements()) { 179 out.add(en.nextElement()); 180 } 181 return out; 182 } 183 184 /** 185 * 186 * @return ComboBox with divisions for this railroad 187 */ 188 public JComboBox<Division> getComboBox() { 189 JComboBox<Division> box = new JComboBox<>(); 190 updateComboBox(box); 191 OperationsPanel.padComboBox(box); 192 return box; 193 } 194 195 public void updateComboBox(JComboBox<Division> box) { 196 box.removeAllItems(); 197 box.addItem(null); 198 for (Division division : getDivisionsByNameList()) { 199 box.addItem(division); 200 } 201 } 202 203 protected int _maxDivisionNameLength = 0; 204 205 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings( value="SLF4J_FORMAT_SHOULD_BE_CONST", 206 justification="I18N of Info Message") 207 public int getMaxDivisionNameLength() { 208 String maxName = TrainManifestHeaderText.getStringHeader_Division(); 209 for (Division div : getList()) { 210 if (div.getName().length() > maxName.length()) { 211 maxName = div.getName(); 212 } 213 } 214 if (maxName.length() != _maxDivisionNameLength) { 215 log.info(Bundle.getMessage("InfoMaxDivisionName", maxName, maxName.length())); 216 _maxDivisionNameLength = maxName.length(); 217 } 218 return _maxDivisionNameLength; 219 } 220 221 public void load(Element root) { 222 if (root.getChild(Xml.DIVISIONS) != null) { 223 List<Element> divisions = root.getChild(Xml.DIVISIONS).getChildren(Xml.DIVISION); 224 log.debug("readFile sees {} divisions", divisions.size()); 225 for (Element division : divisions) { 226 register(new Division(division)); 227 } 228 } 229 } 230 231 public void store(Element root) { 232 Element values; 233 root.addContent(values = new Element(Xml.DIVISIONS)); 234 // add entries 235 List<Division> DivisionList = getDivisionsByNameList(); 236 for (Division division : DivisionList) { 237 values.addContent(division.store()); 238 } 239 } 240 241 protected void setDirtyAndFirePropertyChange(String p, Object old, Object n) { 242 // set dirty 243 InstanceManager.getDefault(LocationManagerXml.class).setDirty(true); 244 firePropertyChange(p, old, n); 245 } 246 247 private final static Logger log = LoggerFactory.getLogger(DivisionManager.class); 248 249 @Override 250 public void initialize() { 251 // do nothing 252 } 253}