001package jmri.jmrix.can.cbus;
002
003import java.beans.PropertyChangeEvent;
004import java.util.Locale;
005
006import javax.annotation.*;
007
008import jmri.*;
009import jmri.jmrix.can.CanSystemConnectionMemo;
010
011/**
012 * Implement SensorManager for CAN CBUS systems.
013 * <p>
014 * System names are "MS+n;-m", where M is the user configurable system prefix, n
015 * and m are the events (signed for on/off, separated by ;).
016 *
017 * @author Bob Jacobsen Copyright (C) 2008
018 */
019public class CbusSensorManager extends jmri.managers.AbstractSensorManager {
020
021    /**
022     * Ctor using a given system connection memo
023     * @param memo System Connection
024     */
025    public CbusSensorManager(CanSystemConnectionMemo memo) {
026        super(memo);
027    }
028
029    /**
030     * {@inheritDoc}
031     *
032     * @throws IllegalArgumentException if the system name is not in a valid format
033     */
034    @Override
035    @Nonnull
036    protected Sensor createNewSensor(@Nonnull String systemName, String userName) throws IllegalArgumentException {
037        String addr = systemName.substring(getSystemNamePrefix().length());
038        // first, check validity
039        String newAddress;
040        try {
041            newAddress = CbusAddress.validateSysName(addr);
042        } catch (IllegalArgumentException e) {
043            log.error("Unable to create CbusSensor, {}", e.getMessage());
044            throw e;
045        }
046        // OK, make
047        Sensor s = new CbusSensor(getSystemPrefix(), newAddress,
048            ((CanSystemConnectionMemo)getMemo()).getTrafficController());
049        s.setUserName(userName);
050        return s;
051    }
052
053    /**
054     * {@inheritDoc}
055     */
056    @Override
057    public String createSystemName(@Nonnull String curAddress, @Nonnull String prefix) throws JmriException {
058        // first, check validity
059        String newAddress;
060        try {
061            validateSystemNamePrefix(prefix + typeLetter() + curAddress, Locale.getDefault());
062            newAddress = CbusAddress.validateSysName(curAddress);
063         } catch (IllegalArgumentException  e) {
064             throw new JmriException(e.getMessage());
065        }
066        return prefix + typeLetter() + newAddress;
067    }
068
069    /**
070     * {@inheritDoc}
071     */
072    @Override
073    public boolean allowMultipleAdditions(@Nonnull String systemName) {
074        return true;
075    }
076
077    @Override
078    @Nonnull
079    @CheckReturnValue
080    public String getNextValidSystemName(@Nonnull NamedBean currentBean) throws JmriException {
081        if (!allowMultipleAdditions(currentBean.getSystemName())) {
082            throw new UnsupportedOperationException("Not supported");
083        }
084
085        String currentName = currentBean.getSystemName();
086        String suffix = Manager.getSystemSuffix(currentName);
087        String type = Manager.getTypeLetter(currentName);
088        String prefix = Manager.getSystemPrefix(currentName);
089
090        String nextName = CbusAddress.getIncrement(suffix);
091
092        if (nextName==null) {
093            throw new JmriException("No existing number found when incrementing " + currentName);
094        }
095        return prefix+type+nextName;
096
097    }
098
099    /**
100     * {@inheritDoc}
101     */
102    @Override
103    @Nonnull
104    public String validateSystemNameFormat(@Nonnull String name, @Nonnull Locale locale) {
105        validateSystemNamePrefix(name, locale);
106        try {
107            return getSystemNamePrefix() + CbusAddress.validateSysName(name.substring(getSystemNamePrefix().length()));
108        } catch (IllegalArgumentException ex) {
109            throw new jmri.NamedBean.BadSystemNameException(locale, "InvalidSystemNameCustom", ex.getMessage());
110        }
111    }
112
113    /**
114     * {@inheritDoc}
115     */
116    @Override
117    public NameValidity validSystemNameFormat(@Nonnull String systemName) {
118        String addr;
119        try {
120            addr = systemName.substring(getSystemNamePrefix().length()); // get only the address part
121            CbusAddress.validateSysName(addr);
122        } catch (StringIndexOutOfBoundsException | IllegalArgumentException e) {
123            return NameValidity.INVALID;
124        }
125        return NameValidity.VALID;
126    }
127
128    /**
129     * {@inheritDoc}
130     */
131    @Override
132    public String getEntryToolTip() {
133        return Bundle.getMessage("AddInputEntryToolTip");
134    }
135
136    @Override
137    public void propertyChange(PropertyChangeEvent e) {
138        super.propertyChange(e);
139        if (e.getPropertyName().equals("inverted")) {
140            firePropertyChange("beaninverted", null, null); //IN18N
141        }
142    }
143
144    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CbusSensorManager.class);
145
146}