Skip to main content
summaryrefslogtreecommitdiffstats
blob: 6ac8c84cdb5ff4c0cf723c868f5b64aab12281c7 (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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
/*******************************************************************************
 * Copyright (c) 2011, 2014 Mia-Software and others.
 * 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:
 *     Nicolas Bros (Mia-Software) - Bug 361612 - New core for new version of the Facet metamodel
 *     Nicolas Bros (Mia-Software) - Bug 361817 - [Restructuring] Dynamic load to the facet catalog
 *     Gregoire Dupe (Mia-Software) - Bug 369987 - [Restructuring][Table] Switch to the new customization and facet framework
 *     Nicolas Bros (Mia-Software) - Bug 371367 - Hierarchical FacetSets
 *     Gregoire Dupe (Mia-Software) - Bug 371367 - Hierarchical FacetSets
 *     Gregoire Dupe (Mia-Software) - Bug 364325 - [Restructuring] The user must be able to navigate into a model using the Facet.
 *     Gregoire Dupe (Mia-Software) - Bug 373510 - EditingDomain, ResourceSet, Catalogs, etc. have to be properly managed between editors and views
 *     Gregoire Dupe (Mia-Software) - Bug 373078 - API Cleaning
 *     Gregoire Dupe (Mia-Software) - Bug 374903 - [Table] ITableWidget.setLoadedFacetSets
 *     Gregoire Dupe (Mia-Software) - Bug 375087 - [Table] ITableWidget.addColumn(List<ETypedElement>, List<FacetSet>)
 *     Olivier Remaud (Soft-Maint) - Bug 361794 - [Restructuring] EMF Facet customization meta-model
 *     Gregoire Dupe (Mia-Software) - Bug 364325 - [Restructuring] The user must be able to navigate into a model using the Facet.
 *     Gregoire Dupe (Mia-Software) - Bug 361794 - [Restructuring] EMF Facet customization meta-model
 *     Gregoire Dupe (Mia-Software) - Bug 373078 - API Cleaning
 *     Gregoire Dupe (Mia-Software) - Bug 372626 - Aggregates
 *     Nicolas Bros (Mia-Software) - Bug 372626 - Aggregates
 *     Gregoire Dupe (Mia-Software) - Bug 376576 - [EFacet] Change the multiplicity of Facet::extendedFacet
 *     Vincent Lorenzo (CEA-LIST) - Bug 357621 - Improve the label displayed for Customization and Facets
 *     Grégoire Dupé (Mia-Software) - Bug 387470 - [EFacet][Custom] Editors
 *     Alban Ménager (Soft-Maint) - Bug 387470 - [EFacet][Custom] Editors
 *     Gregoire Dupe (Mia-Software) - Bug 377870 - [EFacet] ETypedElementDialog doesn't show all available ETypedElement (library example problem?)
 *     Grégoire Dupé (Mia-Software) - Bug 387470 - [EFacet][Custom] Editors
 *     Grégoire Dupé (Mia-Software) - Bug 391442 - Select ETypedElement Dialog doesn't used the subpackages (subEFacetSet)
 *     Sebastien Gabel (Esterel Technologies) - Bug 438931 - Non deterministic order of the facet references defined in custom file
 *
 *******************************************************************************/
package org.eclipse.papyrus.emf.facet.efacet.core;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.papyrus.emf.facet.efacet.core.exception.FacetManagerException;
import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.DerivedTypedElement;
import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.Facet;
import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.FacetOperation;
import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.FacetSet;
import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.runtime.ETypedElementEObjectListResult;
import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.runtime.ETypedElementEObjectResult;
import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.runtime.ETypedElementPrimitiveTypeListResult;
import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.runtime.ETypedElementPrimitiveTypeResult;
import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.runtime.ETypedElementResult;
import org.eclipse.papyrus.emf.facet.util.emf.core.ModelUtils;
import org.eclipse.papyrus.emf.facet.util.emf.core.internal.EMFUtils;

/**
 * @since 0.2
 */
public final class FacetUtils {

	private FacetUtils() {
		// static methods only
	}

	/**
	 * Find a Facet in a FacetSet
	 *
	 * @param facetSet
	 *            the FacetSet
	 * @param facetName
	 *            the name of the Facet to look for
	 * @return the Facet with the given name in the given FacetSet
	 */
	public static Facet getFacet(final FacetSet facetSet, final String facetName) {
		Facet result = null;
		final List<Facet> facets = FacetUtils.getFacets(facetSet);
		for (Facet facet : facets) {
			if (facetName.equals(facet.getName())) {
				result = facet;
				break;
			}
		}
		return result;
	}

	public static <T extends ETypedElement> T getETypedElement(
			final Facet facet, final String name, final Class<T> classs) {
		T result = null;
		final List<ETypedElement> eTypedElements = new ArrayList<ETypedElement>();
		eTypedElements.addAll(facet.getFacetElements());
		eTypedElements.addAll(facet.getFacetOperations());
		for (ETypedElement eTypedElement : eTypedElements) {
			if (name.equals(eTypedElement.getName())
					&& classs.isInstance(eTypedElement)) {
				@SuppressWarnings("unchecked")
				// @SuppressWarnings("unchecked") This assignment is check by
				// the call 'classs.isInstance(structuralFeature)'
				final T castResult = (T) eTypedElement;
				result = castResult;
				break;
			}
		}
		return result;
	}

	public static Object getResultValue(final ETypedElementResult eTEresult) {
		Object result = null;
		if (eTEresult instanceof ETypedElementEObjectListResult<?>) {
			final ETypedElementEObjectListResult<?> eObjectList = (ETypedElementEObjectListResult<?>) eTEresult;
			result = eObjectList.getResultList();
		} else if (eTEresult instanceof ETypedElementEObjectResult<?>) {
			final ETypedElementEObjectResult<?> eObjectRef = (ETypedElementEObjectResult<?>) eTEresult;
			result = eObjectRef.getResult();
		} else if (eTEresult instanceof ETypedElementPrimitiveTypeListResult<?>) {
			final ETypedElementPrimitiveTypeListResult<?> objectList = (ETypedElementPrimitiveTypeListResult<?>) eTEresult;
			result = objectList.getDerivedTypedElement();
		} else if (eTEresult instanceof ETypedElementPrimitiveTypeResult<?>) {
			final ETypedElementPrimitiveTypeResult<?> objectRef = (ETypedElementPrimitiveTypeResult<?>) eTEresult;
			result = objectRef.getResult();
		} else {
			throw new IllegalStateException(
					"Unknown ETypedElementResult type: " + eTEresult.getClass()); //$NON-NLS-1$
		}
		return result;
	}

	/**
	 * Find a FacetSet with the given name among the given list of FacetSets. If several FacetSets have the same name,
	 * then return the first one.
	 *
	 * @param facetSets
	 *            where to look for
	 * @param name
	 *            the name of the FacetSet to find
	 * @return the FacetSet, or <code>null</code> if not found in the given list
	 */
	public static FacetSet getFacetSet(final Collection<FacetSet> facetSets, final String name) {
		FacetSet result = null;
		for (FacetSet facetSet : facetSets) {
			if (name.equals(facetSet.getName())) {
				result = facetSet;
			}
		}
		return result;
	}

	/**
	 * Find all FacetSets with the given name among the given list of FacetSets.
	 *
	 * @param facetSets
	 *            where to look for
	 * @param name
	 *            the name of the FacetSets to find
	 * @return the FacetSets with the given name
	 */
	public static List<FacetSet> getFacetSets(
			final Collection<FacetSet> facetSets, final String name) {
		final List<FacetSet> result = new ArrayList<FacetSet>();
		for (FacetSet facetSet : facetSets) {
			if (name.equals(facetSet.getName())) {
				result.add(facetSet);
			}
		}
		return result;
	}

	/**
	 *
	 * @param facetSet
	 *            a facetSet
	 * @return a set with all the EPackage extended by the facetSet and its
	 *         owned facetSet
	 * @since 0.2
	 */
	public static Set<EPackage> getAllExtendedEPackage(final FacetSet facetSet) {
		final Set<EPackage> extendedEPackages = new HashSet<EPackage>();
		final EPackage res1 = getExtendedEPackage(facetSet);
		if (res1 != null) {
			extendedEPackages.add(res1);
		}
		for (FacetSet current : facetSet.getFacetSets()) {
			extendedEPackages.addAll(getAllExtendedEPackage(current));
		}
		final EList<EPackage> pack = facetSet.getESubpackages();
		for (EPackage current : pack) {
			if (current instanceof FacetSet) {
				extendedEPackages
						.addAll(getAllExtendedEPackage((FacetSet) current));
			}
		}
		return extendedEPackages;
	}

	/**
	 * Find all the FacetSets with the given path among the given list of root
	 * FacetSets. For example: <code>getFacetSetsByPath("a", "b", "c")</code> returns a FacetSet named "c", contained in a FacetSet named "b",
	 * contained in a registered FacetSet named "a".
	 *
	 * @param path
	 *            a list of FacetSet names, starting from the root registered
	 *            FacetSets, and leading to the wanted FacetSet(s)
	 * @return the FacetSets that have the given path
	 */
	public static List<FacetSet> getFacetSetsByPath(
			final Collection<FacetSet> rootFacetSets, final String... path) {
		if (path.length == 0) {
			throw new IllegalArgumentException("The given path cannot be empty"); //$NON-NLS-1$
		}
		List<FacetSet> facetSets = new ArrayList<FacetSet>(rootFacetSets);
		for (int i = 0; i < path.length; i++) {
			if (i > 0) {
				facetSets = getSubFacetSets(facetSets);
			}
			final String name = path[i];
			facetSets = getFacetSets(facetSets, name);
			if (facetSets.isEmpty()) {
				break;
			}

		}
		return facetSets;
	}

	private static List<FacetSet> getSubFacetSets(
			final Collection<FacetSet> parents) {
		final List<FacetSet> subFacetSets = new ArrayList<FacetSet>();
		for (FacetSet facetSet : parents) {
			final EList<EPackage> eSubpackages = facetSet.getESubpackages();
			for (EPackage ePackage : eSubpackages) {
				if (ePackage instanceof FacetSet) {
					final FacetSet subFacetSet = (FacetSet) ePackage;
					subFacetSets.add(subFacetSet);
				}
			}
		}
		return subFacetSets;
	}

	/**
	 * Find a Facet with the given name among the given list of Facets.
	 *
	 * @param facets
	 *            where to look
	 * @param name
	 *            the name of the Facet that is being looked for
	 * @return the first {@link Facet} with this name, or <code>null</code> if
	 *         none
	 */
	public static Facet getFacet(final Collection<Facet> facets,
			final String name) {
		Facet result = null;
		for (Facet facet : facets) {
			if (name.equals(facet.getName())) {
				result = facet;
			}
		}
		return result;
	}

	public static FacetSet getRootFacetSet(final Facet facet) {
		FacetSet result = (FacetSet) facet.eContainer();
		while (result != null && result.eContainer() instanceof FacetSet) {
			result = (FacetSet) result.eContainer();
		}
		return result;
	}

	public static FacetSet getRootFacetSet(final FacetSet facetSet) {
		FacetSet result = facetSet;
		while (result != null && result.eContainer() instanceof FacetSet) {
			result = (FacetSet) result.eContainer();
		}
		return result;
	}

	public static List<Facet> getFacets(final FacetSet facetSet) {
		final List<Facet> result = new ArrayList<Facet>();
		for (EClassifier eClassifier : facetSet.getEClassifiers()) {
			if (eClassifier instanceof Facet) {
				final Facet facet = (Facet) eClassifier;
				result.add(facet);
			}
		}
		return result;
	}

	public static FacetSet getFacetSet(final Facet facet) {
		FacetSet result = null;
		if (facet.getEPackage() instanceof FacetSet) {
			result = (FacetSet) facet.getEPackage();
		}
		return result;
	}

	// Moved from
	// org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.impl.FacetSetImpl
	public static EPackage getExtendedEPackage(final FacetSet facetSet) {
		final List<Facet> facets = FacetUtils.getFacets(facetSet);
		EPackage result = null;
		for (Facet facet : facets) {
			final EClass extendedMetaclass = facet.getExtendedMetaclass();
			if (extendedMetaclass != null) {
				final EPackage ePackage = extendedMetaclass.getEPackage();
				if (ePackage != null) {
					if (result != null && !ePackage.equals(result)) {
						throw new IllegalStateException("The Facets in a FacetSet must all extend EClasses from the same EPackage"); //$NON-NLS-1$
					}
					result = ePackage;
				}
			}
		}
		return result;
	}

	// Copied (and refactored) from
	// org.eclipse.papyrus.emf.facet.efacet.core.internal.FacetManager
	public static <T extends ETypedElement> List<T> getETypedElements(
			final EObject eObject, final Class<T> classs,
			final IFacetManager facetManager) throws FacetManagerException {
		return facetManager.getETypedElements(eObject, classs);
	}

	/**
	 * @param eTypedElement
	 * @return
	 * @since 0.2
	 */
	public static FacetSet getFacetSet(final ETypedElement eTypedElement) {
		FacetSet result = null;
		if (eTypedElement.eContainer() instanceof Facet) {
			final Facet facet = (Facet) eTypedElement.eContainer();
			if (facet.eContainer() instanceof FacetSet) {
				result = (FacetSet) facet.eContainer();
			}
		}
		return result;
	}

	/**
	 *
	 * @param facetOperation
	 * @return
	 * @since 0.2
	 */
	public static DerivedTypedElement getSignature(
			final FacetOperation facetOperation) {
		DerivedTypedElement current = facetOperation;
		while (current.getOverride() != null) {
			current = current.getOverride();
		}
		return current;
	}

	/**
	 *
	 * @param facet
	 * @return
	 * @since 0.2
	 */
	public static EClass getExtendedMetaclass(final Facet facet) {
		EClass result = facet.getExtendedMetaclass();
		if (result == null) {
			final List<EClass> eClasses = new ArrayList<EClass>();
			for (Facet extfacet : facet.getExtendedFacets()) {
				eClasses.add(getExtendedMetaclass(extfacet));
			}
			result = EMFUtils.computeLeastCommonSupertype(eClasses);
		}
		return result;
	}

	/**
	 * Find the top level feature in the override chain
	 *
	 * @param feature
	 * @return The top level feature in the override chain or the feature
	 *         parameter itself if no override
	 * @throws FacetManagerException
	 * @since 0.2
	 *
	 */
	// Copied from
	// org.eclipse.papyrus.emf.facet.efacet.core.internal.FacetManagerContext
	// * Contributors:
	// * Olivier Remaud (Soft-Maint) - Bug 361794 - [Restructuring] EMF Facet
	// customization meta-model
	// * Gregoire Dupe (Mia-Software) - Bug 364325 - [Restructuring] The user
	// must be able to navigate into a model using the Facet.
	// * Gregoire Dupe (Mia-Software) - Bug 361794 - [Restructuring] EMF Facet
	// customization meta-model
	// * Gregoire Dupe (Mia-Software) - Bug 373078 - API Cleaning
	@SuppressWarnings("unchecked")
	// @SuppressWarnings("unchecked") cf. comment in the method body
	public static <T extends DerivedTypedElement> T getTopOverrideFeature(
			final T feature) throws FacetManagerException {
		T signatureFeature = feature;
		while (signatureFeature.getOverride() != null) {
			if (feature.getClass().isInstance(signatureFeature.getOverride())) {
				// @SuppressWarnings("unchecked") the if test check the
				// assignment using the method 'isInstance'
				signatureFeature = (T) signatureFeature.getOverride();
			} else {
				// signature feature type name
				final String sfTypeName = signatureFeature.eClass().getName();
				// signature feature name
				final String sfName = ModelUtils
						.getQualifiedName(signatureFeature);
				final String ofName = signatureFeature.getOverride().eClass()
						.getName(); // overridden feature type name
				throw new FacetManagerException("The " + sfTypeName + " '" //$NON-NLS-1$ //$NON-NLS-2$
						+ sfName + "' overides a " + ofName); //$NON-NLS-1$
			}
		}
		return signatureFeature;
	}

	/**
	 * @since 0.3
	 */
	public static EClass findExtendedEClass(final Facet facet) {
		EClass result = facet.getExtendedMetaclass();
		if (result == null) {
			for (Facet extFacet : facet.getExtendedFacets()) {
				result = findExtendedEClass(extFacet);
				if (result != null) {
					break;
				}
			}
		}
		return result;
	}

	/**
	 * @since 0.3
	 */
	public static DerivedTypedElement getContainingDerivedTypedElement(
			final EObject eObject) {
		DerivedTypedElement dte = null;
		if (eObject instanceof DerivedTypedElement) {
			dte = (DerivedTypedElement) eObject;
		} else if (eObject != null) {
			dte = getContainingDerivedTypedElement(eObject.eContainer());
		}
		return dte;
	}

	/**
	 * Return the main facetSet.
	 *
	 * @param eObject
	 *            the element in the model selected.
	 * @return the main facetSet.
	 * @since 0.3
	 */
	public static FacetSet getContainingFacetSet(final EObject eObject) {
		FacetSet result = null;
		if (eObject instanceof FacetSet) {
			result = (FacetSet) eObject;
		} else {
			final EObject container = eObject.eContainer();
			if (container != null) {
				result = getContainingFacetSet(container);
			}
		}
		return result;
	}

	/**
	 * Return all the operations of the model.
	 *
	 * @param parent
	 *            the first FacetSet of the model.
	 * @return the list of operations.
	 * @since 0.3
	 */
	public static Map<String, FacetOperation> getAllOperationsByName(
			final FacetSet parent) {
		final Map<String, FacetOperation> operations = new HashMap<String, FacetOperation>();
		for (final EClassifier facet : parent.getEClassifiers()) {
			for (final FacetOperation operation : ((Facet) facet)
					.getFacetOperations()) {
				operations.put(operation.getName(), operation);
			}
		}
		for (final EPackage element : parent.getESubpackages()) {
			operations.putAll(getAllOperationsByName((FacetSet) element));
		}
		return operations;
	}

	/**
	 * Return all the facets of the model.
	 *
	 * @param parent
	 *            the first FacetSet of the model.
	 * @return the list of facets.
	 * @since 0.3
	 */
	public static Map<String, Facet> getAllFacetsByName(final FacetSet parent) {
		final Map<String, Facet> facets = new HashMap<String, Facet>();
		for (final EClassifier facet : parent.getEClassifiers()) {
			facets.put(facet.getName(), (Facet) facet);
		}
		for (final EPackage element : parent.getESubpackages()) {
			facets.putAll(getAllFacetsByName((FacetSet) element));
		}

		return facets;
	}

	/**
	 * Return all the facets of the model.
	 *
	 * @param parent
	 *            the first FacetSet of the model.
	 * @return the list of facets.
	 * @since 0.3
	 */
	public static Map<String, FacetSet> getAllFacetSetsByName(
			final EPackage parent) {
		final Map<String, FacetSet> facetSets = new HashMap<String, FacetSet>();
		if (parent instanceof FacetSet) {
			final FacetSet facetSet = (FacetSet) parent;
			facetSets.put(parent.getName(), facetSet);
		}
		for (final EPackage element : parent.getESubpackages()) {
			facetSets.putAll(getAllFacetSetsByName(element));
		}
		return facetSets;
	}

	/**
	 * @since 0.3
	 */
	public static List<Facet> getAllFacet(final FacetSet facetSet) {
		final List<Facet> result = new ArrayList<Facet>();
		for (EClassifier eClassifier : facetSet.getEClassifiers()) {
			if (eClassifier instanceof Facet) {
				final Facet facet = (Facet) eClassifier;
				result.add(facet);
			}
		}
		for (EPackage ePackage : facetSet.getESubpackages()) {
			if (ePackage instanceof FacetSet) {
				final FacetSet subFacetSet = (FacetSet) ePackage;
				result.addAll(getAllFacet(subFacetSet));
			}
		}
		return result;
	}

}

Back to the top