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