001package jmri.implementation; 002 003import java.awt.event.ActionListener; 004import javax.swing.Timer; 005import jmri.Audio; 006import jmri.Conditional; 007import jmri.ConditionalAction; 008import jmri.InstanceManager; 009import jmri.Light; 010import jmri.Memory; 011import jmri.NamedBean; 012import jmri.NamedBeanHandle; 013import jmri.Route; 014import jmri.RouteManager; 015import jmri.Sensor; 016import jmri.SignalHead; 017import jmri.Turnout; 018import jmri.jmrit.Sound; 019import jmri.jmrit.beantable.LogixTableAction; 020import jmri.jmrit.logix.OBlockManager; 021import jmri.jmrit.logix.Warrant; 022import jmri.jmrit.logix.WarrantManager; 023import org.slf4j.Logger; 024import org.slf4j.LoggerFactory; 025 026/** 027 * The consequent of the antecedent of the conditional proposition. The data for 028 * the action to be taken when a Conditional calculates to True 029 * <p> 030 * This is in the implementations package because of a Swing dependence via the 031 * times. Java 1.5 or Java 1.6 might make it possible to break that, which will 032 * simplify things. 033 * 034 * @author Pete Cressman Copyright (C) 2009, 2010, 2011 035 * @author Matthew Harris copyright (c) 2009 036 */ 037public class DefaultConditionalAction implements ConditionalAction { 038 039 private int _option = Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE; 040 private Conditional.Action _type = Conditional.Action.NONE; 041 private String _deviceName = " "; 042 private int _actionData = 0; 043 private String _actionString = ""; 044 private NamedBeanHandle<?> _namedBean = null; 045 046 private Timer _timer = null; 047 private ActionListener _listener = null; 048 private boolean _timerActive = false; 049 private boolean _indirectAction = false; 050 private Sound _sound = null; 051 052 static final java.util.ResourceBundle rbx = java.util.ResourceBundle.getBundle("jmri.jmrit.conditional.ConditionalBundle"); 053 protected jmri.NamedBeanHandleManager nbhm = jmri.InstanceManager.getDefault(jmri.NamedBeanHandleManager.class); 054 055 public DefaultConditionalAction() { 056 } 057 058 public DefaultConditionalAction(int option, Conditional.Action type, String name, int actionData, String actionStr) { 059 _option = option; 060 _type = type; 061 _deviceName = name; 062 _actionData = actionData; 063 _actionString = actionStr; 064 065 NamedBean bean = getIndirectBean(_deviceName); 066 if (bean == null) { 067 bean = getActionBean(_deviceName); 068 } 069 if (bean != null) { 070 _namedBean = nbhm.getNamedBeanHandle(_deviceName, bean); 071 } else { 072 _namedBean = null; 073 } 074 } 075 076 @Override 077 public boolean equals(Object obj) { 078 if (obj == this) { 079 return true; 080 } 081 if (obj == null) { 082 return false; 083 } 084 085 if (!(getClass() == obj.getClass())) { 086 return false; 087 } else { 088 DefaultConditionalAction p = (DefaultConditionalAction) obj; 089 if ((p._option != this._option) 090 || (p._type != this._type) 091 || (p._actionData != this._actionData)) { 092 return false; 093 } 094 095 if ((p._namedBean == null && this._namedBean != null) 096 || (p._namedBean != null && this._namedBean == null) 097 || (p._namedBean != null && this._namedBean != null && !p._namedBean.equals(this._namedBean))) { 098 return false; 099 } 100 101 if ((p._deviceName == null && this._deviceName != null) 102 || (p._deviceName != null && this._deviceName == null) 103 || (p._deviceName != null && this._deviceName != null && !p._deviceName.equals(this._deviceName))) { 104 return false; 105 } 106 107 if ((p._actionString == null && this._actionString != null) 108 || (p._actionString != null && this._actionString == null) 109 || (p._actionString != null && this._actionString != null && !p._actionString.equals(this._actionString))) { 110 return false; 111 } 112 113 } 114 return true; 115 } 116 117 @Override 118 public int hashCode() { 119 int hash = _option * 1000 + _type.getIntValue() * 1000 * 1000 + _actionData; 120 if (_deviceName != null) { 121 hash += _deviceName.hashCode(); 122 } 123 return hash; 124 } 125 126 /** 127 * If this is an indirect reference, return the Memory bean. 128 * 129 */ 130 private Memory getIndirectBean(String devName) { 131 if (devName != null && devName.length() > 0 && devName.charAt(0) == '@') { 132 String memName = devName.substring(1); 133 Memory m = InstanceManager.memoryManagerInstance().getMemory(memName); 134 if (m != null) { 135 _indirectAction = true; 136 return m; 137 } 138 log.error("\"{}\" invalid indirect memory name in action {} of type {}", devName, _actionString, _type); 139 } else { 140 _indirectAction = false; 141 } 142 return null; 143 } 144 145 /** 146 * Return the device bean that will do the action. 147 * 148 */ 149 private NamedBean getActionBean(String devName) { 150 if (devName == null) return null; 151 NamedBean bean = null; 152 try { 153 switch (_type.getItemType()) { 154 case SENSOR: 155 try { 156 bean = InstanceManager.sensorManagerInstance().provideSensor(devName); 157 } catch (IllegalArgumentException e) { 158 bean = null; 159 log.error("invalid sensor name= \"{}\" in conditional action", devName); 160 } 161 break; 162 case TURNOUT: 163 try { 164 bean = InstanceManager.turnoutManagerInstance().provideTurnout(devName); 165 } catch (IllegalArgumentException e) { 166 bean = null; 167 log.error("invalid turnout name= \"{}\" in conditional action", devName); 168 } 169 break; 170 case MEMORY: 171 try { 172 bean = InstanceManager.memoryManagerInstance().provideMemory(devName); 173 } catch (IllegalArgumentException e) { 174 bean = null; 175 log.error("invalid memory name= \"{}\" in conditional action", devName); 176 } 177 break; 178 case LIGHT: 179 try { 180 bean = InstanceManager.lightManagerInstance().getLight(devName); 181 } catch (IllegalArgumentException e) { 182 bean = null; 183 log.error("invalid light name= \"{}\" in conditional action", devName); 184 } 185 break; 186 case SIGNALMAST: 187 try { 188 bean = InstanceManager.getDefault(jmri.SignalMastManager.class).provideSignalMast(devName); 189 } catch (IllegalArgumentException e) { 190 bean = null; 191 log.error("invalid signal mast name= \"{}\" in conditional action", devName); 192 } 193 break; 194 case SIGNALHEAD: 195 try { 196 bean = InstanceManager.getDefault(jmri.SignalHeadManager.class).getSignalHead(devName); 197 } catch (IllegalArgumentException e) { 198 bean = null; 199 log.error("invalid signal head name= \"{}\" in conditional action", devName); 200 } 201 break; 202 case WARRANT: 203 try { 204 bean = InstanceManager.getDefault(WarrantManager.class).getWarrant(devName); 205 } catch (IllegalArgumentException e) { 206 bean = null; 207 log.error("invalid Warrant name= \"{}\" in conditional action", devName); 208 } 209 break; 210 case OBLOCK: 211 try { 212 bean = InstanceManager.getDefault(OBlockManager.class).getOBlock(devName); 213 } catch (IllegalArgumentException e) { 214 bean = null; 215 log.error("invalid OBlock name= \"{}\" in conditional action", devName); 216 } 217 break; 218 case ENTRYEXIT: 219 try { 220 bean = jmri.InstanceManager.getDefault(jmri.jmrit.entryexit.EntryExitPairs.class).getNamedBean(devName); 221 } catch (IllegalArgumentException e) { 222 bean = null; 223 log.error("invalid NX name= \"{}\" in conditional action", devName); 224 } 225 break; 226 case LOGIX: 227 try { 228 bean = jmri.InstanceManager.getDefault(jmri.LogixManager.class).getLogix(devName); 229 } catch (IllegalArgumentException e) { 230 bean = null; 231 log.error("invalid Logix name= \"{}\" in conditional action", devName); 232 } 233 break; 234 default: 235 if (getType() == Conditional.Action.TRIGGER_ROUTE) { 236 try { 237 bean = InstanceManager.getDefault(RouteManager.class).getRoute(devName); 238 } catch (IllegalArgumentException e) { 239 bean = null; 240 log.error("invalid Route name= \"{}\" in conditional action", devName); 241 } 242 } 243 } 244 } catch (java.lang.NumberFormatException ex) { 245 // ingonred, can be considered normal if the logixs are loaded prior to any other beans 246 } 247 return bean; 248 } 249 250 /** 251 * The consequent device or element type. 252 */ 253 @Override 254 public Conditional.Action getType() { 255 return _type; 256 } 257 258 @Override 259 public void setType(Conditional.Action type) { 260 _type = type; 261 } 262 263 /** 264 * Set type from user name for it. 265 */ 266 @Override 267 public void setType(String type) { 268 _type = stringToActionType(type); 269 } 270 271 /** 272 * Name of the device or element that is affected. 273 */ 274 @Override 275 public String getDeviceName() { 276 if (_namedBean != null) { 277 return _namedBean.getName(); 278 } 279 /* As we have a trigger for something using the action, then hopefully 280 all the managers have been loaded and we can get the bean, which prevented 281 the bean from being loaded in the first place */ 282 setDeviceName(_deviceName); 283 return _deviceName; 284 } 285 286 @Override 287 public void setDeviceName(String deviceName) { 288 _deviceName = deviceName; 289 NamedBean bean = getIndirectBean(_deviceName); 290 if (bean == null) { 291 bean = getActionBean(_deviceName); 292 } 293 if (bean != null) { 294 _namedBean = nbhm.getNamedBeanHandle(_deviceName, bean); 295 } else { 296 _namedBean = null; 297 } 298 } 299 300 @Override 301 public NamedBeanHandle<?> getNamedBean() { 302 if (_indirectAction) { 303 Memory m = (Memory) (_namedBean.getBean()); 304 String actionName = (String) m.getValue(); 305 NamedBean bean = getActionBean(actionName); 306 if (bean != null) { 307 return nbhm.getNamedBeanHandle(actionName, bean); 308 } else { 309 return null; 310 } 311 } 312 return _namedBean; 313 } 314 315 @Override 316 public NamedBean getBean() { 317 if (_namedBean != null) { 318 NamedBeanHandle<?> handle = getNamedBean(); 319 if (handle == null) return null; 320 return handle.getBean(); 321 } 322 setDeviceName(_deviceName); //ReApply name as that will create namedBean, save replicating it here 323 if (_namedBean != null) { 324 return getNamedBean().getBean(); 325 } 326 return null; 327 } 328 329 /** 330 * Options on when action is taken. 331 */ 332 @Override 333 public int getOption() { 334 return _option; 335 } 336 337 @Override 338 public void setOption(int option) { 339 _option = option; 340 } 341 342 /** 343 * Integer data for action. 344 */ 345 @Override 346 public int getActionData() { 347 return _actionData; 348 } 349 350 @Override 351 public void setActionData(int actionData) { 352 _actionData = actionData; 353 } 354 355 /** 356 * Set action data from user name for it. 357 */ 358 @Override 359 public void setActionData(String actionData) { 360 _actionData = stringToActionData(actionData); 361 } 362 363 /** 364 * String data for action. 365 */ 366 @Override 367 public String getActionString() { 368 if (_actionString == null) { 369 _actionString = getTypeString(); 370 } 371 return _actionString; 372 } 373 374 @Override 375 public void setActionString(String actionString) { 376 _actionString = actionString; 377 } 378 379 /* 380 * Get timer for delays and other timed events. 381 */ 382 @Override 383 public Timer getTimer() { 384 return _timer; 385 } 386 387 /* 388 * Set timer for delays and other timed events. 389 */ 390 @Override 391 public void setTimer(Timer timer) { 392 _timer = timer; 393 } 394 395 @Override 396 public boolean isTimerActive() { 397 return _timerActive; 398 } 399 400 @Override 401 public void startTimer() { 402 if (_timer != null) { 403 _timer.start(); 404 _timerActive = true; 405 } else { 406 log.error("timer is null for {} of type {}", _deviceName, getTypeString()); 407 } 408 } 409 410 @Override 411 public void stopTimer() { 412 if (_timer != null) { 413 _timer.stop(); 414 _timerActive = false; 415 } 416 } 417 418 /* 419 * Set listener for delays and other timed events. 420 */ 421 @Override 422 public ActionListener getListener() { 423 return _listener; 424 } 425 426 /* 427 * set listener for delays and other timed events 428 */ 429 @Override 430 public void setListener(ActionListener listener) { 431 _listener = listener; 432 } 433 434 /** 435 * Get Sound file. 436 */ 437 @Override 438 public Sound getSound() { 439 return _sound; 440 } 441 442 /** 443 * Set the sound file. 444 * 445 * @param sound the new sound file 446 */ 447 protected void setSound(Sound sound) { 448 _sound = sound; 449 } 450 451 /* 452 * Methods that return user interface strings **** 453 */ 454 455 /** 456 * @return name of this consequent type 457 */ 458 @Override 459 public String getTypeString() { 460 return _type.toString(); 461 } 462 463 /** 464 * @return name of the option for this consequent type 465 */ 466 @Override 467 public String getOptionString(boolean type) { 468 return getOptionString(_option, type); 469 } 470 471 @Override 472 public String getActionDataString() { 473 return getActionDataString(_type, _actionData); 474 } 475 476 /** 477 * Convert Variable Type to Text String. 478 * 479 * @.param t the Action type 480 * @.return a human readable description of the type or an empty String 481 *./ 482 public static String getItemTypeString(int t) { 483 switch (t) { 484 case Conditional.ITEM_TYPE_SENSOR: 485 return (Bundle.getMessage("BeanNameSensor")); 486 case Conditional.ITEM_TYPE_TURNOUT: 487 return (Bundle.getMessage("BeanNameTurnout")); 488 case Conditional.ITEM_TYPE_LIGHT: 489 return (Bundle.getMessage("BeanNameLight")); 490 case Conditional.ITEM_TYPE_SIGNALHEAD: 491 return (Bundle.getMessage("BeanNameSignalHead")); 492 case Conditional.ITEM_TYPE_SIGNALMAST: 493 return (Bundle.getMessage("BeanNameSignalMast")); 494 case Conditional.ITEM_TYPE_MEMORY: 495 return (Bundle.getMessage("BeanNameMemory")); 496 case Conditional.ITEM_TYPE_LOGIX: 497 return (Bundle.getMessage("BeanNameLogix")); 498 case Conditional.ITEM_TYPE_WARRANT: 499 return (Bundle.getMessage("BeanNameWarrant")); 500 case Conditional.ITEM_TYPE_OBLOCK: 501 return (Bundle.getMessage("BeanNameOBlock")); 502 case Conditional.ITEM_TYPE_ENTRYEXIT: 503 return (Bundle.getMessage("BeanNameEntryExit")); 504 case Conditional.ITEM_TYPE_CLOCK: 505 return (Bundle.getMessage("FastClock")); 506 case Conditional.ITEM_TYPE_AUDIO: 507 return (Bundle.getMessage("BeanNameAudio")); 508 case Conditional.ITEM_TYPE_SCRIPT: 509 return (Bundle.getMessage("Script")); 510 case Conditional.ITEM_TYPE_OTHER: 511 return (rbx.getString("Other")); 512 default: 513 // fall through 514 break; 515 } 516 return ""; 517 } 518*/ 519 /** 520 * Convert Consequent Type to text String. 521 * 522 * @.param t the Action type 523 * @.return a human readable description of the type or an empty String 524 *./ 525 public static String getActionTypeString(int t) { 526 switch (t) { 527 case Conditional.ACTION_NONE: 528 return (rbx.getString("ActionNone")); 529 case Conditional.ACTION_SET_TURNOUT: 530 return (rbx.getString("ActionSetTurnout")); 531 case Conditional.ACTION_SET_SIGNAL_APPEARANCE: 532 return (rbx.getString("ActionSetSignal")); 533 case Conditional.ACTION_SET_SIGNAL_HELD: 534 return (rbx.getString("ActionSetSignalHeld")); 535 case Conditional.ACTION_CLEAR_SIGNAL_HELD: 536 return (rbx.getString("ActionClearSignalHeld")); 537 case Conditional.ACTION_SET_SIGNAL_DARK: 538 return (rbx.getString("ActionSetSignalDark")); 539 case Conditional.ACTION_SET_SIGNAL_LIT: 540 return (rbx.getString("ActionSetSignalLit")); 541 case Conditional.ACTION_TRIGGER_ROUTE: 542 return (rbx.getString("ActionTriggerRoute")); 543 case Conditional.ACTION_SET_SENSOR: 544 return (rbx.getString("ActionSetSensor")); 545 case Conditional.ACTION_DELAYED_SENSOR: 546 return (rbx.getString("ActionDelayedSensor")); 547 case Conditional.ACTION_SET_LIGHT: 548 return (rbx.getString("ActionSetLight")); 549 case Conditional.ACTION_SET_MEMORY: 550 return (rbx.getString("ActionSetMemory")); 551 case Conditional.ACTION_ENABLE_LOGIX: 552 return (rbx.getString("ActionEnableLogix")); 553 case Conditional.ACTION_DISABLE_LOGIX: 554 return (rbx.getString("ActionDisableLogix")); 555 case Conditional.ACTION_PLAY_SOUND: 556 return (rbx.getString("ActionPlaySound")); 557 case Conditional.ACTION_RUN_SCRIPT: 558 return (rbx.getString("ActionRunScript")); 559 case Conditional.ACTION_DELAYED_TURNOUT: 560 return (rbx.getString("ActionDelayedTurnout")); 561 case Conditional.ACTION_LOCK_TURNOUT: 562 return (rbx.getString("ActionTurnoutLock")); 563 case Conditional.ACTION_RESET_DELAYED_SENSOR: 564 return (rbx.getString("ActionResetDelayedSensor")); 565 case Conditional.ACTION_CANCEL_SENSOR_TIMERS: 566 return (rbx.getString("ActionCancelSensorTimers")); 567 case Conditional.ACTION_RESET_DELAYED_TURNOUT: 568 return (rbx.getString("ActionResetDelayedTurnout")); 569 case Conditional.ACTION_CANCEL_TURNOUT_TIMERS: 570 return (rbx.getString("ActionCancelTurnoutTimers")); 571 case Conditional.ACTION_SET_FAST_CLOCK_TIME: 572 return (rbx.getString("ActionSetFastClockTime")); 573 case Conditional.ACTION_START_FAST_CLOCK: 574 return (rbx.getString("ActionStartFastClock")); 575 case Conditional.ACTION_STOP_FAST_CLOCK: 576 return (rbx.getString("ActionStopFastClock")); 577 case Conditional.ACTION_COPY_MEMORY: 578 return (rbx.getString("ActionCopyMemory")); 579 case Conditional.ACTION_SET_LIGHT_INTENSITY: 580 return (rbx.getString("ActionSetLightIntensity")); 581 case Conditional.ACTION_SET_LIGHT_TRANSITION_TIME: 582 return (rbx.getString("ActionSetLightTransitionTime")); 583 case Conditional.ACTION_CONTROL_AUDIO: 584 return (rbx.getString("ActionControlAudio")); 585 case Conditional.ACTION_JYTHON_COMMAND: 586 return (rbx.getString("ActionJythonCommand")); 587 case Conditional.ACTION_ALLOCATE_WARRANT_ROUTE: 588 return (rbx.getString("ActionAllocateWarrant")); 589 case Conditional.ACTION_DEALLOCATE_WARRANT_ROUTE: 590 return (rbx.getString("ActionDeallocateWarrant")); 591 case Conditional.ACTION_SET_ROUTE_TURNOUTS: 592 return (rbx.getString("ActionSetWarrantTurnouts")); 593 case Conditional.ACTION_AUTO_RUN_WARRANT: 594 return (rbx.getString("ActionAutoRunWarrant")); 595 case Conditional.ACTION_MANUAL_RUN_WARRANT: 596 return (rbx.getString("ActionManualRunWarrant")); 597 case Conditional.ACTION_CONTROL_TRAIN: 598 return (rbx.getString("ActionControlTrain")); 599 case Conditional.ACTION_SET_TRAIN_ID: 600 return (rbx.getString("ActionSetTrainId")); 601 case Conditional.ACTION_SET_TRAIN_NAME: 602 return (rbx.getString("ActionSetTrainName")); 603 case Conditional.ACTION_SET_SIGNALMAST_ASPECT: 604 return (rbx.getString("ActionSetSignalMastAspect")); 605 case Conditional.ACTION_THROTTLE_FACTOR: 606 return (rbx.getString("ActionSetThrottleFactor")); 607 case Conditional.ACTION_SET_SIGNALMAST_HELD: 608 return (rbx.getString("ActionSetSignalMastHeld")); 609 case Conditional.ACTION_CLEAR_SIGNALMAST_HELD: 610 return (rbx.getString("ActionClearSignalMastHeld")); 611 case Conditional.ACTION_SET_SIGNALMAST_DARK: 612 return (rbx.getString("ActionSetSignalMastDark")); 613 case Conditional.ACTION_SET_SIGNALMAST_LIT: 614 return (rbx.getString("ActionClearSignalMastDark")); 615 case Conditional.ACTION_SET_BLOCK_VALUE: 616 return (rbx.getString("ActionSetBlockValue")); 617 case Conditional.ACTION_SET_BLOCK_ERROR: 618 return (rbx.getString("ActionSetBlockError")); 619 case Conditional.ACTION_CLEAR_BLOCK_ERROR: 620 return (rbx.getString("ActionClearBlockError")); 621 case Conditional.ACTION_DEALLOCATE_BLOCK: 622 return (rbx.getString("ActionDeallocateBlock")); 623 case Conditional.ACTION_SET_BLOCK_OUT_OF_SERVICE: 624 return (rbx.getString("ActionSetBlockOutOfService")); 625 case Conditional.ACTION_SET_BLOCK_IN_SERVICE: 626 return (rbx.getString("ActionBlockInService")); 627 case Conditional.ACTION_SET_NXPAIR_ENABLED: 628 return (rbx.getString("ActionNXPairEnabled")); 629 case Conditional.ACTION_SET_NXPAIR_DISABLED: 630 return (rbx.getString("ActionNXPairDisabled")); 631 case Conditional.ACTION_SET_NXPAIR_SEGMENT: 632 return (rbx.getString("ActionNXPairSegment")); 633 default: 634 // fall through 635 break; 636 } 637 log.warn("Unexpected parameter to getActionTypeString({})", t); 638 return (""); 639 } 640*/ 641 /** 642 * Convert consequent option to String. 643 * 644 * @param opt the option 645 * @param type true if option is a change; false if option is a trigger 646 * @return a human readable description of the option or an empty String 647 */ 648 public static String getOptionString(int opt, boolean type) { 649 switch (opt) { 650 case Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE: 651 if (type) { 652 return (rbx.getString("OnChangeToTrue")); 653 } else { 654 return (rbx.getString("OnTriggerToTrue")); 655 } 656 case Conditional.ACTION_OPTION_ON_CHANGE_TO_FALSE: 657 if (type) { 658 return (rbx.getString("OnChangeToFalse")); 659 } else { 660 return (rbx.getString("OnTriggerToFalse")); 661 } 662 case Conditional.ACTION_OPTION_ON_CHANGE: 663 if (type) { 664 return (rbx.getString("OnChange")); 665 } else { 666 return (rbx.getString("OnTrigger")); 667 } 668 default: 669 // fall through 670 break; 671 } 672 log.warn("Unexpected parameter to getOptionString({})", opt); 673 return ""; 674 } 675 676 /** 677 * Get action type from a String. 678 * 679 * @param str the string to get the type for 680 * @return the type or 0 if str is not a recognized action 681 */ 682 public static Conditional.Action stringToActionType(String str) { 683 if (str != null) { 684 for (Conditional.Action action : Conditional.Action.values()) { 685 if (str.equals(action.toString())) { 686 return action; 687 } 688 } 689 } 690 log.warn("Unexpected parameter to stringToActionType({})", str); 691 return Conditional.Action.NONE; 692 } 693 694 /** 695 * Get action Data from a String. 696 * 697 * @param str the string to get the action data for 698 * @return the action data of -1 is str is not recognized 699 */ 700 public static int stringToActionData(String str) { 701 if (str.equals(Bundle.getMessage("TurnoutStateClosed"))) { 702 return Turnout.CLOSED; 703 } else if (str.equals(Bundle.getMessage("TurnoutStateThrown"))) { 704 return Turnout.THROWN; 705 } else if (str.equals(Bundle.getMessage("SensorStateActive"))) { 706 return Sensor.ACTIVE; 707 } else if (str.equals(Bundle.getMessage("SensorStateInactive"))) { 708 return Sensor.INACTIVE; 709 } else if (str.equals(rbx.getString("LightOn"))) { 710 return Light.ON; 711 } else if (str.equals(rbx.getString("LightOff"))) { 712 return Light.OFF; 713 } else if (str.equals(rbx.getString("TurnoutUnlock"))) { 714 return Turnout.UNLOCKED; 715 } else if (str.equals(rbx.getString("TurnoutLock"))) { 716 return Turnout.LOCKED; 717 } else if (str.equals(Bundle.getMessage("SignalHeadStateRed"))) { 718 return SignalHead.RED; 719 } else if (str.equals(Bundle.getMessage("SignalHeadStateYellow"))) { 720 return SignalHead.YELLOW; 721 } else if (str.equals(Bundle.getMessage("SignalHeadStateGreen"))) { 722 return SignalHead.GREEN; 723 } else if (str.equals(Bundle.getMessage("SignalHeadStateDark"))) { 724 return SignalHead.DARK; 725 } else if (str.equals(Bundle.getMessage("SignalHeadStateFlashingRed"))) { 726 return SignalHead.FLASHRED; 727 } else if (str.equals(Bundle.getMessage("SignalHeadStateFlashingYellow"))) { 728 return SignalHead.FLASHYELLOW; 729 } else if (str.equals(Bundle.getMessage("SignalHeadStateFlashingGreen"))) { 730 return SignalHead.FLASHGREEN; 731 } else if (str.equals(Bundle.getMessage("SignalHeadStateLunar"))) { 732 return SignalHead.LUNAR; 733 } else if (str.equals(Bundle.getMessage("SignalHeadStateFlashingLunar"))) { 734 return SignalHead.FLASHLUNAR; 735 } else if (str.equals(rbx.getString("AudioSourcePlay"))) { 736 return Audio.CMD_PLAY; 737 } else if (str.equals(rbx.getString("AudioSourceStop"))) { 738 return Audio.CMD_STOP; 739 } else if (str.equals(rbx.getString("AudioSourcePlayToggle"))) { 740 return Audio.CMD_PLAY_TOGGLE; 741 } else if (str.equals(rbx.getString("AudioSourcePause"))) { 742 return Audio.CMD_PAUSE; 743 } else if (str.equals(rbx.getString("AudioSourceResume"))) { 744 return Audio.CMD_RESUME; 745 } else if (str.equals(rbx.getString("AudioSourcePauseToggle"))) { 746 return Audio.CMD_PAUSE_TOGGLE; 747 } else if (str.equals(rbx.getString("AudioSourceRewind"))) { 748 return Audio.CMD_REWIND; 749 } else if (str.equals(rbx.getString("AudioSourceFadeIn"))) { 750 return Audio.CMD_FADE_IN; 751 } else if (str.equals(rbx.getString("AudioSourceFadeOut"))) { 752 return Audio.CMD_FADE_OUT; 753 } else if (str.equals(rbx.getString("AudioResetPosition"))) { 754 return Audio.CMD_RESET_POSITION; 755 } 756 // empty strings can occur frequently with types that have no integer data 757 if (str.length() > 0) { 758 log.warn("Unexpected parameter to stringToActionData({})", str); 759 } 760 return -1; 761 } 762 763 public static String getActionDataString(Conditional.Action t, int data) { 764 switch (t) { 765 case SET_TURNOUT: 766 case DELAYED_TURNOUT: 767 case RESET_DELAYED_TURNOUT: 768 if (data == Turnout.CLOSED) { 769 return (Bundle.getMessage("TurnoutStateClosed")); 770 } else if (data == Turnout.THROWN) { 771 return (Bundle.getMessage("TurnoutStateThrown")); 772 } else if (data == Route.TOGGLE) { 773 return (Bundle.getMessage("Toggle")); 774 } 775 break; 776 case SET_SIGNAL_APPEARANCE: 777 return DefaultSignalHead.getDefaultStateName(data); 778 case SET_SENSOR: 779 case DELAYED_SENSOR: 780 case RESET_DELAYED_SENSOR: 781 if (data == Sensor.ACTIVE) { 782 return (Bundle.getMessage("SensorStateActive")); 783 } else if (data == Sensor.INACTIVE) { 784 return (Bundle.getMessage("SensorStateInactive")); 785 } else if (data == Route.TOGGLE) { 786 return (Bundle.getMessage("Toggle")); 787 } 788 break; 789 case SET_LIGHT: 790 if (data == Light.ON) { 791 return (rbx.getString("LightOn")); 792 } else if (data == Light.OFF) { 793 return (rbx.getString("LightOff")); 794 } else if (data == Route.TOGGLE) { 795 return (Bundle.getMessage("Toggle")); 796 } 797 break; 798 case LOCK_TURNOUT: 799 if (data == Turnout.UNLOCKED) { 800 return (rbx.getString("TurnoutUnlock")); 801 } else if (data == Turnout.LOCKED) { 802 return (rbx.getString("TurnoutLock")); 803 } else if (data == Route.TOGGLE) { 804 return (Bundle.getMessage("Toggle")); 805 } 806 break; 807 case CONTROL_AUDIO: 808 switch (data) { 809 case Audio.CMD_PLAY: 810 return (rbx.getString("AudioSourcePlay")); 811 case Audio.CMD_STOP: 812 return (rbx.getString("AudioSourceStop")); 813 case Audio.CMD_PLAY_TOGGLE: 814 return (rbx.getString("AudioSourcePlayToggle")); 815 case Audio.CMD_PAUSE: 816 return (rbx.getString("AudioSourcePause")); 817 case Audio.CMD_RESUME: 818 return (rbx.getString("AudioSourceResume")); 819 case Audio.CMD_PAUSE_TOGGLE: 820 return (rbx.getString("AudioSourcePauseToggle")); 821 case Audio.CMD_REWIND: 822 return (rbx.getString("AudioSourceRewind")); 823 case Audio.CMD_FADE_IN: 824 return (rbx.getString("AudioSourceFadeIn")); 825 case Audio.CMD_FADE_OUT: 826 return (rbx.getString("AudioSourceFadeOut")); 827 case Audio.CMD_RESET_POSITION: 828 return (rbx.getString("AudioResetPosition")); 829 default: 830 log.error("Unhandled Audio operation command: {}", data); 831 break; 832 } 833 break; 834 case CONTROL_TRAIN: 835 switch (data) { 836 case Warrant.HALT: 837 return (rbx.getString("WarrantHalt")); 838 case Warrant.RESUME: 839 return (rbx.getString("WarrantResume")); 840 case Warrant.RETRY_FWD: 841 return (rbx.getString("WarrantMoveToNext")); 842 case Warrant.SPEED_UP: 843 return (rbx.getString("WarrantSpeedUp")); 844 case Warrant.STOP: 845 return (rbx.getString("WarrantStop")); 846 case Warrant.ESTOP: 847 return (rbx.getString("WarrantEStop")); 848 case Warrant.ABORT: 849 return (rbx.getString("WarrantAbort")); 850 default: 851 log.error("Unhandled Warrant control: {}", data); 852 } 853 break; 854 default: 855 // fall through 856 break; 857 } 858 return ""; 859 } 860 861 @Override 862 public String description(boolean triggerType) { 863 String str = getOptionString(triggerType) + ", " + getTypeString(); 864 if (_deviceName.length() > 0) { 865 switch (_type) { 866 case CANCEL_TURNOUT_TIMERS: 867 case SET_SIGNAL_HELD: 868 case CLEAR_SIGNAL_HELD: 869 case SET_SIGNAL_DARK: 870 case SET_SIGNAL_LIT: 871 case TRIGGER_ROUTE: 872 case CANCEL_SENSOR_TIMERS: 873 case SET_MEMORY: 874 case ENABLE_LOGIX: 875 case DISABLE_LOGIX: 876 case COPY_MEMORY: 877 case SET_LIGHT_INTENSITY: 878 case SET_LIGHT_TRANSITION_TIME: 879 case ALLOCATE_WARRANT_ROUTE: 880 case DEALLOCATE_WARRANT_ROUTE: 881 case SET_SIGNALMAST_HELD: 882 case CLEAR_SIGNALMAST_HELD: 883 case SET_SIGNALMAST_DARK: 884 case SET_SIGNALMAST_LIT: 885 case SET_BLOCK_ERROR: 886 case CLEAR_BLOCK_ERROR: 887 case DEALLOCATE_BLOCK: 888 case SET_BLOCK_OUT_OF_SERVICE: 889 case SET_BLOCK_IN_SERVICE: 890 str = str + ", \"" + _deviceName + "\"."; 891 break; 892 case SET_NXPAIR_ENABLED: 893 case SET_NXPAIR_DISABLED: 894 case SET_NXPAIR_SEGMENT: 895 str = str + ", \"" + getBean().getUserName() + "\"."; 896 break; 897 case SET_ROUTE_TURNOUTS: 898 case AUTO_RUN_WARRANT: 899 case MANUAL_RUN_WARRANT: 900 str = str + " " + rbx.getString("onWarrant") + ", \"" + _deviceName + "\"."; 901 break; 902 case SET_SENSOR: 903 case SET_TURNOUT: 904 case SET_LIGHT: 905 case LOCK_TURNOUT: 906 case RESET_DELAYED_SENSOR: 907 case SET_SIGNAL_APPEARANCE: 908 case RESET_DELAYED_TURNOUT: 909 case DELAYED_TURNOUT: 910 case DELAYED_SENSOR: 911 case CONTROL_AUDIO: 912 str = str + ", \"" + _deviceName + "\" " + rbx.getString("to") 913 + " " + getActionDataString(); 914 break; 915 case GET_TRAIN_LOCATION: 916 case GET_BLOCK_WARRANT: 917 case GET_BLOCK_TRAIN_NAME: 918 str = str + " \"" + _deviceName + "\" " + rbx.getString("intoMemory") 919 + " " + _actionString; 920 break; 921 case SET_SIGNALMAST_ASPECT: 922 str = str + ", \"" + _deviceName + "\" " + rbx.getString("to") 923 + " " + _actionString; 924 break; 925 case CONTROL_TRAIN: 926 str = str + " " + rbx.getString("onWarrant") + " \"" + _deviceName + "\" " 927 + rbx.getString("to") + " " + getActionDataString(); 928 break; 929 default: 930 break; // nothing needed for others 931 } 932 } 933 if (_actionString.length() > 0) { 934 switch (_type) { 935 case SET_MEMORY: 936 case COPY_MEMORY: 937 str = str + " " + rbx.getString("to") + " " + _actionString + "."; 938 break; 939 case PLAY_SOUND: 940 case RUN_SCRIPT: 941 str = str + " " + rbx.getString("FromFile") + " " + _actionString + "."; 942 break; 943 case RESET_DELAYED_TURNOUT: 944 case RESET_DELAYED_SENSOR: 945 case DELAYED_TURNOUT: 946 case DELAYED_SENSOR: 947 str = str + rbx.getString("After") + " "; 948 try { 949 Float.parseFloat(_actionString); 950 str = str + _actionString + " " + rbx.getString("Seconds") + "."; 951 } catch (NumberFormatException nfe) { 952 str = str + _actionString + " " + rbx.getString("ValueInMemory") 953 + " " + rbx.getString("Seconds") + "."; 954 } 955 break; 956 case SET_LIGHT_TRANSITION_TIME: 957 case SET_LIGHT_INTENSITY: 958 try { 959 //int t = Integer.parseInt(_actionString); 960 str = str + " " + rbx.getString("to") + " " + _actionString + "."; 961 } catch (NumberFormatException nfe) { 962 str = str + " " + rbx.getString("to") + " " + _actionString + " " 963 + rbx.getString("ValueInMemory") + "."; 964 } 965 break; 966 case JYTHON_COMMAND: 967 str = str + " " + rbx.getString("ExecJythonCmd") + " " + _actionString + "."; 968 break; 969 case SET_TRAIN_ID: 970 case SET_TRAIN_NAME: 971 str = str + ", \"" + _actionString + "\" " + rbx.getString("onWarrant") 972 + " \"" + _deviceName + "\"."; 973 break; 974 case SET_BLOCK_VALUE: 975 str = str + ", \"" + _actionString + "\" " + rbx.getString("onBlock") 976 + " \"" + _deviceName + "\"."; 977 break; 978 default: 979 break; // nothing needed for others 980 } 981 } 982 switch (_type) { 983 case SET_LIGHT_INTENSITY: 984 case SET_LIGHT_TRANSITION_TIME: 985 str = str + " " + rbx.getString("to") + " " + _actionData + "."; 986 break; 987 case SET_FAST_CLOCK_TIME: 988 str = str + " " + rbx.getString("to") + " " 989 + LogixTableAction.formatTime(_actionData / 60, _actionData - ((_actionData / 60) * 60)); 990 break; 991 default: 992 break; // nothing needed for others 993 } 994 return str; 995 } 996 997 /** {@inheritDoc} */ 998 @Override 999 public void dispose() { 1000 if (_sound != null) { 1001 _sound.dispose(); 1002 } 1003 } 1004 1005 private final static Logger log = LoggerFactory.getLogger(DefaultConditionalAction.class); 1006 1007}