001package jmri;
002
003import java.util.Objects;
004
005import javax.annotation.Nonnull;
006
007/**
008 * Describes metadata about a given property key for a NamedBean.
009 * <p>
010 * This metadata is used by the
011 * BeanTable actions to display and edit the properties in question.
012 *
013 * @param <E> class of describer, e.g. Boolean.class
014 * @author Balazs Racz Copyright (C) 2018
015 */
016public abstract class NamedBeanPropertyDescriptor<E> {
017    
018    /**
019     * Key of the property, to be used in the setProperty and getProperty functions on the
020     * NamedBean.
021     */
022    public final String propertyKey;
023    
024    /** What should be displayed when a given Bean does not have this property set. */
025    public final E defaultValue;
026
027    protected NamedBeanPropertyDescriptor(
028            @Nonnull String propertyKey, @Nonnull E defaultValue) {
029        this.propertyKey = Objects.requireNonNull(propertyKey);
030        this.defaultValue = Objects.requireNonNull(defaultValue);
031    }
032
033    /**
034     * Return user-visible text to render as a column header for the BeanTable representing this
035     * setting.
036     * @return localized string
037     */
038    public abstract String getColumnHeaderText();
039
040    /**
041     * Determines whether this property is editable.
042     * @param bean the Bean object of the given row.
043     * @return true for editable, false for disabled.
044     */
045    public abstract boolean isEditable(NamedBean bean);
046
047    /** 
048     * Get the Class of the property.
049     * <p>
050     * This class is used to find a matching Renderer for
051     * the BeanTable column to display and edit the value of this property. 
052     * For example returning Boolean.class will show a checkbox.
053     * @return Class for the property values.
054     */
055    public Class<?> getValueClass() {
056        return defaultValue.getClass();
057    }
058    
059    /**
060     * Equals based on Property Key and Default value Class.
061     * {@inheritDoc}
062     */
063    @Override
064    public boolean equals(Object obj) {
065        return (obj instanceof NamedBeanPropertyDescriptor && obj.hashCode() == this.hashCode());
066    }
067
068    /**
069     * hashCode based on Property Key and Default value Class.
070     * {@inheritDoc}
071     */
072    @Override
073    public int hashCode() {
074        return Objects.hashCode(this.propertyKey) * Objects.hashCode(getValueClass());
075    }
076    
077}