001package jmri;
002
003import javax.annotation.*;
004
005/**
006 * Interface for obtaining Lights.
007 * <p>
008 * This doesn't have a "new" method, as Lights are separately implemented,
009 * instead of being system-specific.
010 * <p>
011 * Based on SignalHeadManager.java
012 * <hr>
013 * This file is part of JMRI.
014 * <p>
015 * JMRI is free software; you can redistribute it and/or modify it under the
016 * terms of version 2 of the GNU General Public License as published by the Free
017 * Software Foundation. See the "COPYING" file for a copy of this license.
018 * <p>
019 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
020 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
021 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
022 *
023 * @author Dave Duchamp Copyright (C) 2004
024 */
025public interface LightManager extends ProvidingManager<Light>, NameIncrementingManager {
026
027    /**
028     * Get the Light with the user name, then system name if needed; if that fails, create a
029     * new Light.
030     * If the name is a valid system name, it will be used for the new Light.
031     * Otherwise, the {@link Manager#makeSystemName} method will attempt to turn it
032     * into a valid system name.
033     * <p>This provides the same function as {@link ProvidingManager#provide}
034     * which has a more generic form.
035     *
036     * @param name User name, system name, or address which can be promoted to
037     *             system name
038     * @return Never null under normal circumstances
039     * @throws IllegalArgumentException when needed
040     */
041    @Nonnull
042    Light provideLight(@Nonnull String name) throws IllegalArgumentException;
043
044    /** {@inheritDoc} */
045    @Override
046    @Nonnull
047    default Light provide(@Nonnull String name) throws IllegalArgumentException { return provideLight(name); }
048
049    /** {@inheritDoc} */
050    @Override
051    void dispose();
052
053    /**
054     * Get an existing Light or return null if it doesn't exist.
055     * <p>
056     * Locates via user name, then system name if needed.
057     * @param name User name, system name, or address which can be promoted to
058     *             system name
059     * @return Light, or null if no existing Light.
060     */
061    @CheckReturnValue
062    @CheckForNull
063    Light getLight(@Nonnull String name);
064
065    /**
066     * Return a Light with the specified user or system name.
067     * Lookup Light by UserName, then Provide New Light by SystemName.
068     * Note that
069     * two calls with the same arguments will get the same instance; there is
070     * only one Light object representing a given physical Light and therefore
071     * only one with a specific system or user name.
072     * <p>
073     * This will always return a valid object reference; a new object will be
074     * created if necessary. In that case:
075     * <ul>
076     * <li>If a null reference is given for user name, no user name will be
077     * associated with the Light object created; a valid system name must be
078     * provided
079     * <li>If both names are provided, the system name defines the hardware
080     * access of the desired sensor, and the user address is associated with it.
081     * The system name must be valid.
082     * </ul>
083     * Note that it is possible to make an inconsistent request if both
084     * addresses are provided, but the given values are associated with
085     * different objects. This is a problem, and we don't have a good solution
086     * except to issue warnings. This will mostly happen if you're creating
087     * Lights when you should be looking them up.
088     *
089     * @param systemName the desired system name
090     * @param userName   the desired user name
091     * @return requested Light object (never null)
092     * @throws IllegalArgumentException if cannot create the Light due to e.g.
093     *                                  an illegal name or name that can't be
094     *                                  parsed.
095     */
096    @Nonnull
097    Light newLight(@Nonnull String systemName, @CheckForNull String userName) throws IllegalArgumentException;
098
099    /**
100     * Locate a Light by its user name.
101     *
102     * @param s the user name
103     * @return the light or null if not found
104     */
105    @CheckReturnValue
106    @CheckForNull
107    @Override
108    Light getByUserName(@Nonnull String s);
109
110    /**
111     * Locate a Light by its system name.
112     *
113     * @param s the system name
114     * @return the light or null if not found
115     */
116    @CheckReturnValue
117    @CheckForNull
118    @Override
119    Light getBySystemName(@Nonnull String s);
120
121    /**
122     * Test if parameter is a valid system name for current configuration.
123     *
124     * @param systemName the system name
125     * @return true if valid; false otherwise
126     */
127    @CheckReturnValue
128    default boolean validSystemNameConfig(@Nonnull String systemName){
129        try {
130            validateSystemNameFormat(systemName);
131            return true;
132        } catch (jmri.NamedBean.BadSystemNameException ex) {
133            return false;
134        }
135    }
136
137    /**
138     * Convert the system name to a normalized alternate name.
139     * <p>
140     * This routine is to allow testing to ensure that two Lights with alternate
141     * names that refer to the same output bit are not created.
142     * <p>
143     * This routine is implemented in AbstractLightManager to return "". If a
144     * system implementation has alternate names, the system specific Light
145     * Manager should override this routine and supply the alternate name.
146     *
147     * @param systemName the system name to convert
148     * @return an alternate name
149     */
150    @CheckReturnValue
151    @Nonnull
152    String convertSystemNameToAlternate(@Nonnull String systemName);
153
154    /**
155     * Activate the control mechanism for each Light controlled by this
156     * LightManager. Note that some Lights don't require any activation. The
157     * activateLight method in AbstractLight.java determines what needs to be
158     * done for each Light.
159     */
160    void activateAllLights();
161
162    /**
163     * Test if system in the given name can support a variable light.
164     *
165     * @param systemName the system name
166     * @return true if variable lights are supported; false otherwise
167     */
168    @CheckReturnValue
169    boolean supportsVariableLights(@Nonnull String systemName);
170
171    /**
172     * Get a system name for a given hardware address and system prefix.
173     *
174     * @param curAddress desired hardware address
175     * @param prefix     system prefix used in system name, excluding Bean type-letter.
176     * @return the complete Light system name for the prefix and current
177     *         address
178     * @throws jmri.JmriException if unable to create a system name for the
179     *                            given address, possibly due to invalid address
180     *                            format
181     */
182    @Nonnull
183    String createSystemName(@Nonnull String curAddress, @Nonnull String prefix) throws JmriException;
184
185}