001package jmri.jmrit.logixng;
002
003import java.io.PrintWriter;
004import java.util.List;
005import java.util.Locale;
006
007import jmri.Manager;
008import jmri.jmrit.logixng.Base.PrintTreeSettings;
009
010import org.apache.commons.lang3.mutable.MutableInt;
011
012/**
013 * Manager for LogixNG modules
014 * 
015 * @author Dave Duchamp       Copyright (C) 2007
016 * @author Daniel Bergqvist   Copyright (C) 2020
017 */
018public interface ModuleManager extends Manager<Module> {
019
020    /**
021     * Create a new Module if the Module does not exist.
022     *
023     * @param systemName the system name
024     * @param userName   the user name
025     * @param socketType the socket type
026     * @return a new Module or null if unable to create
027     */
028    Module createModule(String systemName, String userName,
029            FemaleSocketManager.SocketType socketType)
030            throws IllegalArgumentException;
031    
032    /**
033     * For use with User GUI, to allow the auto generation of systemNames, where
034     * the user can optionally supply a username.
035     *
036     * @param userName the user name
037     * @param socketType the socket type
038     * @return a new Module or null if unable to create
039     */
040    Module createModule(String userName, FemaleSocketManager.SocketType socketType)
041            throws IllegalArgumentException;
042    
043    /**
044     * Locate via user name, then system name if needed. Does not create a new
045     * one if nothing found
046     *
047     * @param name User name or system name to match
048     * @return null if no match found
049     */
050    Module getModule(String name);
051    
052    /** {@inheritDoc} */
053    @Override
054    Module getByUserName(String name);
055    
056    /** {@inheritDoc} */
057    @Override
058    Module getBySystemName(String name);
059    
060    /**
061     * Create a new system name for a Module.
062     * @return a new system name
063     */
064    String getAutoSystemName();
065    
066    /**
067     * Resolve all the Module trees.
068     * <P>
069     * This method ensures that everything in the Module tree has a pointer
070     * to its parent.
071     * 
072     * @param errors a list of potential errors
073     * @return true if success, false otherwise
074     */
075    boolean resolveAllTrees(List<String> errors);
076
077    /**
078     * Setup all Modules. This method is called after a configuration file is
079     * loaded.
080     */
081    void setupAllModules();
082
083    /*.*
084     * Activate all Modules, starts Module processing by connecting all
085     * inputs that are included the ConditionalNGs in this Module.
086     * <p>
087     * A Module must be activated before it will calculate any of its
088     * ConditionalNGs.
089     *./
090    void activateAllModules();
091*/    
092    /**
093     * Delete Module by removing it from the manager. The Module must first
094     * be deactivated so it stops processing.
095     *
096     * @param x the Module to delete
097     */
098    void deleteModule(Module x);
099
100    /*.*
101     * Support for loading Modules in a disabled state
102     * 
103     * @param s true if Module should be disabled when loaded
104     *./
105    void setLoadDisabled(boolean s);
106*/    
107    /**
108     * Print the tree to a stream.
109     * 
110     * @param settings settings for what to print
111     * @param writer the stream to print the tree to
112     * @param indent the indentation of each level
113     * @param lineNumber the line number
114     */
115    void printTree(
116            PrintTreeSettings settings,
117            PrintWriter writer,
118            String indent,
119            MutableInt lineNumber);
120    
121    /**
122     * Print the tree to a stream.
123     * 
124     * @param settings settings for what to print
125     * @param locale The locale to be used
126     * @param writer the stream to print the tree to
127     * @param indent the indentation of each level
128     * @param lineNumber the line number
129     */
130    void printTree(
131            PrintTreeSettings settings,
132            Locale locale,
133            PrintWriter writer,
134            String indent,
135            MutableInt lineNumber);
136    
137    /**
138     * Test if parameter is a properly formatted system name.
139     * <P>
140     * This method should only be used by the managers of the Module system.
141     *
142     * @param subSystemNamePrefix the sub system prefix
143     * @param systemName the system name
144     * @return enum indicating current validity, which might be just as a prefix
145     */
146    static NameValidity validSystemNameFormat(String subSystemNamePrefix, String systemName) {
147        // System names with digits. :AUTO: is generated system names
148        if (systemName.matches(subSystemNamePrefix+"(:AUTO:)?\\d+")) {
149            return NameValidity.VALID;
150            
151        // System names with dollar sign allow any characters in the name
152        } else if (systemName.matches(subSystemNamePrefix+"\\$.+")) {
153            return NameValidity.VALID;
154            
155        // System names with :JMRI: belongs to JMRI itself
156        } else if (systemName.matches(subSystemNamePrefix+":JMRI:.+")) {
157            return NameValidity.VALID;
158            
159        // System names with :JMRI-LIB: belongs to software that uses JMRI as a lib
160        } else if (systemName.matches(subSystemNamePrefix+":JMRI-LIB:.+")) {
161            return NameValidity.VALID;
162            
163        // Other system names are not valid
164        } else {
165//            LoggerFactory.getLogger(Module_Manager.class)
166//                    .warn("system name {} is invalid for sub system prefix {}",
167//                            systemName, subSystemNamePrefix);
168            return NameValidity.INVALID;
169        }
170    }
171    
172    /**
173     * {@inheritDoc}
174     * 
175     * The sub system prefix for the DigitalActionManager is
176     * {@link #getSystemNamePrefix() } and "DA";
177     */
178    @Override
179    default String getSubSystemNamePrefix() {
180        return getSystemNamePrefix() + "M";
181    }
182    
183}