package ptolemy.actor.ptalon.model; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.util.HashSet; import ptolemy.actor.TypedCompositeActor; import ptolemy.actor.TypedIOPort; import ptolemy.actor.TypedIORelation; import ptolemy.actor.ptalon.PtalonTokenTypes; import ptolemy.data.Token; import ptolemy.data.expr.Parameter; import ptolemy.data.expr.Variable; import ptolemy.kernel.ComponentEntity; import ptolemy.kernel.CompositeEntity; import ptolemy.kernel.util.AbstractSettableAttribute; import ptolemy.kernel.util.Attribute; import ptolemy.kernel.util.IllegalActionException; import ptolemy.kernel.util.NameDuplicationException; import antlr.collections.AST; public class ActorInstantiator { public ActorInstantiator(PtalonModelEvaluator evaluator, URI ptalonUrl) { this(evaluator); _ptalonUrl = ptalonUrl; } public ActorInstantiator(PtalonModelEvaluator evaluator, TypedCompositeActor thisReference) { this(evaluator); _entity = thisReference; } public ActorInstantiator(PtalonModelEvaluator evaluator, Class<? extends ComponentEntity> actorClass) { this(evaluator); _actorClass = actorClass; } private ActorInstantiator(PtalonModelEvaluator evaluator) { _evaluator = evaluator; _actor = evaluator.getActor(); } public boolean evaluate(AST ast) throws IllegalActionException, NameDuplicationException { boolean changed = false; changed |= createEntity(ast); AST assignmentAst = ast.getFirstChild(); while (assignmentAst != null) { changed |= processAssignment(assignmentAst); assignmentAst = assignmentAst.getNextSibling(); } return changed; } private boolean createEntity(AST ast) throws IllegalActionException, NameDuplicationException { if (_entity != null) { return false; } String actorNameInPtalon = ast.getText(); try { if (_actorClass != null) { Constructor<? extends ComponentEntity> constructor = _actorClass .getConstructor(CompositeEntity.class, String.class); _entity = constructor.newInstance(_actor, _actor .uniqueName(actorNameInPtalon)); return true; } } catch (SecurityException e) { throw new IllegalActionException(_actor, e, e.getMessage()); } catch (NoSuchMethodException e) { throw new IllegalActionException(_actor, e, e.getMessage()); } catch (IllegalArgumentException e) { throw new IllegalActionException(_actor, e, e.getMessage()); } catch (InstantiationException e) { throw new IllegalActionException(_actor, e, e.getMessage()); } catch (IllegalAccessException e) { throw new IllegalActionException(_actor, e, e.getMessage()); } catch (InvocationTargetException e) { throw new IllegalActionException(_actor, e, e.getMessage()); } try { if (_ptalonUrl != null) { PtalonModel model = new PtalonModel(_actor, _actor.uniqueName(actorNameInPtalon)); File file = new File(_ptalonUrl); FileReader reader; reader = new FileReader(file); StringBuffer buffer = new StringBuffer(); char[] c = new char[1024]; int i = 0; while ((i = reader.read(c, 0, 1024)) > 0) { buffer.append(c, 0, i); } reader.close(); String result = buffer.toString(); model.setCode(result); model.updateModel(); _entity = model; return true; } } catch (FileNotFoundException e) { throw new IllegalActionException(_actor, e, e.getMessage()); } catch (IOException e) { throw new IllegalActionException(_actor, e, e.getMessage()); } return false; } private boolean processAssignment(AST ast) throws IllegalActionException, NameDuplicationException { String lhs = _evaluator.tryGetExpressionPtalonName(ast.getFirstChild()); if (lhs == null) return false; AST rightAst = ast.getFirstChild().getNextSibling(); if (rightAst.getType() == PtalonTokenTypes.EXPRESSION) { Attribute att = _entity.getAttribute(lhs); if (att instanceof Variable) { return assignVariable((Variable) att, rightAst); } else if (att instanceof AbstractSettableAttribute) { return assignAbstractSettableAttribute( (AbstractSettableAttribute) att, rightAst); } Parameter p = new Parameter(_entity, _entity.uniqueName(lhs)); return assignVariable(p, rightAst); } else { TypedIOPort leftPort = (TypedIOPort) _entity.getPort(lhs); if (leftPort != null) return attachPort(leftPort, rightAst); String rhs = _evaluator.tryGetExpressionPtalonName(rightAst); if (rhs != null) { TypedIOPort rightPort = (TypedIOPort) _actor.getPort(rhs); if (rightPort != null) { leftPort = createPort(lhs, rightPort); return attachPort(leftPort, rightAst); } TypedIORelation rightRelation = (TypedIORelation) _actor .getRelation(rhs); if (rightRelation != null) { leftPort = createPort(lhs, rightRelation); return attachPort(leftPort, rightAst); } TransparentRelation tr = new TransparentRelation(rhs); if (_evaluator.getTransparentRelations().contains(tr)) { tr = _evaluator.getTransparentRelations().get(tr); if (tr.hasInitialPortBeenSet()) { leftPort = createPort(lhs, tr.getPort()); return attachPort(leftPort, rightAst); } } } } return false; } private boolean assignVariable(Variable leftVariable, AST rightAst) throws IllegalActionException, NameDuplicationException { if (_setParameters.contains(leftVariable)) return false; String rhs = rightAst.getText(); Token token = _evaluator.evaluateExpression(rhs); if (token == null) return false; leftVariable.setToken(token); _setParameters.add(leftVariable); return true; } private boolean assignAbstractSettableAttribute( AbstractSettableAttribute leftVariable, AST rightAst) throws IllegalActionException, NameDuplicationException { if (_setParameters.contains(leftVariable)) return false; String rhs = rightAst.getText(); leftVariable.setExpression(rhs); _setParameters.add(leftVariable); return true; } private TypedIOPort createPort(String leftName, TypedIORelation rightRelation) throws IllegalActionException, NameDuplicationException { boolean isInput = false; boolean isOutput = false; for (Object x : rightRelation.linkedPortList()) { TypedIOPort p = (TypedIOPort) x; if ((p.isInput() && p.getContainer() == _actor) || (p.isOutput() && p.getContainer() != _actor)) { isInput = true; } if ((p.isOutput() && p.getContainer() == _actor) || (p.isInput() && p.getContainer() != _actor)) { isOutput = true; } } if (!isInput && !isOutput) { isInput = true; isOutput = true; } return new TypedIOPort(_entity, _entity.uniqueName(leftName), isInput, isOutput); } private TypedIOPort createPort(String leftName, TypedIOPort rightPort) throws IllegalActionException, NameDuplicationException { TypedIOPort leftPort; if (rightPort.getContainer().equals(_actor)) { leftPort = new TypedIOPort(_entity, _entity.uniqueName(leftName), rightPort.isInput(), rightPort.isOutput()); } else { leftPort = new TypedIOPort(_entity, _entity.uniqueName(leftName), rightPort.isOutput(), rightPort.isInput()); } leftPort.setMultiport(rightPort.isMultiport()); return leftPort; } private boolean attachPort(TypedIOPort leftPort, AST rightAst) throws IllegalActionException, NameDuplicationException { if (_connectedPorts.contains(leftPort)) return false; String rhs = _evaluator.tryGetExpressionPtalonName(rightAst); if (rhs == null) return false; String rightName = _evaluator.getActualName(rhs); if (rightName == null) { TransparentRelation tr = new TransparentRelation(rhs); if (_evaluator.getTransparentRelations().containsKey(tr)) { tr = _evaluator.getTransparentRelations().get(tr); if (tr.hasInitialPortBeenSet()) { _actor.connect(leftPort, tr.getPort()); } else { tr.setInitialPort(leftPort); } _connectedPorts.add(leftPort); return true; } return false; } TypedIOPort rightPort = (TypedIOPort) _actor.getPort(rightName); if (rightPort != null) { _actor.connect(leftPort, rightPort); _connectedPorts.add(leftPort); return true; } TypedIORelation rightRelation = (TypedIORelation) _actor .getRelation(rightName); if (rightRelation != null) { leftPort.link(rightRelation); _connectedPorts.add(leftPort); return true; } return false; } private TypedCompositeActor _actor; private Class<? extends ComponentEntity> _actorClass; private URI _ptalonUrl; private ComponentEntity _entity; private HashSet<TypedIOPort> _connectedPorts = new HashSet<TypedIOPort>(); private HashSet<AbstractSettableAttribute> _setParameters = new HashSet<AbstractSettableAttribute>(); private PtalonModelEvaluator _evaluator; }