/** * <copyright> * Copyright (c) 2009-2012, 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. * </copyright> */ package net.sf.orcc.df.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import net.sf.orcc.df.Connection; import net.sf.orcc.df.DfPackage; import net.sf.orcc.df.Entity; import net.sf.orcc.df.Port; import net.sf.orcc.df.util.DfUtil; import net.sf.orcc.graph.Edge; import net.sf.orcc.graph.GraphPackage; import net.sf.orcc.graph.Vertex; import net.sf.orcc.ir.Expression; import net.sf.orcc.ir.Var; import net.sf.orcc.util.Attribute; import net.sf.orcc.util.impl.AttributableImpl; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.impl.AdapterImpl; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.util.EObjectResolvingEList; /** * <!-- begin-user-doc --> An implementation of the model object ' * <em><b>Entity</b></em>'. <!-- end-user-doc --> * <p> * The following features are implemented: * <ul> * <li>{@link net.sf.orcc.df.impl.EntityImpl#getIncomingPortMap <em>Incoming Port Map</em>}</li> * <li>{@link net.sf.orcc.df.impl.EntityImpl#getInputs <em>Inputs</em>}</li> * <li>{@link net.sf.orcc.df.impl.EntityImpl#getName <em>Name</em>}</li> * <li>{@link net.sf.orcc.df.impl.EntityImpl#getOutgoingPortMap <em>Outgoing Port Map</em>}</li> * <li>{@link net.sf.orcc.df.impl.EntityImpl#getOutputs <em>Outputs</em>}</li> * <li>{@link net.sf.orcc.df.impl.EntityImpl#getParameters <em>Parameters</em>}</li> * </ul> * </p> * * @generated */ public class EntityImpl extends AttributableImpl implements Entity { /** * This class clears the value of incomingPortMap or outgoingPortMap when * the list of incoming or outgoing connections of the "vertex" field * changes. * * @author Matthieu Wipliez * */ private class ConnectionListAdapter extends AdapterImpl { @Override public void notifyChanged(Notification msg) { Object feature = msg.getFeature(); if (incomingPortMap != null) { if (feature == GraphPackage.Literals.VERTEX__INCOMING) { incomingPortMap = null; } } if (outgoingPortMap != null) { if (feature == GraphPackage.Literals.VERTEX__OUTGOING) { outgoingPortMap = null; } } } } /** * The cached value of the '{@link #getIncomingPortMap() <em>Incoming Port Map</em>}' attribute. * <!-- begin-user-doc --> <!-- * end-user-doc --> * @see #getIncomingPortMap() * @generated * @ordered */ protected Map<Port, Connection> incomingPortMap; /** * The cached value of the '{@link #getInputs() <em>Inputs</em>}' reference list. * <!-- begin-user-doc --> <!-- end-user-doc --> * @see #getInputs() * @generated * @ordered */ protected EList<Port> inputs; /** * The default value of the '{@link #getName() <em>Name</em>}' attribute. * <!-- begin-user-doc --> <!-- end-user-doc --> * @see #getName() * @generated * @ordered */ protected static final String NAME_EDEFAULT = null; /** * The cached value of the '{@link #getName() <em>Name</em>}' attribute. * <!-- begin-user-doc --> <!-- end-user-doc --> * @see #getName() * @generated * @ordered */ protected String name = NAME_EDEFAULT; /** * The cached value of the '{@link #getOutgoingPortMap() <em>Outgoing Port Map</em>}' attribute. * <!-- begin-user-doc --> <!-- * end-user-doc --> * @see #getOutgoingPortMap() * @generated * @ordered */ protected Map<Port, List<Connection>> outgoingPortMap; /** * The cached value of the '{@link #getOutputs() <em>Outputs</em>}' reference list. * <!-- begin-user-doc --> <!-- end-user-doc --> * @see #getOutputs() * @generated * @ordered */ protected EList<Port> outputs; /** * The cached value of the '{@link #getParameters() <em>Parameters</em>}' reference list. * <!-- begin-user-doc --> <!-- end-user-doc --> * @see #getParameters() * @generated * @ordered */ protected EList<Var> parameters; private Vertex vertex; /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ protected EntityImpl() { super(); } /** * <!-- begin-user-doc -->Creates a new Entity with the given name, input * ports, output ports, parameters. This constructor should only be used to * build a temporary entity, or an entity that will NOT be used to compute * incoming/outgoing port map (see the other constructor).<!-- end-user-doc * --> * * @param name * name of the entity * @param inputs * a list of input ports * @param outputs * a list of output ports * @param parameters * a list of parameters */ public EntityImpl(String name, EList<Port> inputs, EList<Port> outputs, EList<Var> parameters) { super(); this.name = name; this.inputs = inputs; this.outputs = outputs; this.parameters = parameters; } /** * <!-- begin-user-doc -->Creates a new Entity on the given vertex, with the * given input ports, output ports, parameters. This constructor can be used * to create an entity that will be used to compute the incoming/outgoing * port map.<!-- end-user-doc --> * * @param name * name of the entity * @param inputs * a list of input ports * @param outputs * a list of output ports * @param parameters * a list of parameters */ public EntityImpl(Vertex vertex, EList<Attribute> attributes, EList<Port> inputs, EList<Port> outputs, EList<Var> parameters) { super(); this.vertex = vertex; this.attributes = attributes; this.inputs = inputs; this.outputs = outputs; this.parameters = parameters; vertex.eAdapters().add(new ConnectionListAdapter()); } /** * <!-- begin-user-doc -->Creates a new Entity on the given vertex, with the * inputs, outputs, parameters of the given entity. This constructor MUST be * used when wrapping another entity so that it can be used to compute the * incoming/outgoing port map.<!-- end-user-doc --> * * @param vertex * the vertex to use when computing incoming/outgoing port map * @param entity * the entity that the new entity will be based on */ protected EntityImpl(Vertex vertex, Entity entity) { this(vertex, entity.getAttributes(), entity.getInputs(), entity .getOutputs(), entity.getParameters()); } /** * Computes the incoming port map of vertex. */ private void computeIncomingPortMap() { incomingPortMap = new HashMap<Port, Connection>(); if (vertex == null) { throw new IllegalArgumentException("cannot compute incoming port " + "map on an entity that is not associated with a vertex"); } for (Edge edge : vertex.getIncoming()) { if (edge instanceof Connection) { Connection connection = (Connection) edge; incomingPortMap.put(connection.getTargetPort(), connection); } } } /** * Computes the outgoing port map of vertex. */ private void computeOutgoingPortMap() { outgoingPortMap = new HashMap<Port, List<Connection>>(); if (vertex == null) { throw new IllegalArgumentException("cannot compute outgoing port " + "map on an entity that is not associated with a vertex"); } for (Edge edge : vertex.getOutgoing()) { if (edge instanceof Connection) { Connection connection = (Connection) edge; Port source = connection.getSourcePort(); List<Connection> conns = outgoingPortMap.get(source); if (conns == null) { conns = new ArrayList<Connection>(1); outgoingPortMap.put(source, conns); } conns.add(connection); } } } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ @Override public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { case DfPackage.ENTITY__INCOMING_PORT_MAP: return getIncomingPortMap(); case DfPackage.ENTITY__INPUTS: return getInputs(); case DfPackage.ENTITY__NAME: return getName(); case DfPackage.ENTITY__OUTGOING_PORT_MAP: return getOutgoingPortMap(); case DfPackage.ENTITY__OUTPUTS: return getOutputs(); case DfPackage.ENTITY__PARAMETERS: return getParameters(); } return super.eGet(featureID, resolve, coreType); } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ @Override public boolean eIsSet(int featureID) { switch (featureID) { case DfPackage.ENTITY__INCOMING_PORT_MAP: return incomingPortMap != null; case DfPackage.ENTITY__INPUTS: return inputs != null && !inputs.isEmpty(); case DfPackage.ENTITY__NAME: return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT .equals(name); case DfPackage.ENTITY__OUTGOING_PORT_MAP: return outgoingPortMap != null; case DfPackage.ENTITY__OUTPUTS: return outputs != null && !outputs.isEmpty(); case DfPackage.ENTITY__PARAMETERS: return parameters != null && !parameters.isEmpty(); } return super.eIsSet(featureID); } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ @Override protected EClass eStaticClass() { return DfPackage.Literals.ENTITY; } @Override @SuppressWarnings("unchecked") public <T> T getAdapter(Class<T> type) { if (type.isAssignableFrom(getClass())) { return (T) this; } // by default an entity cannot be adapted to anything else // subclasses should extend this method return null; } @Override public Map<Port, Connection> getIncomingPortMap() { if (incomingPortMap == null) { computeIncomingPortMap(); } return incomingPortMap; } @Override public Port getInput(String name) { for (Port port : getInputs()) { if (port.getName().equals(name)) { return port; } } return null; } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ public EList<Port> getInputs() { if (inputs == null) { inputs = new EObjectResolvingEList<Port>(Port.class, this, DfPackage.ENTITY__INPUTS); } return inputs; } @Override public String getName() { if (vertex == null) { // if vertex is null, name is valid return name; } else { // otherwise the name is given by the vertex return vertex.getLabel(); } } @Override public Map<Port, List<Connection>> getOutgoingPortMap() { if (outgoingPortMap == null) { computeOutgoingPortMap(); } return outgoingPortMap; } @Override public Port getOutput(String name) { for (Port port : getOutputs()) { if (port.getName().equals(name)) { return port; } } return null; } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ public EList<Port> getOutputs() { if (outputs == null) { outputs = new EObjectResolvingEList<Port>(Port.class, this, DfPackage.ENTITY__OUTPUTS); } return outputs; } @Override public Var getParameter(String name) { for (Var var : getParameters()) { if (var.getName().equals(name)) { return var; } } return null; } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ public EList<Var> getParameters() { if (parameters == null) { parameters = new EObjectResolvingEList<Var>(Var.class, this, DfPackage.ENTITY__PARAMETERS); } return parameters; } @Override public String getSimpleName() { return DfUtil.getSimpleName(getName()); } /** * <!-- begin-user-doc --> <!-- end-user-doc --> * @generated */ @Override public String toString() { if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); result.append(" (incomingPortMap: "); result.append(incomingPortMap); result.append(", name: "); result.append(name); result.append(", outgoingPortMap: "); result.append(outgoingPortMap); result.append(')'); return result.toString(); } @Override public void update(List<Expression> expressions) { // sub-classes should override } } // EntityImpl