001package jmri.jmrit.logixng.actions;
002
003import java.util.Locale;
004import java.util.Map;
005
006import jmri.InstanceManager;
007import jmri.JmriException;
008import jmri.jmrit.logixng.*;
009
010/**
011 * Executes an string action with the result of an string expression.
012 * 
013 * @author Daniel Bergqvist Copyright 2019
014 */
015public class DoStringAction
016        extends AbstractDigitalAction
017        implements FemaleSocketListener {
018
019    private String _stringExpressionSocketSystemName;
020    private String _stringActionSocketSystemName;
021    private final FemaleStringExpressionSocket _stringExpressionSocket;
022    private final FemaleStringActionSocket _stringActionSocket;
023    
024    public DoStringAction(String sys, String user) {
025        super(sys, user);
026        _stringExpressionSocket = InstanceManager.getDefault(StringExpressionManager.class)
027                .createFemaleSocket(this, this, "E");
028        _stringActionSocket = InstanceManager.getDefault(StringActionManager.class)
029                .createFemaleSocket(this, this, "A");
030    }
031    
032    @Override
033    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws JmriException {
034        DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class);
035        String sysName = systemNames.get(getSystemName());
036        String userName = userNames.get(getSystemName());
037        if (sysName == null) sysName = manager.getAutoSystemName();
038        DoStringAction copy = new DoStringAction(sysName, userName);
039        copy.setComment(getComment());
040        return manager.registerAction(copy).deepCopyChildren(this, systemNames, userNames);
041    }
042    
043    /** {@inheritDoc} */
044    @Override
045    public Category getCategory() {
046        return Category.COMMON;
047    }
048
049    /** {@inheritDoc} */
050    @Override
051    public void execute() throws JmriException {
052        String result = _stringExpressionSocket.evaluate();
053        
054        _stringActionSocket.setValue(result);
055    }
056
057    @Override
058    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
059        switch (index) {
060            case 0:
061                return _stringExpressionSocket;
062                
063            case 1:
064                return _stringActionSocket;
065                
066            default:
067                throw new IllegalArgumentException(
068                        String.format("index has invalid value: %d", index));
069        }
070    }
071
072    @Override
073    public int getChildCount() {
074        return 2;
075    }
076
077    @Override
078    public void connected(FemaleSocket socket) {
079        if (socket == _stringExpressionSocket) {
080            _stringExpressionSocketSystemName = socket.getConnectedSocket().getSystemName();
081        } else if (socket == _stringActionSocket) {
082            _stringActionSocketSystemName = socket.getConnectedSocket().getSystemName();
083        } else {
084            throw new IllegalArgumentException("unkown socket");
085        }
086    }
087
088    @Override
089    public void disconnected(FemaleSocket socket) {
090        if (socket == _stringExpressionSocket) {
091            _stringExpressionSocketSystemName = null;
092        } else if (socket == _stringActionSocket) {
093            _stringActionSocketSystemName = null;
094        } else {
095            throw new IllegalArgumentException("unkown socket");
096        }
097    }
098
099    @Override
100    public String getShortDescription(Locale locale) {
101        return Bundle.getMessage(locale, "DoStringAction_Short");
102    }
103
104    @Override
105    public String getLongDescription(Locale locale) {
106        return Bundle.getMessage(locale, "DoStringAction_Long", _stringExpressionSocket.getName(), _stringActionSocket.getName());
107    }
108
109    public FemaleStringActionSocket getStringActionSocket() {
110        return _stringActionSocket;
111    }
112
113    public String getStringActionSocketSystemName() {
114        return _stringActionSocketSystemName;
115    }
116
117    public void setStringActionSocketSystemName(String systemName) {
118        _stringActionSocketSystemName = systemName;
119    }
120
121    public FemaleStringExpressionSocket getStringExpressionSocket() {
122        return _stringExpressionSocket;
123    }
124
125    public String getStringExpressionSocketSystemName() {
126        return _stringExpressionSocketSystemName;
127    }
128
129    public void setStringExpressionSocketSystemName(String systemName) {
130        _stringExpressionSocketSystemName = systemName;
131    }
132
133    /** {@inheritDoc} */
134    @Override
135    public void setup() {
136        try {
137            if (!_stringExpressionSocket.isConnected()
138                    || !_stringExpressionSocket.getConnectedSocket().getSystemName()
139                            .equals(_stringExpressionSocketSystemName)) {
140                
141                String socketSystemName = _stringExpressionSocketSystemName;
142                
143                _stringExpressionSocket.disconnect();
144                
145                if (socketSystemName != null) {
146                    MaleSocket maleSocket =
147                            InstanceManager.getDefault(StringExpressionManager.class)
148                                    .getBySystemName(socketSystemName);
149                    if (maleSocket != null) {
150                        _stringExpressionSocket.connect(maleSocket);
151                        maleSocket.setup();
152                    } else {
153                        log.error("cannot load string expression {}", socketSystemName);
154                    }
155                }
156            } else {
157                _stringExpressionSocket.getConnectedSocket().setup();
158            }
159            
160            if (!_stringActionSocket.isConnected()
161                    || !_stringActionSocket.getConnectedSocket().getSystemName()
162                            .equals(_stringActionSocketSystemName)) {
163                
164                String socketSystemName = _stringActionSocketSystemName;
165                
166                _stringActionSocket.disconnect();
167                
168                if (socketSystemName != null) {
169                    MaleSocket maleSocket =
170                            InstanceManager.getDefault(StringActionManager.class)
171                                    .getBySystemName(socketSystemName);
172                    if (maleSocket != null) {
173                        _stringActionSocket.connect(maleSocket);
174                        maleSocket.setup();
175                    } else {
176                        log.error("cannot load string action {}", socketSystemName);
177                    }
178                }
179            } else {
180                _stringActionSocket.getConnectedSocket().setup();
181            }
182        } catch (SocketAlreadyConnectedException ex) {
183            // This shouldn't happen and is a runtime error if it does.
184            throw new RuntimeException("socket is already connected");
185        }
186    }
187    
188    /** {@inheritDoc} */
189    @Override
190    public void registerListenersForThisClass() {
191    }
192    
193    /** {@inheritDoc} */
194    @Override
195    public void unregisterListenersForThisClass() {
196    }
197    
198    /** {@inheritDoc} */
199    @Override
200    public void disposeMe() {
201    }
202    
203    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DoStringAction.class);
204    
205}