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.locations.LocationManagerXml; 014import jmri.jmrit.operations.trains.TrainManifestHeaderText; 015 016/** 017 * Manages divisions. 018 * 019 * @author Bob Jacobsen Copyright (C) 2003 020 * @author Daniel Boudreau Copyright (C) 2021 021 */ 022public class DivisionManager extends PropertyChangeSupport implements InstanceManagerAutoDefault, InstanceManagerAutoInitialize { 023 024 public static final String LISTLENGTH_CHANGED_PROPERTY = "divisionsListLength"; // NOI18N 025 026 public DivisionManager() { 027 } 028 029 private int _id = 0; 030 031 public void dispose() { 032 _divisionHashTable.clear(); 033 _id = 0; 034 } 035 036 protected Hashtable<String, Division> _divisionHashTable = new Hashtable<String, Division>(); 037 038 /** 039 * @return Number of divisions 040 */ 041 public int getNumberOfdivisions() { 042 return _divisionHashTable.size(); 043 } 044 045 /** 046 * @param name The string name of the Division to get. 047 * @return requested Division object or null if none exists 048 */ 049 public Division getDivisionByName(String name) { 050 Division Division; 051 Enumeration<Division> en = _divisionHashTable.elements(); 052 while (en.hasMoreElements()) { 053 Division = en.nextElement(); 054 if (Division.getName().equals(name)) { 055 return Division; 056 } 057 } 058 return null; 059 } 060 061 public Division getDivisionById(String id) { 062 return _divisionHashTable.get(id); 063 } 064 065 /** 066 * Finds an existing Division or creates a new Division if needed requires 067 * Division's name creates a unique id for this Division 068 * 069 * @param name The string name for a new Division. 070 * 071 * 072 * @return new Division or existing Division 073 */ 074 public Division newDivision(String name) { 075 Division division = getDivisionByName(name); 076 if (division == null) { 077 _id++; 078 division = new Division(Integer.toString(_id), name); 079 Integer oldSize = Integer.valueOf(_divisionHashTable.size()); 080 _divisionHashTable.put(division.getId(), division); 081 setDirtyAndFirePropertyChange(LISTLENGTH_CHANGED_PROPERTY, oldSize, 082 Integer.valueOf(_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 Integer oldSize = Integer.valueOf(_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, Integer.valueOf(_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 Integer oldSize = Integer.valueOf(_divisionHashTable.size()); 113 _divisionHashTable.remove(division.getId()); 114 setDirtyAndFirePropertyChange(LISTLENGTH_CHANGED_PROPERTY, oldSize, Integer.valueOf(_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 return box; 191 } 192 193 public void updateComboBox(JComboBox<Division> box) { 194 box.removeAllItems(); 195 box.addItem(null); 196 for (Division division : getDivisionsByNameList()) { 197 box.addItem(division); 198 } 199 } 200 201 protected int _maxDivisionNameLength = 0; 202 203 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings( value="SLF4J_FORMAT_SHOULD_BE_CONST", 204 justification="I18N of Info Message") 205 public int getMaxDivisionNameLength() { 206 String maxName = TrainManifestHeaderText.getStringHeader_Division(); 207 for (Division div : getList()) { 208 if (div.getName().length() > maxName.length()) { 209 maxName = div.getName(); 210 } 211 } 212 if (maxName.length() != _maxDivisionNameLength) { 213 log.info(Bundle.getMessage("InfoMaxDivisionName", maxName, maxName.length())); 214 _maxDivisionNameLength = maxName.length(); 215 } 216 return _maxDivisionNameLength; 217 } 218 219 public void load(Element root) { 220 if (root.getChild(Xml.DIVISIONS) != null) { 221 List<Element> divisions = root.getChild(Xml.DIVISIONS).getChildren(Xml.DIVISION); 222 log.debug("readFile sees {} divisions", divisions.size()); 223 for (Element division : divisions) { 224 register(new Division(division)); 225 } 226 } 227 } 228 229 public void store(Element root) { 230 Element values; 231 root.addContent(values = new Element(Xml.DIVISIONS)); 232 // add entries 233 List<Division> DivisionList = getDivisionsByNameList(); 234 for (Division division : DivisionList) { 235 values.addContent(division.store()); 236 } 237 } 238 239 protected void setDirtyAndFirePropertyChange(String p, Object old, Object n) { 240 // set dirty 241 InstanceManager.getDefault(LocationManagerXml.class).setDirty(true); 242 firePropertyChange(p, old, n); 243 } 244 245 private final static Logger log = LoggerFactory.getLogger(DivisionManager.class); 246 247 @Override 248 public void initialize() { 249 // do nothing 250 } 251}