001package jmri.managers;
002
003import javax.annotation.Nonnull;
004import jmri.InstanceManager;
005import jmri.Logix;
006import jmri.LogixManager;
007import jmri.Manager;
008import jmri.implementation.DefaultLogix;
009import jmri.jmrit.beantable.LRouteTableAction;
010import jmri.jmrix.internal.InternalSystemConnectionMemo;
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014/**
015 * Basic Implementation of a LogixManager.
016 * <p>
017 * Note that Logix system names must begin with system prefix and type character,
018 * usually IX, and be followed by a string, usually, but not always, a number. This
019 * is enforced when a Logix is created.
020 * <p>
021 * The system names of Conditionals belonging to a Logix begin with the Logix's
022 * system name, then there is a capital C and a number.
023 *
024 * @author Dave Duchamp Copyright (C) 2007
025 */
026public class DefaultLogixManager extends AbstractManager<Logix>
027        implements LogixManager {
028
029    public DefaultLogixManager(InternalSystemConnectionMemo memo) {
030        super(memo);
031        jmri.InstanceManager.turnoutManagerInstance().addVetoableChangeListener(this);
032        jmri.InstanceManager.sensorManagerInstance().addVetoableChangeListener(this);
033        jmri.InstanceManager.memoryManagerInstance().addVetoableChangeListener(this);
034        jmri.InstanceManager.getDefault(jmri.SignalHeadManager.class).addVetoableChangeListener(this);
035        jmri.InstanceManager.getDefault(jmri.SignalMastManager.class).addVetoableChangeListener(this);
036        jmri.InstanceManager.getDefault(jmri.BlockManager.class).addVetoableChangeListener(this);
037        jmri.InstanceManager.lightManagerInstance().addVetoableChangeListener(this);
038        jmri.InstanceManager.getDefault(jmri.ConditionalManager.class).addVetoableChangeListener(this);
039        InstanceManager.getDefault(jmri.jmrit.logix.WarrantManager.class).addVetoableChangeListener(this);
040        InstanceManager.getDefault(jmri.jmrit.logix.OBlockManager.class).addVetoableChangeListener(this);
041        InstanceManager.getDefault(jmri.jmrit.entryexit.EntryExitPairs.class).addVetoableChangeListener(this);
042    }
043
044    @Override
045    public int getXMLOrder() {
046        return Manager.LOGIXS;
047    }
048
049    @Override
050    public char typeLetter() {
051        return 'X';
052    }
053
054    /**
055     * Create a new Logix if the Logix does not exist.
056     *
057     * @return null if a Logix with the same systemName or userName
058     * already exists, or if there is trouble creating a new Logix
059     */
060    @Override
061    public Logix createNewLogix(String systemName, String userName) {
062        // Check that Logix does not already exist
063        Logix x;
064        if (userName != null && !userName.equals("")) {
065            x = getByUserName(userName);
066            if (x != null) {
067                return null;
068            }
069        }
070        x = getBySystemName(systemName);
071        if (x != null) {
072            return null;
073        }
074        // Logix does not exist, create a new Logix
075        x = new DefaultLogix(systemName, userName);
076        // save in the maps
077        register(x);
078
079        // Keep track of the last created auto system name
080        updateAutoNumber(systemName);
081
082        return x;
083    }
084
085    @Override
086    public Logix createNewLogix(String userName) {
087        return createNewLogix(getAutoSystemName(), userName);
088    }
089
090    /**
091     * Remove an existing Logix and delete all its conditionals. Logix must have
092     * been deactivated before invoking this.
093     */
094    @Override
095    public void deleteLogix(Logix x) {
096        // delete the Logix
097        deregister(x);
098        x.dispose();
099    }
100
101    /**
102     * Activate all Logixs that are not currently active This method is called
103     * after a configuration file is loaded.
104     */
105    @Override
106    public void activateAllLogixs() {
107        // Guarantee Initializer executes first.
108        Logix x = getBySystemName(LRouteTableAction.getLogixInitializer());
109        if (x != null) {
110            x.activateLogix();
111            x.setGuiNames();
112        }
113        // iterate thru all Logixs that exist
114        java.util.Iterator<Logix> iter
115                = getNamedBeanSet().iterator();
116        while (iter.hasNext()) {
117            // get the next Logix
118            x = iter.next();
119
120            if (x.getSystemName().equals(LRouteTableAction.getLogixInitializer())) {
121                continue;
122            }
123
124            if (loadDisabled) {
125                // user has requested that Logixs be loaded disabled
126                log.warn("load disabled set - will not activate logic for: {}", x.getDisplayName());
127                x.setEnabled(false);
128            }
129            if (x.getEnabled()) {
130                //System.out.println("logix set enabled");
131                x.activateLogix();
132            }
133            x.setGuiNames();
134        }
135        // reset the load switch
136        loadDisabled = false;
137    }
138
139    /**
140     * Get an existing Logix. First looks up assuming name is a
141     * User Name. If this fails looks up assuming name is a System Name. If
142     * both fail, returns null.
143     */
144    @Override
145    public Logix getLogix(String name) {
146        Logix x = getByUserName(name);
147        if (x != null) {
148            return x;
149        }
150        return getBySystemName(name);
151    }
152
153    /**
154     * Support for loading Logixs in a disabled state to debug loops
155     */
156    boolean loadDisabled = false;
157
158    @Override
159    public void setLoadDisabled(boolean s) {
160        loadDisabled = s;
161    }
162
163    @Override
164    @Nonnull
165    public String getBeanTypeHandled(boolean plural) {
166        return Bundle.getMessage(plural ? "BeanNameLogixes" : "BeanNameLogix");
167    }
168
169    /**
170     * {@inheritDoc}
171     */
172    @Override
173    public Class<Logix> getNamedBeanClass() {
174        return Logix.class;
175    }
176
177    private final static Logger log = LoggerFactory.getLogger(DefaultLogixManager.class);
178
179}