001package jmri.implementation;
002
003import javax.annotation.Nonnull;
004
005/**
006 * SignalMast implemented via one SignalHead object.
007 * <p>
008 * System name specifies the creation information:
009 * <pre>
010 * IF$vsm:basic:one-searchlight($0001)
011 * </pre> The name is a colon-separated series of terms:
012 * <ul>
013 * <li>IF$vsm - defines signal masts of this type
014 * <li>basic - name of the signaling system
015 * <li>one-searchlight - name of the particular aspect map
016 * <li>($0001) - small ordinal number for telling various virtual signal masts
017 * apart
018 * </ul>
019 *
020 * @author Bob Jacobsen Copyright (C) 2009
021 */
022public class VirtualSignalMast extends AbstractSignalMast {
023
024    public VirtualSignalMast(String systemName, String userName) {
025        super(systemName, userName);
026        configureFromName(systemName);
027    }
028
029    public VirtualSignalMast(String systemName) {
030        super(systemName);
031        configureFromName(systemName);
032    }
033
034    private static final String THE_MAST_TYPE = "IF$vsm";
035
036    private void configureFromName(String systemName) {
037        // split out the basic information
038        String[] parts = systemName.split(":");
039        if (parts.length < 3) {
040            log.error("SignalMast system name needs at least three parts: {}", systemName);
041            throw new IllegalArgumentException("System name needs at least three parts: " + systemName);
042        }
043        if (!parts[0].equals(THE_MAST_TYPE)) {
044            log.warn("SignalMast system name should start with {} but is {}", THE_MAST_TYPE, systemName);
045        }
046
047        String system = parts[1];
048        String mast = parts[2];
049        // new style
050        mast = mast.substring(0, mast.indexOf("("));
051        setMastType(mast);
052        String tmp = parts[2].substring(parts[2].indexOf("($") + 2, parts[2].indexOf(")"));
053        try {
054            int autoNumber = Integer.parseInt(tmp);
055            synchronized (VirtualSignalMast.class) {
056                if (autoNumber > getLastRef()) {
057                    setLastRef(autoNumber);
058                }
059            }
060        } catch (NumberFormatException e) {
061            log.warn("Auto generated SystemName {} is not in the correct format", systemName);
062        }
063        configureSignalSystemDefinition(system);
064        configureAspectTable(system, mast);
065    }
066
067    @Override
068    public void setAspect(@Nonnull String aspect) {
069        // check it's a choice
070        if (!map.checkAspect(aspect)) {
071            // not a valid aspect
072            log.warn("attempting to set invalid aspect: {} on mast: {}", aspect, getDisplayName());
073            throw new IllegalArgumentException("attempting to set invalid aspect: " + aspect + " on mast: " + getDisplayName());
074        } else if (disabledAspects.contains(aspect)) {
075            log.warn("attempting to set an aspect that has been disabled: {} on mast: {}", aspect, getDisplayName());
076            throw new IllegalArgumentException("attempting to set an aspect that has been disabled: " + aspect + " on mast: " + getDisplayName());
077        }
078        super.setAspect(aspect);
079    }
080
081    /**
082     *
083     * @param newVal for ordinal of all VirtualSignalMasts in use
084     */
085    protected static void setLastRef(int newVal) {
086        lastRef = newVal;
087    }
088
089    /**
090     * @return highest ordinal of all VirtualSignalMasts in use
091     */
092    public static int getLastRef() {
093        return lastRef;
094    }
095
096    /**
097     * Ordinal of all VirtualSignalMasts to create unique system name.
098     */
099    private static volatile int lastRef = 0;
100
101    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(VirtualSignalMast.class);
102
103}