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