/** | |
* Copyright (c) 2011, 2012, 2013, 2014 Mia-Software. | |
* | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v2.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v20.html | |
* | |
* Contributors: | |
* Gregoire Dupe (Mia-Software) - Bug 333553 - The user has not to deal with two files to create a facet | |
* 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 | |
* Nicolas Bros (Mia-Software) - Bug 362191 - [Restructuring] Query mechanism for eFacet2 | |
* Gregoire Dupe (Mia-Software) - Bug 369987 - [Restructuring][Table] Switch to the new customization and facet framework | |
* 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 373078 - API Cleaning | |
* Nicolas Bros (Mia-Software) - Bug 376941 - [EFacet] Facet operation arguments in Facet model | |
* Alban MĂ©nager (Soft-Maint) - Bug 387470 - [EFacet][Custom] Editors | |
* Gregoire Dupe (Mia-Software) - Bug 418885 - ETypedElementSwitchQuery implemented using a deprecated query evaluator extension point | |
* Gregoire Dupe (Mia-Software) - Bug 441570 - Children custom property | |
*/ | |
package org.eclipse.modisco.facet.efacet.core.internal; | |
import java.util.Collection; | |
import java.util.LinkedList; | |
import java.util.List; | |
import org.eclipse.emf.ecore.EClass; | |
import org.eclipse.emf.ecore.EClassifier; | |
import org.eclipse.emf.ecore.EDataType; | |
import org.eclipse.emf.ecore.EObject; | |
import org.eclipse.modisco.facet.efacet.core.IDerivedTypedElementManager; | |
import org.eclipse.modisco.facet.efacet.core.IFacetManager; | |
import org.eclipse.modisco.facet.efacet.core.exception.DerivedTypedElementException; | |
import org.eclipse.modisco.facet.efacet.core.internal.exception.DerivedTypedElementEvaluationException; | |
import org.eclipse.modisco.facet.efacet.core.internal.exception.DerivedTypedElementTypeCheckingException; | |
import org.eclipse.modisco.facet.efacet.core.internal.exception.UnmatchingExpectedTypeException; | |
import org.eclipse.modisco.facet.efacet.core.internal.query.QueryImplementationFactoryRegistry; | |
import org.eclipse.modisco.facet.efacet.core.internal.query.QueryUtils; | |
import org.eclipse.modisco.facet.efacet.core.query.IQueryImplementation; | |
import org.eclipse.modisco.facet.efacet.metamodel.v0_2_0.efacet.DerivedTypedElement; | |
import org.eclipse.modisco.facet.efacet.metamodel.v0_2_0.efacet.ParameterValue; | |
import org.eclipse.modisco.facet.efacet.metamodel.v0_2_0.efacet.extensible.Query; | |
import org.eclipse.modisco.facet.efacet.metamodel.v0_2_0.efacet.runtime.ETypedElementResult; | |
import org.eclipse.modisco.facet.util.core.Logger; | |
public class DerivedTypedElementManager implements IDerivedTypedElementManager { | |
private static final boolean SET_AS_LIST = Boolean.getBoolean(DerivedTypedElementManager.class.getName() + ".setAsList"); //$NON-NLS-1$ | |
public Object evaluate(final DerivedTypedElement derivedTypedElement, | |
final EObject source, final List<ParameterValue> parameterValues, | |
final IFacetManager facetManager) | |
throws DerivedTypedElementException { | |
Object result; | |
if (derivedTypedElement.isMany()) { | |
result = evaluateMultiValued(derivedTypedElement, source, parameterValues, null, facetManager); | |
} else { | |
result = evaluateSingleValued(derivedTypedElement, source, parameterValues, null, facetManager); | |
} | |
return result; | |
} | |
public Object evaluate(final Query query, final EObject source, final List<ParameterValue> parameterValues, final IFacetManager facetManager) | |
throws DerivedTypedElementException { | |
final IQueryImplementation evaluator = QueryImplementationFactoryRegistry.INSTANCE.getEvaluatorFor(query, this); | |
final DerivedTypedElement derivedTE = QueryUtils.getOwningDerivedTypedElement(query); | |
Object result; | |
try { | |
result = evaluator.getValue(query, derivedTE, source, parameterValues, facetManager); | |
} catch (Exception e) { | |
throw new DerivedTypedElementEvaluationException(e); | |
} | |
return result; | |
} | |
public <T> T evaluateSingleValued(final DerivedTypedElement derivedTypedElement, | |
final EObject source, final List<ParameterValue> parameterValues, final Class<T> expectedType, final IFacetManager facetManager) | |
throws DerivedTypedElementException { | |
if (derivedTypedElement.isMany()) { | |
throw new IllegalArgumentException("This method doesn't accept a multi-valued derived typed element."); //$NON-NLS-1$ | |
} | |
Query query = derivedTypedElement.getQuery(); | |
if (query == null) { | |
throw new DerivedTypedElementException("The given derived typed element doesn't contain a query"); //$NON-NLS-1$ | |
} | |
Object queryResult = evaluate(derivedTypedElement, source, parameterValues, facetManager, query); | |
// expectedResultType == null means match everything | |
// And a null value for queryResult matches any type | |
if (expectedType != null && queryResult != null && !expectedType.isInstance(queryResult)) { | |
Exception e1 = new UnmatchingExpectedTypeException( | |
"The derived typed element did not evaluate to the expected type", expectedType, queryResult); //$NON-NLS-1$ | |
throw new DerivedTypedElementException(e1); | |
} | |
// just checked | |
@SuppressWarnings("unchecked") | |
T typedQueryResult = (T) queryResult; | |
return typedQueryResult; | |
} | |
public <T> List<T> evaluateMultiValued(final DerivedTypedElement derivedTypedElement, | |
final EObject source, final List<ParameterValue> parameterValues, final Class<T> expectedType, final IFacetManager facetManager) | |
throws DerivedTypedElementException { | |
if (!derivedTypedElement.isMany()) { | |
throw new IllegalArgumentException("This method doesn't accept a single-valued derived typed element."); //$NON-NLS-1$ | |
} | |
Query query = derivedTypedElement.getQuery(); | |
if (query == null) { | |
throw new DerivedTypedElementException("The given derived typed element doesn't contain a query"); //$NON-NLS-1$ | |
} | |
Object queryResult = evaluate(derivedTypedElement, source, parameterValues, facetManager, query); | |
if (SET_AS_LIST) { | |
/* | |
* gdupe> This conversion seem to be a bit too magic to be a default | |
* behavior. | |
*/ | |
queryResult = setAsList(queryResult); | |
} | |
List<T> result = null; | |
if (queryResult instanceof List<?>) { | |
List<?> queryListResult = (List<?>) queryResult; | |
for (Object queryResultElement : queryListResult) { | |
// expectedType == null means match everything | |
// And a null queryResultElement for queryResult matches any type | |
if (expectedType != null && queryResultElement != null && !expectedType.isInstance(queryResultElement)) { | |
Exception e1 = new UnmatchingExpectedTypeException( | |
"The derived typed element did not evaluate to the expected type"); //$NON-NLS-1$ | |
throw new DerivedTypedElementException(e1); | |
} | |
} | |
// just checked | |
@SuppressWarnings("unchecked") | |
List<T> typedQueryListResult = (List<T>) queryListResult; | |
result = typedQueryListResult; | |
} else if (queryResult != null) { | |
throw new DerivedTypedElementException("The given multi-valued derived typed element did not evaluate to a List."); //$NON-NLS-1$ | |
} | |
return result; | |
} | |
protected Object evaluate(final DerivedTypedElement derivedTE, final EObject source, final List<ParameterValue> parameterValues, | |
final IFacetManager facetManager, final Query query) throws DerivedTypedElementException { | |
final IQueryImplementation evaluator = QueryImplementationFactoryRegistry.INSTANCE | |
.getEvaluatorFor(query, this); | |
return evaluateAndCheck(derivedTE.getQuery(), source, parameterValues, | |
evaluator, facetManager); | |
} | |
private static Object evaluateAndCheck(final Query query, final EObject source, final List<ParameterValue> parameterValues, | |
final IQueryImplementation evaluator, final IFacetManager facetManager) | |
throws DerivedTypedElementException { | |
checkQuery(query, source); | |
Object result; | |
try { | |
result = evaluator.getValue(query, QueryUtils.getOwningDerivedTypedElement(query), source, parameterValues, facetManager); | |
} catch (Throwable e) { | |
if (e instanceof DerivedTypedElementEvaluationException) { | |
throw (DerivedTypedElementEvaluationException) e; | |
} | |
throw new DerivedTypedElementEvaluationException(e); | |
} | |
checkResult(query, result, evaluator.isCheckResultType(), isPrimitive(QueryUtils.getReturnType(query))); | |
return result; | |
} | |
private static void checkQuery(final Query query, final EObject source) throws DerivedTypedElementException { | |
if (query == null) { | |
throw new IllegalArgumentException("query cannot be null"); //$NON-NLS-1$ | |
} | |
EClassifier sourceType = QueryUtils.getSourceType(query); | |
if (sourceType == null && source != null) { | |
throw new DerivedTypedElementException("the query's sourceType is null and the source is not null"); //$NON-NLS-1$ | |
} | |
// a null value for eObject matches any type | |
if (sourceType != null && source != null && !sourceType.isInstance(source)) { | |
StringBuffer message = new StringBuffer(); | |
message.append("Wrong source type (for " + QueryUtils.getQueryDescription(query) + "): '"); //$NON-NLS-1$ //$NON-NLS-2$ | |
message.append(source.eClass().getName()); | |
message.append("' found; expected '"); //$NON-NLS-1$ | |
message.append(sourceType.getName()); | |
message.append("'."); //$NON-NLS-1$ | |
throw new DerivedTypedElementTypeCheckingException(message.toString()); | |
} | |
} | |
// public List<? extends AbstractDerivedTypedElementResult> evaluate(final DerivedTypedElement | |
// derivedTypedElement, final Collection<EObject> sources, | |
// final List<ParameterValue> parameterValues) throws DerivedTypedElementException { | |
// if (derivedTypedElement.isMany()) { | |
// try { | |
// return evaluateSingleValued(derivedTypedElement, sources, parameterValues, null); | |
// } catch (UnmatchingExpectedTypeException e) { | |
// // should never happen | |
// throw new IllegalStateException("Unexpected error"); //$NON-NLS-1$ | |
// } | |
// } else { | |
// try { | |
// return evaluateMultiValued(derivedTypedElement, sources, parameterValues, null); | |
// } catch (UnmatchingExpectedTypeException e) { | |
// // should never happen | |
// throw new IllegalStateException("Unexpected error"); //$NON-NLS-1$ | |
// } | |
// } | |
// } | |
// batch evaluation disabled : Bug 365429 - DerivedTypedElementManager : re-implement batch evaluation | |
public <T extends ETypedElementResult> List<T> batchEvaluate(final DerivedTypedElement derivedTypedElement, | |
final Collection<? extends EObject> sources, final List<ParameterValue> parameterValues, final Class<T> expectedType, final IFacetManager facetManager) | |
throws DerivedTypedElementException { | |
throw new UnsupportedOperationException("not implemented yet"); //$NON-NLS-1$ | |
// if (derivedTypedElement == null) { | |
// throw new IllegalArgumentException("The given derived typed element must not be null"); //$NON-NLS-1$ | |
// } | |
// | |
// List<T> abstractResultList; | |
// | |
// Query query = derivedTypedElement.getQuery(); | |
// if (query == null) { | |
// throw new DerivedTypedElementException("The given derived typed element doesn't contain a query"); //$NON-NLS-1$ | |
// } | |
// EClassifier eType = derivedTypedElement.getEType(); | |
// if (eType == null) { | |
// throw new DerivedTypedElementException("The given derived typed element has a null type"); //$NON-NLS-1$ | |
// } | |
// IDerivedTypedElementImplementation evaluator = DerivedTypedElementImplementationFactoryRegistry.INSTANCE.getEvaluatorFor(query); | |
// if (evaluator == null) { | |
// throw new DerivedTypedElementEvaluationException("No evaluator was found for a query of type " + query.getClass().getName()); //$NON-NLS-1$ | |
// } | |
// | |
// final boolean primitiveType = isPrimitive(eType); | |
// | |
// // if the evaluator implements multiple evaluation itself, then use it | |
// if (evaluator instanceof IDerivedTypedElementCollectionImplementation) { | |
// IDerivedTypedElementCollectionImplementation collectionEvaluator = (IDerivedTypedElementCollectionImplementation) evaluator; | |
// if (derivedTypedElement.isMany()) { | |
// if (primitiveType) { | |
// if (expectedType != DerivedTypedElementPrimitiveTypeListResult.class) { | |
// throw new UnmatchingExpectedTypeException("The derivedTypedElement is multi-valued, and its type is primitive, " + //$NON-NLS-1$ | |
// "so expectedType must be " + DerivedTypedElementPrimitiveTypeListResult.class.getSimpleName()); //$NON-NLS-1$ | |
// } | |
// List<DerivedTypedElementPrimitiveTypeListResult<?>> listResultList = batchEvaluateMultiValuedPrimitiveDerivedTypedElementWithCollectionEvaluator( | |
// derivedTypedElement, sources, parameterValues, collectionEvaluator); | |
// // we just checked the type parameter T through expectedType | |
// @SuppressWarnings("unchecked") | |
// List<T> castList = (List<T>) listResultList; | |
// abstractResultList = castList; | |
// } else { | |
// if (expectedType != DerivedTypedElementEObjectListResult.class) { | |
// throw new UnmatchingExpectedTypeException("The derivedTypedElement is multi-valued, and it returns model elements, " + //$NON-NLS-1$ | |
// "so expectedType must be " + DerivedTypedElementEObjectListResult.class.getSimpleName()); //$NON-NLS-1$ | |
// } | |
// List<DerivedTypedElementEObjectListResult<?>> listResultList = batchEvaluateMultiValuedEObjectDerivedTypedElementWithCollectionEvaluator( | |
// derivedTypedElement, sources, parameterValues, collectionEvaluator); | |
// // we just checked the type parameter T through expectedType | |
// @SuppressWarnings("unchecked") | |
// List<T> castList = (List<T>) listResultList; | |
// abstractResultList = castList; | |
// } | |
// } else { | |
// if (primitiveType) { | |
// if (expectedType != DerivedTypedElementPrimitiveTypeResult.class) { | |
// throw new UnmatchingExpectedTypeException("The derivedTypedElement is single-valued, and its type is primitive, " + //$NON-NLS-1$ | |
// "so expectedType must be " + DerivedTypedElementPrimitiveTypeResult.class.getSimpleName()); //$NON-NLS-1$ | |
// } | |
// List<DerivedTypedElementPrimitiveTypeResult<?>> resultList = batchEvaluateSingleValuedPrimitiveDerivedTypedElementWithCollectionEvaluator( | |
// derivedTypedElement, sources, parameterValues, collectionEvaluator); | |
// // we just checked the type parameter T through expectedType | |
// @SuppressWarnings("unchecked") | |
// List<T> castList = (List<T>) resultList; | |
// abstractResultList = castList; | |
// } else { | |
// if (expectedType != DerivedTypedElementEObjectResult.class) { | |
// throw new UnmatchingExpectedTypeException("The derivedTypedElement is single-valued, and it returns a model element, " + //$NON-NLS-1$ | |
// "so expectedType must be " + DerivedTypedElementEObjectResult.class.getSimpleName()); //$NON-NLS-1$ | |
// } | |
// List<DerivedTypedElementEObjectResult<?>> resultList = batchEvaluateSingleValuedEObjectDerivedTypedElementWithCollectionEvaluator( | |
// derivedTypedElement, sources, parameterValues, collectionEvaluator); | |
// // we just checked the type parameter T through expectedType | |
// @SuppressWarnings("unchecked") | |
// List<T> castList = (List<T>) resultList; | |
// abstractResultList = castList; | |
// } | |
// } | |
// | |
// } else { | |
// // otherwise, do multiple evaluation by calling the evaluator's | |
// // single evaluation multiple times | |
// | |
// if (derivedTypedElement.isMany()) { | |
// if (primitiveType) { | |
// if (expectedType != DerivedTypedElementPrimitiveTypeListResult.class) { | |
// throw new UnmatchingExpectedTypeException("The derivedTypedElement is multi-valued, and its type is primitive, " + //$NON-NLS-1$ | |
// "so expectedType must be " + DerivedTypedElementPrimitiveTypeListResult.class.getSimpleName()); //$NON-NLS-1$ | |
// } | |
// List<DerivedTypedElementPrimitiveTypeListResult<?>> listResultList = batchEvaluateMultiValuedPrimitiveDerivedTypedElementWithSimpleEvaluator( | |
// derivedTypedElement, sources, parameterValues, evaluator); | |
// @SuppressWarnings("unchecked") | |
// List<T> castList = (List<T>) listResultList; | |
// abstractResultList = castList; | |
// } else { | |
// if (expectedType != DerivedTypedElementEObjectListResult.class) { | |
// throw new UnmatchingExpectedTypeException("The derivedTypedElement is multi-valued, and it returns model elements, " + //$NON-NLS-1$ | |
// "so expectedType must be " + DerivedTypedElementEObjectListResult.class.getSimpleName()); //$NON-NLS-1$ | |
// } | |
// List<DerivedTypedElementEObjectListResult<?>> listResultList = batchEvaluateMultiValuedEObjectDerivedTypedElementWithSimpleEvaluator( | |
// derivedTypedElement, sources, parameterValues, evaluator); | |
// @SuppressWarnings("unchecked") | |
// List<T> castList = (List<T>) listResultList; | |
// abstractResultList = castList; | |
// } | |
// } else { | |
// if (primitiveType) { | |
// if (expectedType != DerivedTypedElementPrimitiveTypeResult.class) { | |
// throw new UnmatchingExpectedTypeException("The derivedTypedElement is single-valued, and its type is primitive, " + //$NON-NLS-1$ | |
// "so expectedType must be " + DerivedTypedElementPrimitiveTypeResult.class.getSimpleName()); //$NON-NLS-1$ | |
// } | |
// List<DerivedTypedElementPrimitiveTypeResult<?>> resultList = batchEvaluateSingleValuedPrimitiveDerivedTypedElementWithSimpleCollectionEvaluator( | |
// derivedTypedElement, sources, parameterValues, evaluator); | |
// @SuppressWarnings("unchecked") | |
// List<T> castList = (List<T>) resultList; | |
// abstractResultList = castList; | |
// } else { | |
// if (expectedType != DerivedTypedElementEObjectResult.class) { | |
// throw new UnmatchingExpectedTypeException("The derivedTypedElement is single-valued, and it returns a model element, " + //$NON-NLS-1$ | |
// "so expectedType must be " + DerivedTypedElementEObjectResult.class.getSimpleName()); //$NON-NLS-1$ | |
// } | |
// List<DerivedTypedElementEObjectResult<?>> resultList = batchEvaluateSingleValuedEObjectDerivedTypedElementWithSimpleCollectionEvaluator( | |
// derivedTypedElement, sources, parameterValues, null); | |
// @SuppressWarnings("unchecked") | |
// List<T> castList = (List<T>) resultList; | |
// abstractResultList = castList; | |
// } | |
// } | |
// } | |
// return abstractResultList; | |
} | |
// private static List<DerivedTypedElementPrimitiveTypeListResult<?>> batchEvaluateMultiValuedPrimitiveDerivedTypedElementWithCollectionEvaluator( | |
// final DerivedTypedElement derivedTypedElement, final Collection<EObject> sources, final List<ParameterValue> parameterValues, | |
// final IDerivedTypedElementCollectionImplementation collectionEvaluator) | |
// throws DerivedTypedElementException { | |
// | |
// List<? extends AbstractDerivedTypedElementResult> listResultList = collectionEvaluator | |
// .getValues(derivedTypedElement, sources, parameterValues); | |
// | |
// // check the return type from the evaluator in order to be able to cast safely | |
// for (int index = 0; index < listResultList.size(); index++) { | |
// AbstractDerivedTypedElementResult elementResult = listResultList.get(index); | |
// if (elementResult instanceof DerivedTypedElementPrimitiveTypeListResult<?>) { | |
// DerivedTypedElementPrimitiveTypeListResult<?> derivedTypedElementPrimitiveTypeListResult = (DerivedTypedElementPrimitiveTypeListResult<?>) elementResult; | |
// checkResult(derivedTypedElement.getQuery(), derivedTypedElementPrimitiveTypeListResult.getResultList(), | |
// collectionEvaluator.getCheckResultType()); | |
// } else { | |
// throw new DerivedTypedElementEvaluationException(ErrorHandlingUtils.buildWrongTypeMessage( | |
// "Wrong element type at index " + index + " in the result from the evaluator: " + collectionEvaluator.getClass().getName(), //$NON-NLS-1$//$NON-NLS-2$ | |
// DerivedTypedElementPrimitiveTypeListResult.class, elementResult)); | |
// } | |
// } | |
// | |
// // just checked | |
// @SuppressWarnings("unchecked") | |
// List<DerivedTypedElementPrimitiveTypeListResult<?>> result = (List<DerivedTypedElementPrimitiveTypeListResult<?>>) listResultList; | |
// return result; | |
// } | |
// | |
// private static List<DerivedTypedElementEObjectListResult<?>> batchEvaluateMultiValuedEObjectDerivedTypedElementWithCollectionEvaluator( | |
// final DerivedTypedElement derivedTypedElement, final Collection<EObject> sources, final List<ParameterValue> parameterValues, | |
// final IDerivedTypedElementCollectionImplementation collectionEvaluator) | |
// throws DerivedTypedElementException { | |
// List<? extends AbstractDerivedTypedElementResult> listResultList = collectionEvaluator | |
// .getValues(derivedTypedElement, sources, parameterValues); | |
// | |
// // check the return type from the evaluator in order to be able to cast safely | |
// for (int index = 0; index < listResultList.size(); index++) { | |
// AbstractDerivedTypedElementResult elementResult = listResultList.get(index); | |
// if (elementResult instanceof DerivedTypedElementEObjectListResult<?>) { | |
// DerivedTypedElementEObjectListResult<?> derivedTypedElementEObjectListResult = (DerivedTypedElementEObjectListResult<?>) elementResult; | |
// checkResult(derivedTypedElement.getQuery(), derivedTypedElementEObjectListResult.getResultList(), | |
// collectionEvaluator.getCheckResultType()); | |
// } else { | |
// throw new DerivedTypedElementEvaluationException(ErrorHandlingUtils.buildWrongTypeMessage( | |
// "Wrong element type at index " + index + " in the result from the evaluator: " + collectionEvaluator.getClass().getName(), //$NON-NLS-1$//$NON-NLS-2$ | |
// DerivedTypedElementEObjectListResult.class, elementResult)); | |
// } | |
// } | |
// | |
// // just checked | |
// @SuppressWarnings("unchecked") | |
// List<DerivedTypedElementEObjectListResult<?>> result = (List<DerivedTypedElementEObjectListResult<?>>) listResultList; | |
// return result; | |
// } | |
// | |
// private static List<DerivedTypedElementPrimitiveTypeResult<?>> batchEvaluateSingleValuedPrimitiveDerivedTypedElementWithCollectionEvaluator( | |
// final DerivedTypedElement derivedTypedElement, final Collection<EObject> sources, final List<ParameterValue> parameterValues, | |
// final IDerivedTypedElementCollectionImplementation collectionEvaluator) | |
// throws DerivedTypedElementException { | |
// // TODO Auto-generated method stub | |
// return null; | |
// } | |
// | |
// private static List<DerivedTypedElementEObjectResult<?>> batchEvaluateSingleValuedEObjectDerivedTypedElementWithCollectionEvaluator( | |
// final DerivedTypedElement derivedTypedElement, final Collection<EObject> sources, final List<ParameterValue> parameterValues, | |
// final IDerivedTypedElementCollectionImplementation collectionEvaluator) throws DerivedTypedElementException { | |
// // TODO Auto-generated method stub | |
// return null; | |
// } | |
// | |
// private static List<DerivedTypedElementPrimitiveTypeListResult<?>> batchEvaluateMultiValuedPrimitiveDerivedTypedElementWithSimpleEvaluator( | |
// final DerivedTypedElement derivedTypedElement, final Collection<EObject> sources, final List<ParameterValue> parameterValues, | |
// final IDerivedTypedElementImplementation evaluator) { | |
// | |
// Query query = derivedTypedElement.getQuery(); | |
// | |
// List<DerivedTypedElementPrimitiveTypeListResult<?>> listResultList = new ArrayList<DerivedTypedElementPrimitiveTypeListResult<?>>(); | |
// for (EObject eObject : sources) { | |
// DerivedTypedElementPrimitiveTypeListResult<Object> primitiveTypeListResult = EFacetFactory.eINSTANCE | |
// .createDerivedTypedElementPrimitiveTypeListResult(); | |
// | |
// Throwable error = null; | |
// try { | |
// primitiveTypeListResult.setSource(eObject); | |
// primitiveTypeListResult.setDerivedTypedElement(derivedTypedElement); | |
// setParameterValues(primitiveTypeListResult.getParameterValues(), parameterValues); | |
// checkSourceType(query.getSourceType(), query, eObject); | |
// } catch (Throwable e) { | |
// error = e; | |
// } | |
// if (error != null) { | |
// primitiveTypeListResult.setException(error); | |
// } else { | |
// try { | |
// Object evaluationResult = evaluator.getValue(derivedTypedElement, eObject, parameterValues); | |
// checkResult(query, evaluationResult, evaluator.getCheckResultType()); | |
// // checked by checkResult | |
// Collection<?> evaluationResultCollection = (Collection<?>) evaluationResult; | |
// for (Object object : evaluationResultCollection) { | |
// primitiveTypeListResult.getResultList().add(object); | |
// } | |
// } catch (Throwable e) { | |
// primitiveTypeListResult.setException(e); | |
// } | |
// } | |
// listResultList.add(primitiveTypeListResult); | |
// | |
// } | |
// return listResultList; | |
// } | |
// | |
// private static List<DerivedTypedElementEObjectListResult<?>> batchEvaluateMultiValuedEObjectDerivedTypedElementWithSimpleEvaluator( | |
// final DerivedTypedElement derivedTypedElement, final Collection<EObject> sources, final List<ParameterValue> parameterValues, | |
// final IDerivedTypedElementImplementation evaluator) { | |
// Query query = derivedTypedElement.getQuery(); | |
// | |
// List<DerivedTypedElementEObjectListResult<?>> listResultList = new ArrayList<DerivedTypedElementEObjectListResult<?>>(); | |
// for (EObject eObject : sources) { | |
// DerivedTypedElementEObjectListResult<EObject> eObjectListResult = EFacetFactory.eINSTANCE | |
// .createDerivedTypedElementEObjectListResult(); | |
// | |
// Throwable error = null; | |
// try { | |
// eObjectListResult.setSource(eObject); | |
// eObjectListResult.setDerivedTypedElement(derivedTypedElement); | |
// setParameterValues(eObjectListResult.getParameterValues(), parameterValues); | |
// checkSourceType(query.getSourceType(), query, eObject); | |
// } catch (Throwable e) { | |
// error = e; | |
// } | |
// if (error != null) { | |
// eObjectListResult.setException(error); | |
// } else { | |
// try { | |
// Object evaluationResult = evaluator.getValue(derivedTypedElement, eObject, parameterValues); | |
// checkResult(query, evaluationResult, evaluator.getCheckResultType(), false); | |
// // checked by checkResult | |
// @SuppressWarnings("unchecked") | |
// Collection<? extends EObject> evaluationResultCollection = (Collection<? extends EObject>) evaluationResult; | |
// for (EObject e : evaluationResultCollection) { | |
// eObjectListResult.getResultList().add(e); | |
// } | |
// } catch (Throwable e) { | |
// eObjectListResult.setException(e); | |
// } | |
// } | |
// listResultList.add(eObjectListResult); | |
// | |
// } | |
// return listResultList; | |
// } | |
// | |
// private static List<DerivedTypedElementPrimitiveTypeResult<?>> batchEvaluateSingleValuedPrimitiveDerivedTypedElementWithSimpleCollectionEvaluator( | |
// final DerivedTypedElement derivedTypedElement, final Collection<EObject> sources, final List<ParameterValue> parameterValues, | |
// final IDerivedTypedElementImplementation evaluator) | |
// throws DerivedTypedElementException { | |
// // TODO Auto-generated method stub | |
// return null; | |
// } | |
// | |
// private static List<DerivedTypedElementEObjectResult<?>> batchEvaluateSingleValuedEObjectDerivedTypedElementWithSimpleCollectionEvaluator( | |
// final DerivedTypedElement derivedTypedElement, final Collection<EObject> sources, final List<ParameterValue> parameterValues, | |
// final IDerivedTypedElementImplementation evaluator) | |
// throws DerivedTypedElementException { | |
// // TODO Auto-generated method stub | |
// return null; | |
// } | |
// public <T> List<DerivedTypedElementListResult<T>> evaluateMultiValued(final DerivedTypedElement derivedTypedElement, | |
// final Collection<? extends EObject> sources, final List<ParameterValue> parameterValues, | |
// final Class<T> expectedType) | |
// throws DerivedTypedElementException, UnmatchingExpectedTypeException { | |
// if (!derivedTypedElement.isMany()) { | |
// throw new IllegalArgumentException("This method doesn't accept a single-valued derived typed element."); //$NON-NLS-1$ | |
// } | |
// | |
// Query query = derivedTypedElement.getQuery(); | |
// if (query == null) { | |
// throw new DerivedTypedElementException("The given derived typed element doesn't contain a query"); //$NON-NLS-1$ | |
// } | |
// IDerivedTypedElementImplementation evaluator = | |
// DerivedTypedElementImplementationFactoryRegistry.INSTANCE.getEvaluatorFor(query); | |
// | |
// List<?> queryResult = batchEvaluateAndCheck(derivedTypedElement, sources, parameterValues, | |
// evaluator); | |
// // Java doesn't support co- or contra-variance on generics, | |
// // so we can't return the right type | |
// @SuppressWarnings("unchecked") | |
// List<DerivedTypedElementListResult<T>> multiResultList = | |
// (List<DerivedTypedElementListResult<T>>) queryResult; | |
// | |
// // check each result element in each result list | |
// if (expectedType != null) { | |
// int sourceIndex = 0; | |
// for (DerivedTypedElementListResult<?> derivedTypedElementResult : multiResultList) { | |
// EList<?> resultList = derivedTypedElementResult.getResultList(); | |
// int index = 0; | |
// for (Object resultElement : resultList) { | |
// // a null value for resultElement matches any type | |
// if (resultElement != null && !expectedType.isInstance(resultElement)) { | |
// throw new UnmatchingExpectedTypeException( | |
// "The element at index " + index + " in the list that resulted from the evaluation of the multi-valued " //$NON-NLS-1$ //$NON-NLS-2$ | |
// + "derived typed element does not match the expected type " //$NON-NLS-1$ | |
// + "for the source element at index " + sourceIndex, expectedType, resultElement); //$NON-NLS-1$ | |
// } | |
// index++; | |
// } | |
// sourceIndex++; | |
// } | |
// } | |
// return multiResultList; | |
// } | |
// | |
// private static List<?> batchEvaluateAndCheck(final DerivedTypedElement derivedTypedElement, | |
// final Collection<EObject> eObjects, | |
// final List<ParameterValue> parameterValues, final IDerivedTypedElementImplementation | |
// evaluator) | |
// throws DerivedTypedElementException { | |
// List<?> result; | |
// | |
// Query query = derivedTypedElement.getQuery(); | |
// if (query == null) { | |
// throw new IllegalArgumentException("the query cannot be null"); //$NON-NLS-1$ | |
// } | |
// | |
// EClassifier sourceType = query.getSourceType(); | |
// | |
// final boolean primitiveType = derivedTypedElement instanceof EAttribute; | |
// | |
// if (derivedTypedElement.isMany()) { | |
// if (evaluator instanceof IDerivedTypedElementCollectionImplementation) { | |
// IDerivedTypedElementCollectionImplementation collectionEvaluator = | |
// (IDerivedTypedElementCollectionImplementation) evaluator; | |
// // List<? extends AbstractDerivedTypedElementResult> listResultList = | |
// // collectionEvaluator | |
// // .getValues(derivedTypedElement, eObjects, parameterValues); | |
// // int index = 0; | |
// // for (AbstractDerivedTypedElementResult listResult : listResultList) { | |
// // EList<?> resultList; | |
// // if (primitiveType && listResult instanceof | |
// // DerivedTypedElementPrimitiveTypeListResult<?>) { | |
// // DerivedTypedElementPrimitiveTypeListResult<?> primitiveListResult = | |
// // (DerivedTypedElementPrimitiveTypeListResult<?>) listResult; | |
// // resultList = primitiveListResult.getResultList(); | |
// // } else if (!primitiveType && listResult instanceof | |
// // DerivedTypedElementEObjectListResult<?>) { | |
// // DerivedTypedElementEObjectListResult<?> eObjectListResult = | |
// // (DerivedTypedElementEObjectListResult<?>) listResult; | |
// // resultList = eObjectListResult.getResultList(); | |
// // } else { | |
// // throw new DerivedTypedElementEvaluationException( | |
// // "Wrong element type at index " + index + " in the result from the evaluator " + collectionEvaluator.getClass().getName()); //$NON-NLS-1$//$NON-NLS-2$ | |
// // } | |
// // checkResult(query, resultList, evaluator.getCheckResultType()); | |
// // index++; | |
// // } | |
// // result = listResultList; | |
// } else { | |
// | |
// // List<AbstractDerivedTypedElementResult> listResultList = new | |
// // ArrayList<AbstractDerivedTypedElementResult>(); | |
// // for (EObject eObject : eObjects) { | |
// // AbstractDerivedTypedElementResult listResult; | |
// // List<?> resultList; | |
// // if (primitiveType) { | |
// // DerivedTypedElementPrimitiveTypeListResult<?> primitiveTypeListResult = | |
// // EFacetFactory.eINSTANCE | |
// // .createDerivedTypedElementPrimitiveTypeListResult(); | |
// // listResult = primitiveTypeListResult; | |
// // resultList = primitiveTypeListResult.getResultList(); | |
// // } else { | |
// // DerivedTypedElementEObjectListResult<?> eObjectTypeListResult = | |
// // EFacetFactory.eINSTANCE | |
// // .createDerivedTypedElementEObjectListResult(); | |
// // listResult = eObjectTypeListResult; | |
// // resultList = eObjectTypeListResult.getResultList(); | |
// // } | |
// // | |
// // Throwable error = null; | |
// // try { | |
// // listResult.setSource(eObject); | |
// // listResult.setDerivedTypedElement(derivedTypedElement); | |
// // setParameterValues(listResult.getParameterValues(), parameterValues); | |
// // checkSourceType(sourceType, query, eObject); | |
// // } catch (Throwable e) { | |
// // error = e; | |
// // } | |
// // if (error != null) { | |
// // listResult.setException(error); | |
// // } else { | |
// // try { | |
// // Object evaluationResult = evaluator.getValue(derivedTypedElement, eObject, | |
// // parameterValues); | |
// // checkResult(query, evaluationResult, evaluator.getCheckResultType()); | |
// // // checked by checkResult | |
// // Collection<?> evaluationResultCollection = (Collection<?>) evaluationResult; | |
// // for (Object object : evaluationResultCollection) { | |
// // resultList.add(object); | |
// // } | |
// // } catch (Throwable e) { | |
// // listResult.setException(e); | |
// // } | |
// // } | |
// // listResultList.add(listResult); | |
// // | |
// // } | |
// // result = listResultList; | |
// | |
// } | |
// } else { | |
// // if the evaluator implements multiple evaluation itself, then use it | |
// if (evaluator instanceof IDerivedTypedElementCollectionImplementation) { | |
// IDerivedTypedElementCollectionImplementation collectionEvaluator = | |
// (IDerivedTypedElementCollectionImplementation) evaluator; | |
// List<? extends AbstractDerivedTypedElementResult> singleResultList = collectionEvaluator | |
// .getValues(derivedTypedElement, eObjects, parameterValues); | |
// int index = 0; | |
// for (AbstractDerivedTypedElementResult singleResult : singleResultList) { | |
// Object resultElement; | |
// if (primitiveType && singleResult instanceof DerivedTypedElementPrimitiveTypeResult<?>) { | |
// DerivedTypedElementPrimitiveTypeResult<?> primitiveResult = | |
// (DerivedTypedElementPrimitiveTypeResult<?>) singleResult; | |
// resultElement = primitiveResult.getResult(); | |
// } else if (!primitiveType && singleResult instanceof DerivedTypedElementEObjectResult<?>) { | |
// DerivedTypedElementEObjectResult<?> eObjectResult = (DerivedTypedElementEObjectResult<?>) | |
// singleResult; | |
// resultElement = eObjectResult.getResult(); | |
// } else { | |
// throw new DerivedTypedElementEvaluationException( | |
// "Wrong element type at index " + index + " in the result from the evaluator " + collectionEvaluator.getClass().getName()); //$NON-NLS-1$//$NON-NLS-2$ | |
// } | |
// checkResult(query, result, evaluator.getCheckResultType()); | |
// index++; | |
// } | |
// } else { | |
// // otherwise, do multiple evaluation by calling the evaluator's | |
// // single evaluation multiple times | |
// List<DerivedTypedElementResult<?>> resultList = new | |
// ArrayList<DerivedTypedElementResult<?>>(); | |
// for (EObject eObject : eObjects) { | |
// DerivedTypedElementResult<Object> singleResult = | |
// EFacetFactory.eINSTANCE.createDerivedTypedElementResult(); | |
// Throwable error = null; | |
// try { | |
// singleResult.setSource(eObject); | |
// singleResult.setDerivedTypedElement(derivedTypedElement); | |
// setParameterValues(singleResult.getParameterValues(), parameterValues); | |
// checkSourceType(sourceType, query, eObject); | |
// } catch (Throwable e) { | |
// error = e; | |
// } | |
// if (error != null) { | |
// singleResult.setException(error); | |
// } else { | |
// try { | |
// Object evaluationResult = evaluator.getValue(derivedTypedElement, eObject, parameterValues); | |
// checkResult(query, evaluationResult, evaluator.getCheckResultType()); | |
// singleResult.setResult(evaluationResult); | |
// } catch (Throwable e) { | |
// singleResult.setException(e); | |
// } | |
// } | |
// resultList.add(singleResult); | |
// } | |
// result = resultList; | |
// } | |
// } | |
// | |
// return result; | |
// } | |
// private static void checkSourceType(final EClassifier sourceType, final Query query, final EObject eObject) | |
// throws DerivedTypedElementException { | |
// if (sourceType != null) { | |
// // a null value for eObject matches any type | |
// if (eObject != null && !sourceType.isInstance(eObject)) { | |
// StringBuffer message = new StringBuffer(); | |
// message.append("Wrong source type (for " + QueryUtils.getQueryDescription(query) + "): '"); //$NON-NLS-1$ //$NON-NLS-2$ | |
// message.append(eObject.eClass().getName()); | |
// message.append("' found; expected '"); //$NON-NLS-1$ | |
// message.append(sourceType.getName()); | |
// message.append("'."); //$NON-NLS-1$ | |
// throw new DerivedTypedElementTypeCheckingException(message.toString()); | |
// } | |
// } else { | |
// if (eObject != null) { | |
// throw new DerivedTypedElementException("the query's sourceType is null and the source is not null"); //$NON-NLS-1$ | |
// } | |
// } | |
// } | |
// | |
// private static void setParameterValues(final EList<ParameterValue> target, final List<ParameterValue> parameterValues) { | |
// if (parameterValues != null) { | |
// for (ParameterValue parameterValue : parameterValues) { | |
// if (parameterValue == null) { | |
// throw new IllegalArgumentException("null parameter value"); //$NON-NLS-1$ | |
// } | |
// // containment link -> we need to copy since we can have the same | |
// // parameter for several results | |
// target.add(EcoreUtil.copy(parameterValue)); | |
// } | |
// } | |
// } | |
private static final void checkResult(final Query query, final Object result, | |
final boolean checkResultType, final boolean primitive) throws DerivedTypedElementTypeCheckingException { | |
if (result != null) { | |
if (QueryUtils.isMany(query)) { | |
if (!(result instanceof Collection<?>)) { | |
final String message = String.format( | |
"A collection is expected as result. The result is an instance of %s (on %s)", //$NON-NLS-1$ | |
result.getClass().getName(), | |
QueryUtils.getQueryDescription(query)); | |
throw new DerivedTypedElementTypeCheckingException(message); | |
} | |
if (checkResultType) { | |
for (Object collectionElement : (Collection<?>) result) { | |
if (collectionElement != null | |
&& !(QueryUtils.getReturnType(query) | |
.isInstance(collectionElement))) { | |
throw new DerivedTypedElementTypeCheckingException( | |
"Wrong result collection element type: " + collectionElement.getClass().getName() //$NON-NLS-1$ | |
+ "(" + QueryUtils.getReturnType(query).getName() + " is expected) " //$NON-NLS-1$ //$NON-NLS-2$ | |
+ " on " + QueryUtils.getQueryDescription(query)); //$NON-NLS-1$ | |
} | |
} | |
} else if (!primitive) { | |
// at least check that EObjects are returned | |
for (Object collectionElement : (Collection<?>) result) { | |
if (collectionElement != null && !(collectionElement instanceof EObject)) { | |
throw new DerivedTypedElementTypeCheckingException( | |
"Wrong result collection element type: " + collectionElement.getClass().getName() //$NON-NLS-1$ | |
+ "(an instance of " + EObject.class.getName() + " is expected) " //$NON-NLS-1$ //$NON-NLS-2$ | |
+ " on " + QueryUtils.getQueryDescription(query)); //$NON-NLS-1$ | |
} | |
} | |
} | |
} else { | |
if (result instanceof Collection<?>) { | |
throw new DerivedTypedElementTypeCheckingException("A " //$NON-NLS-1$ | |
+ QueryUtils.getSourceType(query).getName() | |
+ " instance is expected as result. The result is: " //$NON-NLS-1$ | |
+ result + " (on " + QueryUtils.getQueryDescription(query) + ")"); //$NON-NLS-1$//$NON-NLS-2$ | |
} | |
if (checkResultType) { | |
if (result != null && !(QueryUtils.getReturnType(query).isInstance(result))) { | |
throw new DerivedTypedElementTypeCheckingException("Wrong result type: " //$NON-NLS-1$ | |
+ result.getClass().getName() | |
+ " is returned while " //$NON-NLS-1$ | |
+ QueryUtils.getReturnType(query).getInstanceClassName() | |
+ " is expected." + " (on " + QueryUtils.getQueryDescription(query) + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |
} | |
} else if (!primitive) { | |
// at least check that an EObject is returned | |
if (result != null && !(result instanceof EObject)) { | |
throw new DerivedTypedElementTypeCheckingException( | |
"Wrong result collection element type: " + result.getClass().getName() //$NON-NLS-1$ | |
+ "(an instance of " + EObject.class.getName() + " is expected) " //$NON-NLS-1$ //$NON-NLS-2$ | |
+ " on " + QueryUtils.getQueryDescription(query)); //$NON-NLS-1$ | |
} | |
} | |
} | |
} | |
} | |
private static boolean isPrimitive(final EClassifier eType) { | |
final boolean primitiveType; | |
if (eType instanceof EDataType) { | |
primitiveType = true; | |
} else if (eType instanceof EClass) { | |
primitiveType = false; | |
} else { | |
throw new IllegalArgumentException("unhandled derived typed element type: " + eType.getName()); //$NON-NLS-1$ | |
} | |
return primitiveType; | |
} | |
/** | |
* Transform the element in parameter in list (if necessary). | |
* | |
* @param element | |
* the element to transform | |
* @return a list. | |
*/ | |
protected static List<Object> setAsList(final Object element) { | |
List<Object> newList = new LinkedList<Object>(); | |
if (element instanceof List) { | |
@SuppressWarnings("unchecked") | |
//@SuppressWarnings("unchecked") the cast is safe because were | |
//casting a List to a List<Object> | |
final List<Object> tmpList = (List<Object>) element; | |
newList = tmpList; | |
} else { | |
newList.add(element); | |
} | |
return newList; | |
} | |
} |