blob: b0a3191686c90a61b408329b291a847a1cbe60d1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2016 Mia-Software, and Soft-Maint.
* 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
* Jonathan Pepin (Soft-Maint) - Bug 510034 - Null value is wrongly casted in a new list
*******************************************************************************/
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(), true);
//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);
}
}