001/*
002 * JMRI is free software; you can redistribute it and/or modify it under the
003 * terms of version 2 of the GNU General Public License as published by the Free
004 * Software Foundation. See the "COPYING" file for a copy of this license.
005 *
006 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
007 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
008 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
009 *
010 */
011package jmri;
012
013import javax.annotation.CheckForNull;
014import javax.annotation.Nonnull;
015
016/**
017 * Locate a Memory object representing some specific information.
018 * <p>
019 * Memory objects are obtained from a MemoryManager, which in turn is generally
020 * located from the InstanceManager. A typical call sequence might be:
021 * <pre>
022 * Memory memory = InstanceManager.memoryManagerInstance().provideMemory("status");
023 * </pre>
024 * <p>
025 * Each Memory has two names. The "user" name is entirely free form, and can
026 * be used for any purpose. The "system" name is provided by the system-specific
027 * implementations, if any, and provides a unique mapping to the layout control
028 * system (for example LocoNet or NCE) and address within that system. Note that
029 * most (all?) layout systems don't have anything corresponding to this, in
030 * which case the "Internal" Memory objects are still available with names like
031 * IM23.
032 * <p>
033 * Much of the bookkeeping is implemented in the <code>AbstractMemoryManager</code> class,
034 * which can form the basis for a system-specific implementation.
035 * @see jmri.Memory
036 * @see jmri.managers.AbstractMemoryManager
037 * @see jmri.InstanceManager
038 * @author Bob Jacobsen, Copyright (C) 2004
039 */
040public interface MemoryManager extends ProvidingManager<Memory> {
041
042    /**
043     * Get the Memory with the user name, then system name if needed; if that fails, create a
044     * new Memory. 
045     * If the name is a valid system name, it will be used for the
046     * new Memory. Otherwise, the makeSystemName method will attempt to turn it
047     * into a valid system name.
048     *
049     * @param name User name, system name, or address which can be promoted to
050     *             system name
051     * @return Never null
052     * @throws IllegalArgumentException if Memory doesn't already exist and the
053     *                                  manager cannot create the Memory due to
054     *                                  an illegal name or name that can't
055     *                                  be parsed.
056     */
057    @Nonnull
058    Memory provideMemory(@Nonnull String name) throws IllegalArgumentException;
059
060    /**
061     * Get an existing Turnout or return null if it doesn't exist. 
062     * 
063     * Locates via user name, then system name if needed.
064     *
065     * @param name User name or system name to match
066     * @return null if no match found
067     */
068    @CheckForNull
069    Memory getMemory(@Nonnull String name);
070
071    /**
072     * Locate an existing Memory based on a system name.
073     * Returns null if no instance already exists.
074     *
075     * @param systemName the system name
076     * @return requested Memory object or null if none exists
077     */
078    @CheckForNull
079    @Override
080    Memory getBySystemName(@Nonnull String systemName);
081
082    /**
083     * Locate an existing Memory based on a user name.
084     * Returns null if no instance already exists.
085     *
086     * @param userName the user name
087     * @return requested Memory object or null if none exists
088     */
089    @CheckForNull
090    @Override
091    Memory getByUserName(@Nonnull String userName);
092
093    /**
094     * Return a Memory with the specified system and user names. Note that
095     * two calls with the same arguments will get the same instance; there is
096     * only one Memory object representing a given physical Memory and therefore
097     * only one with a specific system or user name.
098     * <p>
099     * This will always return a valid object reference; a new object will be
100     * created if necessary. In that case:
101     * <ul>
102     * <li>If a null reference is given for user name, no user name will be
103     * associated with the Memory object created; a valid system name must be
104     * provided
105     * <li>If both names are provided, the system name defines the hardware
106     * access of the desired Memory, and the user address is associated with it.
107     * The system name must be valid.
108     * </ul>
109     * Note that it is possible to make an inconsistent request if both
110     * addresses are provided, but the given values are associated with
111     * different objects. This is a problem, and we don't have a good solution
112     * except to issue warnings. This will mostly happen if you're creating
113     * Memory objects when you should be looking them up.
114     *
115     * @param systemName the system name
116     * @param userName   the user name
117     * @return requested Memory object (never null)
118     * @throws IllegalArgumentException if cannot create the Memory due to e.g.
119     *                                  an illegal name or name that can't be
120     *                                  parsed.
121     */
122    @Nonnull
123    Memory newMemory(@Nonnull String systemName, @CheckForNull String userName) throws IllegalArgumentException;
124
125    /**
126     * For use with User GUI, to allow the auto generation of systemNames, where
127     * the user can optionally supply a username.
128     * <p>
129     * This will always return a valid object reference; a new object will be
130     * created if necessary.
131     *
132     * @param userName the user name, can be null
133     * @return requested Memory object (never null)
134     * @throws IllegalArgumentException if cannot create the Memory due to e.g.
135     *                                  an illegal name or name that can't be
136     *                                  parsed.
137     */
138    @Nonnull
139    Memory newMemory(@CheckForNull String userName) throws IllegalArgumentException;
140
141}