001package jmri.managers;
002
003import java.util.Objects;
004
005import javax.annotation.CheckForNull;
006import javax.annotation.Nonnull;
007
008import jmri.Light;
009import jmri.LightManager;
010import jmri.Manager;
011import jmri.SystemConnectionMemo;
012
013import org.slf4j.Logger;
014import org.slf4j.LoggerFactory;
015
016/**
017 * Abstract partial implementation of a LightManager.
018 * <p>
019 * Based on AbstractSignalHeadManager.java and AbstractSensorManager.java
020 *
021 * @author Dave Duchamp Copyright (C) 2004
022 */
023public abstract class AbstractLightManager extends AbstractManager<Light>
024        implements LightManager {
025
026    /**
027     * Create a new LightManager instance.
028     * 
029     * @param memo the system connection
030     */
031    public AbstractLightManager(SystemConnectionMemo memo) {
032        super(memo);
033    }
034
035    /** {@inheritDoc} */
036    @Override
037    public int getXMLOrder() {
038        return Manager.LIGHTS;
039    }
040
041    /**
042     * {@inheritDoc}
043     */
044    @Override
045    public char typeLetter() {
046        return 'L';
047    }
048
049    /**
050     * {@inheritDoc}
051     */
052    @Override
053    @Nonnull
054    public Light provideLight(@Nonnull String name) {
055        Light light = getLight(name);
056        // makeSystemName checks for validity
057        return light == null ? newLight(makeSystemName(name, true), null) : light;
058    }
059
060    /**
061     * {@inheritDoc}
062     */
063    @Override
064    @CheckForNull
065    public Light getLight(@Nonnull String name) {
066        Light result = getByUserName(name);
067        if (result == null) {
068            result = getBySystemName(name);
069        }
070        return result;
071    }
072
073    /**
074     * Lookup Light by UserName, then provide by SystemName.
075     * {@inheritDoc}
076     */
077    @Override
078    @Nonnull
079    public Light newLight(@Nonnull String systemName, @CheckForNull String userName) throws IllegalArgumentException {
080        Objects.requireNonNull(systemName, "SystemName cannot be null. UserName was " + ((userName == null) ? "null" : userName));  // NOI18N
081        log.debug("newLight: {};{}", systemName, userName);
082        
083        systemName = validateSystemNameFormat(systemName);
084        // return existing if there is one
085        Light l;
086        if (userName != null) {
087            l = getByUserName(userName);
088            if (l != null) {
089                if (getBySystemName(systemName) != l) {
090                    log.error("inconsistent user '{}' and system name '{}' results; user name related to {}",
091                        userName, systemName, l.getSystemName());
092                }
093                return l;
094            }
095        }
096        l = getBySystemName(systemName);
097        if (l != null) {
098            if ((l.getUserName() == null) && (userName != null)) {
099                l.setUserName(userName);
100            } else if (userName != null) {
101                log.warn("Found light via system name '{}' with non-null user name '{}'",
102                        systemName, userName);
103            }
104            return l;
105        }
106        // doesn't exist, make a new one
107        l = createNewLight(systemName, userName);
108        // save in the maps
109        register(l);
110
111        return l;
112    }
113
114    /**
115     * Internal method to invoke the factory, after all the logic for returning
116     * an existing Light has been invoked.
117     *
118     * @param systemName the system name to use for this light
119     * @param userName   the user name to use for this light
120     * @return the new light or null if unsuccessful
121     */
122    @Nonnull
123    abstract protected Light createNewLight(@Nonnull String systemName, String userName) throws IllegalArgumentException;
124
125    /**
126     * {@inheritDoc}
127     */
128    @Override
129    public void activateAllLights() {
130        // Set up an iterator over all Lights contained in this manager
131        for (Light l : getNamedBeanSet()) {
132            log.debug("Activated Light system name is {}", l.getSystemName());
133            l.activateLight();
134        }
135    }
136
137    /**
138     * {@inheritDoc}
139     */
140    @Override
141    @Nonnull
142    public String convertSystemNameToAlternate(@Nonnull String systemName) {
143        return "";
144    }
145
146    /**
147     * {@inheritDoc}
148     */
149    @Override
150    public boolean supportsVariableLights(@Nonnull String systemName) {
151        return false;
152    }
153
154    /**
155     * {@inheritDoc}
156     */
157    @Override
158    public boolean allowMultipleAdditions(@Nonnull String systemName) {
159        return false;
160    }
161
162    /**
163     * Get bean type handled.
164     *
165     * @return a string for the type of object handled by this manager
166     */
167    @Override
168    @Nonnull
169    public String getBeanTypeHandled(boolean plural) {
170        return Bundle.getMessage(plural ? "BeanNameLights" : "BeanNameLight");
171    }
172
173    /**
174     * {@inheritDoc}
175     */
176    @Override
177    public Class<Light> getNamedBeanClass() {
178        return Light.class;
179    }
180
181    /**
182     * {@inheritDoc}
183     */
184    @Override
185    @CheckForNull
186    public String getEntryToolTip() {
187        return Bundle.getMessage("EnterNumber1to9999ToolTip");
188    }
189
190    private final static Logger log = LoggerFactory.getLogger(AbstractLightManager.class);
191
192}