Skip to main content
summaryrefslogtreecommitdiffstats
blob: c43eb9f95b68d7973e66d507649f100b98b72e32 (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
/*******************************************************************************
 * Copyright (c) 2011 Mia-Software
 * 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:
 * 	   Emmanuelle Rouillé (Mia-Software) - Bug 352618 - To be able to use non derived facet structural features and save them values.
 *     Nicolas Bros (Mia-Software) - Bug 361612 - New core for new version of the Facet metamodel
 *     Grégoire Dupé (Mia-Software) - Bug 361612 - [Restructuring] New core for new version of the Facet metamodel
 *     Gregoire Dupe (Mia-Software) - Bug 375087 - [Table] ITableWidget.addColumn(List<ETypedElement>, List<FacetSet>)
 *     Gregoire Dupe (Mia-Software) - Bug 372626 - Aggregates
 *******************************************************************************/
package org.eclipse.emf.facet.efacet.core.internal;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.List;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.facet.efacet.core.internal.exception.UnmatchingExpectedTypeException;

public final class EmfUtils {
	
	private EmfUtils() {
		//Must not be used
	}

	public static void checkAssignment(final Object value, final ETypedElement eTypedElement)
			throws UnmatchingExpectedTypeException {
		final String typedElementName = getTypeElementDescription(eTypedElement);
		//Begin checking precondition
		if (eTypedElement.getEType() == null) {
			throw new IllegalArgumentException(typedElementName + " has a null type"); //$NON-NLS-1$
		}
		//End checking precondition
		if (value == null && (eTypedElement.getLowerBound() > 0)) {
			throw new IllegalArgumentException(
					"The assigned value cannot be null for " + typedElementName + " because multiplicity is " + eTypedElement.getLowerBound() + ".." + eTypedElement.getUpperBound()); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
		}
		if (value != null) {
			if (eTypedElement.getUpperBound() == 1) {
				if (!eTypedElement.getEType().isInstance(value)) {
					throw new IllegalArgumentException(
							"Type mismatch for " + EcoreUtil.getURI(eTypedElement) + ": expected '" + eTypedElement.getEType().getName() + "' but got '" + value.getClass().getName() + "'."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
				}
			} else { // expect a list for multiplicity-many
				if (!(value instanceof List<?>)) {
					throw new IllegalArgumentException("Type mismatch for " + typedElementName + "': expected a List because the parameter is multiplicity-many. But got a " + //$NON-NLS-1$ //$NON-NLS-2$
							value.getClass().getName() + "'."); //$NON-NLS-1$
				}
				final List<?> argumentList = (List<?>) value;
				try {
					CastUtils.checkTypeOfAllListElements(argumentList, eTypedElement.getEType().getInstanceClass());
					//FIXME What happens if we use a not generated meta-model ?
				} catch (UnmatchingExpectedTypeException e) {
					throw new UnmatchingExpectedTypeException(
							"Type mismatch for an element of the list value " + typedElementName , e); //$NON-NLS-1$
				}
			} 
		}
	}

	private static String getTypeElementDescription(final ETypedElement eTypedElement) {
		String containerName = ""; //$NON-NLS-1$
		if (eTypedElement.eContainer() instanceof ENamedElement) {
			final ENamedElement namedContainer = (ENamedElement) eTypedElement.eContainer();
			containerName = "the " + namedContainer.eClass().getName() + " named '" + namedContainer.getName() + "'"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
		}
		return "the " + eTypedElement.eClass().getName() + " named '" + eTypedElement.getName() + "' in " + containerName; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
	}

	public static Object ecoreInvoke(final EObject eObject, final EOperation operation, final Object... arguments) throws InvocationTargetException {
		// delegate to Ecore
		final BasicEList<Object> operationParams = new BasicEList<Object>();
		for (Object param : arguments) {
			operationParams.add(param);
		}
		return eObject.eInvoke(operation, operationParams);
	}

	public static <T> T checkAssignment(final EStructuralFeature eStructuralFeature, final Class<T> expectedType, final Object value)
			throws UnmatchingExpectedTypeException {
		if (eStructuralFeature.isMany() && expectedType != null) {
			if (expectedType != Object.class
					&& !Collection.class.isAssignableFrom(expectedType)) {
				throw new UnmatchingExpectedTypeException("The required eStructuralFeature is multi-valued, so expectedType must be a subtype of Collection."); //$NON-NLS-1$
			}
			if (!expectedType.isInstance(value)) {
				throw new UnmatchingExpectedTypeException("The derived typed element did not evaluate to the expected type", Collection.class, value); //$NON-NLS-1$
			}
		}
		return CastUtils.castToExpectedType(value, expectedType);
	}

}

Back to the top