001package jmri.managers;
002
003import java.util.Objects;
004import javax.annotation.Nonnull;
005import javax.annotation.CheckForNull;
006import jmri.Manager;
007import jmri.Memory;
008import jmri.MemoryManager;
009import jmri.SystemConnectionMemo;
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013/**
014 * Abstract partial implementation of a MemoryManager.
015 *
016 * @author Bob Jacobsen Copyright (C) 2004
017 */
018public abstract class AbstractMemoryManager extends AbstractManager<Memory>
019        implements MemoryManager {
020
021    /**
022     * Create a new MemoryManager instance.
023     * 
024     * @param memo the system connection
025     */
026    public AbstractMemoryManager(SystemConnectionMemo memo) {
027        super(memo);
028    }
029
030    /** {@inheritDoc} */
031    @Override
032    public int getXMLOrder() {
033        return Manager.MEMORIES;
034    }
035
036    /** {@inheritDoc} */
037    @Override
038    public char typeLetter() {
039        return 'M';
040    }
041
042    /** {@inheritDoc} */
043    @Nonnull
044    @Override
045    public Memory provideMemory(@Nonnull String sName) throws IllegalArgumentException {
046        Memory m = getMemory(sName);
047        if (m != null) {
048            return m;
049        }
050        if (sName.startsWith(getSystemNamePrefix())) {
051            return newMemory(sName, null);
052        } else {
053            return newMemory(makeSystemName(sName), null);
054        }
055    }
056
057    /** {@inheritDoc} */
058    @CheckForNull
059    @Override
060    public Memory getMemory(@Nonnull String name) {
061        Memory t = getByUserName(name);
062        if (t != null) {
063            return t;
064        }
065
066        return getBySystemName(name);
067    }
068
069    /** {@inheritDoc} */
070    @Override
071    @Nonnull
072    public Memory newMemory(@Nonnull String systemName, @CheckForNull String userName) throws IllegalArgumentException {
073        log.debug("new Memory: {}; {}", systemName, (userName == null ? "null" : userName)); // NOI18N
074        Objects.requireNonNull(systemName, "SystemName cannot be null. UserName was "
075                + ((userName == null) ? "null" : userName));  // NOI18N
076        // return existing if there is one
077        Memory m;
078        if (userName != null) {
079            m = getByUserName(userName);
080            if ( m!= null) {
081                if (getBySystemName(systemName) != m) {
082                    log.error("inconsistent user ({}) and system name ({}) results; userName related to ({})", userName, systemName, m.getSystemName()); // NOI18N
083                }
084                return m;
085            }
086        }
087        m = getBySystemName(systemName);
088        if (m != null) {
089            // handle user name from request
090            if (userName != null) {
091                // check if already on set in Object, might be inconsistent
092                if (m.getUserName()!=null && !userName.equals(m.getUserName())) {
093                    // this is a problem
094                    log.warn("newMemory request for system name \"{}\" user name \"{}\" found memory with existing user name \"{}\"", systemName, userName, m.getUserName());
095                } else {
096                    m.setUserName(userName);
097                }
098            }
099            return m;
100        }
101
102        // doesn't exist, make a new one
103        m = createNewMemory(systemName, userName);
104
105        // save in the maps
106        register(m);
107        // Keep track of the last created auto system name
108        updateAutoNumber(systemName);
109
110        return m;
111    }
112
113    /** {@inheritDoc} */
114    @Nonnull
115    @Override
116    public Memory newMemory(@CheckForNull String userName) throws IllegalArgumentException {
117        return newMemory(getAutoSystemName(), userName);
118    }
119
120    /**
121     * Internal method to invoke the factory, after all the logic for returning
122     * an existing Memory has been invoked.
123     *
124     * @param systemName Memory system name
125     * @param userName   Memory user name
126     * @return a new Memory
127     */
128    @Nonnull
129    abstract protected Memory createNewMemory(@Nonnull String systemName, @CheckForNull String userName) throws IllegalArgumentException;
130
131    /** {@inheritDoc} */
132    @Override
133    @Nonnull 
134    public String getBeanTypeHandled(boolean plural) {
135        return Bundle.getMessage(plural ? "BeanNameMemories" : "BeanNameMemory");
136    }
137
138    /**
139     * {@inheritDoc}
140     */
141    @Override
142    public Class<Memory> getNamedBeanClass() {
143        return Memory.class;
144    }
145
146    /** {@inheritDoc} */
147    @Override
148    @Nonnull
149    public Memory provide(@Nonnull String name) throws IllegalArgumentException {
150        return provideMemory(name);
151    }
152
153    private final static Logger log = LoggerFactory.getLogger(AbstractMemoryManager.class);
154
155}