001package jmri.jmrit.logixng.implementation;
002
003import java.util.ArrayList;
004import java.util.HashMap;
005import java.util.List;
006import java.util.Map;
007import java.util.ServiceLoader;
008
009import javax.annotation.Nonnull;
010
011import jmri.InstanceManager;
012import jmri.InstanceManagerAutoDefault;
013import jmri.InvokeOnGuiThread;
014import jmri.jmrit.logixng.*;
015import jmri.util.*;
016
017/**
018 * Class providing the basic logic of the ExpressionManager interface.
019 * 
020 * @author Dave Duchamp       Copyright (C) 2007
021 * @author Daniel Bergqvist   Copyright (C) 2018
022 */
023public class DefaultAnalogExpressionManager extends AbstractBaseManager<MaleAnalogExpressionSocket>
024        implements AnalogExpressionManager, InstanceManagerAutoDefault {
025
026    private final Map<Category, List<Class<? extends Base>>> expressionClassList = new HashMap<>();
027    private MaleSocket _lastRegisteredBean;
028
029    
030    public DefaultAnalogExpressionManager() {
031        InstanceManager.getDefault(LogixNG_Manager.class).registerManager(this);
032        
033        for (AnalogExpressionFactory expressionFactory : ServiceLoader.load(AnalogExpressionFactory.class)) {
034            expressionFactory.init();
035        }
036        
037        for (Category category : Category.values()) {
038            expressionClassList.put(category, new ArrayList<>());
039        }
040        
041//        System.out.format("Read expressions%n");
042        for (AnalogExpressionFactory expressionFactory : ServiceLoader.load(AnalogExpressionFactory.class)) {
043            expressionFactory.getClasses().forEach((entry) -> {
044//                System.out.format("Add expression: %s, %s%n", entry.getKey().name(), entry.getValue().getName());
045                expressionClassList.get(entry.getKey()).add(entry.getValue());
046            });
047        }
048        
049        for (MaleAnalogExpressionSocketFactory maleSocketFactory : ServiceLoader.load(MaleAnalogExpressionSocketFactory.class)) {
050            _maleSocketFactories.add(maleSocketFactory);
051        }
052    }
053
054    /** {@inheritDoc} */
055    @Override
056    public Class<? extends MaleSocket> getMaleSocketClass() {
057        return DefaultMaleAnalogExpressionSocket.class;
058    }
059
060    protected MaleAnalogExpressionSocket createMaleAnalogExpressionSocket(AnalogExpressionBean expression) {
061        MaleAnalogExpressionSocket socket = new DefaultMaleAnalogExpressionSocket(this, expression);
062        expression.setParent(socket);
063        return socket;
064    }
065
066    /** {@inheritDoc} */
067    @Override
068    public MaleSocket getLastRegisteredMaleSocket() {
069        return _lastRegisteredBean;
070    }
071    
072    /** {@inheritDoc} */
073    @Override
074    public MaleAnalogExpressionSocket registerBean(MaleAnalogExpressionSocket maleSocket) {
075        MaleAnalogExpressionSocket bean = super.registerBean(maleSocket);
076        _lastRegisteredBean = maleSocket;
077        return bean;
078    }
079    
080    /**
081     * Remember a NamedBean Object created outside the manager.
082     * This method creates a MaleActionSocket for the action.
083     *
084     * @param expression the bean
085     */
086    @Override
087    public MaleAnalogExpressionSocket registerExpression(@Nonnull AnalogExpressionBean expression)
088            throws IllegalArgumentException {
089        
090        if (expression instanceof MaleAnalogExpressionSocket) {
091            throw new IllegalArgumentException("registerExpression() cannot register a MaleAnalogExpressionSocket. Use the method register() instead.");
092        }
093        
094        // Check if system name is valid
095        if (this.validSystemNameFormat(expression.getSystemName()) != NameValidity.VALID) {
096            log.warn("SystemName {} is not in the correct format", expression.getSystemName());
097            throw new IllegalArgumentException(String.format("System name is invalid: %s", expression.getSystemName()));
098        }
099        
100        // Keep track of the last created auto system name
101        updateAutoNumber(expression.getSystemName());
102        
103        // save in the maps
104        MaleAnalogExpressionSocket maleSocket = createMaleAnalogExpressionSocket(expression);
105        return registerBean(maleSocket);
106    }
107    
108    @Override
109    public int getXMLOrder() {
110        return LOGIXNG_ANALOG_EXPRESSIONS;
111    }
112
113    @Override
114    public String getBeanTypeHandled() {
115        return Bundle.getMessage("BeanNameAnalogExpression");
116    }
117
118    /** {@inheritDoc} */
119    @Override
120    public void deleteAnalogExpression(MaleAnalogExpressionSocket x) {
121        // delete the MaleAnalogExpressionSocket
122        deregister(x);
123        x.dispose();
124    }
125
126    @Override
127    public char typeLetter() {
128        return 'Q';
129    }
130
131    /*.*
132     * Test if parameter is a properly formatted system name.
133     *
134     * @param systemName the system name
135     * @return enum indicating current validity, which might be just as a prefix
136     *./
137    @Override
138    public NameValidity validSystemNameFormat(String systemName) {
139        return LogixNG_Manager.validSystemNameFormat(
140                getSubSystemNamePrefix(), systemName);
141    }
142*/
143    @Override
144    public FemaleAnalogExpressionSocket createFemaleSocket(
145            Base parent, FemaleSocketListener listener, String socketName) {
146        
147        return new DefaultFemaleAnalogExpressionSocket(parent, listener, socketName);
148    }
149    
150    @Override
151    public Map<Category, List<Class<? extends Base>>> getExpressionClasses() {
152        return expressionClassList;
153    }
154
155    /** {@inheritDoc} */
156    @Override
157    public String getBeanTypeHandled(boolean plural) {
158        return Bundle.getMessage(plural ? "BeanNameAnalogExpressions" : "BeanNameAnalogExpression");
159    }
160    
161    static volatile DefaultAnalogExpressionManager _instance = null;
162
163    @InvokeOnGuiThread  // this method is not thread safe
164    static public DefaultAnalogExpressionManager instance() {
165        if (!ThreadingUtil.isGUIThread()) {
166            LoggingUtil.warnOnce(log, "instance() called on wrong thread");
167        }
168        
169        if (_instance == null) {
170            _instance = new DefaultAnalogExpressionManager();
171        }
172        return (_instance);
173    }
174
175    @Override
176    public Class<MaleAnalogExpressionSocket> getNamedBeanClass() {
177        return MaleAnalogExpressionSocket.class;
178    }
179
180    @Override
181    protected MaleAnalogExpressionSocket castBean(MaleSocket maleSocket) {
182        return (MaleAnalogExpressionSocket)maleSocket;
183    }
184
185
186    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultAnalogExpressionManager.class);
187
188}