001package jmri;
002
003import java.util.ArrayList;
004import javax.annotation.Nonnull;
005import jmri.managers.AbstractManager;
006
007/**
008 * Implementation of a Transit Manager
009 * <p>
010 * This doesn't need an interface, since Transits are globaly implemented,
011 * instead of being system-specific.
012 * <p>
013 * Note that Transit system names must begin with system prefix and type character,
014 * usually IZ, and be followed by a string, usually, but not always, a number. This
015 * is enforced when a Transit is created.
016 * <br>
017 * <hr>
018 * This file is part of JMRI.
019 * <p>
020 * JMRI is free software; you can redistribute it and/or modify it under the
021 * terms of version 2 of the GNU General Public License as published by the Free
022 * Software Foundation. See the "COPYING" file for a copy of this license.
023 * <p>
024 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
025 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
026 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
027 *
028 * @author Dave Duchamp Copyright (C) 2008, 2011
029 */
030public class TransitManager extends AbstractManager<Transit> implements InstanceManagerAutoDefault {
031
032    public TransitManager() {
033        super();
034        InstanceManager.getDefault(jmri.SectionManager.class).addVetoableChangeListener(this);
035    }
036
037    @Override
038    public int getXMLOrder() {
039        return Manager.TRANSITS;
040    }
041
042    @Override
043    public char typeLetter() {
044        return 'Z';
045    }
046
047    /**
048     * Create a new Transit if the Transit does not exist.
049     *
050     * @param systemName the desired system name
051     * @param userName   the desired user name
052     * @return a new Transit or null if a Transit with the same systemName or
053     *         userName already exists, or if there is trouble creating a new
054     *         Transit
055     */
056    public Transit createNewTransit(String systemName, String userName) {
057        // check system name
058        if ((systemName == null) || (systemName.length() < 1)) {
059            // no valid system name entered, return without creating
060            return null;
061        }
062        String sysName = systemName;
063        if (!sysName.startsWith(getSystemNamePrefix())) {
064            sysName = makeSystemName(sysName);
065        }
066        // Check that Transit does not already exist
067        Transit z;
068        if (userName != null && !userName.equals("")) {
069            z = getByUserName(userName);
070            if (z != null) {
071                return null;
072            }
073        }
074        z = getBySystemName(sysName);
075        if (z != null) {
076            return null;
077        }
078        // Transit does not exist, create a new Transit
079        z = new Transit(sysName, userName);
080        // save in the maps
081        register(z);
082
083        // Keep track of the last created auto system name
084        updateAutoNumber(systemName);
085
086        return z;
087    }
088
089    /**
090     * For use with User GUI, to allow the auto generation of systemNames, where
091     * the user can optionally supply a username.
092     * <p>
093     * Note: Since system names should be kept short for use in Dispatcher,
094     * automatically generated system names are in the form {@code IZnn}, where
095     * {@code nn} is the first available number.
096     *
097     * @param userName the desired user name
098     * @return a new Transit or null if userName is already associated with
099     *         another Transit
100     */
101    public Transit createNewTransit(String userName) {
102        return createNewTransit(getAutoSystemName(), userName);
103    }
104
105    /**
106     * Get an existing Transit. First looks up assuming that name is a User
107     * Name. If this fails looks up assuming that name is a System Name. If both
108     * fail, returns null.
109     *
110     * @param name User name or system name to match
111     * @return null if no match found
112     */
113    public Transit getTransit(String name) {
114        Transit z = getByUserName(name);
115        if (z != null) {
116            return z;
117        }
118        return getBySystemName(name);
119    }
120
121    /**
122     * Remove an existing Transit.
123     *
124     * @param z the transit to remove
125     */
126    public void deleteTransit(Transit z) {
127        // delete the Transit
128        deregister(z);
129        z.dispose();
130    }
131
132    /**
133     * Get a list of Transits which use a specified Section.
134     *
135     * @param s the section to check Transits against
136     * @return a list, possibly empty, of Transits using s
137     */
138    public ArrayList<Transit> getListUsingSection(Section s) {
139        ArrayList<Transit> list = new ArrayList<>();
140        for (Transit tTransit : getNamedBeanSet()) {
141            if (tTransit.containsSection(s)) {
142                // this Transit uses the specified Section
143                list.add(tTransit);
144            }
145        }
146        return list;
147    }
148
149    public ArrayList<Transit> getListUsingBlock(Block b) {
150        ArrayList<Transit> list = new ArrayList<>();
151        for (Transit tTransit : getNamedBeanSet()) {
152            if (tTransit.containsBlock(b)) {
153                // this Transit uses the specified Section
154                list.add(tTransit);
155            }
156        }
157        return list;
158    }
159
160    public ArrayList<Transit> getListEntryBlock(Block b) {
161        ArrayList<Transit> list = new ArrayList<>();
162        for (Transit tTransit : getNamedBeanSet()) {
163            ArrayList<Block> entryBlock = tTransit.getEntryBlocksList();
164            if (entryBlock.contains(b)) {
165                // this Transit uses the specified Section
166                list.add(tTransit);
167            }
168        }
169        return list;
170    }
171    @Override
172    @Nonnull
173    public String getBeanTypeHandled(boolean plural) {
174        return Bundle.getMessage(plural ? "BeanNameTransits" : "BeanNameTransit");
175    }
176
177    /**
178     * {@inheritDoc}
179     */
180    @Override
181    public Class<Transit> getNamedBeanClass() {
182        return Transit.class;
183    }
184
185    // private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TransitManager.class);
186
187}