();
newObject._modelUpdater = (PteraModalModel) _modelUpdater
.clone(workspace);
newObject._modelUpdater.setContainer(newObject._configurer);
} catch (KernelException e) {
throw new InternalErrorException(e);
}
return newObject;
}
/** Configure the object with data from the specified input source
* (a URL) and/or textual data. The object should interpret the
* source first, if it is specified, followed by the literal text,
* if that is specified. The new configuration should usually
* override any old configuration wherever possible, in order to
* ensure that the current state can be successfully retrieved.
*
* This method is defined to throw a very general exception to allow
* classes that implement the interface to use whatever exceptions
* are appropriate.
* @param base The base relative to which references within the input
* are found, or null if this is not known, or there is none.
* @param source The input source, which specifies a URL, or null
* if none.
* @param text Configuration information given as text, or null if
* none.
* @exception Exception If something goes wrong.
*/
@Override
public void configure(URL base, String source, String text)
throws Exception {
_configureSource = source;
// Coverity says that MoMLParser could call configure with the text = null.
if (text != null && !text.trim().equals("")) {
MoMLParser parser = new MoMLParser(workspace());
_configurer.removeAllEntities();
parser.setContext(_configurer);
parser.parse(base, source, new StringReader(text));
_modelUpdater = (PteraModalModel) _configurer.entityList().get(0);
_clearURI(_modelUpdater);
}
StringParameter typeParameter = (StringParameter) getAttribute("_type");
String type = typeParameter == null ? null : typeParameter
.getExpression();
if ("delayed".equals(type)) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
getContainer().requestChange(
new ChangeRequest(this,
"Perform delayed transformation.") {
@Override
protected void _execute() throws Exception {
try {
executeTransformation();
} finally {
setContainer(null);
}
}
});
}
});
} else if ("immediate".equals(type)) {
try {
executeTransformation();
} finally {
setContainer(null);
}
}
}
/** Execute the transformation with the container of this attribute as the
* model to be transformed.
*
* @exception Exception If error occurs in the transformation.
* @see #executeTransformation(CompositeEntity)
*/
public void executeTransformation() throws Exception {
executeTransformation((CompositeEntity) getContainer());
}
/** Execute the transformation with the given model as the model to be
* transformed.
*
* @param model The model to be transformed.
* @exception Exception If error occurs in the transformation.
*/
public void executeTransformation(CompositeEntity model) throws Exception {
Manager manager = getModelUpdater().getManager();
manager.addExecutionListener(new TransformationListener(manager,
"_transformationListener", model));
for (ExecutionListener listener : _executionListeners) {
manager.addExecutionListener(listener);
}
NamedObj container = getContainer();
List parsers = container
.attributeList(ParserAttribute.class);
ParserAttribute parserAttribute = parsers.size() > 0 ? parsers.get(0)
: new ParserAttribute(container,
container.uniqueName("_parser"));
MoMLParser oldParser = parsers.size() > 0 ? parserAttribute.getParser()
: null;
parserAttribute.setParser(new MoMLParser());
manager.enablePrintTimeAndMemory(false);
try {
manager.execute();
} finally {
manager.enablePrintTimeAndMemory(true);
if (oldParser == null) {
parserAttribute.setContainer(null);
} else {
parserAttribute.setParser(oldParser);
}
}
}
/** Return the input source that was specified the last time the configure
* method was called.
* @return The string representation of the input URL, or null if the
* no source has been used to configure this object, or null if no
* external source need be used to configure this object.
*/
@Override
public String getConfigureSource() {
return _configureSource;
}
/** Return the text string that represents the current configuration of
* this object. Note that any configuration that was previously
* specified using the source attribute need not be represented here
* as well.
* @return A configuration string, or null if no configuration
* has been used to configure this object, or null if no
* configuration string need be used to configure this object.
*/
@Override
public String getConfigureText() {
return null;
}
/** Get the model updater encapsulated in this attribute.
*
* @return The model updater.
*/
public PteraModalModel getModelUpdater() {
return _modelUpdater;
}
/** Remove an execution listener from the list of execution listeners, which\
* are invoked at specific points when the transformation is executed.
*
* @param listener The listener to be removed.
* @see #addExecutionListener(ExecutionListener)
*/
public void removeExecutionListener(ExecutionListener listener) {
_executionListeners.remove(listener);
}
/** The condition under which this attribute is applicable. It must evaluate
* to a BooleanToken. If its value is false, execution of the
* transformation causes no effect.
*/
public Parameter condition;
/** The editor factory for the contents in this attribute (the model
* updater).
*/
public TransformationAttributeEditorFactory editorFactory;
/** Write a MoML description of the contents of this object, which
* in this base class is the attributes. This method is called
* by _exportMoML(). If there are attributes, then
* each attribute description is indented according to the specified
* depth and terminated with a newline character.
* Callers of this method should hold read access before
* calling this method. Note that exportMoML() does this for us.
*
* @param output The output stream to write to.
* @param depth The depth in the hierarchy, to determine indenting.
* @exception IOException If an I/O error occurs.
*/
@Override
protected void _exportMoMLContents(Writer output, int depth)
throws IOException {
super._exportMoMLContents(output, depth);
String sourceSpec = "";
if (_configureSource != null && !_configureSource.trim().equals("")) {
sourceSpec = " source=\"" + _configureSource + "\"";
}
output.write(_getIndentPrefix(depth) + "\n");
_modelUpdater.exportMoML(output, depth + 1);
output.write(_getIndentPrefix(depth) + "\n");
}
/** Clear the URI attribute of the given object.
*
* @param object The object.
* @exception IllegalActionException If the URI attribute of the object
* cannot be removed.
*/
private static void _clearURI(NamedObj object)
throws IllegalActionException {
URIAttribute attribute = (URIAttribute) object.getAttribute("_uri",
URIAttribute.class);
if (attribute != null) {
try {
attribute.setContainer(null);
} catch (NameDuplicationException e) {
throw new IllegalActionException(attribute, e,
"Unexpected exception.");
}
}
}
/** Create the parameters and private fields of this attribute.
*
* @exception IllegalActionException If thrown when creating the
* parameters.
* @exception NameDuplicationException If thrown when creating the
* parameters.
*/
private void _init() throws IllegalActionException,
NameDuplicationException {
condition = new Parameter(this, "condition");
condition.setExpression("true");
_configurer = new Configurer(workspace());
_configurer.setName("Configurer");
new DEDirector(_configurer, "_director");
_configurer.setManager(new Manager(workspace(), "_manager"));
_configurer.setConfiguredObject(this);
String moml = "";
MoMLParser parser = new MoMLParser();
parser.setContext(_configurer);
try {
parser.parse(moml);
} catch (Exception e) {
throw new IllegalActionException(this, e, "Unable to populate "
+ "the transformation rule within \"" + getFullName()
+ "\".");
}
_modelUpdater = (PteraModalModel) _configurer.getEntity("ModelUpdater");
new TransformationAttributeIcon(this, "_icon");
new TransformationAttributeController.Factory(this,
"_controllerFactory");
editorFactory = new TransformationAttributeEditorFactory(this,
"editorFactory");
}
/** The configure source.
*/
private String _configureSource;
/** The configurer containing the model updater.
*/
private Configurer _configurer;
/** The list of execution listeners.
*/
private List _executionListeners = new LinkedList();
/** The model updater.
*/
private PteraModalModel _modelUpdater;
///////////////////////////////////////////////////////////////////
//// TransformationListener
/**
An execution listener that sets the model parameter to contain the
container of the transformation attribute at the beginning of the
transformation.
@author Thomas Huining Feng
@version $Id: TransformationAttribute.java 70402 2014-10-23 00:52:20Z cxh $
@since Ptolemy II 8.0
@Pt.ProposedRating Yellow (tfeng)
@Pt.AcceptedRating Red (tfeng)
*/
private class TransformationListener extends Attribute implements
ExecutionListener {
/** Construct an attribute with the given name contained by the specified
* entity. The container argument must not be null, or a
* NullPointerException will be thrown. This attribute will use the
* workspace of the container for synchronization and version counts.
* If the name argument is null, then the name is set to the empty string.
* Increment the version of the workspace.
* @param manager The container of this listener.
* @param name The name of this attribute.
* @param model The model to be transformed.
* @exception IllegalActionException If the attribute is not of an
* acceptable class for the container, or if the name contains a period.
* @exception NameDuplicationException If the name coincides with
* an attribute already in the container.
*/
public TransformationListener(Manager manager, String name,
CompositeEntity model) throws IllegalActionException,
NameDuplicationException {
super(manager, name);
_model = model;
}
/** Do nothing.
*
* @param manager The manager controlling the execution.
* @param throwable The throwable to report.
*/
@Override
public void executionError(Manager manager, Throwable throwable) {
}
/** Do nothing.
*
* @param manager The manager controlling the execution.
*/
@Override
public void executionFinished(Manager manager) {
}
/** If the manager's state becomes {@link Manager#INITIALIZING}, set the
* model parameter in the model updater of the transformation attribute
* to contain the container of the transformation attribute. Do nothing
* otherwise.
*
* @param manager The manager controlling the execution.
*/
@Override
public void managerStateChanged(Manager manager) {
if (manager.getState() == Manager.INITIALIZING) {
ModelParameter modelAttribute = (ModelParameter) _modelUpdater
.getController().getAttribute("Model");
modelAttribute.setModel(_model);
}
}
/** The model to be transformed.
*/
private CompositeEntity _model;
}
}