Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: e9f705584c534e197fd4c823043ba6d643f52fc8 (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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/*****************************************************************************
 * Copyright (c) 2012 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:
 *  CEA LIST - Initial API and implementation
 *
 *****************************************************************************/
package org.eclipse.papyrus.moka.fuml.Semantics.Loci.LociL1;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.papyrus.moka.fuml.Activator;
import org.eclipse.papyrus.moka.fuml.debug.Debug;
import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.Evaluation;
import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.Object_;
import org.eclipse.papyrus.moka.fuml.Semantics.CommonBehaviors.BasicBehaviors.Execution;
import org.eclipse.papyrus.moka.fuml.Semantics.CommonBehaviors.BasicBehaviors.OpaqueBehaviorExecution;
import org.eclipse.uml2.uml.Behavior;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.OpaqueBehavior;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.ValueSpecification;

public abstract class ExecutionFactory implements Cloneable {

	/*
	 * The locus at which this factory resides.
	 */
	public Locus locus;

	public Locus getLocus() {
		return locus;
	}

	public void setLocus(Locus locus) {
		this.locus = locus;
	}

	/*
	 * The set of opaque behavior executions to be used to execute the primitive
	 * behaviors known to the factory.
	 */
	public List<OpaqueBehaviorExecution> primitiveBehaviorPrototypes;

	/*
	 * The set of primitive types that have corresponding literal value
	 * specifications. Must include Integer, Boolean, String and
	 * UnlimitedNatural.
	 */
	// FIXME: Sounds better to have a list of Type because built in types can only be classes
	// public List<PrimitiveType> builtInTypes = new ArrayList<PrimitiveType>();

	public List<Type> builtInTypes;

	/*
	 * The set of semantic strategies currently registered with this execution
	 * factory.
	 */
	public List<SemanticStrategy> strategies;

	public ExecutionFactory() {
		super();
		this.builtInTypes = new ArrayList<Type>();
		this.strategies = new ArrayList<SemanticStrategy>();
		this.primitiveBehaviorPrototypes = new ArrayList<OpaqueBehaviorExecution>();
	}

	public Execution createExecution(Behavior behavior, Object_ context) {
		// Create an execution object for a given behavior.
		// The execution will take place at the locus of the factory in the
		// given context.
		// If the context is empty, the execution is assumed to provide its own
		// context.
		Execution execution;
		if (behavior instanceof OpaqueBehavior) {
			execution = this.instantiateOpaqueBehaviorExecution((OpaqueBehavior) behavior);
		} else {
			execution = (Execution) this.instantiateVisitor(behavior);
			execution.types.add(behavior);
			execution.createFeatureValues();
		}
		this.locus.add(execution);
		if (context == null) {
			execution.context = execution;
		} else {
			execution.context = context;
		}
		return execution;
	}

	public Evaluation createEvaluation(ValueSpecification specification) {
		// Create an evaluation object for a given value specification.
		// The evaluation will take place at the locus of the factory.
		Evaluation evaluation = (Evaluation) this.instantiateVisitor(specification);
		evaluation.specification = specification;
		evaluation.locus = this.locus;
		return evaluation;
	}

	public abstract SemanticVisitor instantiateVisitor(Element element);

	public OpaqueBehaviorExecution instantiateOpaqueBehaviorExecution(OpaqueBehavior behavior) {
		// Return a copy of the prototype for the primitive behavior execution
		// of the given opaque behavior.
		OpaqueBehaviorExecution execution = null;
		int i = 1;
		while (execution == null & i <= this.primitiveBehaviorPrototypes.size()) {
			// Debug.println("[instantiateOpaqueExecution] Checking " +
			// this.primitiveBehaviorPrototypes.get(i).objectId() + "...");
			OpaqueBehaviorExecution prototype = this.primitiveBehaviorPrototypes.get(i - 1);
			if (prototype.getBehavior() == behavior) {
				execution = (OpaqueBehaviorExecution) (prototype.copy());
			}
			i = i + 1;
		}
		if (execution == null) {
			Debug.println("[instantiateOpaqueExecution] No prototype execution found for " + behavior.getName() + ".");
		}
		return execution;
	}

	public void addPrimitiveBehaviorPrototype(OpaqueBehaviorExecution execution) {
		// Add an opaque behavior execution to use as a prototype for
		// instantiating the corresponding primitive opaque behavior.
		// Precondition: No primitive behavior prototype for the type of the
		// given execution should already exist.
		this.primitiveBehaviorPrototypes.add(execution);
	}

	/*
	 * public void addBuiltInType(PrimitiveType type) {
	 * // Add the given primitive type as a built-in type.
	 * // Precondition: No built-in type with the same name should already
	 * // exist.
	 * this.builtInTypes.add(type);
	 * }
	 */

	public void addBuiltInType(Type type) {
		this.builtInTypes.add(type);
	}

	/*
	 * public PrimitiveType getBuiltInType(String name) {
	 * // Return the built-in type with the given name.
	 * PrimitiveType type = null;
	 * int i = 1;
	 * while(type == null & i <= this.builtInTypes.size()) {
	 * PrimitiveType primitiveType = this.builtInTypes.get(i - 1);
	 * if(primitiveType.getName().equals(name)) {
	 * type = primitiveType;
	 * }
	 * i = i + 1;
	 * }
	 * return type;
	 * }
	 */

	public Type getBuiltInType(String name) {
		// Return the built-in type with the given name.
		Type type = null;
		int i = 1;
		while (type == null & i <= this.builtInTypes.size()) {
			Type currentType = this.builtInTypes.get(i - 1);
			if (currentType.getName().equals(name)) {
				type = currentType;
			}
			i = i + 1;
		}
		return type;
	}

	public void setStrategy(SemanticStrategy strategy) {
		// Set the strategy for a semantic variation point. Any existing
		// strategy for the same SVP is replaced.
		int i = this.getStrategyIndex(strategy.getName());
		if (i <= this.strategies.size()) {
			this.strategies.remove(i - 1);
		}
		this.strategies.add(strategy);
	}

	public SemanticStrategy getStrategy(String name) {
		// Get the strategy with the given name.
		int i = this.getStrategyIndex(name);
		SemanticStrategy strategy = null;
		if (i <= this.strategies.size()) {
			strategy = this.strategies.get(i - 1);
		}
		return strategy;
	}

	public Integer getStrategyIndex(String name) {
		// Get the index of the strategy with the given name.
		// If there is no such strategy, return the size of the strategies list.
		List<SemanticStrategy> strategies = this.strategies;
		int i = 1;
		boolean unmatched = true;
		while (unmatched & (i <= strategies.size())) {
			if (strategies.get(i - 1).getName().equals(name)) {
				unmatched = false;
			} else {
				i = i + 1;
			}
		}
		return i;
	}

	@Override
	public ExecutionFactory clone() {
		ExecutionFactory clone = null;
		try {
			clone = (ExecutionFactory) super.clone();
		} catch (CloneNotSupportedException e) {
			Activator.log.error(e);
		}
		return clone;
	}
}

Back to the top