001package jmri.managers;
002
003import java.util.Objects;
004import javax.annotation.CheckForNull;
005import javax.annotation.Nonnull;
006import jmri.Manager;
007import jmri.Reporter;
008import jmri.ReporterManager;
009import jmri.SystemConnectionMemo;
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013/**
014 * Abstract partial implementation of a ReporterManager.
015 *
016 * @author Bob Jacobsen Copyright (C) 2004
017 */
018public abstract class AbstractReporterManager extends AbstractManager<Reporter>
019        implements ReporterManager {
020
021    /**
022     * Create a new ReporterManager instance.
023     *
024     * @param memo the system connection
025     */
026    public AbstractReporterManager(SystemConnectionMemo memo) {
027        super(memo);
028    }
029
030    /** {@inheritDoc} */
031    @Override
032    public int getXMLOrder() {
033        return Manager.REPORTERS;
034    }
035
036    /** {@inheritDoc} */
037    @Override
038    public char typeLetter() {
039        return 'R';
040    }
041
042    /** {@inheritDoc} */
043    @Override
044    @Nonnull
045    public Reporter provideReporter(@Nonnull String sName) throws IllegalArgumentException {
046        Reporter r = getReporter(sName);
047        return r == null ? newReporter(makeSystemName(sName, true), null) : r;
048    }
049
050    /** {@inheritDoc} */
051    @Override
052    @CheckForNull
053    public Reporter getReporter(@Nonnull String name) {
054        Reporter r = getByUserName(name);
055        return r == null ? getBySystemName(name) : r;
056    }
057
058    /** {@inheritDoc} */
059    @Override
060    @Nonnull
061    public String getBeanTypeHandled(boolean plural) {
062        return Bundle.getMessage(plural ? "BeanNameReporters" : "BeanNameReporter");
063    }
064
065    /**
066     * {@inheritDoc}
067     */
068    @Override
069    public Class<Reporter> getNamedBeanClass() {
070        return Reporter.class;
071    }
072
073    /** {@inheritDoc} */
074    @Override
075    @CheckForNull
076    public Reporter getByDisplayName(@Nonnull String key) {
077        return getReporter(key);
078    }
079
080    /** {@inheritDoc} */
081    @Override
082    @Nonnull
083    public Reporter newReporter(@Nonnull String systemName, @CheckForNull String userName) throws IllegalArgumentException {
084        Objects.requireNonNull(systemName, "SystemName cannot be null. UserName was "
085               + ((userName == null) ? "null" : userName));  // NOI18N
086        log.debug("new Reporter: {} {}", systemName, userName);
087
088       // is system name in correct format?
089        if (!systemName.startsWith(getSystemNamePrefix())
090                || !(systemName.length() > (getSystemNamePrefix()).length())) {
091            log.error("Invalid system name for reporter: {} needed {}{}",
092                    systemName, getSystemPrefix(), typeLetter());
093            throw new IllegalArgumentException("Invalid system name for turnout: " + systemName
094                    + " needed " + getSystemNamePrefix());
095        }
096
097        // return existing if there is one
098        Reporter r;
099        if (userName != null) {
100            r = getByUserName(userName);
101            if (r!=null) {
102                if (getBySystemName(systemName) != r) {
103                    log.error("inconsistent user ({}) and system name ({}) results; userName related to ({})",
104                            userName, systemName, r.getSystemName());
105                }
106                return r;
107            }
108        }
109        r = getBySystemName(systemName);
110        if (r != null) {
111            if ((r.getUserName() == null) && (userName != null)) {
112                r.setUserName(userName);
113            } else if (userName != null) {
114                log.warn("Found reporter via system name ({}}) with non-null user name ({}})", systemName, userName);
115            }
116            return r;
117        }
118
119        // doesn't exist, make a new one
120        r = createNewReporter(systemName, userName);
121
122        // Some implementations of createNewReporter() registers the bean, some
123        // don't. Check if the bean is registered and register it if it isn't
124        // registered.
125        if (getBySystemName(systemName) == null) {
126            // save in the maps
127            register(r);
128        }
129        return r;
130    }
131
132    /**
133     * Internal method to invoke the factory, after all the logic for returning
134     * an existing Reporter has been invoked.
135     *
136     * @param systemName system name.
137     * @param userName username.
138     * @return never null
139     */
140    @Nonnull
141    abstract protected Reporter createNewReporter(@Nonnull String systemName, String userName) throws IllegalArgumentException;
142
143    /** {@inheritDoc} */
144    @Override
145    public String getEntryToolTip() {
146        return Bundle.getMessage("EnterNumber1to9999ToolTip");
147    }
148
149    private final static Logger log = LoggerFactory.getLogger(AbstractReporterManager.class);
150
151}