001package jmri;
002
003import java.util.Objects;
004
005import javax.annotation.Nonnull;
006
007import jmri.util.NamedBeanExpectedState;
008
009/**
010 * Represent a NamedBean (such as a Turnout) and specific desired setting for
011 * it. These can be used to represent the setting a NamedBean has as part of a
012 * particular path through a layout, or a condition that has to be true as part
013 * of something.
014 * <p>
015 * Objects of this class are immutable, in that once created the selected bean
016 * and required setting cannot be changed. However, the value of the
017 * {@link #check} method does change, because it's a function of the current
018 * bean setting(s).
019 *
020 * @author Bob Jacobsen Copyright (C) 2006, 2008, 2010
021 */
022@javax.annotation.concurrent.Immutable
023public class BeanSetting extends NamedBeanExpectedState<NamedBean> {
024
025    public BeanSetting(NamedBean t, String pName, int setting) {
026        super(t, pName, setting);
027    }
028
029    public BeanSetting(NamedBean t, int setting) {
030        super(t, setting);
031    }
032
033    /**
034     * Convenience method; check if the Bean currently has the desired setting.
035     *
036     * @return true if bean has expected setting; false otherwise
037     */
038    public boolean check() {
039        return getObject().getState() == getExpectedState();
040    }
041
042    @Nonnull
043    public NamedBean getBean() {
044        return getObject();
045    }
046
047    public String getBeanName() {
048        return super.getName();
049    }
050
051    public int getSetting() {
052        return getExpectedState();
053    }
054
055    /**
056     * {@inheritDoc}
057     * <p>
058     * This implementation always throws an UnsupportedOperationException since
059     * a BeanSetting is immutable.
060     *
061     * @throws UnsupportedOperationException if called
062     */
063    @Override
064    public void setExpectedState(Integer state) {
065        throw new UnsupportedOperationException("The expected state of a BeanSetting is immutable");
066    }
067
068    // include bean and expected state in equals() and hashCode() because they can't
069    // change after construction
070    @Override
071    public boolean equals(Object obj) {
072        if (obj == this) {
073            return true;
074        } else if (obj == null) {
075            return false;
076        } else if (!Objects.equals(getClass(), obj.getClass())) {
077            return false;
078        } else {
079            BeanSetting p = (BeanSetting) obj;
080            if (p.getSetting() != this.getSetting()) {
081                return false;
082            }
083            if (!p.getBean().equals(this.getBean())) {
084                return false;
085            }
086
087        }
088        return true;
089    }
090
091    @Override
092    public int hashCode() {
093        int hash = getSetting() * 1000;
094        hash += getBean().hashCode();
095        return hash;
096    }
097}