001package jmri.jmrit.operations.trains.manualtrainbuilder; 002 003import org.slf4j.Logger; 004import org.slf4j.LoggerFactory; 005 006import jmri.InstanceManager; 007import jmri.beans.PropertyChangeSupport; 008import jmri.jmrit.operations.locations.*; 009import jmri.jmrit.operations.routes.RouteLocation; 010import jmri.jmrit.operations.routes.RouteManager; 011import jmri.jmrit.operations.trains.TrainManagerXml; 012import jmri.jmrit.operations.trains.schedules.TrainSchedule; 013import jmri.jmrit.operations.trains.schedules.TrainScheduleManager; 014 015/** 016 * Represents one manual build item of a manual build. 017 * 018 * @author Daniel Boudreau Copyright (C) 2026 019 */ 020public class TrainManualBuildItem extends PropertyChangeSupport { 021 022 public static final String NONE = ""; // NOI18N 023 024 protected String _id = NONE; 025 protected int _sequenceId = 0; // used to determine order in the manual build 026 protected String _type = NONE; // the type of car 027 protected String _road = NONE; // the car road 028 protected String _load = NONE; // the car load 029 protected RouteLocation _routeLocation = null; // car route location 030 protected Track _trackLocation = null;// car location track 031 protected Location _destination = null; // car destination 032 protected Track _trackDestination = null;// car destination track 033 protected String _trainScheduleId = NONE; // which day of the week to pickup car 034 protected int _count = 1; 035 protected boolean _warn = false; // when true issue warning 036 protected boolean _fail = false; // when true issue build failure 037 protected boolean _remove = false; // when true issue build failure 038 039 public static final String TRAIN_SCHEDULE_CHANGED_PROPERTY = "trainScheduleProteryId"; // NOI18N 040 public static final String TYPE_CHANGED_PROPERTY = "manualItemType"; // NOI18N 041 public static final String ROAD_CHANGED_PROPERTY = "manualItemRoad"; // NOI18N 042 public static final String LOAD_CHANGED_PROPERTY = "manualItemLoad"; // NOI18N 043 public static final String ROUTE_LOCATION_CHANGED_PROPERTY = "manualItemRouteLocation"; // NOI18N 044 public static final String LOCATION_TRACK_CHANGED_PROPERTY = "manualItemLocationTrack"; // NOI18N 045 public static final String DESTINATION_CHANGED_PROPERTY = "manualItemDestination"; // NOI18N 046 public static final String DESTINATION_TRACK_CHANGED_PROPERTY = "manualItemDestinationTrack"; // NOI18N 047 public static final String COUNT_CHANGED_PROPERTY = "manualItemCount"; // NOI18N 048 public static final String WARN_CHANGED_PROPERTY = "manualItemWarn"; // NOI18N 049 public static final String FAIL_CHANGED_PROPERTY = "manualItemFail"; // NOI18N 050 public static final String REMOVE_CHANGED_PROPERTY = "manualItemRemove"; // NOI18N 051 public static final String DISPOSE = "manualItemDispose"; // NOI18N 052 053 /** 054 * @param id ManualItem string id 055 */ 056 public TrainManualBuildItem(String id) { 057 log.debug("New manual build item id: {}", id); 058 _id = id; 059 } 060 061 public String getId() { 062 return _id; 063 } 064 065 public int getSequenceId() { 066 return _sequenceId; 067 } 068 069 public void setSequenceId(int sequence) { 070 // property change not needed 071 _sequenceId = sequence; 072 } 073 074 public String getTypeName() { 075 return _type; 076 } 077 078 /** 079 * Sets the type of car requested. 080 * 081 * @param type The car type requested. 082 */ 083 public void setTypeName(String type) { 084 String old = _type; 085 _type = type; 086 setDirtyAndFirePropertyChange(TYPE_CHANGED_PROPERTY, old, type); 087 } 088 089 public String getTrainScheduleId() { 090 return _trainScheduleId; 091 } 092 093 public String getTrainScheduleName() { 094 String name = NONE; 095 TrainSchedule sch = InstanceManager.getDefault(TrainScheduleManager.class) 096 .getScheduleById(getTrainScheduleId()); 097 if (sch != null) { 098 name = sch.getName(); 099 } 100 return name; 101 } 102 103 public void setTrainScheduleId(String id) { 104 String old = _trainScheduleId; 105 _trainScheduleId = id; 106 setDirtyAndFirePropertyChange(TRAIN_SCHEDULE_CHANGED_PROPERTY, old, id); 107 } 108 109 public String getRoadName() { 110 return _road; 111 } 112 113 /** 114 * Sets the requested car road name. 115 * 116 * @param road The car road requested. 117 */ 118 public void setRoadName(String road) { 119 String old = _road; 120 _road = road; 121 setDirtyAndFirePropertyChange(ROAD_CHANGED_PROPERTY, old, road); 122 } 123 124 /** 125 * Sets the car load requested. 126 * 127 * @param load The load name requested. 128 */ 129 public void setLoadName(String load) { 130 String old = _load; 131 _load = load; 132 setDirtyAndFirePropertyChange(LOAD_CHANGED_PROPERTY, old, load); 133 } 134 135 public String getLoadName() { 136 return _load; 137 } 138 139 public RouteLocation getRouteLocation() { 140 return _routeLocation; 141 } 142 143 public void setRouteLocation(RouteLocation rl) { 144 RouteLocation old = _routeLocation; 145 _routeLocation = rl; 146 setDirtyAndFirePropertyChange(ROUTE_LOCATION_CHANGED_PROPERTY, old, rl); 147 } 148 149 public String getLocationName() { 150 if (_routeLocation != null) { 151 return _routeLocation.getName(); 152 } 153 return NONE; 154 } 155 156 public String getRouteLocationId() { 157 if (_routeLocation != null) { 158 return _routeLocation.getId(); 159 } 160 return NONE; 161 } 162 163 public Track getLocationTrack() { 164 return _trackLocation; 165 } 166 167 public void setLocationTrack(Track track) { 168 Track old = _trackLocation; 169 _trackLocation = track; 170 setDirtyAndFirePropertyChange(LOCATION_TRACK_CHANGED_PROPERTY, old, track); 171 } 172 173 public String getLocationTrackName() { 174 if (_trackLocation != null) { 175 return _trackLocation.getName(); 176 } 177 return NONE; 178 } 179 180 public String getLocationTrackId() { 181 if (_trackLocation != null) { 182 return _trackLocation.getId(); 183 } 184 return NONE; 185 } 186 187 public Location getDestination() { 188 return _destination; 189 } 190 191 public void setDestination(Location destination) { 192 Location old = _destination; 193 _destination = destination; 194 setDirtyAndFirePropertyChange(DESTINATION_CHANGED_PROPERTY, old, destination); 195 } 196 197 public String getDestinationName() { 198 if (_destination != null) { 199 return _destination.getName(); 200 } 201 return NONE; 202 } 203 204 public String getDestinationId() { 205 if (_destination != null) { 206 return _destination.getId(); 207 } 208 return NONE; 209 } 210 211 public Track getDestinationTrack() { 212 return _trackDestination; 213 } 214 215 public void setDestinationTrack(Track track) { 216 Track old = _trackDestination; 217 _trackDestination = track; 218 setDirtyAndFirePropertyChange(DESTINATION_TRACK_CHANGED_PROPERTY, old, track); 219 } 220 221 public String getDestinationTrackName() { 222 if (_trackDestination != null) { 223 return _trackDestination.getName(); 224 } 225 return NONE; 226 } 227 228 public String getDestinationTrackId() { 229 if (_trackDestination != null) { 230 return _trackDestination.getId(); 231 } 232 return NONE; 233 } 234 235 public int getCount() { 236 return _count; 237 } 238 239 public void setCount(int count) { 240 int old = _count; 241 _count = count; 242 setDirtyAndFirePropertyChange(COUNT_CHANGED_PROPERTY, old, count); 243 } 244 245 public boolean isWarnEnabled() { 246 return _warn; 247 } 248 249 public void setWarnEnabled(boolean warn) { 250 boolean old = _warn; 251 _warn = warn; 252 setDirtyAndFirePropertyChange(WARN_CHANGED_PROPERTY, old, warn); 253 } 254 255 public boolean isFailEnabled() { 256 return _fail; 257 } 258 259 public void setFailEnabled(boolean fail) { 260 boolean old = _fail; 261 _fail = fail; 262 setDirtyAndFirePropertyChange(FAIL_CHANGED_PROPERTY, old, fail); 263 } 264 265 public boolean isRemoveEnabled() { 266 return _remove; 267 } 268 269 public void setRemoveEnabled(boolean fail) { 270 boolean old = _remove; 271 _remove = fail; 272 setDirtyAndFirePropertyChange(REMOVE_CHANGED_PROPERTY, old, fail); 273 } 274 275 protected void setDirtyAndFirePropertyChange(String p, Object old, Object n) { 276 InstanceManager.getDefault(TrainManagerXml.class).setDirty(true); 277 firePropertyChange(p, old, n); 278 } 279 280 public void copyManualBuildItem(TrainManualBuildItem mbi) { 281 setCount(mbi.getCount()); 282 setTypeName(mbi.getTypeName()); 283 setLoadName(mbi.getLoadName()); 284 setRoadName(mbi.getRoadName()); 285 setRouteLocation(mbi.getRouteLocation()); 286 setLocationTrack(mbi.getLocationTrack()); 287 setDestination(mbi.getDestination()); 288 setDestinationTrack(mbi.getDestinationTrack()); 289 setTrainScheduleId(mbi.getTrainScheduleId()); 290 setFailEnabled(mbi.isFailEnabled()); 291 setWarnEnabled(mbi.isWarnEnabled()); 292 } 293 294 public void dispose() { 295 firePropertyChange(DISPOSE, null, DISPOSE); 296 } 297 298 /** 299 * Construct this Entry from XML. This member has to remain synchronized 300 * with the detailed DTD in operations-config.xml 301 * 302 * @param e Consist XML element 303 */ 304 public TrainManualBuildItem(org.jdom2.Element e) { 305 org.jdom2.Attribute a; 306 if ((a = e.getAttribute(Xml.ID)) != null) { 307 _id = a.getValue(); 308 } else { 309 log.warn("no id attribute in Schedule Item element when reading operations"); 310 } 311 if ((a = e.getAttribute(Xml.SEQUENCE_ID)) != null) { 312 _sequenceId = Integer.parseInt(a.getValue()); 313 } 314 if ((a = e.getAttribute(Xml.TRAIN_SCHEDULE_ID)) != null) { 315 _trainScheduleId = a.getValue(); 316 } 317 if ((a = e.getAttribute(Xml.TYPE)) != null) { 318 _type = a.getValue(); 319 } 320 if ((a = e.getAttribute(Xml.ROAD)) != null) { 321 _road = a.getValue(); 322 } 323 if ((a = e.getAttribute(Xml.LOAD)) != null) { 324 _load = a.getValue(); 325 } 326 if ((a = e.getAttribute(Xml.ROUTE_LOCATION_ID)) != null) { 327 _routeLocation = InstanceManager.getDefault(RouteManager.class).getRouteLocationById(a.getValue()); 328 } 329 if ((a = e.getAttribute(Xml.LOC_TRACK_ID)) != null && _routeLocation != null) { 330 _trackLocation = _routeLocation.getLocation().getTrackById(a.getValue()); 331 } 332 if ((a = e.getAttribute(Xml.DESTINATION_ID)) != null) { 333 _destination = InstanceManager.getDefault(LocationManager.class).getLocationById(a.getValue()); 334 } 335 if ((a = e.getAttribute(Xml.DEST_TRACK_ID)) != null && _destination != null) { 336 _trackDestination = _destination.getTrackById(a.getValue()); 337 } 338 if ((a = e.getAttribute(Xml.COUNT)) != null) { 339 _count = Integer.parseInt(a.getValue()); 340 } 341 if ((a = e.getAttribute(Xml.WARN)) != null) { 342 _warn = a.getValue().equals(Xml.TRUE); 343 } 344 if ((a = e.getAttribute(Xml.FAIL)) != null) { 345 _fail = a.getValue().equals(Xml.TRUE); 346 } 347 if ((a = e.getAttribute(Xml.REMOVE)) != null) { 348 _remove = a.getValue().equals(Xml.TRUE); 349 } 350 } 351 352 /** 353 * Create an XML element to represent this Entry. This member has to remain 354 * synchronized with the detailed DTD in operations-config.xml. 355 * 356 * @return Contents in a JDOM Element 357 */ 358 public org.jdom2.Element store() { 359 org.jdom2.Element e = new org.jdom2.Element(Xml.MANUAL_BUILD_ITEM); 360 e.setAttribute(Xml.ID, getId()); 361 e.setAttribute(Xml.SEQUENCE_ID, Integer.toString(getSequenceId())); 362 e.setAttribute(Xml.TRAIN_SCHEDULE_ID, getTrainScheduleId()); 363 e.setAttribute(Xml.TYPE, getTypeName()); 364 e.setAttribute(Xml.ROAD, getRoadName()); 365 e.setAttribute(Xml.LOAD, getLoadName()); 366 if (!getRouteLocationId().equals(NONE)) { 367 e.setAttribute(Xml.ROUTE_LOCATION_ID, getRouteLocationId()); 368 } 369 if (!getLocationTrackId().equals(NONE)) { 370 e.setAttribute(Xml.LOC_TRACK_ID, getLocationTrackId()); 371 } 372 if (!getDestinationId().equals(NONE)) { 373 e.setAttribute(Xml.DESTINATION_ID, getDestinationId()); 374 } 375 if (!getDestinationTrackId().equals(NONE)) { 376 e.setAttribute(Xml.DEST_TRACK_ID, getDestinationTrackId()); 377 } 378 e.setAttribute(Xml.COUNT, Integer.toString(getCount())); 379 e.setAttribute(Xml.WARN, isWarnEnabled() ? Xml.TRUE : Xml.FALSE); 380 e.setAttribute(Xml.FAIL, isFailEnabled() ? Xml.TRUE : Xml.FALSE); 381 e.setAttribute(Xml.REMOVE, isRemoveEnabled() ? Xml.TRUE : Xml.FALSE); 382 return e; 383 } 384 385 private static final Logger log = LoggerFactory.getLogger(TrainManualBuildItem.class); 386 387}