001package jmri;
002
003import javax.annotation.CheckForNull;
004import javax.annotation.Nonnull;
005
006/**
007 * Locate a Reporter object representing some specific device on the layout.
008 * <p>
009 * Reporter objects are obtained from a ReporterManager, which in turn is
010 * generally located from the InstanceManager. A typical call sequence might be:
011 * <pre>
012 * Reporter device = InstanceManager.getDefault(jmri.ReporterManager.class).newReporter("23",null);
013 * </pre>
014 * <p>
015 * Each Reporter has a two names. The "user" name is entirely free form, and can
016 * be used for any purpose. The "system" name is provided by the system-specific
017 * implementations, and provides a unique mapping to the layout control system
018 * (for example LocoNet or NCE) and address within that system.
019 * <p>
020 * Much of the book-keeping is implemented in the AbstractReporterManager class,
021 * which can form the basis for a system-specific implementation.
022 *
023 * <hr>
024 * This file is part of JMRI.
025 * <p>
026 * JMRI is free software; you can redistribute it and/or modify it under the
027 * terms of version 2 of the GNU General Public License as published by the Free
028 * Software Foundation. See the "COPYING" file for a copy of this license.
029 * <p>
030 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
031 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
032 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
033 *
034 * @author Bob Jacobsen Copyright (C) 2001
035 * @see jmri.Reporter
036 * @see jmri.InstanceManager
037 */
038public interface ReporterManager extends ProvidingManager<Reporter>, NameIncrementingManager {
039
040    /**
041     * Locate via user name, then system name if needed. If that fails, create a
042     * new Reporter. If the name is a valid system name, it will be used for the
043     * new Reporter. Otherwise, the makeSystemName method will attempt to turn
044     * it into a valid system name.
045     * <p>This provides the same function as {@link ProvidingManager#provide}
046     * which has a more generic form.
047     *
048     * @param name User name, system name, or address which can be promoted to
049     *             system name
050     * @return Never null
051     * @throws IllegalArgumentException if Reporter doesn't already exist and
052     *                                  the manager cannot create the Reporter
053     *                                  due to an illegal name or name that
054     *                                  can't be parsed.
055     */
056    @Nonnull
057    public Reporter provideReporter(@Nonnull String name) throws IllegalArgumentException;
058
059    /** {@inheritDoc} */
060    @Override
061    @Nonnull
062    default public Reporter provide(@Nonnull String name) throws IllegalArgumentException { return provideReporter(name); }
063
064    /**
065     * Locate via user name, then system name if needed. If that fails, return
066     * null
067     *
068     * @param name User name or system name to match
069     * @return null if no match found
070     */
071    @CheckForNull
072    public Reporter getReporter(@Nonnull String name);
073
074    /**
075     * Locate an instance based on a system name. Returns null if no instance
076     * already exists.
077     *
078     * @param systemName the system name to locate
079     * @return requested Reporter object or null if none exists
080     */
081    @CheckForNull
082    @Override
083    public Reporter getBySystemName(@Nonnull String systemName);
084
085    /**
086     * Locate an instance based on a user name. Returns null if no instance
087     * already exists.
088     *
089     * @param userName the user name to locate
090     * @return requested Reporter object or null if none exists
091     */
092    @CheckForNull
093    @Override
094    public Reporter getByUserName(@Nonnull String userName);
095
096    /**
097     * Locate an instance based on a user name, or if that fails, by system
098     * name. Returns null if no instance already exists.
099     *
100     * @param userName the name to locate
101     * @return requested Reporter object or null if none exists
102     */
103    @CheckForNull
104    public Reporter getByDisplayName(@Nonnull String userName);
105
106    /**
107     * Return an instance with the specified system and user names.
108     * <p>
109     * Note that
110     * two calls with the same arguments will get the same instance; there is
111     * only one Reporter object representing a given physical Reporter and
112     * therefore only one with a specific system or user name.
113     * <p>
114     * This will always return a valid object reference; a new object will be
115     * created if necessary. In that case:
116     * <ul>
117     * <li>If a null reference is given for user name, no user name will be
118     * associated with the Reporter object created; a valid system name must be
119     * provided
120     * <li>If both names are provided, the system name defines the hardware
121     * access of the desired Reporter, and the user address is associated with
122     * it. The system name must be valid.
123     * </ul>
124     * Note that it is possible to make an inconsistent request if both
125     * addresses are provided, but the given values are associated with
126     * different objects. This is a problem, and we don't have a good solution
127     * except to issue warnings. This will mostly happen if you're creating
128     * Reporters when you should be looking them up.
129     *
130     * @param systemName the system name
131     * @param userName   the user name
132     * @return requested Reporter object (never null)
133     * @throws IllegalArgumentException if cannot create the Reporter due to
134     *                                  an illegal name or name that can't
135     *                                  be parsed.
136     */
137    @Nonnull
138    public Reporter newReporter(@Nonnull String systemName, String userName) throws IllegalArgumentException;
139
140    /**
141     * Get a system name for a given hardware address and system prefix.
142     *
143     * @param curAddress desired hardware address
144     * @param prefix     system prefix used in system name, excluding Bean type-letter..
145     * @return the complete Reporter system name for the prefix and current
146     *         address
147     * @throws jmri.JmriException if unable to create a system name for the
148     *                            given address, possibly due to invalid address
149     *                            format
150     */
151    @Nonnull
152    public String createSystemName(@Nonnull String curAddress, @Nonnull String prefix) throws JmriException;
153
154    /**
155     * {@inheritDoc}
156     */
157    @Override
158    public String getEntryToolTip();
159
160}