package ptolemy.actor.ptalon.model;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import ptolemy.actor.TypedCompositeActor;
import ptolemy.actor.ptalon.PtalonAST;
import ptolemy.actor.ptalon.PtalonLexer;
import ptolemy.actor.ptalon.PtalonRecognizer;
import ptolemy.actor.ptalon.model.controls.PtalonEditorFactory;
import ptolemy.data.StringToken;
import ptolemy.data.expr.ExpertParameter;
import ptolemy.data.expr.Parameter;
import ptolemy.data.type.BaseType;
import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.Attribute;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;
import ptolemy.kernel.util.NamedObj;
import ptolemy.kernel.util.Settable;
import ptolemy.moml.MoMLChangeRequest;
/**
* @author adam
*
*/
public class PtalonModel extends TypedCompositeActor {
public PtalonModel(CompositeEntity container, String name)
throws IllegalActionException, NameDuplicationException {
super(container, name);
setClassName("sdc.ptalon.PtalonModel");
new PtalonEditorFactory(this, "_editorFactory", this);
_ptalonCode = new ExpertParameter(this, "_ptalonCode");
_ptalonCode.setTypeEquals(BaseType.STRING);
_ptalonCode.setPersistent(true);
}
public void attributeChanged(Attribute attribute)
throws IllegalActionException {
super.attributeChanged(attribute);
if (attribute == _ptalonCode) {
StringToken token = (StringToken) _ptalonCode.getToken();
if (token == null)
return;
if (_code == null)
{
_code = token.stringValue();
return;
}
String pararemterCode = token.stringValue();
if (!_code.equals(pararemterCode)) {
_code = pararemterCode;
}
}
}
private ExpertParameter _ptalonCode;
// The code for this Ptalon Model.
private String _code = null;
public void setCode(String code) {
_code = code;
try {
_ptalonCode.setToken(new StringToken(_code));
} catch (Exception e) {
}
}
public String getCode() {
return _code;
}
private File _file = null;
public void setFile(File fileName) {
_file = fileName;
}
public File getFile() {
return _file;
}
public void updateModel() throws IllegalActionException {
if (_code != null) {
clear();
evaluate();
}
}
private void deepClear() {
removeAllPorts();
removeAllRelations();
removeAllEntities();
for (Parameter p : parameterList(this)) {
_removeAttribute(p);
}
}
private void clear() {
removeAllPorts();
removeAllRelations();
removeAllEntities();
_expressions.clear();
for (Parameter p : parameterList(this)) {
_expressions.put(p.getName(), p.getExpression());
_removeAttribute(p);
}
}
private void evaluate() throws IllegalActionException {
try {
// Open the code location. Use urls for WebStart and jar files.
PtalonLexer lex = null;
PtalonRecognizer rec = null;
InputStream inputStream = null;
inputStream = new ByteArrayInputStream(_code.getBytes());
lex = new PtalonLexer(inputStream);
inputStream.close();
rec = new PtalonRecognizer(lex);
rec.setASTNodeClass("ptolemy.actor.ptalon.PtalonAST");
rec.actor_definition();
PtalonAST ast = (PtalonAST) rec.getAST();
PtalonModelEvaluator evaluator = new PtalonModelEvaluator();
int parameterCount = 0;
while (evaluator.evaluate(this, ast)) {
if (_expressions.size() == 0)
break;
List<Parameter> paramList = parameterList(this);
if (paramList.size() > parameterCount)
parameterCount = parameterList(this).size();
else
break;
HashSet<String> needsRemove = new HashSet<String>();
for (String name : _expressions.keySet()) {
Attribute a = this.getAttribute(name);
if (a instanceof Parameter) {
Parameter p = (Parameter) a;
p.setExpression(_expressions.get(name));
needsRemove.add(name);
}
}
for (String name : needsRemove) {
_expressions.remove(name);
}
}
String moml = exportMoML();
deepClear();
getContainer().requestChange(
new MoMLChangeRequest(this, getContainer(), moml));
} catch (Exception ex) {
throw new IllegalActionException(this, ex, ex.getMessage());
}
}
public static List<Parameter> parameterList(NamedObj actor) {
ArrayList<Parameter> parameters = new ArrayList<Parameter>();
for (Object attribute : actor.attributeList()) {
if (attribute instanceof Parameter) {
Parameter parameter = (Parameter) attribute;
if (parameter.getVisibility().equals(Settable.FULL) &&
!parameter.getName().equals("_ptalonCode")) {
parameters.add(parameter);
}
}
}
return parameters;
}
private Hashtable<String, String> _expressions = new Hashtable<String, String>();
public String uniqueName(String prefix) {
if (prefix == null) {
prefix = "null";
}
String candidate = prefix;
int uniqueNameIndex = 1;
while ((getAttribute(candidate) != null)
|| (getPort(candidate) != null)
|| (getEntity(candidate) != null)
|| (getRelation(candidate) != null)) {
candidate = prefix + ++uniqueNameIndex;
}
return candidate;
}
}