001package jmri.jmrit.logixng.actions;
002
003import java.util.*;
004
005import jmri.InstanceManager;
006import jmri.JmriException;
007import jmri.jmrit.logixng.*;
008
009/**
010 * This action executes an action and then runs some code.
011 * It is used internally.
012 *
013 * @author Daniel Bergqvist Copyright 2025
014 */
015public final class RunFinally extends AbstractDigitalAction
016        implements FemaleSocketListener {
017
018    /**
019     * The caller can send its own data to the runFinally() method using this
020     * interface.
021     */
022    public interface Data {}
023
024    /**
025     * The function the caller wants called after the action has been executed.
026     */
027    public interface RunFinallyFunction {
028        void runFinally(ConditionalNG conditionalNG, Exception ex, Data data);
029    }
030
031    private final FemaleDigitalActionSocket _socket;
032    private final RunFinallyFunction _runFinally;
033    private final Data _data;
034
035    public RunFinally(String sysName, RunFinallyFunction runFinally, Data data)
036            throws BadUserNameException {
037        super(sysName, null);
038        _socket = InstanceManager.getDefault(DigitalActionManager.class)
039                .createFemaleSocket(this, this, "A");
040        this._data = data;
041        this._runFinally = runFinally;
042    }
043
044    public RunFinally(String sysName, String userName, RunFinallyFunction runFinally, Data data)
045            throws BadUserNameException {
046        super(sysName, userName);
047        _socket = InstanceManager.getDefault(DigitalActionManager.class)
048                .createFemaleSocket(this, this, "A");
049        this._data = data;
050        this._runFinally = runFinally;
051    }
052
053    @Override
054    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames)
055            throws JmriException {
056        DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class);
057        String sysName = systemNames.get(getSystemName());
058        String userName = userNames.get(getSystemName());
059        if (sysName == null) sysName = manager.getAutoSystemName();
060        DigitalActionBean copy = new RunFinally(sysName, userName, _runFinally, _data);
061        copy.setComment(getComment());
062        return manager.registerAction(copy).deepCopyChildren(this, systemNames, userNames);
063    }
064
065    /** {@inheritDoc} */
066    @Override
067    public LogixNG_Category getCategory() {
068        return LogixNG_Category.OTHER;
069    }
070
071    /** {@inheritDoc} */
072    @Override
073    public void execute() throws JmriException {
074        Exception ex = null;
075        try {
076            if (_socket != null) {
077                _socket.execute();
078            }
079        } catch (JmriException | RuntimeException e) {
080            ex = e;
081        }
082        _runFinally.runFinally(getConditionalNG(), ex, _data);
083    }
084
085    @Override
086    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
087        return _socket;
088    }
089
090    @Override
091    public int getChildCount() {
092        return 1;
093    }
094
095    @Override
096    public String getShortDescription(Locale locale) {
097        return Bundle.getMessage(locale, "SetLocalVariables_Short");
098    }
099
100    @Override
101    public String getLongDescription(Locale locale) {
102        return Bundle.getMessage(locale, "SetLocalVariables_Long");
103    }
104
105    /** {@inheritDoc} */
106    @Override
107    public void setup() {
108        // Do nothing. This class is never stored to disk.
109    }
110
111    /** {@inheritDoc} */
112    @Override
113    public void registerListenersForThisClass() {
114    }
115
116    /** {@inheritDoc} */
117    @Override
118    public void unregisterListenersForThisClass() {
119    }
120
121    @Override
122    public void connected(FemaleSocket socket) {
123        // Do nothing. This class is never stored to disk.
124    }
125
126    @Override
127    public void disconnected(FemaleSocket socket) {
128        // Do nothing. This class is never stored to disk.
129    }
130
131    /** {@inheritDoc} */
132    @Override
133    public void disposeMe() {
134    }
135
136}