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 int oldSize = _divisionHashTable.size(); 081 _divisionHashTable.put(division.getId(), division); 082 setDirtyAndFirePropertyChange(LISTLENGTH_CHANGED_PROPERTY, oldSize, _divisionHashTable.size()); 083 } 084 return division; 085 } 086 087 /** 088 * Remember a NamedBean Object created outside the manager. 089 * 090 * @param division The Division to add. 091 */ 092 public void register(Division division) { 093 int oldSize = _divisionHashTable.size(); 094 _divisionHashTable.put(division.getId(), division); 095 // find last id created 096 int id = Integer.parseInt(division.getId()); 097 if (id > _id) { 098 _id = id; 099 } 100 setDirtyAndFirePropertyChange(LISTLENGTH_CHANGED_PROPERTY, oldSize, _divisionHashTable.size()); 101 } 102 103 /** 104 * Forget a NamedBean Object created outside the manager. 105 * 106 * @param division The Division to delete. 107 */ 108 public void deregister(Division division) { 109 if (division == null) { 110 return; 111 } 112 int oldSize = _divisionHashTable.size(); 113 _divisionHashTable.remove(division.getId()); 114 setDirtyAndFirePropertyChange(LISTLENGTH_CHANGED_PROPERTY, oldSize, _divisionHashTable.size()); 115 } 116 117 /** 118 * Sort by Division name 119 * 120 * @return list of divisions ordered by name 121 */ 122 public List<Division> getDivisionsByNameList() { 123 // first get id list 124 List<Division> sortList = getList(); 125 // now re-sort 126 List<Division> out = new ArrayList<Division>(); 127 for (Division division : sortList) { 128 for (int j = 0; j < out.size(); j++) { 129 if (division.getName().compareToIgnoreCase(out.get(j).getName()) < 0) { 130 out.add(j, division); 131 break; 132 } 133 } 134 if (!out.contains(division)) { 135 out.add(division); 136 } 137 } 138 return out; 139 140 } 141 142 /** 143 * Sort by Division id 144 * 145 * @return list of divisions ordered by id numbers 146 */ 147 public List<Division> getDivisionsByIdList() { 148 List<Division> sortList = getList(); 149 // now re-sort 150 List<Division> out = new ArrayList<Division>(); 151 for (Division Division : sortList) { 152 for (int j = 0; j < out.size(); j++) { 153 try { 154 if (Integer.parseInt(Division.getId()) < Integer.parseInt(out.get(j).getId())) { 155 out.add(j, Division); 156 break; 157 } 158 } catch (NumberFormatException e) { 159 log.debug("list id number isn't a number"); 160 } 161 } 162 if (!out.contains(Division)) { 163 out.add(Division); 164 } 165 } 166 return out; 167 } 168 169 /** 170 * Gets an unsorted list of all divisions. 171 * 172 * @return All divisions. 173 */ 174 public List<Division> getList() { 175 List<Division> out = new ArrayList<Division>(); 176 Enumeration<Division> en = _divisionHashTable.elements(); 177 while (en.hasMoreElements()) { 178 out.add(en.nextElement()); 179 } 180 return out; 181 } 182 183 /** 184 * 185 * @return ComboBox with divisions for this railroad 186 */ 187 public JComboBox<Division> getComboBox() { 188 JComboBox<Division> box = new JComboBox<>(); 189 updateComboBox(box); 190 OperationsPanel.padComboBox(box); 191 return box; 192 } 193 194 public void updateComboBox(JComboBox<Division> box) { 195 box.removeAllItems(); 196 box.addItem(null); 197 for (Division division : getDivisionsByNameList()) { 198 box.addItem(division); 199 } 200 } 201 202 protected int _maxDivisionNameLength = 0; 203 204 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings( value="SLF4J_FORMAT_SHOULD_BE_CONST", 205 justification="I18N of Info Message") 206 public int getMaxDivisionNameLength() { 207 String maxName = TrainManifestHeaderText.getStringHeader_Division(); 208 for (Division div : getList()) { 209 if (div.getName().length() > maxName.length()) { 210 maxName = div.getName(); 211 } 212 } 213 if (maxName.length() != _maxDivisionNameLength) { 214 log.info(Bundle.getMessage("InfoMaxDivisionName", maxName, maxName.length())); 215 _maxDivisionNameLength = maxName.length(); 216 } 217 return _maxDivisionNameLength; 218 } 219 220 public void load(Element root) { 221 if (root.getChild(Xml.DIVISIONS) != null) { 222 List<Element> divisions = root.getChild(Xml.DIVISIONS).getChildren(Xml.DIVISION); 223 log.debug("readFile sees {} divisions", divisions.size()); 224 for (Element division : divisions) { 225 register(new Division(division)); 226 } 227 } 228 } 229 230 public void store(Element root) { 231 Element values; 232 root.addContent(values = new Element(Xml.DIVISIONS)); 233 // add entries 234 List<Division> DivisionList = getDivisionsByNameList(); 235 for (Division division : DivisionList) { 236 values.addContent(division.store()); 237 } 238 } 239 240 protected void setDirtyAndFirePropertyChange(String p, Object old, Object n) { 241 // set dirty 242 InstanceManager.getDefault(LocationManagerXml.class).setDirty(true); 243 firePropertyChange(p, old, n); 244 } 245 246 private static final Logger log = LoggerFactory.getLogger(DivisionManager.class); 247 248 @Override 249 public void initialize() { 250 // do nothing 251 } 252}