001package jmri.jmrix.mqtt.logixng;
002
003import jmri.jmrit.logixng.actions.*;
004
005import java.util.*;
006
007import jmri.*;
008import jmri.jmrit.logixng.*;
009import jmri.jmrit.logixng.util.LogixNG_SelectString;
010import jmri.jmrit.logixng.util.parser.ParserException;
011import jmri.jmrix.mqtt.MqttSystemConnectionMemo;
012import jmri.util.ThreadingUtil;
013
014/**
015 * This action publishes a message to MQTT.
016 *
017 * @author Daniel Bergqvist Copyright 2022
018 */
019public class Publish extends AbstractDigitalAction {
020
021    private final LogixNG_SelectString _selectTopic = new LogixNG_SelectString(this);
022    private final LogixNG_SelectString _selectMessage = new LogixNG_SelectString(this);
023
024    private MqttSystemConnectionMemo _memo;
025
026    private Retain _retain;
027
028
029    public Publish(String sys, String user, MqttSystemConnectionMemo memo)
030            throws BadUserNameException, BadSystemNameException {
031        super(sys, user);
032        _memo = memo;
033        _retain = Retain.Default;
034    }
035
036    @Override
037    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws ParserException {
038        DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class);
039        String sysName = systemNames.get(getSystemName());
040        String userName = userNames.get(getSystemName());
041        if (sysName == null) sysName = manager.getAutoSystemName();
042        Publish copy = new Publish(sysName, userName, _memo);
043        copy.setComment(getComment());
044        _selectTopic.copy(copy._selectTopic);
045        _selectMessage.copy(copy._selectMessage);
046        copy.setRetain(_retain);
047        return manager.registerAction(copy);
048    }
049
050    public void setMemo(MqttSystemConnectionMemo memo) {
051        assertListenersAreNotRegistered(log, "setMemo");
052        _memo = memo;
053    }
054
055    public MqttSystemConnectionMemo getMemo() {
056        return _memo;
057    }
058
059    public LogixNG_SelectString getSelectTopic() {
060        return _selectTopic;
061    }
062
063    public LogixNG_SelectString getSelectMessage() {
064        return _selectMessage;
065    }
066
067    public void setRetain(Retain retain) {
068        assertListenersAreNotRegistered(log, "setRetain");
069        _retain = retain;
070    }
071
072    public Retain getRetain() {
073        return _retain;
074    }
075
076    /** {@inheritDoc} */
077    @Override
078    public LogixNG_Category getCategory() {
079        return CategoryMqtt.MQTT;
080    }
081
082    /** {@inheritDoc} */
083    @Override
084    public void execute() throws JmriException {
085
086        String topic = _selectTopic.evaluateValue(getConditionalNG());
087        String data = _selectMessage.evaluateValue(getConditionalNG());
088
089        boolean retain = _retain.getRetainValue(_memo);
090
091        ThreadingUtil.runOnLayoutWithJmriException(() -> {
092            _memo.getMqttAdapter().publish(topic, data, retain);
093        });
094    }
095
096    @Override
097    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
098        throw new UnsupportedOperationException("Not supported.");
099    }
100
101    @Override
102    public int getChildCount() {
103        return 0;
104    }
105
106    @Override
107    public String getShortDescription(Locale locale) {
108        return Bundle.getMessage(locale, "Publish_Short");
109    }
110
111    @Override
112    public String getLongDescription(Locale locale) {
113        return Bundle.getMessage(locale, "Publish_Long",
114                _selectTopic.getDescription(locale),
115                _selectMessage.getDescription(locale),
116                _retain.toString());
117    }
118
119    /** {@inheritDoc} */
120    @Override
121    public void setup() {
122        // Do nothing
123    }
124
125    /** {@inheritDoc} */
126    @Override
127    public void disposeMe() {
128    }
129
130
131    public enum Retain {
132        Default(Bundle.getMessage("Publish_Retain_Default")),
133        Yes(Bundle.getMessage("Publish_Retain_Yes")),
134        No(Bundle.getMessage("Publish_Retain_No"));
135
136        private final String _text;
137
138        private Retain(String text) {
139            this._text = text;
140        }
141
142        public boolean getRetainValue(MqttSystemConnectionMemo memo) {
143            switch (this) {
144                case Default:
145                    return memo.getMqttAdapter().retained;
146                case Yes:
147                    return true;
148                case No:
149                    return false;
150                default:
151                    throw new IllegalArgumentException("invalid retain");
152            }
153        }
154
155        @Override
156        public String toString() {
157            return _text;
158        }
159
160    }
161
162
163    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Publish.class);
164
165}