/* A decorator attribute that monitors decorator values to enforce constraints. Copyright (c) 2000-2014 The Regents of the University of California. All rights reserved. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. PT_COPYRIGHT_VERSION_2 COPYRIGHTENDKEY */ package ptolemy.data.expr; import java.util.Collection; import java.util.LinkedList; import java.util.List; import ptolemy.data.BooleanToken; import ptolemy.data.DoubleToken; import ptolemy.data.Token; import ptolemy.data.type.BaseType; import ptolemy.kernel.CompositeEntity; import ptolemy.kernel.Entity; import ptolemy.kernel.util.Attribute; import ptolemy.kernel.util.Decorator; import ptolemy.kernel.util.DecoratorAttributes; import ptolemy.kernel.util.HierarchyListener; import ptolemy.kernel.util.IllegalActionException; import ptolemy.kernel.util.InternalErrorException; import ptolemy.kernel.util.NameDuplicationException; import ptolemy.kernel.util.NamedObj; import ptolemy.kernel.util.Settable; import ptolemy.kernel.util.Workspace; import ptolemy.util.MessageHandler; /////////////////////////////////////////////////////////////////// //// ConstraintMonitor /** A contract monitor that decorates each entity in a model with a value parameter and monitors the sum of all such values. If the sum of the values equals or exceeds the value given in {@link #threshold} and {@link #warningEnabled} is true, then this class will issue a warning when the aggregate value matches or exceeds the threshold. The decorator values default to 0.0, so the default total is 0.0. The default threshold is Infinity, so no warnings will be issued by default.
If the {@link #includeOpaqueContents} parameter is true, then this decorator will also decorate entities within opaque composite actors. By default, this is false.
This object is a {@link Parameter} whose value is the total of the values of all the decorator values. To use it, simply drag it into a model.
@author Edward A. Lee
@version $Id: ConstraintMonitor.java 70402 2014-10-23 00:52:20Z cxh $
@since Ptolemy II 10.0
@Pt.ProposedRating Yellow (eal)
@Pt.AcceptedRating Red (eal)
*/
public class ConstraintMonitor extends Parameter implements Decorator {
/** Construct an instance in the given container with the given name.
* The container argument must not be null, or a
* NullPointerException will be thrown.
* If the name argument is null, then the name is set to the
* empty string. Increment the version number of the workspace.
* @param container The container, which contains the objects to be decorated
* @param name Name of this constraint monitor.
* @exception IllegalActionException If this object is not compatible
* with the specified container.
* @exception NameDuplicationException If the name collides with an
* attribute in the container or if there is a name duplication during
* initialization.
*/
public ConstraintMonitor(CompositeEntity container, String name)
throws IllegalActionException, NameDuplicationException {
super(container, name);
setTypeEquals(BaseType.DOUBLE);
setExpression("0.0");
setVisibility(Settable.NOT_EDITABLE);
threshold = new Parameter(this, "threshold");
threshold.setTypeEquals(BaseType.DOUBLE);
threshold.setExpression("Infinity");
warningEnabled = new Parameter(this, "warningEnabled");
warningEnabled.setExpression("true");
warningEnabled.setTypeEquals(BaseType.BOOLEAN);
includeOpaqueContents = new Parameter(this, "includeOpaqueContents");
includeOpaqueContents.setExpression("false");
includeOpaqueContents.setTypeEquals(BaseType.BOOLEAN);
includeTransparents = new Parameter(this, "includeTransparents");
includeTransparents.setExpression("false");
includeTransparents.setTypeEquals(BaseType.BOOLEAN);
}
///////////////////////////////////////////////////////////////////
//// parameters ////
/** If true, then this decorator decorates entities within
* opaque composite actors. This is a boolean that defaults to
* false.
*/
public Parameter includeOpaqueContents;
/** If true, then this decorator decorates transparent composite
* entities. This is a boolean that defaults to false.
*/
public Parameter includeTransparents;
/** Threshold at which this monitor issues a warning, if
* {@link #warningEnabled} is true.
* This is a double that defaults to Infinity, meaning no
* constraint on the sum of the decorator values.
*/
public Parameter threshold;
/** If true (the default), then a warning is issued when the
* aggregate value equals or exceeds the specified {@link #threshold}.
* This is a boolean that defaults to true.
*/
public Parameter warningEnabled;
///////////////////////////////////////////////////////////////////
//// public methods ////
/** Override the base class to invalidate if parameters have changed.
* @exception IllegalActionException If the change is not acceptable
* to this container (not thrown in this base class).
*/
@Override
public void attributeChanged(Attribute attribute)
throws IllegalActionException {
if (attribute == includeOpaqueContents
|| attribute == includeTransparents) {
invalidate();
}
super.attributeChanged(attribute);
}
/** Clone the object into the specified workspace. The new object is
* not added to the directory of that workspace (you must do this
* yourself if you want it there).
* The result is an object with no container.
* @param workspace The workspace for the cloned object.
* @exception CloneNotSupportedException Not thrown in this base class
* @return The new object.
*/
@Override
public Object clone(Workspace workspace) throws CloneNotSupportedException {
ConstraintMonitor newObject = (ConstraintMonitor) super
.clone(workspace);
newObject._lastValueWarning = null;
newObject._decoratedObjects = null;
newObject._decoratedObjectsVersion = -1L;
return newObject;
}
/** Return the decorated attributes for the target NamedObj, or null
* if the target is not decorated by this decorator.
* Specification, every Entity that is not a class definition
* that is contained (deeply) by the container of this decorator
* is decorated. This includes atomic entities and both opaque and
* transparent composite entities.
* @param target The NamedObj that will be decorated.
* @return The decorated attributes for the target NamedObj.
* @exception IllegalActionException If some object cannot be determined to
* be decorated or not (e.g., a parameter cannot be evaluated).
*/
@Override
public DecoratorAttributes createDecoratorAttributes(NamedObj target)
throws IllegalActionException {
boolean transparents = ((BooleanToken) includeTransparents.getToken())
.booleanValue();
boolean opaques = ((BooleanToken) includeOpaqueContents.getToken())
.booleanValue();
NamedObj container = getContainer();
// If the container of this decorator is not a CompositeEntity,
// then it cannot possibly deeply contain the target.
if (!(container instanceof CompositeEntity)) {
return null;
}
if (target instanceof Entity
&& !((Entity) target).isClassDefinition()
&& (transparents || !(target instanceof CompositeEntity) || ((CompositeEntity) target)
.isOpaque())
&& _deepContains((CompositeEntity) container, (Entity) target,
opaques)) {
try {
return new ConstraintMonitorAttributes(target, this);
} catch (NameDuplicationException e) {
// This should not occur.
throw new InternalErrorException(e);
}
} else {
return null;
}
}
/** Return a list of the entities deeply contained by the container
* of this resource scheduler. This includes all entities, whether
* transparent or opaque, including those inside opaque entities.
* It does not include entities that are class definitions.
* @return A list of the objects decorated by this decorator.
* @exception IllegalActionException If some object cannot be determined to
* be decorated or not (e.g., a parameter cannot be evaluated).
*/
@Override
public List