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     * @throws IllegalArgumentException something failed in the names
122     */
123    @Nonnull
124    abstract protected Light createNewLight(@Nonnull String systemName, String userName) throws IllegalArgumentException;
125
126    /**
127     * {@inheritDoc}
128     */
129    @Override
130    public void activateAllLights() {
131        // Set up an iterator over all Lights contained in this manager
132        for (Light l : getNamedBeanSet()) {
133            log.debug("Activated Light system name is {}", l.getSystemName());
134            l.activateLight();
135        }
136    }
137
138    /**
139     * {@inheritDoc}
140     */
141    @Override
142    @Nonnull
143    public String convertSystemNameToAlternate(@Nonnull String systemName) {
144        return "";
145    }
146
147    /**
148     * {@inheritDoc}
149     */
150    @Override
151    public boolean supportsVariableLights(@Nonnull String systemName) {
152        return false;
153    }
154
155    /**
156     * Get bean type handled.
157     *
158     * @return a string for the type of object handled by this manager
159     */
160    @Override
161    @Nonnull
162    public String getBeanTypeHandled(boolean plural) {
163        return Bundle.getMessage(plural ? "BeanNameLights" : "BeanNameLight");
164    }
165
166    /**
167     * {@inheritDoc}
168     */
169    @Override
170    public Class<Light> getNamedBeanClass() {
171        return Light.class;
172    }
173
174    /**
175     * {@inheritDoc}
176     */
177    @Override
178    @CheckForNull
179    public String getEntryToolTip() {
180        return Bundle.getMessage("EnterNumber1to9999ToolTip");
181    }
182
183    private final static Logger log = LoggerFactory.getLogger(AbstractLightManager.class);
184
185}