001package jmri.jmrit.logixng.actions;
002
003import jmri.InstanceManager;
004import jmri.JmriException;
005import jmri.Manager;
006import jmri.jmrit.logixng.implementation.AbstractBase;
007import jmri.jmrit.logixng.Base;
008import jmri.jmrit.logixng.Category;
009import jmri.jmrit.logixng.DigitalActionBean;
010import jmri.jmrit.logixng.DigitalActionManager;
011
012/**
013 * The base class for LogixNG Actions
014 *
015 * @author Daniel Bergqvist Copyright 2018
016 */
017public abstract class AbstractDigitalAction extends AbstractBase
018        implements DigitalActionBean {
019
020    private Base _parent = null;
021    private int _state = DigitalActionBean.UNKNOWN;
022
023
024    public AbstractDigitalAction(String sys, String user)
025            throws BadUserNameException, BadSystemNameException {
026        this(sys, user, Category.ITEM);
027    }
028
029    public AbstractDigitalAction(String sys, String user, Category category)
030            throws BadUserNameException, BadSystemNameException {
031        super(sys, user, category);
032
033        // Do this test here to ensure all the tests are using correct system names
034        Manager.NameValidity isNameValid = InstanceManager.getDefault(DigitalActionManager.class).validSystemNameFormat(mSystemName);
035        if (isNameValid != Manager.NameValidity.VALID) {
036            throw new IllegalArgumentException("system name is not valid: "+mSystemName);
037        }
038    }
039
040    /** {@inheritDoc} */
041    @Override
042    public Base getParent() {
043        return _parent;
044    }
045
046    /** {@inheritDoc} */
047    @Override
048    public void setParent(Base parent) {
049        _parent = parent;
050    }
051
052    protected String getPreferredSocketPrefix() {
053        return "A";
054    }
055
056    public String getNewSocketName() {
057        String[] names = new String[getChildCount()];
058        for (int i=0; i < getChildCount(); i++) {
059            names[i] = getChild(i).getName();
060        }
061        return getNewSocketName(names);
062    }
063
064    public String getNewSocketName(String[] names) {
065        String prefix = getPreferredSocketPrefix();
066
067        int x = 1;
068        while (x < 10000) {     // Protect from infinite loop
069            String name = prefix + Integer.toString(x);
070            boolean validName = true;
071            for (int i=0; i < names.length; i++) {
072                if (name.equals(names[i])) {
073                    validName = false;
074                    break;
075                }
076            }
077            if (validName) {
078                return name;
079            }
080            x++;
081        }
082        throw new RuntimeException("Unable to find a new socket name");
083    }
084
085    @Override
086    public String getBeanType() {
087        return Bundle.getMessage("BeanNameDigitalAction");
088    }
089
090    @Override
091    public void setState(int s) throws JmriException {
092        log.warn("Unexpected call to setState in AbstractDigitalAction.");  // NOI18N
093        _state = s;
094    }
095
096    @Override
097    public int getState() {
098        log.warn("Unexpected call to getState in AbstractDigitalAction.");  // NOI18N
099        return _state;
100    }
101
102
103    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AbstractDigitalAction.class);
104}