/*
 * $RCSfile: PropertySource.java,v $
 *
 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
 *
 * Use is subject to license terms.
 *
 * $Revision: 1.1 $
 * $Date: 2005/02/11 04:57:17 $
 * $State: Exp $
 */
package com.lightcrafts.mediax.jai;

/**
 * An interface encapsulating the set of operations involved in
 * identifying and reading properties.
 *
 * <p> The interface includes the <code>getProperty()</code> and 
 * <code>getPropertyNames()</code> methods familiar from the
 * <code>RenderedImage</code> and <code>RenderableImage</code> interfaces.
 * Classes which implement this interface should do so in a manner which
 * treats the property names as case-retentive.  That is to say that as
 * concerns operations effected using the property name as a key, the
 * operation should ignore the case of the property name while on the
 * other hand the property name retrieval methods should return the names
 * with their case preserved.
 *
 * <p> <code>PropertySource</code> is implemented by the <code>ImageJAI</code>
 * interface and, among other classes, by <code>PlanarImage</code>,
 * <code>RenderableOp</code> and <code>CollectionImage</code>.
 * Since all <code>RenderedImage</code>s used with JAI are "wrapped" 
 * by a <code>RenderedImageAdapter</code>, all JAI <code>RenderedImage</code>s
 * may be assumed to implement <code>PropertySource</code>.
 *
 * <p> If a <code>PropertySource</code> is also a
 * <code>PropertyChangeEmitter</code>
 * then it should fire <code>PropertySourceChangeEvent</code>s to all
 * registered listeners whenever this is reasonable to do so in the context
 * of the <code>PropertySource</code> in question.
 *
 * <p> Property name space collisions may be prevented by adhering to
 * an hierarchical naming convention.  This could for example be based
 * on the name of the package in question, e.g.,
 * <i>com.lightcrafts.media.jai.MyProperty</i>.
 * The names of properties generated by JAI itself will not adhere to the
 * aforementioned naming convention, but this should not pose a problem if
 * users adopt this convention for their own property names.

 * <p> Another approach to handling multiple property name spaces would
 * be to define a separate PropertySource for each name space of properties.
 * These PropertySources could themselves be attached to images as properties.
 * Inheritance of these properties would occur by the default mechanism.
 * Modification of these properties within an operation chain could be
 * managed by PropertyGenerators which are capable of recognizing these
 * properties.  Note that a potential problem with this approach exists
 * when a <code>PropertySourceChangeEvent</code> is fired: it might be
 * necessary to clone the entire tree of properties in order to obtain
 * the old value of event object.
 *
 * @see ImageJAI
 * @see PlanarImage
 * @see PropertyChangeEmitter
 * @see WritablePropertySource
 * @see java.awt.image.RenderedImage
 * @see java.awt.image.renderable.RenderableImage
 */
public interface PropertySource {

    /**
     * Returns an array of <code>String</code>s recognized as names by
     * this property source.  If no properties are available,
     * <code>null</code> will be returned.
     *
     * @return an array of <code>String</code>s giving the valid
     *         property names or <code>null</code>.
     */
    String[] getPropertyNames();

    /**
     * Returns an array of <code>String</code>s recognized as names by
     * this property source that begin with the supplied prefix.  If
     * no property names match, <code>null</code> will be returned.
     * The comparison is done in a case-independent manner.
     *
     * @return an array of <code>String</code>s giving the valid
     * property names.
     *
     * @exception IllegalArgumentException if <code>prefix</code>
     *                                     is <code>null</code>.
     */
    String[] getPropertyNames(String prefix);

    /**
     * Returns the class expected to be returned by a request for
     * the property with the specified name.  If this information
     * is unavailable, <code>null</code> will be returned indicating
     * that <code>getProperty(propertyName).getClass()</code> should
     * be executed instead.  A <code>null</code> value might
     * be returned for example to prevent generating the value of
     * a deferred property solely to obtain its class.  <code>null</code>
     * will also be returned if the requested property is not emitted
     * by this property source.
     *
     * @param propertyName the name of the property, as a <code>String</code>.
     *
     * @return The <code>Class</code> expected to be return by a
     *         request for the value of this property or <code>null</code>.
     *
     * @exception IllegalArgumentException if <code>propertyName</code>
     *                                     is <code>null</code>.
     *
     * @since JAI 1.1
     */
    Class getPropertyClass(String propertyName);

    /**
     * Returns the value of a property.  If the property name is not
     * recognized, <code>java.awt.Image.UndefinedProperty</code> will
     * be returned.
     *
     * @param propertyName the name of the property, as a <code>String</code>.
     *
     * @return the value of the property, as an
     *         <code>Object</code>, or the value
     *         <code>java.awt.Image.UndefinedProperty</code>.
     *
     * @exception IllegalArgumentException if <code>propertyName</code>
     *                                     is <code>null</code>.
     */
    Object getProperty(String propertyName);
}
