001package jmri.jmrix.internal;
002
003import java.util.Comparator;
004import java.util.ResourceBundle;
005
006import jmri.*;
007import jmri.jmrix.debugthrottle.DebugThrottleManager;
008import jmri.managers.DefaultPowerManager;
009import jmri.managers.DefaultProgrammerManager;
010import jmri.progdebugger.DebugProgrammerManager;
011import jmri.util.NamedBeanPreferNumericComparator;
012
013/**
014 * Lightweight class to denote that a system is active, and provide general
015 * information.
016 * <p>
017 * Things this needed to do:
018 * <ul>
019 * <li>One of these must be automatically, transparently available - this is
020 * done by inheriting from jmri.InstanceManagerAutoDefault
021 * <li>It must be possible to have more than one of these, so you can have
022 * multiple internal systems defined - each one keeps internal references to its
023 * objects
024 * <li>It must make sure that its objects are available individually through the
025 * instance manager.
026 * <li>But it also has to handle the ProxyManager special cases in the
027 * InstanceManager
028 * </ul>
029 *
030 * @author Bob Jacobsen Copyright (C) 2010, 2016
031 */
032public class InternalSystemConnectionMemo extends jmri.jmrix.DefaultSystemConnectionMemo implements jmri.InstanceManagerAutoDefault {
033
034    public InternalSystemConnectionMemo(String prefix, String name, boolean defaultInstanceType) {
035        super(prefix, name);
036        InstanceManager.store(this, InternalSystemConnectionMemo.class); // also register as specific type
037        register();
038        this.defaultInstanceType = defaultInstanceType;
039    }
040
041    public InternalSystemConnectionMemo(String prefix, String name) {
042        this(prefix, name, true);
043    }
044
045    public InternalSystemConnectionMemo(boolean defaultInstanceType) {
046        this("I", "Internal", defaultInstanceType);
047    }
048
049    // invoked by i.e. InstanceManager via the InstanceManagerAutoDefault
050    // mechanism, this creates a partial system
051    public InternalSystemConnectionMemo() {
052        this(true);
053    }
054
055    boolean configured = false;
056
057    // if true, this is the default Internal instance, which
058    // only provides a subset of types
059    boolean defaultInstanceType = false;
060
061    /**
062     * Configure the common managers for Internal connections. This puts the
063     * common manager config in one place.
064     * <p>
065     * Note: The Proxy system can cause some managers to be created early. We
066     * don't call configureManagers in that case, as it causes an infinite loop.
067     */
068    public void configureManagers() {
069
070        log.debug("Do configureManagers - doesn't pre-build anything");
071        if (configured) {
072            log.warn("configureManagers called for a second time", new Exception("traceback"));
073        }
074        configured = true;
075    }
076
077    public InternalSensorManager getSensorManager() {
078        InternalSensorManager sensorManager = (InternalSensorManager) classObjectMap.get(SensorManager.class);
079        if(sensorManager == null ) {
080            log.debug("Create InternalSensorManager \"{}\" by request", getSystemPrefix());
081            sensorManager = new InternalSensorManager(this);
082            store(sensorManager,SensorManager.class);
083            // special due to ProxyManager support
084            InstanceManager.setSensorManager(sensorManager);
085        }
086        return sensorManager;
087    }
088
089    public InternalLightManager getLightManager() {
090        InternalLightManager lightManager = (InternalLightManager) classObjectMap.get(LightManager.class);
091        if(lightManager == null) {
092            log.debug("Create InternalLightManager by request");
093            lightManager = new InternalLightManager(this);
094            store(lightManager,LightManager.class);
095            // special due to ProxyManager support
096            InstanceManager.setLightManager(lightManager);
097        }
098        return lightManager;
099    }
100
101    public InternalReporterManager getReporterManager() {
102        InternalReporterManager reporterManager = (InternalReporterManager) classObjectMap.get(ReporterManager.class);
103        if(reporterManager == null ) {
104            log.debug("Create InternalReporterManager by request");
105            reporterManager = new InternalReporterManager(this);
106            store(reporterManager,ReporterManager.class);
107            // special due to ProxyManager support
108            InstanceManager.setReporterManager(reporterManager);
109        }
110        return reporterManager;
111    }
112
113    public InternalTurnoutManager getTurnoutManager() {
114        InternalTurnoutManager turnoutManager = (InternalTurnoutManager) classObjectMap.get(TurnoutManager.class);
115        if(turnoutManager == null ) {
116            log.debug("Create InternalTurnoutManager \"{}\" by request", getSystemPrefix());
117            turnoutManager = new InternalTurnoutManager(this);
118            store(turnoutManager,TurnoutManager.class);
119            // special due to ProxyManager support
120            InstanceManager.setTurnoutManager(turnoutManager);
121        }
122        return turnoutManager;
123    }
124
125    public InternalMeterManager getMeterManager() {
126        InternalMeterManager meterManager = (InternalMeterManager) classObjectMap.get(MeterManager.class);
127        if (meterManager == null) {
128            log.debug("Create InternalMeterManager by request {}", getSystemPrefix());
129            meterManager = new InternalMeterManager(this);
130            // special due to ProxyManager support
131            InstanceManager.setMeterManager(meterManager);
132        }
133        return meterManager;
134    }
135
136    public InternalStringIOManager getStringIOManager() {
137        InternalStringIOManager stringIOManager = (InternalStringIOManager) classObjectMap.get(StringIOManager.class);
138        if (stringIOManager == null) {
139            log.debug("Create InternalStringIOManager by request {}", getSystemPrefix());
140            stringIOManager = new InternalStringIOManager(this);
141            // special due to ProxyManager support
142            InstanceManager.setStringIOManager(stringIOManager);
143        }
144        return stringIOManager;
145    }
146
147    public DefaultPowerManager getPowerManager() {
148        return (DefaultPowerManager) classObjectMap.computeIfAbsent(PowerManager.class, (Class<?> c) -> {
149            log.debug("Create DefaultPowerManager by request");
150            PowerManager powerManager = new jmri.managers.DefaultPowerManager(this);
151            jmri.InstanceManager.store(powerManager, PowerManager.class);
152            return powerManager;
153        });
154    }
155
156    @Override
157    public InternalConsistManager getConsistManager() {
158        if (defaultInstanceType) {
159            return null;
160        }
161        return (InternalConsistManager) classObjectMap.computeIfAbsent((ConsistManager.class), (Class<?> c) -> {
162            log.debug("Create InternalConsistManager by request");
163            ConsistManager consistManager = new InternalConsistManager();
164            InstanceManager.store(consistManager, jmri.ConsistManager.class);
165            return consistManager;
166        });
167    }
168
169    public DebugThrottleManager getThrottleManager() {
170        if (defaultInstanceType) {
171            return null;
172        }
173        return (DebugThrottleManager) classObjectMap.computeIfAbsent(ThrottleManager.class, ( Class<?> c) -> {
174            log.debug("Create DebugThrottleManager by request");
175            // Install a debug throttle manager
176            ThrottleManager throttleManager = new jmri.jmrix.debugthrottle.DebugThrottleManager(this);
177            jmri.InstanceManager.setThrottleManager(throttleManager);
178            return throttleManager;
179        });
180    }
181
182    public DebugProgrammerManager getProgrammerManager() {
183        if (defaultInstanceType) {
184            return null;
185        }
186        return (DebugProgrammerManager) classObjectMap.computeIfAbsent(DefaultProgrammerManager.class,
187                (Class<?> c) -> {
188                    // Install a debug programmer
189                    log.debug("Create DebugProgrammerManager by request");
190                    return new DebugProgrammerManager(this);
191                });
192    }
193
194    @Override
195    public boolean provides(Class<?> type) {
196        if (getDisabled()) {
197            return false;
198        }
199
200        if (!configured) {
201            configureManagers();
202        }
203
204        if (type.equals(jmri.SensorManager.class)) {
205            return true;
206        }
207        if (type.equals(jmri.LightManager.class)) {
208            return true;
209        }
210        if (type.equals(jmri.ReporterManager.class)) {
211            return true;
212        }
213        if (type.equals(jmri.TurnoutManager.class)) {
214            return true;
215        }
216
217        if (!defaultInstanceType) {
218            if (type.equals(jmri.PowerManager.class)) {
219                return true;
220            }
221
222            if (type.equals(jmri.GlobalProgrammerManager.class)) {
223                return getProgrammerManager().isGlobalProgrammerAvailable();
224            }
225            if (type.equals(jmri.AddressedProgrammerManager.class)) {
226                return getProgrammerManager().isAddressedModePossible();
227            }
228
229            if (type.equals(jmri.ThrottleManager.class)) {
230                return true;
231            }
232            if (type.equals(jmri.ConsistManager.class)) {
233                return true;
234            }
235        }
236
237        return super.provides(type);
238    }
239
240    @SuppressWarnings("unchecked")
241    @Override
242    public <T> T get(Class<T> type) {
243        if (getDisabled()) {
244            return null;
245        }
246
247        if (!configured) {
248            configureManagers();
249        }
250
251        if (type.equals(jmri.SensorManager.class)) {
252            return (T) getSensorManager();
253        }
254        if (type.equals(jmri.LightManager.class)) {
255            return (T) getLightManager();
256        }
257        if (type.equals(jmri.ReporterManager.class)) {
258            return (T) getReporterManager();
259        }
260        if (type.equals(jmri.TurnoutManager.class)) {
261            return (T) getTurnoutManager();
262        }
263
264        if (!defaultInstanceType) {
265            if (type.equals(jmri.PowerManager.class)) {
266                return (T) getPowerManager();
267            }
268
269            if (type.equals(jmri.GlobalProgrammerManager.class)) {
270                return (T) getProgrammerManager();
271            }
272            if (type.equals(jmri.AddressedProgrammerManager.class)) {
273                return (T) getProgrammerManager();
274            }
275
276            if (type.equals(jmri.ThrottleManager.class)) {
277                return (T) getThrottleManager();
278            }
279            if (type.equals(jmri.ConsistManager.class)) {
280                return (T) getConsistManager();
281            }
282        }
283
284        return super.get(type);
285    }
286
287    @Override
288    protected ResourceBundle getActionModelResourceBundle() {
289        // No actions to add at start up
290        return null;
291    }
292
293    @Override
294    public <B extends NamedBean> Comparator<B> getNamedBeanComparator(Class<B> type) {
295        return new NamedBeanPreferNumericComparator<>();
296    }
297
298    @Override
299    public void dispose() {
300        SensorManager sensorManager = (SensorManager) classObjectMap.get(SensorManager.class);
301        if (sensorManager != null) {
302            sensorManager.dispose();
303        }
304
305        TurnoutManager turnoutManager = (TurnoutManager) classObjectMap.get(TurnoutManager.class);
306        if (turnoutManager != null) {
307            turnoutManager.dispose();
308        }
309        super.dispose();
310    }
311
312    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(InternalSystemConnectionMemo.class);
313
314}