package data;

import java.io.Serializable;
import java.beans.*;

/**
  * An object that has a name that complies with a NameContext's rules.
  *
  * <p>When implementing nameable objects you migth want to subclass {@link AbstractNameable}, which already
  * implements all the methods required by Nameable.</p>
  *
  * @see Catalog
  * @see Stock
  * @see CatalogItem
  * @see NameContext
  *
  * @author Steffen Zschaler
  * @version 2.0 25/05/1999
  * @since v2.0
  */
public interface Nameable extends Serializable {

  /**
    * Attach a NameContext to this Nameable.
    *
    * <p>No naming conventions are checked neither in the old nor in the new NameContext.</p>
    *
    * @param nc the new NameContext of this Nameable object.
    *
    * @return the previous NameContext, if any.
    *
    * @override Always
    */
  public NameContext attach (NameContext nc);

  /**
    * Detach the current NameContext from this Nameable.
    *
    * @return the previously attached NameContext, if any.
    *
    * @override Always
    */
  public NameContext detachNC();

  /**
    * Set the Nameable's name.
    *
    * <p><code>setName()</code> must implement the following protocol (Let <code>nc</code> be the Nameable's
    * current NameContext):</p>
    *
    * <pre>
    * if (nc != null) {
    *   synchronized (nc.getNCMonitor()) {
    *     nc.checkNameChange (db, getName(), sName);
    *
    *     // set the internal name attribute(s), leaving old name in sOldName
    *
    *     nc.nameHasChanged (db, sOldName, getName());
    *   }
    * }
    * else {
    *   // set the internal name attribute(s)
    * }
    * </pre>
    *
    * @param sName the new name of the object
    * @param db the DataBasket relative to which the operation is to be performed.
    *
    * @exception NameContextException if the name change was not approved of by the NameContext.
    *
    * @see NameContext
    *
    * @override Always
    */
  public void setName (String sName, DataBasket db)
    throws NameContextException;

  /**
    * Get the name of this Nameable object.
    *
    * @override Always
    */
  public String getName();

  /**
    * Register a listener to receive events whenever propertiy changes.
    *
    * @override Always
    */
  public void addPropertyChangeListener (PropertyChangeListener pcl);

  /**
    * Stop a listener from receiving events whenever a property changes.
    *
    * @override Always
    */
  public void removePropertyChangeListener (PropertyChangeListener pcl);

  /**
    * Add a PropertyChangeListener that will receive events whenever the &quot;name&quot; property changes.
    *
    * @override Always
    */
  public void addNameListener (PropertyChangeListener pcl);

  /**
    * Remove a PropertyChangeListener for the &quot;name&quot; property.
    *
    * @override Always
    */
  public void removeNameListener (PropertyChangeListener pcl);

  /**
    * The programmatical name of the &quot;name&quot; property. This is &quot;name&quot;.
    */
  public final static String NAME_PROPERTY = "name";
}