001/* A token that contains an actor.
002
003 Copyright (c) 2003-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 */
027package ptolemy.data;
028
029import java.io.IOException;
030import java.io.Writer;
031
032import ptolemy.data.type.ActorType;
033import ptolemy.data.type.Type;
034import ptolemy.kernel.Entity;
035import ptolemy.kernel.util.IllegalActionException;
036import ptolemy.kernel.util.Workspace;
037import ptolemy.util.StringUtilities;
038
039///////////////////////////////////////////////////////////////////
040//// ActorToken
041
042/**
043 A token that contains an actor.  This token allows components to be
044 moved around in a model.  One subtlety is that actors are not,
045 generally immutable objects.  In order to prevent the actor
046 transmitted from appearing in multiple places in a model, and the
047 semantic fuzziness that would result, the actor is always cloned when
048 being retrieved from this token.
049
050 @author Steve Neuendorffer
051 @version $Id$
052 @since Ptolemy II 4.0
053 @Pt.ProposedRating Red (cxh)
054 @Pt.AcceptedRating Red (cxh)
055 */
056public class ActorToken extends Token implements Cloneable {
057    /** Construct an ActorToken.
058     *  @param entity The entity that this Token contains.
059     *  @exception IllegalActionException If cloning the entity fails.
060     */
061    public ActorToken(Entity entity) throws IllegalActionException {
062        super();
063
064        try {
065            // Be sure to clone into a workspace.
066            _entity = (Entity) entity.clone(entity.workspace());
067        } catch (CloneNotSupportedException ex) {
068            throw new IllegalActionException(null, ex,
069                    "Failed to create actor token");
070        }
071    }
072
073    /** Construct an empty ActorToken to be used as a reference for the Actor type designator. */
074    private ActorToken() {
075        super();
076    }
077
078    ///////////////////////////////////////////////////////////////////
079    ////                         public methods                    ////
080
081    /** Return a clone of the entity contained by this token.
082     *  @return The clone of the entity.
083     */
084    public Entity getEntity() {
085        try {
086            return (Entity) _entity.clone();
087        } catch (CloneNotSupportedException ex) {
088            throw new RuntimeException(
089                    "Failed to clone actor, but I already cloned it once!!!");
090        }
091    }
092
093    /** Return a clone of the entity contained by this token.
094     *
095     *  @param workspace The workspace that the returned entity is in.
096     *  @return The clone of the entity.
097     */
098    public Entity getEntity(Workspace workspace) {
099        try {
100            return (Entity) _entity.clone(workspace);
101        } catch (CloneNotSupportedException ex) {
102            throw new RuntimeException(
103                    "Failed to clone actor, but I already cloned it once!!!");
104        }
105    }
106
107    /** Output the MoML of the enclosed entity to the given writer.
108     *
109     *  @param output The writer to which the MoML is output.
110     *  @exception IOException If an I/O error occurs.
111     */
112    public void getMoML(Writer output) throws IOException {
113        _entity.exportMoML(output);
114    }
115
116    /** Return the type of this token.
117     *  @return the type of this token.
118     */
119    @Override
120    public Type getType() {
121        return TYPE;
122    }
123
124    /** Test for closeness of the values of this Token and the argument
125     *  Token.  For actor tokens, checking for closeness is the same
126     *  as checking for equality.
127     *  @param rightArgument The token to compare to this token.
128     *  @param epsilon This argument is ignored in this method.
129     *  @return A true-valued token if the first argument is equal to
130     *  this token.
131     *  @exception IllegalActionException If thrown by
132     *  {@link #isEqualTo(Token)}.
133     */
134    @Override
135    public BooleanToken isCloseTo(Token rightArgument, double epsilon)
136            throws IllegalActionException {
137        return isEqualTo(rightArgument);
138    }
139
140    /** Model for equality of the values of this Token and the argument Token.
141     *  It should be overridden in derived classes to provide type specific
142     *  actions for equality testing.
143     *  @param token The token with which to test equality.
144     *  @exception IllegalActionException If this method is not
145     *   supported by the derived class.
146     *  @return A BooleanToken which contains the result of the test.
147     */
148    @Override
149    public BooleanToken isEqualTo(Token token) throws IllegalActionException {
150        if (token instanceof ActorToken) {
151            return new BooleanToken(toString().equals(token.toString()));
152        } else {
153            throw new IllegalActionException(
154                    "Equality test not supported between "
155                            + this.getClass().getName() + " and "
156                            + token.getClass().getName() + ".");
157        }
158    }
159
160    /** Return the value of this token as a string that can be parsed
161     *  by the expression language to recover a token with the same value.
162     *  This method returns a string of the form `parseMoML("<i>text</i>")',
163     *  where <i>text</i> is a MoML description of this actor with quotation
164     *  marks and backslashes escaped.
165     *  @return A MoML description of this actor.
166     */
167    @Override
168    public String toString() {
169        return "parseMoML(\""
170                + StringUtilities.escapeString(_entity.exportMoMLPlain())
171                + "\")";
172    }
173
174    /** Empty Entity instance of this token. */
175    public static final ActorToken EMPTY = new ActorToken();
176
177    /** Singleton reference to this type. */
178    public static final Type TYPE = new ActorType();
179
180    ///////////////////////////////////////////////////////////////////
181    ////                         private variables                 ////
182    private Entity _entity;
183}