/* * Copyright (c) 2011, IETR/INSA of Rennes * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the IETR/INSA of Rennes nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ package net.sf.orcc.df.transform; import java.util.ArrayList; import java.util.List; import net.sf.orcc.df.Actor; import net.sf.orcc.df.Argument; import net.sf.orcc.df.Connection; import net.sf.orcc.df.Instance; import net.sf.orcc.df.Network; import net.sf.orcc.df.Port; import net.sf.orcc.df.util.DfVisitor; import net.sf.orcc.graph.Edge; import net.sf.orcc.graph.Vertex; import net.sf.orcc.ir.Expression; import net.sf.orcc.ir.Var; import net.sf.orcc.ir.util.IrUtil; import net.sf.orcc.util.OrccLogger; import net.sf.orcc.util.SwitchUtil; import net.sf.orcc.util.Void; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil.Copier; /** * This class defines a transformation that transforms a network into a new * network where instances of actors and networks are replaced by new actors and * networks where the value of parameters have been appropriately replaced. * * @author Matthieu Wipliez * @author Hervé Yviquel * */ public class Instantiator extends DfVisitor<Void> { private final boolean instantiateActors; /** * Creates an instantiator that will replace * instances of networks by instantiated networks. If instantiateActors * is <code>true</code>, then the instantiator also replaces instances of * actors by instantiated actors. The instantiator does not set default FIFO * size. * * @param instantiateActors * <code>true</code> if actors should be duplicated */ public Instantiator(boolean instantiateActors) { this.instantiateActors = instantiateActors; } @Override public Void caseNetwork(Network network) { // copy instances to entities/instances List<Vertex> children = new ArrayList<Vertex>(network.getChildren()); for (Vertex vertex : children) { Instance instance = vertex.getAdapter(Instance.class); if (instance == null) { // cannot instantiate anything else than an instance continue; } EObject entity = instance.getEntity(); if (entity instanceof Network) { instantiate(network, instance); } else if (entity instanceof Actor) { if (instantiateActors) { instantiate(network, instance); } // set attribute's value when passed as instance parameter Actor actor = instance.getAdapter(Actor.class); for (Argument argument : instance.getArguments()) { Var parameter = actor.getParameter(argument .getVariable().getName()); if (parameter != null) { parameter.setValue(argument.getValue()); } else { OrccLogger.warnln("Instance argument " + argument.getVariable().getName() + " is not a parameter of actor" + actor.getSimpleName()); } } } } return SwitchUtil.DONE; } /** * Replaces connections to the instance by connections to the entity. * * @param copier * a copier object used to create the newEntity * @param instance * an instance * @param newEntity * the new entity */ private void connect(Copier copier, Instance instance, Vertex newEntity) { List<Edge> incoming = new ArrayList<Edge>(instance.getIncoming()); for (Edge edge : incoming) { edge.setTarget(newEntity); Connection connection = (Connection) edge; connection.setTargetPort((Port) copier.get(connection .getTargetPort())); } List<Edge> outgoing = new ArrayList<Edge>(instance.getOutgoing()); for (Edge edge : outgoing) { edge.setSource(newEntity); Connection connection = (Connection) edge; connection.setSourcePort((Port) copier.get(connection .getSourcePort())); } } /** * Instantiates the object referenced by the instance in the given network. * * @param network * network that contains instance * @param instance * an instance that references an actor or sub-network */ private void instantiate(Network network, Instance instance) { // copy object Copier copier = new Copier(true); Vertex newEntity = (Vertex) IrUtil.copy(copier, instance.getEntity()); // instantiate sub network doSwitch(newEntity); // rename sub network newEntity.setLabel(instance.getName()); // replace connections of instance network.add(newEntity); connect(copier, instance, newEntity); // assigns arguments' values to network's variables for (Argument argument : instance.getArguments()) { Var var = (Var) copier.get(argument.getVariable()); // If instance's parameter correspond to an actor's parameter if(var != null) { Expression value = argument.getValue(); var.setInitialValue(value); } else { // TODO : Display a warning ? } } // remove instance network.remove(instance); } }