Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/ContainerTrafo.java')
-rw-r--r--extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/ContainerTrafo.java303
1 files changed, 189 insertions, 114 deletions
diff --git a/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/ContainerTrafo.java b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/ContainerTrafo.java
index 7626b23535c..d2aece79dd0 100644
--- a/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/ContainerTrafo.java
+++ b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/ContainerTrafo.java
@@ -18,7 +18,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.util.EcoreUtil;
@@ -27,7 +26,6 @@ import org.eclipse.papyrus.FCM.InteractionComponent;
import org.eclipse.papyrus.FCM.InterceptionKind;
import org.eclipse.papyrus.FCM.InterceptionRule;
import org.eclipse.papyrus.qompass.designer.core.ConnectorUtils;
-import org.eclipse.papyrus.qompass.designer.core.Log;
import org.eclipse.papyrus.qompass.designer.core.Messages;
import org.eclipse.papyrus.qompass.designer.core.PortUtils;
import org.eclipse.papyrus.qompass.designer.core.StUtils;
@@ -35,6 +33,7 @@ import org.eclipse.papyrus.qompass.designer.core.Utils;
import org.eclipse.papyrus.qompass.designer.core.acceleo.UMLTool;
import org.eclipse.papyrus.qompass.designer.core.deployment.DepCreation;
import org.eclipse.papyrus.qompass.designer.core.deployment.DepUtils;
+import org.eclipse.papyrus.qompass.designer.core.deployment.DeployConstants;
import org.eclipse.papyrus.qompass.designer.core.extensions.InstanceConfigurator;
import org.eclipse.papyrus.qompass.designer.core.templates.TemplateInstantiation;
import org.eclipse.papyrus.qompass.designer.core.templates.TemplateUtils;
@@ -44,9 +43,11 @@ import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Connector;
import org.eclipse.uml2.uml.ConnectorEnd;
+import org.eclipse.uml2.uml.EncapsulatedClassifier;
import org.eclipse.uml2.uml.Feature;
import org.eclipse.uml2.uml.InstanceSpecification;
import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.Port;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Slot;
@@ -54,6 +55,8 @@ import org.eclipse.uml2.uml.TemplateBinding;
import org.eclipse.uml2.uml.TemplateSignature;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLPackage;
+import org.eclipse.uml2.uml.ValueSpecification;
+import org.eclipse.uml2.uml.VisibilityKind;
import org.eclipse.uml2.uml.util.UMLUtil;
/**
@@ -78,10 +81,11 @@ public class ContainerTrafo extends AbstractContainerTrafo {
* @param tmCDP
* deployment plan within target model
*/
- public ContainerTrafo(Copy copy, Package tmCDP) {
+ public ContainerTrafo(Copy copy, Package tmCDP, InstanceSpecification executorIS) {
this.copy = copy;
this.tmCDP = tmCDP;
- configureOnly = false;
+ this.executorIS = executorIS;
+ portInfo = new HashMap<Property, Port>();
}
/**
@@ -114,18 +118,20 @@ public class ContainerTrafo extends AbstractContainerTrafo {
// model. Yet code generation works, as port names are identical
for(Port port : PortUtils.getAllPorts(tmComponent)) {
// copy port
- Port newPort = EcoreUtil.copy(port); // don't use E3CM copy, since this is not a copy from source to target model
- tmContainerImpl.getOwnedAttributes().add(newPort);
- StUtils.copyStereotypes(port, newPort);
-
- // create delegation for application port
- Connector containerDelegation = tmContainerImpl.createOwnedConnector("delegation " + port.getName()); //$NON-NLS-1$
- Copy.copyID(tmContainerImpl, containerDelegation);
- ConnectorEnd end1 = containerDelegation.createEnd();
- end1.setRole(newPort);
- ConnectorEnd end2 = containerDelegation.createEnd();
- end2.setPartWithPort(executorPart);
- end2.setRole(port);
+ if (port.getVisibility() == VisibilityKind.PUBLIC_LITERAL) {
+ Port newPort = EcoreUtil.copy(port); // don't use E3CM copy, since this is not a copy from source to target model
+ tmContainerImpl.getOwnedAttributes().add(newPort);
+ StUtils.copyStereotypes(port, newPort);
+
+ // create delegation for application port
+ Connector containerDelegation = tmContainerImpl.createOwnedConnector("delegation " + port.getName()); //$NON-NLS-1$
+ Copy.copyID(tmContainerImpl, containerDelegation);
+ ConnectorEnd end1 = containerDelegation.createEnd();
+ end1.setRole(newPort);
+ ConnectorEnd end2 = containerDelegation.createEnd();
+ end2.setPartWithPort(executorPart);
+ end2.setRole(port);
+ }
}
// Inheritance issues:
@@ -171,32 +177,62 @@ public class ContainerTrafo extends AbstractContainerTrafo {
* Additional information about the container that is used by instance configurators
*/
@Override
- public void createContainerInstance(Class tmComponent, InstanceSpecification tmIS, ContainerContext context) throws TransformationException {
+ public InstanceSpecification createContainerInstance(Class tmComponent, InstanceSpecification tmIS, ContainerContext context) throws TransformationException {
// create an instance specification for the container
- containerIS = (InstanceSpecification)tmCDP.createPackagedElement(tmIS.getName(), UMLPackage.eINSTANCE.getInstanceSpecification());
+ InstanceSpecification containerIS =
+ (InstanceSpecification)tmCDP.createPackagedElement(tmIS.getName(), UMLPackage.eINSTANCE.getInstanceSpecification());
// assign new name to original instance specification which reflects
// role within containment hierarchy
tmIS.setName(tmIS.getName() + "." + executorPartName); //$NON-NLS-1$
containerIS.getClassifiers().add(tmContainerImpl);
// existing instance specification (tmIS) is the executor instance specification
DepCreation.createSlot(containerIS, tmIS, executorPart);
- executorIS = tmIS;
counter = 0;
// containers.put(tmComponent, this);
- this.context = context;
- context.executorIS = executorIS;
+ context.executorIS = tmIS;
+ EList<Slot> connectorSlots = new BasicEList<Slot>();
// now create instances for the contained elements
for(Property extensionPart : tmContainerImpl.getAttributes()) {
Type tmContainerExtImpl = extensionPart.getType();
if(tmContainerExtImpl instanceof Class) {
- InstanceSpecification containerExtIS = DepCreation.createDepPlan(tmCDP, (Class)tmContainerExtImpl, containerIS.getName() + "." + //$NON-NLS-1$
- extensionPart.getName(), false);
- // configure extension
- InstanceConfigurator.configureInstance(containerExtIS, extensionPart, null);
- DepCreation.createSlot(containerIS, containerExtIS, extensionPart);
+ if (DepUtils.getSlot(executorIS, extensionPart) == null) {
+ // no slot for part exists => assume that the part has been added by the container and create an instance specification for it.
+ String isName;
+ InstanceSpecification containerExtIS = null;
+ if(Utils.isSingleton((Class)tmContainerExtImpl)) {
+ // is a singleton - exactly one instance exists
+ // use a common instance prefix for singletons
+ isName = DeployConstants.singletonPrefix + extensionPart.getName();
+ PackageableElement pe = tmCDP.getPackagedElement(isName);
+ if (pe instanceof InstanceSpecification) {
+ containerExtIS = (InstanceSpecification) pe;
+ }
+ }
+ else {
+ isName = containerIS.getName() + "." + extensionPart.getName(); //$NON-NLS-1$
+ }
+ if (containerExtIS == null) {
+ containerExtIS = DepCreation.createDepPlan(tmCDP, (Class)tmContainerExtImpl, isName, false);
+ }
+ // configure extension
+ context.port = portInfo.get(extensionPart);
+ InstanceConfigurator.configureInstance(containerExtIS, extensionPart, context);
+ Slot partSlot = DepCreation.createSlot(containerIS, containerExtIS, extensionPart);
+ if (StereotypeUtil.isApplied(tmContainerExtImpl, InteractionComponent.class)) {
+ connectorSlots.add(partSlot);
+ }
+ }
}
- }
+ }
+
+ // handle propagation of node allocation for connectors. Do that in 2nd loop, since the allocation
+ // of parts might be incomplete before.
+ for(Slot connectorSlot : connectorSlots) {
+ ConnectorReification.propagateNodeAllocation(tmContainerImpl, containerIS, connectorSlot);
+ }
+ moveSlots(executorIS);
+ return containerIS;
}
/**
@@ -205,17 +241,27 @@ public class ContainerTrafo extends AbstractContainerTrafo {
* @param tmComponent
* @param tmIS
*/
- public void createHwContainerInstance(Class tmComponent, InstanceSpecification tmNode, ContainerContext context) {
+ public InstanceSpecification createHwContainerInstance(Class tmComponent, InstanceSpecification tmNode, ContainerContext context) {
// create an instance specification for the container
- containerIS = (InstanceSpecification)tmCDP.createPackagedElement(tmNode.getName() + hwContainerPostfix, UMLPackage.eINSTANCE.getInstanceSpecification());
+ InstanceSpecification containerIS =
+ (InstanceSpecification)tmCDP.createPackagedElement(tmNode.getName() + hwContainerPostfix, UMLPackage.eINSTANCE.getInstanceSpecification());
// assign new name to original instance specification which reflects
// role within containment hierarchy
containerIS.getClassifiers().add(tmContainerImpl);
// containers.put(tmComponent, this);
counter = 0;
executorIS = tmNode;
- this.context = context;
context.executorIS = executorIS;
+ // copy slots from HW instance specification
+ for (Slot slot : tmNode.getSlots()) {
+ Slot slotCopy = containerIS.createSlot();
+ slotCopy.setDefiningFeature(slot.getDefiningFeature());
+ // copy values (use CopyTo.copyTo(slot, containerIS) instead?)
+ for (ValueSpecification value : slot.getValues()) {
+ Copy.copyValue(value, slotCopy);
+ }
+ }
+ return containerIS;
}
/**
@@ -283,7 +329,7 @@ public class ContainerTrafo extends AbstractContainerTrafo {
}
else {
Property extensionPart =
- expandAggregationExtension(part.getName(), extOrInterceptor, tmComponent);
+ expandAggregationExtension(part, extOrInterceptor, tmComponent);
// register relation to facilitate connector copy
copy.setPackageTemplate(smContainerRule.getBase_Class(), tmContainerImpl);
copy.putPair(part, extensionPart);
@@ -325,7 +371,7 @@ public class ContainerTrafo extends AbstractContainerTrafo {
org.eclipse.papyrus.FCM.Connector fcmConn = StUtils.getConnector(connector);
if(fcmConn != null) {
ConnectorReification.reifyConnector(copy, tmContainerImpl,
- UMLTool.varName(connector), connector, containerIS, null);
+ UMLTool.varName(connector), connector, executorIS, null);
}
else {
copy.remove(connector);
@@ -342,42 +388,31 @@ public class ContainerTrafo extends AbstractContainerTrafo {
* application component also inherits from the type of the container
* extension in order to avoid copying ports.
*/
- Property expandAggregationExtension(String name, Class smContainerExtImpl, Class tmComponent) throws TransformationException {
+ Property expandAggregationExtension(Property smExtensionPart, Class smContainerExtImpl, Class tmComponent) throws TransformationException {
Property extensionPart;
+ String name = smExtensionPart.getName();
Class tmContainerExtImpl = null;
- if(configureOnly) {
- extensionPart = tmContainerImpl.getAttribute(name, null);
- if((extensionPart != null) && extensionPart.getType() instanceof Class) {
- tmContainerExtImpl = (Class)extensionPart.getType();
- }
+
+ TemplateSignature signature = TemplateUtils.getSignature(smContainerExtImpl);
+ if(signature == null) {
+ // no template signature, just copy the container extension into the target model
+ tmContainerExtImpl = copy.getCopy(smContainerExtImpl);
+ } else {
+ // template signature found, instantiate container extension via the
+ // template binding mechanism
+ TemplateBinding binding = TemplateUtils.fixedBinding(copy.target, smContainerExtImpl, tmComponent);
+ Object[] args = new Object[]{};
+ TemplateInstantiation ti = new TemplateInstantiation(copy, binding, args);
+ tmContainerExtImpl = (Class)ti.bindNamedElement(smContainerExtImpl);
}
- else {
- TemplateSignature signature = TemplateUtils.getSignature(smContainerExtImpl);
- if(signature == null) {
- // no template signature, just copy the container extension into the target model
- tmContainerExtImpl = copy.getCopy(smContainerExtImpl);
- } else {
- // template signature found, instantiate container extension via the
- // template binding mechanism
- TemplateBinding binding = TemplateUtils.fixedBinding(copy.target, smContainerExtImpl, tmComponent);
- Object[] args = new Object[]{};
- TemplateInstantiation ti = new TemplateInstantiation(copy, binding, args);
- tmContainerExtImpl = (Class)ti.bindNamedElement(smContainerExtImpl);
- }
- // add part associated with the extension to the container
- extensionPart = tmContainerImpl.createOwnedAttribute(name, tmContainerExtImpl);
- }
- // problem: would not be unique in case of multiple extensions
- // Copy.copyID(tmComponent, extensionPart, "a");
- extensionPart.setIsComposite(true);
- // TODO separation of container creation and instance creation
- InstanceSpecification containerExtIS = DepCreation.createDepPlan(tmCDP, tmContainerExtImpl, containerIS.getName() + "." + extensionPart.getName(), false); //$NON-NLS-1$
- // configure extension
- context.port = null;
- InstanceConfigurator.configureInstance(containerExtIS, extensionPart, context);
- DepCreation.createSlot(containerIS, containerExtIS, extensionPart);
+ // add part associated with the extension to the container
+ extensionPart = tmContainerImpl.createOwnedAttribute(name, tmContainerExtImpl);
+ // Copy.copyID(tmComponent, extensionPart, "a");
+ extensionPart.setAggregation(smExtensionPart.getAggregation());
+ Copy.copyMultElemModifiers(smExtensionPart, extensionPart);
+ Copy.copyFeatureModifiers(smExtensionPart, extensionPart);
return extensionPart;
}
@@ -421,53 +456,37 @@ public class ContainerTrafo extends AbstractContainerTrafo {
Property connectorPart;
String interceptionName = interceptorName + port.getName() + counter;
- if(configureOnly) {
- // counter is reset before instance configuration
- connectorPart = tmContainerImpl.getAttribute(interceptionName, null);
- }
- else {
- Connector interceptionConnector = null;
- // get delegation connector
- for(Connector connector : tmContainerImpl.getOwnedConnectors()) {
- if(ConnectorUtils.connectsPort(connector, port)) {
- interceptionConnector = connector;
- break;
- }
- }
- // interceptionConnector = tmContainerImpl.getOwnedConnector
- // ("delegation " + port.getName ());
- if(interceptionConnector == null) {
- throw new TransformationException(Messages.ContainerTrafo_CannotFindDelegationConn);
+ Connector interceptionConnector = null;
+ // get delegation connector
+ for(Connector connector : tmContainerImpl.getOwnedConnectors()) {
+ if(ConnectorUtils.connectsPort(connector, port)) {
+ interceptionConnector = connector;
+ break;
}
-
- interceptionConnector.setName(interceptorName + port.getName() + counter);
- org.eclipse.papyrus.FCM.Connector fcmConn = StereotypeUtil.applyApp(interceptionConnector, org.eclipse.papyrus.FCM.Connector.class);
- InteractionComponent fcmConnType = UMLUtil.getStereotypeApplication(smContainerConnImpl, InteractionComponent.class);
- fcmConn.setIc(fcmConnType);
-
- // pass target component and port to interceptor (not clean, define
- // suitable template signature as for instance in methodCall_comp
- Object[] args = new Object[]{ executorIS, port };
- TransformationContext.instance = executorIS;
- TransformationContext.port = port;
- connectorPart = ConnectorReification.reifyConnector(copy, tmContainerImpl, UMLTool.varName(interceptionConnector), interceptionConnector, executorIS, args);
- connectorParts.add(connectorPart);
- TransformationContext.port = null;
- // delete intermediate connector (has been replaced by two
- // connections to the reified connector)
- interceptionConnector.destroy();
}
- // Now create an instance specification for the reified connector
- InstanceSpecification reifiedConnectorIS = DepCreation.createDepPlan(tmCDP, (Class)connectorPart.getType(),
- containerIS.getName() + "." + interceptionName, false); //$NON-NLS-1$
- // configure connector
- context.port = port;
- InstanceConfigurator.configureInstance(reifiedConnectorIS, connectorPart, context);
-
- Slot partSlot = DepCreation.createSlot(containerIS, reifiedConnectorIS, connectorPart);
-
+ // interceptionConnector = tmContainerImpl.getOwnedConnector
+ // ("delegation " + port.getName ());
+ if(interceptionConnector == null) {
+ throw new TransformationException(Messages.ContainerTrafo_CannotFindDelegationConn);
+ }
- ConnectorReification.propagateNodeAllocation(tmComponent, executorIS, partSlot);
+ interceptionConnector.setName(interceptorName + port.getName() + counter);
+ org.eclipse.papyrus.FCM.Connector fcmConn = StereotypeUtil.applyApp(interceptionConnector, org.eclipse.papyrus.FCM.Connector.class);
+ InteractionComponent fcmConnType = UMLUtil.getStereotypeApplication(smContainerConnImpl, InteractionComponent.class);
+ fcmConn.setIc(fcmConnType);
+
+ // pass target component and port to interceptor (not clean, define
+ // suitable template signature as for instance in methodCall_comp
+ Object[] args = new Object[]{ executorIS, port };
+ TransformationContext.instance = executorIS;
+ TransformationContext.port = port;
+ connectorPart = ConnectorReification.reifyConnector(copy, tmContainerImpl, UMLTool.varName(interceptionConnector), interceptionConnector, executorIS, args);
+ connectorParts.add(connectorPart);
+ TransformationContext.port = null;
+ portInfo.put(connectorPart, port);
+ // delete intermediate connector (has been replaced by two
+ // connections to the reified connector)
+ interceptionConnector.destroy();
}
counter++;
return connectorParts;
@@ -475,12 +494,21 @@ public class ContainerTrafo extends AbstractContainerTrafo {
/**
* Move a slot from the executor instance specification to an instance
- * specification of an extension/interceptor This is required, since the
+ * specification of an extension/interceptor. This is required, since
* users cannot configure containers directly. The modification is done in
* the target model, i.e. the user model is not affected.
+ *
+ * Configuration is based on the idea that we can have multiple classifiers for an
+ * instance specification and that we add additional slots for attributes of the 2nd
+ * classifier which becomes "visible" after container transformation.
+ * Main use: configure priority of thread within container.
+ *
+ * TODO: Not clear, whether we should keep this operation, since configuration of elements that are not
+ * (directly) part of the user model is confusing. Application was: configuration
+ * of thread priorities within container.
*/
- public void moveSlots() {
- Log.log(Status.INFO, Log.TRAFO_CONTAINER, String.format(Messages.ContainerTrafo_InfoMoveSlots, executorIS.getQualifiedName()));
+ public void moveSlots(InstanceSpecification containerIS) {
+ // Log.log(Status.INFO, Log.TRAFO_CONTAINER, String.format(Messages.ContainerTrafo_InfoMoveSlots, executorIS.getQualifiedName()));
Classifier mainCl = DepUtils.getClassifier(executorIS);
Iterator<Slot> slotIt = executorIS.getSlots().iterator();
while(slotIt.hasNext()) {
@@ -546,27 +574,74 @@ public class ContainerTrafo extends AbstractContainerTrafo {
}
}
+ @Override
+ public void finalize() {
+ discoverServices();
+ }
+
+ /**
+ * Connector ports of executor with compatible ports offered by container extensions
+ * (runtime system)
+ */
+ public void discoverServices() {
+ Type executorType = executorPart.getType();
+ if (!(executorType instanceof EncapsulatedClassifier)) {
+ return;
+ }
+ EncapsulatedClassifier ec = (EncapsulatedClassifier) executorType;
+ for (Port executorPort : ec.getOwnedPorts()) {
+ for (Property svcPart : tmContainerImpl.getOwnedAttributes()) {
+ if (svcPart == executorPart) {
+ continue;
+ }
+ Type containerSvcType = svcPart.getType();
+ if (containerSvcType instanceof EncapsulatedClassifier) {
+ EncapsulatedClassifier containerSvc = (EncapsulatedClassifier) containerSvcType;
+ for (Port svcPort : containerSvc.getOwnedPorts()) {
+ if (PortUtils.matches(executorPort, svcPort, true)) {
+ // create connector
+ Connector c = tmContainerImpl.createOwnedConnector("auto"); //$NON-NLS-1$
+ ConnectorEnd ce1 = c.createEnd();
+ ConnectorEnd ce2 = c.createEnd();
+ ce1.setPartWithPort(executorPart);
+ ce1.setRole(executorPort);
+ ce2.setPartWithPort(svcPart);
+ ce2.setRole(svcPort);
+ }
+ }
+ }
+ }
+ }
+ }
+
/**
* The attribute within the container that holds the executor, i.e. the
* original component
*/
- private Property executorPart;
+ protected Property executorPart;
/**
* An instance specification of the executor in the target model (todo: should be source model instead?), i.e.
* of the component before container expansion
*/
- private InstanceSpecification executorIS;
+ protected InstanceSpecification executorIS;
/**
* The created container implementation (prefixed with tm, since part of
* target model)
*/
- private Class tmContainerImpl;
+ protected Class tmContainerImpl;
/**
* A counter which is used to manage unique names for interceptors (if
* multiple interceptors are applied)
*/
- private int counter;
+ protected int counter;
+
+ /**
+ * Store information about intercepted port. The map contains a mapping from the part representing
+ * a reified connector to the port that was intercepted. It is stored, since it might be used by instance
+ * configurators that configure the container instance.
+ */
+ protected Map<Property, Port> portInfo;
}

Back to the top