blob: fda567579076a335d9755c02d68f4b8095f04f6d [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2013 CEA LIST.
*
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ansgar Radermacher ansgar.radermacher@cea.fr
*
*****************************************************************************/
package org.eclipse.papyrus.designer.components.modellibs.core.mappingrules;
import org.eclipse.papyrus.FCM.util.IMappingRule;
import org.eclipse.papyrus.FCM.util.MapUtil;
import org.eclipse.papyrus.designer.components.transformation.core.OperationUtils;
import org.eclipse.papyrus.designer.components.transformation.core.PortUtils;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.InstanceSpecification;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Port;
import org.eclipse.uml2.uml.Type;
/**
* An extended Port in the sense of the DDS4CCM standard: a port typed with a component
* type. Since the component typing the port can have multiple provided and required
* ports, the ports are implicitly owned by the port. Conjugation on the level of an extended
* port level will conjugate all ports of the component typing the port.
*
* The derived interface that is provided will concatenate provided port names within the
* extended port with the port name and provided a "big" interface.
* The derived interface that is required is identical, except for a conjugation on the
* extended port level.
*
* Creates a fixed template binding that binds T (of the extended Port) to the used data type
*
* Here, the idea is that the port type is a classifier, e.g. the data type that is
* transported by a DDS port. The port kind is the extended port, e.g. DDSWrite.
*
* The derived property isExtended of FCM port-kind is true, if the class representing the port-kind owns at least one
* port
*
* @author ansgar
*
*/
public class ExtendedPort implements IMappingRule {
public Interface getProvided(org.eclipse.papyrus.FCM.Port p, InstanceSpecification config, boolean update)
{
return getDerived(p, false, config, update);
}
public Interface getRequired(org.eclipse.papyrus.FCM.Port p, InstanceSpecification config, boolean update)
{
return getDerived(p, true, config, update);
}
public Interface getDerived(org.eclipse.papyrus.FCM.Port extPort, boolean isRequired, InstanceSpecification config, boolean update)
{
Type type = extPort.getBase_Port().getType();
if(!(type instanceof Classifier)) {
return null;
}
Class extendedPort = extPort.getKind().getBase_Class();
String prefix = extendedPort.getName() + "_" + (isRequired ? "R_" : "P_");
Interface derivedInterface = MapUtil.getOrCreateDerivedInterfaceFP(extPort, prefix, type, update);
if (!update) {
return derivedInterface;
}
if(derivedInterface == null) {
return null;
}
/*
TemplateSignature signature = TemplateUtils.getSignature(type.getNearestPackage());
if(signature != null) {
Package model = Utils.getTop(derivedInterface);
try {
TemplateBinding binding =
TemplateUtils.fixedBinding(model, extendedPort, (Classifier)type);
Copy copy = new Copy(model, model, false);
TemplateInstantiation ti = new TemplateInstantiation(copy, binding);
// create a bound element of the extended port. Add bound class to derived interface class
Class boundClass = ti.bindNamedElement(extendedPort);
derivedInterface.getNearestPackage().getPackagedElements().add(boundClass);
} catch (TransformationException e) {
return null;
}
}
*/
// obtain first template parameter = port type
// kind.getBase_Class().getNearestPackage().getTemplateParameter();
for(Port port : extendedPort.getOwnedPorts()) {
Interface derivedIntf = (isRequired) ?
PortUtils.getRequired(port) :
PortUtils.getProvided(port);
if(derivedIntf != null) {
for(Operation op : derivedIntf.getAllOperations()) {
String name = port.getName() + "_" + op.getName(); //$NON-NLS-1$
// check whether operation already exists. Create, if not
Operation derivedOperation = derivedInterface.getOperation(name, null, null);
if(derivedOperation == null) {
derivedOperation = derivedInterface.createOwnedOperation(name, null, null);
OperationUtils.syncOperation(op, derivedOperation);
derivedOperation.setName(name);
}
else {
if (!OperationUtils.isSameOperation(derivedOperation, op, false)) {
OperationUtils.syncOperation(op, derivedOperation);
derivedOperation.setName(name);
}
}
}
}
}
return derivedInterface;
}
}