001package jmri.beans;
002
003import java.util.Set;
004import javax.annotation.Nonnull;
005import javax.annotation.CheckForNull;
006
007/**
008 * Simple interface for basic methods that implement JMRI Bean handling methods.
009 *
010 * Various methods in {@link BeanUtil} test that objects implement this
011 * interface before attempting to get or set properties of those objects.
012 * Classes implementing this interface can bypass the need to introspect the
013 * class to manipulate a property, and can also implement properties that the
014 * Beans class will be able to manipulate that do not conform to JavaBeans
015 * coding standards.
016 *
017 * {@link ArbitraryBean} provides generic implementations of these methods that
018 * allow the manipulation of properties defined at runtime if your class can
019 * extend or extends a subclass of Bean.
020 *
021 * @author Randall Wood
022 * @see BeanUtil
023 * @see Bean
024 */
025public interface BeanInterface {
026
027    /**
028     * Set the value of an element in an indexed property.
029     * <p>
030     * <b>NOTE</b> Implementing methods <i>must not call</i>
031     * <code>Bean.setIndexedProperty()</code>, as doing so will cause a stack
032     * overflow. Implementing methods may call
033     * <code>Beans.setIntrospectedIndexedProperty()</code> instead.
034     *
035     * @param key   name of the property
036     * @param index index of the property element to change
037     * @param value the value to set the property to
038     */
039    void setIndexedProperty(@Nonnull String key, int index, @CheckForNull Object value);
040
041    /**
042     * Get the value of an element in an indexed property.
043     * <p>
044     * <b>NOTE</b> Implementing methods <i>must not call</i>
045     * <code>Bean.getIndexedProperty()</code>, as doing so will cause a stack
046     * overflow. Implementing methods may call
047     * <code>Beans.getIntrospectedIndexedProperty()</code> instead.
048     *
049     * @param key   name of the property
050     * @param index index of the property element to change
051     * @return value of the property or null
052     */
053    @CheckForNull
054    Object getIndexedProperty(@Nonnull String key, int index);
055
056    /**
057     * Set the value of a property.
058     * <p>
059     * <b>NOTE</b> Implementing methods <i>must not call</i>
060     * <code>Bean.setProperty()</code>, as doing so will cause a stack overflow.
061     * Implementing methods may call
062     * <code>Beans.setIntrospectedProperty()</code> instead.
063     *
064     * @param key   name of the property
065     * @param value the value to set the property to
066     */
067    void setProperty(@Nonnull String key, @CheckForNull Object value);
068
069    /**
070     * Get the value of a property.
071     * <p>
072     * <b>NOTE</b> Implementing methods <i>must not call</i>
073     * <code>Bean.getProperty()</code>, as doing so will cause a stack overflow.
074     * Implementing methods may call
075     * <code>Beans.getIntrospectedProperty()</code> instead.
076     *
077     * @param key name of the property
078     * @return The value of the property or null
079     */
080    @CheckForNull
081    Object getProperty(@Nonnull String key);
082
083    /**
084     * Test that a property exists.
085     * <p>
086     * <b>NOTE</b> Implementing method <i>must not call</i>
087     * <code>Bean.hasProperty()</code>, as doing so will cause a stack overflow.
088     * Implementing methods may call
089     * <code>Beans.hasIntrospectedProperty()</code> instead.
090     *
091     * @param key name of the property
092     * @return true is property <i>key</i> exists
093     */
094    boolean hasProperty(@Nonnull String key);
095
096    /**
097     * Test that a property exists and is indexed.
098     * <p>
099     * <b>NOTE</b> Implementing method <i>must not call</i>
100     * <code>Bean.hasIndexedProperty()</code>, as doing so will cause a stack
101     * overflow. Implementing methods may call
102     * <code>Beans.hasIntrospectedIndexedProperty()</code> instead.
103     *
104     * @param key name of the property
105     * @return true is property <i>key</i> exists and is indexed
106     */
107    boolean hasIndexedProperty(@Nonnull String key);
108
109    /**
110     * List all property names or keys.
111     * <p>
112     * <b>NOTE</b> Implementing method <i>must not call</i>
113     * <code>Bean.getPropertyNames()</code>, as doing so will cause a stack
114     * overflow. Implementing methods may call
115     * <code>Beans.getIntrospectedPropertyNames()</code> instead.
116     * <p>
117     * <b>NOTE</b> Implementations of this method should not return null.
118     *
119     * @return property names or an empty Set.
120     */
121    @Nonnull
122    Set<String> getPropertyNames();
123}