001/* An implementation of containment extender for modal models.
002
003@Copyright (c) 2008-2014 The Regents of the University of California.
004All rights reserved.
005
006Permission is hereby granted, without written agreement and without
007license or royalty fees, to use, copy, modify, and distribute this
008software and its documentation for any purpose, provided that the
009above copyright notice and the following two paragraphs appear in all
010copies of this software.
011
012IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
013FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
014ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
015THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
016SUCH DAMAGE.
017
018THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
019INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
021PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
022CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
023ENHANCEMENTS, OR MODIFICATIONS.
024
025                        PT_COPYRIGHT_VERSION_2
026                        COPYRIGHTENDKEY
027
028
029
030 */
031
032package ptolemy.domains.modal.kernel;
033
034import ptolemy.kernel.util.Attribute;
035import ptolemy.kernel.util.IllegalActionException;
036import ptolemy.kernel.util.NameDuplicationException;
037import ptolemy.kernel.util.NamedObj;
038
039/**
040 An implementation of containment extender for modal models as an attribute.
041 This attribute defines a special containment relationship that is slightly
042 different from the containment relationship defined by {@link
043 NamedObj#getContainer()}. The {@link #getExtendedContainer()} method returns
044 the container of the object that contains the implementing attribute. The
045 returned container is supposed to be the object that visually contains the
046 object that owns the implementing attribute, as seen by the model designer. In
047 particular, for a modal model (either FSM or Ptera), even though a refinement is
048 visually contained by a state or an event, {@link NamedObj#getContainer()} of
049 that refinement does not return the state or event because of a difference
050 between the visual representation and internal data representation. In that
051 case, {@link #getExtendedContainer()} of this class returns the state or event.
052
053 @author Thomas Huining Feng
054 @version $Id$
055 @since Ptolemy II 8.0
056 @Pt.ProposedRating Red (tfeng)
057 @Pt.AcceptedRating Red (tfeng)
058 */
059public class ContainmentExtender extends Attribute
060        implements ptolemy.data.expr.ContainmentExtender {
061
062    /** Construct a ContainmentExtender attribute with the given name contained
063     *  by the specified Refinement. The container argument must not be null,
064     *  or a NullPointerException will be thrown.  This attribute will use the
065     *  workspace of the container for synchronization and version counts.
066     *  If the name argument is null, then the name is set to the empty string.
067     *  Increment the version of the workspace.
068     *  @param container The container.
069     *  @param name The name of this attribute.
070     *  @exception IllegalActionException If the attribute is not of an
071     *   acceptable class for the container, or if the name contains a period.
072     *  @exception NameDuplicationException If the name coincides with
073     *   an attribute already in the container.
074     */
075    public ContainmentExtender(RefinementActor container, String name)
076            throws IllegalActionException, NameDuplicationException {
077        super((NamedObj) container, name);
078        setPersistent(false);
079    }
080
081    /** Construct a ContainmentExtender attribute with the given name contained
082     *  by the specified State. The container argument must not be null,
083     *  or a NullPointerException will be thrown.  This attribute will use the
084     *  workspace of the container for synchronization and version counts.
085     *  If the name argument is null, then the name is set to the empty string.
086     *  Increment the version of the workspace.
087     *  @param container The container.
088     *  @param name The name of this attribute.
089     *  @exception IllegalActionException If the attribute is not of an
090     *   acceptable class for the container, or if the name contains a period.
091     *  @exception NameDuplicationException If the name coincides with
092     *   an attribute already in the container.
093     */
094    public ContainmentExtender(State container, String name)
095            throws IllegalActionException, NameDuplicationException {
096        super(container, name);
097        setPersistent(false);
098    }
099
100    /** Get an object with the given name within the container.
101     *
102     *  @param name The name of the object.
103     *  @return The object, or null if not found.
104     *  @exception IllegalActionException If the refinement of the containing
105     *   state cannot be found, or if a comma-separated list is malformed.
106     */
107    @Override
108    public NamedObj getContainedObject(String name)
109            throws IllegalActionException {
110        NamedObj container = getContainer();
111        if (container instanceof State) {
112            return ((State) container).getObjectInRefinement(name);
113        } else {
114            return null;
115        }
116    }
117
118    /** Get the extended container.
119     *
120     *  @return The container.
121     *  @exception IllegalActionException If the specified refinement cannot be
122     *   found in a state, or if a comma-separated list is malformed.
123     */
124    @Override
125    public NamedObj getExtendedContainer() throws IllegalActionException {
126        NamedObj container = getContainer();
127        if (container instanceof RefinementActor) {
128            return ((RefinementActor) container).getRefinedState();
129        } else {
130            return container.getContainer();
131        }
132    }
133}