Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 1a138465cb190de28458a319329c9788d215bdd7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*****************************************************************************
 * 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.qompass.designer.core.templates;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.papyrus.C_Cpp.ConstInit;
import org.eclipse.papyrus.qompass.designer.core.Messages;
import org.eclipse.papyrus.qompass.designer.core.PortUtils;
import org.eclipse.papyrus.qompass.designer.core.StUtils;
import org.eclipse.papyrus.qompass.designer.core.transformations.LazyCopier;
import org.eclipse.papyrus.qompass.designer.core.transformations.TransformationContext;
import org.eclipse.papyrus.qompass.designer.core.transformations.TransformationException;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.OpaqueBehavior;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Parameter;
import org.eclipse.uml2.uml.Port;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.util.UMLUtil;

public class BindingUtils {

	/**
	 * Bind an operation by copying the signature from the actual.
	 *
	 * @param copy
	 *            the copier
	 * @param actual
	 *            the actual. If an operation, its signature is copied to the template
	 * @param operation
	 *            The operation template
	 * @return
	 */
	public static Operation instantiateOperation(LazyCopier copy, Element actual, Operation operation) {
		try {
			Operation newOperation = copy.getCopy(operation);
			if (actual instanceof Operation) {
				for (Parameter parameter : ((Operation) actual).getOwnedParameters()) {
					Parameter newParam = EcoreUtil.copy(parameter); // copy parameter via EcoreUtil
					newParam.setType(copy.getCopy(parameter.getType()));
					newOperation.getOwnedParameters().add(newParam);
					StUtils.copyStereotypes(parameter, newParam); // copy stereotypes of the parameter
				}
			}
			TransformationContext.classifier = newOperation.getClass_();
			if (actual instanceof Classifier) {
				bindOperation(newOperation, (Classifier) actual);
			}
			String newName = TextTemplateBinding.bind(operation.getName(), actual, null);
			newOperation.setName(newName);

			return newOperation;
		} catch (TransformationException e) {
			// throw runtime exception
			throw new RuntimeException(String.format(Messages.TemplateInstantiationListener_TrafoException, e.getMessage()));
		}
	}

	/**
	 * Instantiate a behavior
	 *
	 * @param copy
	 *            copier
	 * @param actual
	 *            actual in template instantiation
	 * @param opaqueBehavior
	 *            behavior with body in form of an Acceleo template.
	 * @return instantiated (bound) behavior.
	 * @throws TransformationException
	 */
	public static OpaqueBehavior instantiateBehavior(LazyCopier copy, Element actual, OpaqueBehavior opaqueBehavior) throws TransformationException {
		OpaqueBehavior newBehavior = copy.getCopy(opaqueBehavior);
		if (actual instanceof NamedElement) {
			String newName = TextTemplateBinding.bind(opaqueBehavior.getName(), actual, null);
			newBehavior.setName(newName);
		}
		EList<String> bodyList = newBehavior.getBodies();
		for (int i = 0; i < bodyList.size(); i++) {
			String body = bodyList.get(i);
			TransformationContext.classifier = (Classifier) newBehavior.getOwner();
			// pass qualified operation name as template name. Used to identify script in case of an error
			String newBody = TextTemplateBinding.bind(body, actual);
			bodyList.set(i, newBody);
		}
		return newBehavior;
	}



	/**
	 * Bind C++ const initializer
	 *
	 * @param operation
	 * @param actual
	 * @throws TransformationException
	 */
	public static void bindOperation(Operation operation, Classifier actual) throws TransformationException {
		// perform binding in case of C++ initializer
		ConstInit cppConstInit = UMLUtil.getStereotypeApplication(operation, ConstInit.class);
		if (cppConstInit != null) {
			// TODO: specific to C++
			String init = cppConstInit.getInitialisation();
			String newInit = TextTemplateBinding.bind(init, actual);
			cppConstInit.setInitialisation(newInit);
		}
	}

	/**
	 * @param actual
	 *            the actual template parameter
	 * @param boundClass
	 *            the bound class
	 * @param provides
	 *            true, if the provided interface should be returned
	 * @return the provided or required interface of a port (of the passed
	 *         boundClass) that is typed with the the actual.
	 */
	public static Interface getInterfaceFromPortTypedWithActual(Type actual, Class boundClass, boolean provided) {
		for (Port port : PortUtils.getAllPorts(boundClass)) {
			Interface provOrReqIntf;
			if (provided) {
				provOrReqIntf = PortUtils.getProvided(port);
			} else {
				provOrReqIntf = PortUtils.getRequired(port);
			}

			if ((port.getType() == actual) && (provOrReqIntf != null)) {
				return provOrReqIntf;
			}
		}
		return null;
	}
}

Back to the top