001package jmri.jmrit.logixng;
002
003import java.io.PrintWriter;
004import java.util.*;
005
006import jmri.Manager;
007import jmri.jmrit.logixng.Base.PrintTreeSettings;
008
009import org.apache.commons.lang3.mutable.MutableInt;
010
011/**
012 * Manager for LogixNG
013 *
014 * @author Dave Duchamp       Copyright (C) 2007
015 * @author Daniel Bergqvist   Copyright (C) 2018
016 */
017public interface LogixNG_Manager extends Manager<LogixNG> {
018
019    /**
020     * This property is fired when the {@link #setupAllLogixNGs()} method is completed.
021     */
022    public static final String PROPERTY_SETUP = "LogixNG_Setup";
023
024    /**
025     * This is the name of the error handling module.
026     */
027    public static final String ERROR_HANDLING_MODULE_NAME = "IQM:JMRI:ErrorHandlingModule";
028
029    /**
030     * Create a new LogixNG if the LogixNG does not exist.
031     *
032     * @param systemName the system name
033     * @param userName   the user name
034     * @return a new LogixNG or null if unable to create
035     */
036    LogixNG createLogixNG(String systemName, String userName)
037            throws IllegalArgumentException;
038
039    /**
040     * Create a new LogixNG if the LogixNG does not exist.
041     *
042     * @param systemName the system name
043     * @param userName   the user name
044     * @param inline     true if this LogixNG is an inline LogixNG
045     * @return a new LogixNG or null if unable to create
046     */
047    LogixNG createLogixNG(String systemName, String userName, boolean inline)
048            throws IllegalArgumentException;
049
050    /**
051     * For use with User GUI, to allow the auto generation of systemNames, where
052     * the user can optionally supply a username.
053     *
054     * @param userName the user name
055     * @return a new LogixNG or null if unable to create
056     */
057    LogixNG createLogixNG(String userName)
058            throws IllegalArgumentException;
059
060    /**
061     * For use with User GUI, to allow the auto generation of systemNames, where
062     * the user can optionally supply a username.
063     *
064     * @param userName  the user name
065     * @param inline    true if this LogixNG is an inline LogixNG
066     * @return a new LogixNG or null if unable to create
067     */
068    LogixNG createLogixNG(String userName, boolean inline)
069            throws IllegalArgumentException;
070
071    /**
072     * Locate via user name, then system name if needed. Does not create a new
073     * one if nothing found
074     *
075     * @param name User name or system name to match
076     * @return null if no match found
077     */
078    LogixNG getLogixNG(String name);
079
080    /** {@inheritDoc} */
081    @Override
082    LogixNG getByUserName(String name);
083
084    /** {@inheritDoc} */
085    @Override
086    LogixNG getBySystemName(String name);
087
088    /**
089     * Create a new system name for a LogixNG.
090     * @return a new system name
091     */
092    String getAutoSystemName();
093
094    /**
095     * Should the LogixNGs be disabled when the configuration file is loaded?
096     * @param value true if they should be disabled, false otherwise.
097     */
098    void setLoadDisabled(boolean value);
099
100    /**
101     * Should the LogixNGs be started when the configuration file is loaded?
102     * @param value true if they should be started, false otherwise.
103     */
104    void startLogixNGsOnLoad(boolean value);
105
106    /**
107     * Should the LogixNGs not be started when the configuration file is loaded?
108     * @return true if they should be started, false otherwise.
109     */
110    boolean isStartLogixNGsOnLoad();
111
112    /**
113     * Setup all LogixNGs. This method is called after a configuration file is
114     * loaded.
115     */
116    void setupAllLogixNGs();
117
118    /**
119     * Activate all LogixNGs, starts LogixNG processing by connecting all
120     * inputs that are included the ConditionalNGs in this LogixNG.
121     * <p>
122     * A LogixNG must be activated before it will calculate any of its
123     * ConditionalNGs.
124     */
125    void activateAllLogixNGs();
126
127    /**
128     * Activate all LogixNGs, starts LogixNG processing by connecting all
129     * inputs that are included the ConditionalNGs in this LogixNG.
130     * <p>
131     * A LogixNG must be activated before it will calculate any of its
132     * ConditionalNGs.
133     *
134     * @param runDelayed true if execute() should run on LogixNG thread delayed,
135     *                   false otherwise.
136     * @param runOnSeparateThread true if the activation should run on a
137     *                            separate thread, false otherwise
138     */
139    void activateAllLogixNGs(boolean runDelayed, boolean runOnSeparateThread);
140
141    /**
142     * DeActivate all LogixNGs, stops LogixNG processing by disconnecting all
143     * inputs that are included the ConditionalNGs in this LogixNG.
144     * <p>
145     * A LogixNG must be activated before it will calculate any of its
146     * ConditionalNGs.
147     */
148    void deActivateAllLogixNGs();
149
150    /**
151     * Is LogixNGs active?
152     * @return true if LogixNGs are active, false otherwise
153     */
154    boolean isActive();
155
156    /**
157     * Delete LogixNG by removing it from the manager. The LogixNG must first
158     * be deactivated so it stops processing.
159     *
160     * @param x the LogixNG to delete
161     */
162    void deleteLogixNG(LogixNG x);
163
164    /**
165     * Print the tree to a stream.
166     *
167     * @param writer the stream to print the tree to
168     * @param indent the indentation of each level
169     * @param lineNumber the line number
170     */
171    default void printTree(
172            PrintWriter writer,
173            String indent,
174            MutableInt lineNumber) {
175
176        printTree(new PrintTreeSettings(), writer, indent, lineNumber);
177    }
178
179    /**
180     * Print the tree to a stream.
181     *
182     * @param settings settings for what to print
183     * @param writer the stream to print the tree to
184     * @param indent the indentation of each level
185     * @param lineNumber the line number
186     */
187    void printTree(
188            PrintTreeSettings settings,
189            PrintWriter writer,
190            String indent,
191            MutableInt lineNumber);
192
193    /**
194     * Print the tree to a stream.
195     *
196     * @param locale The locale to be used
197     * @param writer the stream to print the tree to
198     * @param indent the indentation of each level
199     * @param lineNumber the line number
200     */
201    default void printTree(
202            Locale locale,
203            PrintWriter writer,
204            String indent,
205            MutableInt lineNumber) {
206
207        printTree(new PrintTreeSettings(), locale, writer, indent, lineNumber);
208    }
209
210    /**
211     * Print the tree to a stream.
212     *
213     * @param settings settings for what to print
214     * @param locale The locale to be used
215     * @param writer the stream to print the tree to
216     * @param indent the indentation of each level
217     * @param lineNumber the line number
218     */
219    void printTree(
220            PrintTreeSettings settings,
221            Locale locale,
222            PrintWriter writer,
223            String indent,
224            MutableInt lineNumber);
225
226    /**
227     * Test if parameter is a properly formatted system name.
228     * <P>
229     * This method should only be used by the managers of the LogixNG system.
230     *
231     * @param subSystemNamePrefix the sub system prefix
232     * @param systemName the system name
233     * @return enum indicating current validity, which might be just as a prefix
234     */
235    static NameValidity validSystemNameFormat(String subSystemNamePrefix, String systemName) {
236        // System names with digits. :AUTO: is generated system names
237        if (systemName.matches(subSystemNamePrefix+"(:AUTO:)?\\d+")) {
238            return NameValidity.VALID;
239
240        // System names with dollar sign allow any characters in the name
241        } else if (systemName.matches(subSystemNamePrefix+"\\$.+")) {
242            return NameValidity.VALID;
243
244        // System names with :JMRI: belongs to JMRI itself
245        } else if (systemName.matches(subSystemNamePrefix+":JMRI:.+")) {
246            return NameValidity.VALID;
247
248        // System names with :JMRI-LIB: belongs to software that uses JMRI as a lib
249        } else if (systemName.matches(subSystemNamePrefix+":JMRI-LIB:.+")) {
250            return NameValidity.VALID;
251
252        // Other system names are not valid
253        } else {
254//            LoggerFactory.getLogger(LogixNG_Manager.class)
255//                    .warn("system name {} is invalid for sub system prefix {}",
256//                            systemName, subSystemNamePrefix);
257            return NameValidity.INVALID;
258        }
259    }
260
261    /**
262     * Get the clipboard
263     * @return the clipboard
264     */
265    Clipboard getClipboard();
266
267    /**
268     * Register a manager for later retrieval by getManager()
269     * @param manager the manager
270     */
271    void registerManager(Manager<? extends MaleSocket> manager);
272
273    /**
274     * Get manager by class name
275     * @param className the class name of the manager
276     * @return the manager
277     */
278    Manager<? extends MaleSocket> getManager(String className);
279
280    /**
281     * Register a task to be run when setup LogixNGs
282     * @param task the task
283     */
284    void registerSetupTask(Runnable task);
285
286    /**
287     * Executes a LogixNG Module.
288     * Note that the module must be a Digital Action Module.
289     * @param module     The module to be executed
290     * @param parameter  The parameter. The module must have exactly one parameter.
291     * @throws IllegalArgumentException If module is null or if module is not a
292     *                   DigitalActionModule.
293     */
294    void executeModule(Module module, Object parameter)
295            throws IllegalArgumentException;
296
297    /**
298     * Executes a LogixNG Module.
299     * Note that the module must be a Digital Action Module.
300     * @param module      The module to be executed
301     * @param parameters  The parameters
302     * @throws IllegalArgumentException If module or parameters is null or if module
303     *                    is not a DigitalActionModule.
304     */
305    void executeModule(Module module, Map<String, Object> parameters)
306            throws IllegalArgumentException;
307
308    /**
309     * Get the female socket of the error handling module.
310     * @return the socket.
311     */
312    FemaleSocket getErrorHandlingModuleSocket();
313
314    /**
315     * Is the error handling module enabled?
316     * It's enabled if it exists and the root socket is connected.
317     * @return true if it's in use, false otherwise.
318     */
319    boolean isErrorHandlingModuleEnabled();
320
321}