001package jmri.implementation;
002
003import java.io.File;
004import java.util.Date;
005import java.util.List;
006
007import javax.annotation.Nonnull;
008import javax.script.ScriptException;
009import javax.swing.Timer;
010
011import jmri.*;
012import jmri.implementation.DefaultConditional.TimeSensor;
013import jmri.implementation.DefaultConditional.TimeTurnout;
014import jmri.jmrit.Sound;
015import jmri.jmrit.audio.AudioListener;
016import jmri.jmrit.audio.AudioSource;
017import jmri.jmrit.entryexit.DestinationPoints;
018import jmri.jmrit.entryexit.EntryExitPairs;
019import jmri.jmrit.logix.OBlock;
020import jmri.jmrit.logix.Warrant;
021import jmri.script.JmriScriptEngineManager;
022import jmri.script.swing.ScriptOutput;
023
024/**
025 * Helper class for DefaultConditional that executes the  actions of a
026 * DefaultConditional.
027 * @author Daniel Bergqvist (C) 2021
028 */
029public class DefaultConditionalExecute {
030
031    private final DefaultConditional conditional;
032
033    DefaultConditionalExecute(@Nonnull DefaultConditional conditional) {
034        this.conditional = conditional;
035    }
036
037    void setTurnout(@Nonnull ConditionalAction action, Turnout t, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
038        if (t == null) {
039            errorList.add("invalid turnout name in action - " + action.getDeviceName());  // NOI18N
040        } else {
041            int act = action.getActionData();
042            if (act == Route.TOGGLE) {
043                int state = t.getKnownState();
044                if (state == Turnout.CLOSED) {
045                    act = Turnout.THROWN;
046                } else {
047                    act = Turnout.CLOSED;
048                }
049            }
050            t.setCommandedState(act);
051            increaseCounter(actionCount);
052        }
053    }
054
055    void delayedTurnout(@Nonnull ConditionalAction action, @Nonnull Reference<Integer> actionCount, @Nonnull TimeTurnout timeTurnout, boolean reset, String devName) {
056        if (reset) {
057            action.stopTimer();
058        }
059        if (!action.isTimerActive()) {
060            // Create a timer if one does not exist
061            Timer timer = action.getTimer();
062            if (timer == null) {
063                action.setListener(timeTurnout);
064                timer = new Timer(2000, action.getListener());
065                timer.setRepeats(true);
066            }
067            // Start the Timer to set the turnout
068            int value = conditional.getMillisecondValue(action);
069            if (value < 0) {
070                return;
071            }
072            timer.setInitialDelay(value);
073            action.setTimer(timer);
074            action.startTimer();
075            increaseCounter(actionCount);
076        } else {
077            log.warn("timer already active on request to start delayed turnout action - {}", devName);
078        }
079    }
080
081    void cancelTurnoutTimers(@Nonnull ConditionalAction action, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList, String devName) {
082        ConditionalManager cmg = InstanceManager.getDefault(ConditionalManager.class);
083        java.util.Iterator<Conditional> iter = cmg.getNamedBeanSet().iterator();
084        while (iter.hasNext()) {
085            String sname = iter.next().getSystemName();
086
087            Conditional c = cmg.getBySystemName(sname);
088            if (c == null) {
089                errorList.add("Conditional null during cancel turnout timers for "  // NOI18N
090                        + action.getDeviceName());
091                continue; // no more processing of this one
092            }
093
094            c.cancelTurnoutTimer(devName);
095            increaseCounter(actionCount);
096        }
097    }
098
099    void lockTurnout(@Nonnull ConditionalAction action, Turnout tl, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
100        if (tl == null) {
101            errorList.add("invalid turnout name in action - " + action.getDeviceName());  // NOI18N
102        } else {
103            int act = action.getActionData();
104            if (act == Route.TOGGLE) {
105                if (tl.getLocked(Turnout.CABLOCKOUT)) {
106                    act = Turnout.UNLOCKED;
107                } else {
108                    act = Turnout.LOCKED;
109                }
110            }
111            if (act == Turnout.LOCKED) {
112                tl.setLocked(Turnout.CABLOCKOUT + Turnout.PUSHBUTTONLOCKOUT, true);
113            } else if (act == Turnout.UNLOCKED) {
114                tl.setLocked(Turnout.CABLOCKOUT + Turnout.PUSHBUTTONLOCKOUT, false);
115            }
116            increaseCounter(actionCount);
117        }
118    }
119
120    void setSignalAppearance(@Nonnull ConditionalAction action, SignalHead h, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
121        if (h == null) {
122            errorList.add("invalid Signal Head name in action - " + action.getDeviceName());  // NOI18N
123        } else {
124            h.setAppearance(action.getActionData());
125            increaseCounter(actionCount);
126        }
127    }
128
129    void setSignalHeld(@Nonnull ConditionalAction action, SignalHead h, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
130        if (h == null) {
131            errorList.add("invalid Signal Head name in action - " + action.getDeviceName());  // NOI18N
132        } else {
133            h.setHeld(true);
134            increaseCounter(actionCount);
135        }
136    }
137
138    void clearSignalHeld(@Nonnull ConditionalAction action, SignalHead h, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
139        if (h == null) {
140            errorList.add("invalid Signal Head name in action - " + action.getDeviceName());  // NOI18N
141        } else {
142            h.setHeld(false);
143            increaseCounter(actionCount);
144        }
145    }
146
147    void setSignalDark(@Nonnull ConditionalAction action, SignalHead h, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
148        if (h == null) {
149            errorList.add("invalid Signal Head name in action - " + action.getDeviceName());  // NOI18N
150        } else {
151            h.setLit(false);
152            increaseCounter(actionCount);
153        }
154    }
155
156    void setSignalLit(@Nonnull ConditionalAction action, SignalHead h, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
157        if (h == null) {
158            errorList.add("invalid Signal Head name in action - " + action.getDeviceName());  // NOI18N
159        } else {
160            h.setLit(true);
161            increaseCounter(actionCount);
162        }
163    }
164
165    void triggerRoute(@Nonnull ConditionalAction action, Route r, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
166        if (r == null) {
167            errorList.add("invalid Route name in action - " + action.getDeviceName());  // NOI18N
168        } else {
169            r.setRoute();
170            increaseCounter(actionCount);
171        }
172    }
173
174    void setSensor(@Nonnull ConditionalAction action, Sensor sn, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList, String devName) {
175        if (sn == null) {
176            errorList.add("invalid Sensor name in action - " + action.getDeviceName());  // NOI18N
177        } else {
178            int act = action.getActionData();
179            if (act == Route.TOGGLE) {
180                int state = sn.getState();
181                if (state == Sensor.ACTIVE) {
182                    act = Sensor.INACTIVE;
183                } else {
184                    act = Sensor.ACTIVE;
185                }
186            }
187            try {
188                sn.setKnownState(act);
189                increaseCounter(actionCount);
190            } catch (JmriException e) {
191                log.warn("Exception setting Sensor {} in action", devName);  // NOI18N
192            }
193        }
194    }
195
196    void delayedSensor(@Nonnull ConditionalAction action, @Nonnull Reference<Integer> actionCount, @Nonnull TimeSensor timeSensor, int delay, boolean reset, String devName) {
197        if (reset) {
198            action.stopTimer();
199        }
200        if (!action.isTimerActive()) {
201            // Create a timer if one does not exist
202            Timer timer = action.getTimer();
203            if (timer == null) {
204                action.setListener(timeSensor);
205                timer = new Timer(2000, action.getListener());
206                timer.setRepeats(true);
207            }
208            // Start the Timer to set the sensor
209            if (delay < 0) {
210                return;
211            }
212            timer.setInitialDelay(delay);
213            action.setTimer(timer);
214            action.startTimer();
215            increaseCounter(actionCount);
216        } else {
217            log.warn("timer already active on request to start delayed sensor action - {}", devName);
218        }
219    }
220
221    void cancelSensorTimers(@Nonnull ConditionalAction action, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList, String devName) {
222        ConditionalManager cm = InstanceManager.getDefault(ConditionalManager.class);
223        java.util.Iterator<Conditional> itr = cm.getNamedBeanSet().iterator();
224        while (itr.hasNext()) {
225            String sname = itr.next().getSystemName();
226            Conditional c = cm.getBySystemName(sname);
227            if (c == null) {
228                errorList.add("Conditional null during cancel sensor timers for "  // NOI18N
229                        + action.getDeviceName());
230                continue; // no more processing of this one
231            }
232
233            c.cancelSensorTimer(devName);
234            increaseCounter(actionCount);
235        }
236    }
237
238    void setLight(@Nonnull ConditionalAction action, Light lgt, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
239        if (lgt == null) {
240            errorList.add("invalid light name in action - " + action.getDeviceName());  // NOI18N
241        } else {
242            int act = action.getActionData();
243            if (act == Route.TOGGLE) {
244                int state = lgt.getState();
245                if (state == Light.ON) {
246                    act = Light.OFF;
247                } else {
248                    act = Light.ON;
249                }
250            }
251            lgt.setState(act);
252            increaseCounter(actionCount);
253        }
254    }
255
256    void setLightIntensity(@Nonnull ConditionalAction action, Light lgt, int intensity, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
257        if (lgt == null) {
258            errorList.add("invalid light name in action - " + action.getDeviceName());  // NOI18N
259        } else {
260            try {
261                if (intensity < 0) {
262                    return;
263                }
264                if (lgt instanceof VariableLight) {
265                    ((VariableLight)lgt).setTargetIntensity((intensity) / 100.0);
266                } else {
267                    lgt.setState(intensity > 0.5 ? Light.ON : Light.OFF);
268                }
269                increaseCounter(actionCount);
270            } catch (IllegalArgumentException e) {
271                errorList.add("Exception in set light intensity action - " + action.getDeviceName());  // NOI18N
272            }
273        }
274    }
275
276    void setLightTransitionTime(@Nonnull ConditionalAction action, Light lgt, int time, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
277        if (lgt == null) {
278            errorList.add("invalid light name in action - " + action.getDeviceName());  // NOI18N
279        } else {
280            try {
281                if (time  < 0) {
282                    return;
283                }
284                if (lgt instanceof VariableLight) {
285                    ((VariableLight)lgt).setTransitionTime(time );
286                }
287                increaseCounter(actionCount);
288            } catch (IllegalArgumentException e) {
289                errorList.add("Exception in set light transition time action - " + action.getDeviceName());  // NOI18N
290            }
291        }
292    }
293
294    void setMemory(@Nonnull ConditionalAction action, Memory m, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
295        if (m == null) {
296            errorList.add("invalid memory name in action - " + action.getDeviceName());  // NOI18N
297        } else {
298            m.setValue(action.getActionString());
299            increaseCounter(actionCount);
300        }
301    }
302
303    void copyMemory(@Nonnull ConditionalAction action, Memory mFrom, Memory mTo, String actionStr, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
304        if (mFrom == null) {
305            errorList.add("invalid memory name in action - " + action.getDeviceName());  // NOI18N
306        } else {
307            if (mTo == null) {
308                errorList.add("invalid memory name in action - " + action.getActionString());  // NOI18N
309            } else {
310                mTo.setValue(mFrom.getValue());
311                increaseCounter(actionCount);
312            }
313        }
314    }
315
316    void enableLogix(@Nonnull ConditionalAction action, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList, String devName) {
317        Logix x = InstanceManager.getDefault(LogixManager.class).getLogix(devName);
318        if (x == null) {
319            errorList.add("invalid logix name in action - " + action.getDeviceName());  // NOI18N
320        } else {
321            x.setEnabled(true);
322            increaseCounter(actionCount);
323        }
324    }
325
326    void disableLogix(@Nonnull ConditionalAction action, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList, String devName) {
327        Logix x = InstanceManager.getDefault(LogixManager.class).getLogix(devName);
328        if (x == null) {
329            errorList.add("invalid logix name in action - " + action.getDeviceName());  // NOI18N
330        } else {
331            x.setEnabled(false);
332            increaseCounter(actionCount);
333        }
334    }
335
336    void playSound(@Nonnull ConditionalAction action, String actionStr, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
337        String path = actionStr;
338        if (!path.equals("")) {
339            Sound sound = action.getSound();
340            if (sound == null) {
341                try {
342                    sound = new Sound(path);
343                } catch (NullPointerException ex) {
344                    errorList.add("invalid path to sound: " + path);  // NOI18N
345                }
346            }
347            if (sound != null) {
348                sound.play();
349            }
350            increaseCounter(actionCount);
351        }
352    }
353
354    void runScript(@Nonnull ConditionalAction action, String actionStr, @Nonnull Reference<Integer> actionCount) {
355        if (!(actionStr.equals(""))) {
356            JmriScriptEngineManager.getDefault().runScript(new File(jmri.util.FileUtil.getExternalFilename(actionStr)));
357            increaseCounter(actionCount);
358        }
359    }
360
361    @SuppressWarnings({"deprecation"})  // date.setHours, date.setMinutes, date.setSeconds
362    void setFastClockTime(@Nonnull ConditionalAction action, @Nonnull Reference<Integer> actionCount) {
363        Date date = InstanceManager.getDefault(Timebase.class).getTime();
364        date.setHours(action.getActionData() / 60);
365        date.setMinutes(action.getActionData() - ((action.getActionData() / 60) * 60));
366        date.setSeconds(0);
367        InstanceManager.getDefault(Timebase.class).userSetTime(date);
368        increaseCounter(actionCount);
369    }
370
371    void startFastClock(@Nonnull Reference<Integer> actionCount) {
372        InstanceManager.getDefault(Timebase.class).setRun(true);
373        increaseCounter(actionCount);
374    }
375
376    void stopFastClock(@Nonnull Reference<Integer> actionCount) {
377        InstanceManager.getDefault(Timebase.class).setRun(false);
378        increaseCounter(actionCount);
379    }
380
381    void controlAudio(@Nonnull ConditionalAction action, String devName) {
382        Audio audio = InstanceManager.getDefault(AudioManager.class).getAudio(devName);
383        if (audio == null) {
384            return;
385        }
386        if (audio.getSubType() == Audio.SOURCE) {
387            AudioSource audioSource = (AudioSource) audio;
388            switch (action.getActionData()) {
389                case Audio.CMD_PLAY:
390                    audioSource.play();
391                    break;
392                case Audio.CMD_STOP:
393                    audioSource.stop();
394                    break;
395                case Audio.CMD_PLAY_TOGGLE:
396                    audioSource.togglePlay();
397                    break;
398                case Audio.CMD_PAUSE:
399                    audioSource.pause();
400                    break;
401                case Audio.CMD_RESUME:
402                    audioSource.resume();
403                    break;
404                case Audio.CMD_PAUSE_TOGGLE:
405                    audioSource.togglePause();
406                    break;
407                case Audio.CMD_REWIND:
408                    audioSource.rewind();
409                    break;
410                case Audio.CMD_FADE_IN:
411                    audioSource.fadeIn();
412                    break;
413                case Audio.CMD_FADE_OUT:
414                    audioSource.fadeOut();
415                    break;
416                case Audio.CMD_RESET_POSITION:
417                    audioSource.resetCurrentPosition();
418                    break;
419                default:
420                    break;
421            }
422        } else if (audio.getSubType() == Audio.LISTENER) {
423            AudioListener audioListener = (AudioListener) audio;
424            switch (action.getActionData()) {
425                case Audio.CMD_RESET_POSITION:
426                    audioListener.resetCurrentPosition();
427                    break;
428                default:
429                    break; // nothing needed for others
430            }
431        }
432    }
433
434    void jythonCommand(@Nonnull ConditionalAction action, String actionStr, @Nonnull Reference<Integer> actionCount) {
435        if (!(actionStr.isEmpty())) {
436            // add the text to the output frame
437            ScriptOutput.writeScript(actionStr);
438            // and execute
439
440            javax.script.ScriptEngine se =  JmriScriptEngineManager.getDefault().getEngine(JmriScriptEngineManager.JYTHON);
441            if (se!=null) {
442                try {
443                    JmriScriptEngineManager.getDefault().eval(actionStr, se);
444                } catch (ScriptException ex) {
445                    log.error("Error executing script:", ex);  // NOI18N
446                }
447            } else {
448                log.error("Error getting default ScriptEngine");
449            }
450            increaseCounter(actionCount);
451        }
452    }
453
454    void allocateWarrantRoute(@Nonnull ConditionalAction action, Warrant w, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
455        if (w == null) {
456            errorList.add("invalid Warrant name in action - " + action.getDeviceName());  // NOI18N
457        } else {
458            String msg = w.allocateRoute(false, null);
459            if (msg != null) {
460                log.info("Warrant {} - {}", action.getDeviceName(), msg);  // NOI18N
461            }
462            increaseCounter(actionCount);
463        }
464    }
465
466    void deallocateWarrantRoute(@Nonnull ConditionalAction action, Warrant w, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
467        if (w == null) {
468            errorList.add("invalid Warrant name in action - " + action.getDeviceName());  // NOI18N
469        } else {
470            w.deAllocate();
471            increaseCounter(actionCount);
472        }
473    }
474
475    void setRouteTurnouts(@Nonnull ConditionalAction action, Warrant w, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
476        if (w == null) {
477            errorList.add("invalid Warrant name in action - " + action.getDeviceName());  // NOI18N
478        } else {
479            String msg = w.setRoute(false, null);
480            if (msg != null) {
481                log.info("Warrant {} unable to Set Route - {}", action.getDeviceName(), msg);  // NOI18N
482            }
483            increaseCounter(actionCount);
484        }
485    }
486
487    void setTrainId(@Nonnull ConditionalAction action, Warrant w, String actionStr, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
488        if (w == null) {
489            errorList.add("invalid Warrant name in action - " + action.getDeviceName());  // NOI18N
490        } else {
491            if (w.getRunMode() != Warrant.MODE_NONE) {
492                errorList.add("Cannot set when Warrant is running - " + action.getActionString());  // NOI18N
493            } else if(!w.getSpeedUtil().setAddress(actionStr)) {
494                errorList.add("invalid train ID in action - " + action.getDeviceName());  // NOI18N
495            }
496            increaseCounter(actionCount);
497        }
498    }
499
500    void setTrainName(@Nonnull ConditionalAction action, Warrant w, String actionStr, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
501        if (w == null) {
502            errorList.add("invalid Warrant name in action - " + action.getDeviceName());  // NOI18N
503        } else {
504            w.setTrainName(actionStr);
505            increaseCounter(actionCount);
506        }
507    }
508
509    void getTrainLocation(@Nonnull ConditionalAction action, Warrant w, Memory mTo, String actionStr, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
510        if (w == null) {
511            errorList.add("invalid Warrant name in action - " + action.getDeviceName());  // NOI18N
512        } else {
513            if (mTo == null) {
514                errorList.add("invalid memory name in action - " + action.getActionString());  // NOI18N
515            } else {
516                mTo.setValue(w.getCurrentBlockName());
517                increaseCounter(actionCount);
518            }
519        }
520    }
521
522    void autoRunWarrant(@Nonnull ConditionalAction action, Warrant w, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
523        if (w == null) {
524            errorList.add("invalid Warrant name in action - " + action.getDeviceName());  // NOI18N
525        } else {
526            jmri.jmrit.logix.WarrantTableFrame frame = jmri.jmrit.logix.WarrantTableFrame.getDefault();
527            String err = frame.runTrain(w, Warrant.MODE_RUN);
528            if (err != null) {
529                errorList.add("runAutoTrain error - " + err);  // NOI18N
530                w.stopWarrant(true, true);
531            }
532            increaseCounter(actionCount);
533        }
534    }
535
536    void manualRunWarrant(@Nonnull ConditionalAction action, Warrant w, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
537        if (w == null) {
538            errorList.add("invalid Warrant name in action - " + action.getDeviceName());  // NOI18N
539        } else {
540            if (w.getRunMode() != Warrant.MODE_NONE) {
541                errorList.add("Cannot set when Warrant is running - " + action.getActionString());  // NOI18N
542            } else {
543                String err = w.setRoute(false, null);
544                if (err == null) {
545                    err = w.setRunMode(Warrant.MODE_MANUAL, null, null, null, false);
546                }
547                if (err != null) {
548                    errorList.add("runManualTrain error - " + err);  // NOI18N
549                }
550            }
551            increaseCounter(actionCount);
552        }
553    }
554
555    void controlTrain(@Nonnull ConditionalAction action, Warrant w, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList, String devName) {
556        if (w == null) {
557            errorList.add("invalid Warrant name in action - " + action.getDeviceName());  // NOI18N
558        } else {
559            if (!w.controlRunTrain(action.getActionData())) {
560                log.info("Train {} not running  - {}", w.getSpeedUtil().getRosterId(), devName);  // NOI18N
561            }
562            increaseCounter(actionCount);
563        }
564    }
565
566    void setSignalMastAspect(@Nonnull ConditionalAction action, SignalMast f, String actionStr, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
567        if (f == null) {
568            errorList.add("invalid Signal Mast name in action - " + action.getDeviceName());  // NOI18N
569        } else {
570            f.setAspect(actionStr);
571            increaseCounter(actionCount);
572        }
573    }
574
575    void setSignalMastHeld(@Nonnull ConditionalAction action, SignalMast f, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
576        if (f == null) {
577            errorList.add("invalid Signal Mast name in action - " + action.getDeviceName());  // NOI18N
578        } else {
579            f.setHeld(true);
580            increaseCounter(actionCount);
581        }
582    }
583
584    void clearSignalMastHeld(@Nonnull ConditionalAction action, SignalMast f, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
585        if (f == null) {
586            errorList.add("invalid Signal Mast name in action - " + action.getDeviceName());  // NOI18N
587        } else {
588            f.setHeld(false);
589            increaseCounter(actionCount);
590        }
591    }
592
593    void setSignalMastDark(@Nonnull ConditionalAction action, SignalMast f, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
594        if (f == null) {
595            errorList.add("invalid Signal Head name in action - " + action.getDeviceName());  // NOI18N
596        } else {
597            f.setLit(false);
598            increaseCounter(actionCount);
599        }
600    }
601
602    void setSignalMastLit(@Nonnull ConditionalAction action, SignalMast f, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
603        if (f == null) {
604            errorList.add("invalid Signal Head name in action - " + action.getDeviceName());  // NOI18N
605        } else {
606            f.setLit(true);
607            increaseCounter(actionCount);
608        }
609    }
610
611    void setBlockValue(@Nonnull ConditionalAction action, OBlock b, String actionStr, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
612        if (b == null) {
613            errorList.add("invalid Block name in action - " + action.getDeviceName());  // NOI18N
614        } else {
615            b.setValue(actionStr);
616            increaseCounter(actionCount);
617        }
618    }
619
620    void setBlockError(@Nonnull ConditionalAction action, OBlock b, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
621        if (b == null) {
622            errorList.add("invalid Block name in action - " + action.getDeviceName());  // NOI18N
623        } else {
624            b.setError(true);
625            increaseCounter(actionCount);
626        }
627    }
628
629    void clearBlockError(@Nonnull ConditionalAction action, OBlock b, @Nonnull List<String> errorList) {
630        if (b == null) {
631            errorList.add("invalid Block name in action - " + action.getDeviceName());  // NOI18N
632        } else {
633            b.setError(false);
634        }
635    }
636
637    void deallocateBlock(@Nonnull ConditionalAction action, OBlock b, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
638        if (b == null) {
639            errorList.add("invalid Block name in action - " + action.getDeviceName());  // NOI18N
640        } else {
641            b.deAllocate(null);
642            increaseCounter(actionCount);
643        }
644    }
645
646    void setBlockOutOfService(@Nonnull ConditionalAction action, OBlock b, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
647        if (b == null) {
648            errorList.add("invalid Block name in action - " + action.getDeviceName());  // NOI18N
649        } else {
650            b.setOutOfService(true);
651            increaseCounter(actionCount);
652        }
653    }
654
655    void setBlockInService(@Nonnull ConditionalAction action, OBlock b, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
656        if (b == null) {
657            errorList.add("invalid Block name in action - " + action.getDeviceName());  // NOI18N
658        } else {
659            b.setOutOfService(false);
660            increaseCounter(actionCount);
661        }
662    }
663
664    void getBlockTrainName(@Nonnull ConditionalAction action, OBlock b, Memory mTo, String actionStr, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
665        if (b == null) {
666            errorList.add("invalid Block name in action - " + action.getDeviceName());  // NOI18N
667        } else {
668            if (mTo == null) {
669                errorList.add("invalid memory name in action - " + action.getActionString());  // NOI18N
670            } else {
671                String name = (String)b.getValue();
672                if (name == null) {
673                    name = " ";
674                }
675                mTo.setValue(name);
676                increaseCounter(actionCount);
677            }
678        }
679    }
680
681    void getBlockWarrant(@Nonnull ConditionalAction action, OBlock b, Memory mTo, String actionStr, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList) {
682        if (b == null) {
683            errorList.add("invalid Block name in action - " + action.getDeviceName());  // NOI18N
684        } else {
685            if (mTo == null) {
686                errorList.add("invalid memory name in action - " + action.getActionString());  // NOI18N
687            } else {
688                Warrant w = b.getWarrant();
689                String name;
690                if (w != null) {
691                    name = w.getDisplayName();
692                } else {
693                    name = " ";
694                }
695                mTo.setValue(name);
696                increaseCounter(actionCount);
697            }
698        }
699    }
700
701    void setNXPairEnabled(@Nonnull ConditionalAction action, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList, String devName) {
702        DestinationPoints dp = InstanceManager.getDefault(EntryExitPairs.class).getNamedBean(devName);
703        if (dp == null) {
704            errorList.add("Invalid NX Pair name in action - " + action.getDeviceName());  // NOI18N
705        } else {
706            dp.setEnabled(true);
707            increaseCounter(actionCount);
708        }
709    }
710
711    void setNXPairDisabled(@Nonnull ConditionalAction action, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList, String devName) {
712        DestinationPoints dp = InstanceManager.getDefault(EntryExitPairs.class).getNamedBean(devName);
713        if (dp == null) {
714            errorList.add("Invalid NX Pair name in action - " + action.getDeviceName());  // NOI18N
715        } else {
716            dp.setEnabled(false);
717            increaseCounter(actionCount);
718        }
719    }
720
721    void setNXPairSegment(@Nonnull ConditionalAction action, @Nonnull Reference<Integer> actionCount, @Nonnull List<String> errorList, String devName) {
722        DestinationPoints dp = InstanceManager.getDefault(EntryExitPairs.class).getNamedBean(devName);
723        if (dp == null) {
724            errorList.add("Invalid NX Pair name in action - " + action.getDeviceName());  // NOI18N
725        } else {
726            InstanceManager.getDefault(EntryExitPairs.class).
727                    setSingleSegmentRoute(devName);
728            increaseCounter(actionCount);
729        }
730    }
731
732    private void increaseCounter(@Nonnull Reference<Integer> actionCount) {
733        // actionCount.get() is never null, but Spotbugs doesn't know that
734        Integer value = actionCount.get();
735        actionCount.set(value != null ? value+1 : 0);
736    }
737
738    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultConditionalExecute.class);
739}