001package jmri.jmrit.logixng;
002
003import java.util.List;
004
005import javax.annotation.Nonnull;
006
007import jmri.JmriException;
008import jmri.NamedBean;
009import jmri.jmrit.logixng.SymbolTable.InitialValueType;
010import jmri.jmrit.logixng.SymbolTable.VariableData;
011
012import org.slf4j.Logger;
013
014/**
015 * A LogixNG male socket.
016 *
017 * @author Daniel Bergqvist Copyright 2018
018 */
019public interface MaleSocket extends Debugable {
020
021    enum ErrorHandlingType {
022
023        Default(Bundle.getMessage("ErrorHandling_Default")),
024        ShowDialogBox(Bundle.getMessage("ErrorHandling_ShowDialogBox")),
025        LogError(Bundle.getMessage("ErrorHandling_LogError")),
026        LogErrorOnce(Bundle.getMessage("ErrorHandling_LogErrorOnce")),
027        ThrowException(Bundle.getMessage("ErrorHandling_ThrowException")),
028        AbortExecution(Bundle.getMessage("ErrorHandling_AbortExecution"));
029
030        private final String _description;
031
032        private ErrorHandlingType(String description) {
033            _description = description;
034        }
035
036        @Override
037        public String toString() {
038            return _description;
039        }
040    }
041
042    /**
043     * Set whenether this male socket is enabled or disabled.
044     * <P>
045     * This method must call registerListeners() / unregisterListeners().
046     *
047     * @param enable true if this male socket should be enabled, false otherwise
048     */
049    void setEnabled(boolean enable);
050
051    /**
052     * Set whenether this male socket is enabled or disabled, without activating
053     * the male socket. This is used when loading the xml file and when copying
054     * an item.
055     * <P>
056     * This method must call registerListeners() / unregisterListeners().
057     *
058     * @param enable true if this male socket should be enabled, false otherwise
059     */
060    void setEnabledFlag(boolean enable);
061
062    /**
063     * Determines whether this male socket is enabled.
064     *
065     * @return true if the male socket is enabled, false otherwise
066     */
067    @Override
068    boolean isEnabled();
069
070    /**
071     * Get whenether the node should listen to changes or not.
072     * @return true if listen, false if not listen
073     */
074    boolean getListen();
075
076    /**
077     * Set whenether the node should listen to changes or not.
078     * @param listen true if listen, false if not listen
079     */
080    void setListen(boolean listen);
081
082    /**
083     * Is the node locked?
084     * @return true if locked, false otherwise
085     */
086    boolean isLocked();
087
088    /**
089     * Set if the node is locked or not.
090     * @param locked true if locked, false otherwise
091     */
092    void setLocked(boolean locked);
093
094    /**
095     * Is the node a system node?
096     * @return true if system, false otherwise
097     */
098    boolean isSystem();
099
100    /**
101     * Set if the node is system or not.
102     * @param system true if system, false otherwise
103     */
104    void setSystem(boolean system);
105
106    /**
107     * Is the node catching AbortExecution or not?
108     * @return true if catching, false otherwise
109     */
110    boolean getCatchAbortExecution();
111
112    /**
113     * Set if the node should catch AbortExecution or not.
114     * @param catchAbortExecution true if catch, false otherwise
115     */
116    void setCatchAbortExecution(boolean catchAbortExecution);
117
118    void addLocalVariable(
119            String name,
120            InitialValueType initialValueType,
121            String initialValueData);
122
123    void addLocalVariable(VariableData variableData);
124
125    void clearLocalVariables();
126
127    List<VariableData> getLocalVariables();
128
129    default boolean isSupportingLocalVariables() {
130        return true;
131    }
132
133    /**
134     * Get the error handling type for this socket.
135     * @return the error handling type
136     */
137    ErrorHandlingType getErrorHandlingType();
138
139    /**
140     * Set the error handling type for this socket.
141     * @param errorHandlingType the error handling type
142     */
143    void setErrorHandlingType(ErrorHandlingType errorHandlingType);
144
145    /**
146     * Handle an error that has happened during execution or evaluation of
147     * this item.
148     * @param  item           the item that had the error
149     * @param  message        the error message
150     * @param  e              the exception that has happened
151     * @param  log            the logger
152     * @throws JmriException  if the male socket is configured to
153     *                        throw an exception
154     */
155    void handleError(
156            Base item,
157            String message,
158            JmriException e,
159            Logger log)
160            throws JmriException;
161
162    /**
163     * Handle an error that has happened during execution or evaluation of
164     * this item.
165     * @param  item           the item that had the error
166     * @param  message        the error message
167     * @param  messageList    a list of error messages
168     * @param  e              the exception that has happened
169     * @param  log            the logger
170     * @throws JmriException  if the male socket is configured to
171     *                        throw an exception
172     */
173    void handleError(
174            Base item,
175            String message,
176            List<String> messageList,
177            JmriException e,
178            Logger log)
179            throws JmriException;
180
181    /**
182     * Handle an error that has happened during execution or evaluation of
183     * this item.
184     * @param  item           the item that had the error
185     * @param  message        the error message
186     * @param  e              the exception that has happened
187     * @param  log            the logger
188     * @throws JmriException  if the male socket is configured to
189     *                        throw an exception
190     */
191    void handleError(
192            Base item,
193            String message,
194            RuntimeException e,
195            Logger log)
196            throws JmriException;
197
198    /**
199     * Get the object that this male socket holds.
200     * This method is used when the object is going to be configured.
201     *
202     * @return the object this male socket holds
203     */
204    @Nonnull
205    Base getObject();
206
207    /**
208     * Get the manager that stores this socket.
209     * This method is used when the object is going to be configured.
210     *
211     * @return the manager
212     */
213    BaseManager<? extends NamedBean> getManager();
214
215    /** {@inheritDoc} */
216    @Override
217    default void setup() {
218        getObject().setup();
219    }
220
221    /**
222     * Find a male socket of a particular type.
223     * Male sockets can be stacked and this method travels thru the stacked
224     * male sockets to find the desired male socket.
225     * @param clazz the type of the male socket we are looking for
226     * @return the found male socket or null if not found
227     */
228    default MaleSocket find(Class<?> clazz) {
229
230        if (! MaleSocket.class.isAssignableFrom(clazz)) {
231            throw new IllegalArgumentException("clazz is not a MaleSocket");
232        }
233
234        Base item = this;
235
236        while ((item instanceof MaleSocket) && !clazz.isInstance(item)) {
237            item = item.getParent();
238        }
239
240        if (clazz.isInstance(item)) return (MaleSocket)item;
241        else return null;
242    }
243
244}