001/* Abstract base class for attributes that can have their values
002 externally set.
003
004 Copyright (c) 2004-2014 The Regents of the University of California.
005 All rights reserved.
006 Permission is hereby granted, without written agreement and without
007 license or royalty fees, to use, copy, modify, and distribute this
008 software and its documentation for any purpose, provided that the above
009 copyright notice and the following two paragraphs appear in all copies
010 of this software.
011
012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
016 SUCH DAMAGE.
017
018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
023 ENHANCEMENTS, OR MODIFICATIONS.
024
025 PT_COPYRIGHT_VERSION_2
026 COPYRIGHTENDKEY
027
028 */
029package ptolemy.kernel.util;
030
031import java.util.List;
032
033///////////////////////////////////////////////////////////////////
034//// AbstractSettableAttribute
035
036/**
037 This is an abstract base class for attributes that implement the
038 Settable interface. In particular, it provides a default implementation
039 of the getDefaultExpression() method.  If this object is derived from
040 another, then the default value is obtained from that other.
041 Otherwise, the default value is the first value set using
042 setExpression().
043
044 @author Edward A. Lee
045 @version $Id$
046 @since Ptolemy II 4.1
047 @Pt.ProposedRating Green (eal)
048 @Pt.AcceptedRating Green (hyzheng)
049 */
050public abstract class AbstractSettableAttribute extends Attribute
051        implements Settable {
052    /** Construct an attribute in the default workspace with an empty string
053     *  as its name.
054     *  The object is added to the directory of the workspace.
055     *  Increment the version number of the workspace.
056     */
057    public AbstractSettableAttribute() {
058        super();
059    }
060
061    /** Construct an attribute in the specified workspace with an empty
062     *  string as a name. You can then change the name with setName().
063     *  If the workspace argument
064     *  is null, then use the default workspace.
065     *  The object is added to the directory of the workspace.
066     *  Increment the version number of the workspace.
067     *  @param workspace The workspace that will list the attribute.
068     */
069    public AbstractSettableAttribute(Workspace workspace) {
070        super(workspace);
071    }
072
073    /** Construct an attribute with the given name contained by the specified
074     *  entity. The container argument must not be null, or a
075     *  NullPointerException will be thrown.  This attribute will use the
076     *  workspace of the container for synchronization and version counts.
077     *  If the name argument is null, then the name is set to the empty string.
078     *  Increment the version of the workspace.
079     *  @param container The container.
080     *  @param name The name of this attribute.
081     *  @exception IllegalActionException If the attribute is not of an
082     *   acceptable class for the container, or if the name contains a period.
083     *  @exception NameDuplicationException If the name coincides with
084     *   an attribute already in the container.
085     */
086    public AbstractSettableAttribute(NamedObj container, String name)
087            throws IllegalActionException, NameDuplicationException {
088        super(container, name);
089    }
090
091    /** Construct an attribute with the given name contained by the specified
092     *  entity. The container argument must not be null, or a
093     *  NullPointerException will be thrown.  This attribute will use the
094     *  workspace of the container for synchronization and version counts.
095     *  If the name argument is null, then the name is set to the empty string.
096     *  Increment the version of the workspace.
097     *  @param container The container.
098     *  @param name The name of this attribute.
099     *  @param incrementWorkspaceVersion False to not add this to the workspace
100     *   or do anything else that might change the workspace version number.
101     *  @exception IllegalActionException If the attribute is not of an
102     *   acceptable class for the container, or if the name contains a period.
103     *  @exception NameDuplicationException If the name coincides with
104     *   an attribute already in the container.
105     */
106    protected AbstractSettableAttribute(NamedObj container, String name,
107            boolean incrementWorkspaceVersion)
108            throws IllegalActionException, NameDuplicationException {
109        super(container, name, incrementWorkspaceVersion);
110    }
111
112    ///////////////////////////////////////////////////////////////////
113    ////                         public methods                    ////
114
115    /** Return the default value of this Settable, or null if no default
116     *  has been set.  If this object is derived (in the actor-oriented
117     *  class mechanism, see the Instantiable interface), then the default
118     *  is the value of the object from which this is derived (the
119     *  "prototype").  If this is not a derived object, then the default
120     *  is the first value set using setExpression(), or null if
121     *  setExpression() has not been called.
122     *  @return The default value of this attribute, or null
123     *   if there is none.
124     *  @see #setExpression(String)
125     *  @see Instantiable
126     */
127    @Override
128    public String getDefaultExpression() {
129        try {
130            // Get the list of objects from which this is derived,
131            // the first of which will be the immediate prototype.
132            List prototypeList = getPrototypeList();
133
134            if (prototypeList.size() > 0) {
135                return ((Settable) prototypeList.get(0)).getExpression();
136            }
137        } catch (IllegalActionException e) {
138            // This should not occur.
139            throw new InternalErrorException(e);
140        }
141
142        return _default;
143    }
144
145    /** Get the value of the attribute, which is the evaluated expression.
146     *  @return The same as getExpression().
147     *  @see #getExpression()
148     */
149    @Override
150    public String getValueAsString() {
151        return getExpression();
152    }
153
154    /** Set the value of this attribute to the specified expression.
155     *  This base class implementation merely records the first
156     *  value to serve as the default value if needed.
157     *  Subclasses are required to override this to also record
158     *  the value and to call super.setExpression().
159     *  @param expression The value of this attribute.
160     *  @exception IllegalActionException If the expression is invalid
161     *   (not thrown in this base class).
162     *  @see #getDefaultExpression()
163     */
164    @Override
165    public void setExpression(String expression) throws IllegalActionException {
166        if (_default == null) {
167            _default = expression;
168        }
169    }
170
171    ///////////////////////////////////////////////////////////////////
172    ////                         private members                   ////
173
174    /** The default value.  */
175    private String _default = null;
176}