001/** An interface for decorators.
002
003 Copyright (c) 2009-2014 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.kernel.util;
029
030import java.util.List;
031
032//////////////////////////////////////////////////////////////////////////
033//// Decorator
034
035/**
036A decorator is a class that decorates other instances of NamedObj
037with extra attributes that are specific to both the decorator
038and the NamedObj. Those extra attributes are contained by an
039attribute of class {@link DecoratorAttributes} that is created
040by calling {@link #createDecoratorAttributes(NamedObj)} and specifying
041the object that will contain the additional attributes.
042The decorated NamedObj will contain these instances of DecoratorAttributes.
043These attributes are stored separately and can be retrieved by using
044{@link NamedObj#getDecoratorAttributes(Decorator)} or
045{@link NamedObj#getDecoratorAttributes(Decorator)}.
046<p>
047<b>NOTE:</b> An implementer of this interface should override the
048setContainer() method to look for objects that will be in scope with the
049new container and establish a connection with them. Specifically, it should
050do this:
051<pre>
052    public void setContainer(NamedObj container) throws IllegalActionException,
053            NameDuplicationException {
054        super.setContainer(container);
055        if (container != null) {
056            List&lt;NamedObj&gt; decoratedObjects = decoratedObjects();
057            for (NamedObj decoratedObject : decoratedObjects) {
058                // The following will create the DecoratorAttributes if it does not
059                // already exist, and associate it with this decorator.
060                decoratedObject.getDecoratorAttributes(this);
061            }
062        }
063    }
064</pre>
065
066<p>For a description of a decorator pattern, see
067<a href="http://en.wikipedia.org/wiki/Decorator_pattern">http://en.wikipedia.org/wiki/Decorator_pattern</a>.
068
069@author Bert Rodiers
070@author Edward A. Lee
071@version $Id$
072@since Ptolemy II 8.0
073@Pt.ProposedRating Red (rodiers)
074@Pt.AcceptedRating Red (rodiers)
075 */
076
077public interface Decorator extends Nameable {
078
079    /** Create and return the decorated attributes for the target NamedObj.
080     *  Implementations of this method should create an Attribute that implements
081     *  {@link DecoratorAttributes}. Implementations should populate that attribute
082     *  with parameters that have appropriate default values.
083     *  <p>
084     *  This method is called if {@link NamedObj#getDecoratorAttribute(Decorator, String)}
085     *  or {@link NamedObj#getDecoratorAttributes(Decorator)} is called,
086     *  and the specified target object does not already have
087     *  decorated attributes for this decorator.
088     *  <p>
089     *  The implementer of this method is responsible for ensuring consistency
090     *  with the {@link #decoratedObjects()} method. Specifically, any
091     *  object returned by {@link #decoratedObjects()}, when passed as an argument
092     *  to this method, should not result in a null returned value. And conversely,
093     *  any object passed to this method that is not in the list returned by
094     *  decoratedObjects() should result in a null returned value.
095     *
096     *  @param target The NamedObj that will be decorated.
097     *  @return The decorated attributes for the target NamedObj, or null if the
098     *   specified NamedObj is not decorated by this decorator.
099     *  @exception IllegalActionException If the target cannot be determined to
100     *   be decorated or not (e.g., a parameter cannot be evaluated).
101     */
102    public DecoratorAttributes createDecoratorAttributes(NamedObj target)
103            throws IllegalActionException;
104
105    /** Return a list of the objects that this decorator decorates. This could
106     *  be, for example, all of the entities contained by the container of
107     *  this decorator. An implementer of this method is responsible for ensuring
108     *  that {@link #createDecoratorAttributes(NamedObj)} will not return null
109     *  for any object included in the returned list.
110     *  <p>
111     *  Implementers of this method are required to maintain consistency
112     *  with {@link #createDecoratorAttributes(NamedObj)}.
113     *  @return A list of the objects decorated by this decorator.
114     *  @exception IllegalActionException If some object cannot be determined to
115     *   be decorated or not (e.g., a parameter cannot be evaluated).
116     */
117    public List<NamedObj> decoratedObjects() throws IllegalActionException;
118
119    /** Return true if this decorator should decorate objects across
120     *  opaque hierarchy boundaries. That is, return true to make this
121     *  decorator visible to objects even within opaque composites.
122     *  @return True if decorator is global.
123     *  @exception IllegalActionException If it cannot be determined whether
124     *   this is global or not (e.g., a parameter cannot be evaluated).
125     */
126    public boolean isGlobalDecorator() throws IllegalActionException;
127}