001package jmri.managers;
002
003import java.io.File;
004import java.net.URISyntaxException;
005import java.util.ArrayList;
006import java.util.List;
007import javax.annotation.Nonnull;
008import jmri.InstanceManager;
009import jmri.Manager;
010import jmri.SignalGroup;
011import jmri.SignalGroupManager;
012import jmri.implementation.DefaultSignalGroup;
013import jmri.jmrix.internal.InternalSystemConnectionMemo;
014import jmri.util.FileUtil;
015import org.slf4j.Logger;
016import org.slf4j.LoggerFactory;
017
018/**
019 * Default implementation of a SignalGroupManager.
020 * <p>
021 * This loads automatically the first time used.
022 *
023 * @author Bob Jacobsen Copyright (C) 2009, 2018
024 */
025public class DefaultSignalGroupManager extends AbstractManager<SignalGroup>
026        implements SignalGroupManager {
027
028    public DefaultSignalGroupManager(InternalSystemConnectionMemo memo) {
029        super(memo);
030
031        // load when created, which will generally
032        // be the first time referenced
033        //load();
034    }
035
036    @Override
037    public int getXMLOrder() {
038        return Manager.SIGNALGROUPS;
039    }
040
041    @Override
042    public char typeLetter() {
043        return 'G'; // according to JMRI: Names and Naming
044    }
045
046    @Override
047    public SignalGroup getSignalGroup(@Nonnull String name) {
048        SignalGroup t = getByUserName(name);
049        if (t != null) {
050            return t;
051        }
052
053        return getBySystemName(name);
054    }
055
056    @Override
057    public SignalGroup getBySystemName(@Nonnull String key) {
058        return _tsys.get(key);
059    }
060
061    @Override
062    public SignalGroup getByUserName(@Nonnull String key) {
063        return _tuser.get(key);
064    }
065
066    /**
067     * {@inheritDoc}
068     *
069     * Keep autostring in line with {@link #newSignalGroup(String)},
070     * {@link #getSystemPrefix()} and {@link #typeLetter()}
071     */
072    @Override
073    @Nonnull
074    public SignalGroup provideSignalGroup(@Nonnull String systemName, String userName) {
075        log.debug("provideGroup({})", systemName);
076        SignalGroup r;
077        r = getByUserName(systemName);
078        if (r != null) {
079            return r;
080        }
081        r = getBySystemName(systemName);
082        if (r != null) {
083            return r;
084        }
085        // Group does not exist, create a new signal group
086        r = new DefaultSignalGroup(systemName, userName);
087        // save in the maps
088        register(r);
089
090        // Keep track of the last created auto system name
091        updateAutoNumber(systemName);
092
093        return r;
094    }
095
096    /**
097     * {@inheritDoc}
098     * @deprecated 4.15.2 use newSignaGroupWithUserName
099     */
100    @Nonnull
101    @Override
102    @Deprecated //  4.15.2 use newSignaGroupWithUserName
103    public SignalGroup newSignalGroup(@Nonnull String userName) {
104        jmri.util.LoggingUtil.deprecationWarning(log, "newSignalGroup");
105        return newSignaGroupWithUserName(userName);
106    }
107    
108    /**
109     * {@inheritDoc}
110     *
111     * Keep autostring in line with {@link #provideSignalGroup(String, String)},
112     * {@link #getSystemPrefix()} and {@link #typeLetter()}
113     */
114    @Nonnull
115    @Override
116    public SignalGroup newSignaGroupWithUserName(@Nonnull String userName) {
117        return provideSignalGroup(getAutoSystemName(), userName);
118    }
119
120    List<String> getListOfNames() {
121        List<String> retval = new ArrayList<String>();
122        // first locate the signal system directory
123        // and get names of systems
124        File signalDir;
125        File[] files = new File[0];
126        try {
127            signalDir = new File(FileUtil.findURL("xml/signals", FileUtil.Location.INSTALLED).toURI());
128            files = signalDir.listFiles();
129        } catch (URISyntaxException | NullPointerException ex) {
130            log.error("No signals are defined.", ex);
131        }
132        if (files == null) { // not a directory
133            return retval; // empty, but not null
134        }
135        for (File file : files) {
136            if (file.isDirectory()) {
137                // check that there's an aspects.xml file
138                File aspects = new File(file.getPath() + File.separator + "aspects.xml");
139                if (aspects.exists()) {
140                    log.debug("found system: {}", file.getName());
141                    retval.add(file.getName());
142                }
143            }
144        }
145        return retval;
146    }
147
148    /**
149     * 
150     * @return the default instance of DefaultSignalGroupManager
151     * @deprecated since 4.17.3; use {@link jmri.InstanceManager#getDefault(java.lang.Class)} instead
152     */
153    @Deprecated
154    static public DefaultSignalGroupManager instance() {
155        return InstanceManager.getDefault(DefaultSignalGroupManager.class);
156    }
157
158    @Override
159    public void deleteSignalGroup(SignalGroup s) {
160        deregister(s);
161    }
162
163    @Override
164    @Nonnull
165    public String getBeanTypeHandled(boolean plural) {
166        return Bundle.getMessage(plural ? "BeanNameSignalGroups" : "BeanNameSignalGroup");
167    }
168
169    /**
170     * {@inheritDoc}
171     */
172    @Override
173    public Class<SignalGroup> getNamedBeanClass() {
174        return SignalGroup.class;
175    }
176
177    private final static Logger log = LoggerFactory.getLogger(DefaultSignalGroupManager.class);
178
179}