001package jmri.jmrit.logixng.actions;
002
003import java.beans.*;
004import java.util.*;
005
006import jmri.*;
007import jmri.jmrit.logixng.*;
008import jmri.jmrit.logixng.util.LogixNG_SelectNamedBean;
009import jmri.jmrit.logixng.util.parser.ParserException;
010
011/**
012 * Executes a digital action.
013 *
014 * @author Daniel Bergqvist Copyright 2024
015 */
016public class ExecuteAction extends AbstractDigitalAction
017        implements PropertyChangeListener, VetoableChangeListener {
018
019    private final LogixNG_SelectNamedBean<MaleDigitalActionSocket> _selectNamedBean =
020            new LogixNG_SelectNamedBean<>(
021                    this, MaleDigitalActionSocket.class, InstanceManager.getDefault(DigitalActionManager.class), this);
022
023    public ExecuteAction(String sys, String user)
024            throws BadUserNameException, BadSystemNameException {
025        super(sys, user);
026        _selectNamedBean.setOnlyDirectAddressingAllowed();
027    }
028
029    @Override
030    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws ParserException {
031        DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class);
032        String sysName = systemNames.get(getSystemName());
033        String userName = userNames.get(getSystemName());
034        if (sysName == null) sysName = manager.getAutoSystemName();
035        ExecuteAction copy = new ExecuteAction(sysName, userName);
036        copy.setComment(getComment());
037        _selectNamedBean.copy(copy._selectNamedBean);
038        return manager.registerAction(copy);
039    }
040
041    public LogixNG_SelectNamedBean<MaleDigitalActionSocket> getSelectNamedBean() {
042        return _selectNamedBean;
043    }
044
045    /** {@inheritDoc} */
046    @Override
047    public Category getCategory() {
048        return Category.OTHER;
049    }
050
051    /** {@inheritDoc} */
052    @Override
053    public void execute() throws JmriException {
054        MaleDigitalActionSocket action =
055                _selectNamedBean.evaluateNamedBean(getConditionalNG());
056
057        if (action == null) {
058            log.error("The action is null");
059            return;
060        }
061
062        if (getConditionalNG() != action.getConditionalNG()) {
063            // If the action is not in the same ConditionalNG, the action
064            // might be executed concurrent by the other ConditionalNG if
065            // the two ConditionalNGs executes in two different threads.
066            // And LogixNG actions/expressions are not designed to handle
067            // that.
068            log.error("The action is not in the same ConditionalNG as this action.");
069            return;
070        }
071
072        action.execute();
073    }
074
075    @Override
076    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
077        throw new UnsupportedOperationException("Not supported.");
078    }
079
080    @Override
081    public int getChildCount() {
082        return 0;
083    }
084
085    @Override
086    public String getShortDescription(Locale locale) {
087        return Bundle.getMessage(locale, "ExecuteAction_Short");
088    }
089
090    @Override
091    public String getLongDescription(Locale locale) {
092        String beanName = _selectNamedBean.getDescription(locale);
093
094        return Bundle.getMessage(locale, "ExecuteAction_Long",
095                beanName);
096    }
097
098    /** {@inheritDoc} */
099    @Override
100    public void setup() {
101        _selectNamedBean.setup();
102    }
103
104    /** {@inheritDoc} */
105    @Override
106    public void registerListenersForThisClass() {
107        if (!_listenersAreRegistered) {
108            _selectNamedBean.addPropertyChangeListener(PROPERTY_LAST_RESULT_CHANGED, this);
109            _selectNamedBean.registerListeners();
110            _listenersAreRegistered = true;
111        }
112    }
113
114    /** {@inheritDoc} */
115    @Override
116    public void unregisterListenersForThisClass() {
117        if (_listenersAreRegistered) {
118            _selectNamedBean.removePropertyChangeListener(PROPERTY_LAST_RESULT_CHANGED, this);
119            _selectNamedBean.unregisterListeners();
120            _listenersAreRegistered = false;
121        }
122    }
123
124    /** {@inheritDoc} */
125    @Override
126    public void propertyChange(PropertyChangeEvent evt) {
127        getConditionalNG().execute();
128    }
129
130    /** {@inheritDoc} */
131    @Override
132    public void disposeMe() {
133    }
134
135    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExecuteAction.class);
136
137}