@Override public @Nullable Object evaluate( @NonNull Executor executor, @NonNull TypeId returnTypeId, @Nullable Object sourceValue) { IdResolver idResolver = executor.getIdResolver(); Property oppositeProperty = idResolver.getProperty(oppositePropertyId); ModelManager.ModelManagerExtension modelManager = (ModelManager.ModelManagerExtension) executor.getModelManager(); Type thatType = ClassUtil.nonNullModel(oppositeProperty.getType()); if (thatType instanceof CollectionType) { thatType = ((CollectionType) thatType).getElementType(); } List<Object> results = new ArrayList<Object>(); if (thatType instanceof org.eclipse.ocl.pivot.Class) { for (@NonNull Object eObject : modelManager.get((org.eclipse.ocl.pivot.Class) thatType)) { // FIXME Use a cache EClass eClass = modelManager.eClass(eObject); EStructuralFeature eFeature = eClass.getEStructuralFeature(oppositeProperty.getName()); assert eFeature != null; Object eGet = modelManager.eGet(eObject, eFeature); if (eGet == sourceValue) { results.add(eObject); } } } return results; }
/** Tests the basic name accesses */ @Test public void test_container_navigation() throws InvocationTargetException { TestOCL ocl = createOCL(); initFruitPackage(ocl); MetamodelManagerInternal metamodelManager = ocl.getMetamodelManager(); IdResolver idResolver = ocl.getIdResolver(); metamodelManager.addGlobalNamespace("fruit", fruitPackage); // // Simple model: aTree contains redApple // EObject redApple = fruitEFactory.create(apple); redApple.eSet(fruit_color, color_red); // EObject greenApple = fruitEFactory.create(apple); // greenApple.eSet(fruit_color, color_green); EObject aTree = fruitEFactory.create(tree); @SuppressWarnings("unchecked") List<Object> treeFruits = (List<Object>) aTree.eGet(tree_fruits); treeFruits.add(redApple); // Type pivotTree = metamodelManager.getASOfEcore(Type.class, tree); // ocl.assertQueryEquals(redApple, color_red, "let aFruit : fruit::Fruit = self in aFruit.color"); ocl.assertQueryEquals( aTree, idResolver.createOrderedSetOfEach(null, redApple), "let aTree : fruit::Tree = self in aTree.fruits"); ocl.assertQueryEquals(aTree, idResolver.createOrderedSetOfEach(null, redApple), "self.fruits"); ocl.assertQueryEquals(aTree, idResolver.createOrderedSetOfEach(null, redApple), "fruits"); ocl.assertQueryEquals(redApple, aTree, "self.oclContainer()"); ocl.assertQueryEquals(redApple, aTree, "self.Tree"); // // type/property ambiguity is resolved to type. // ocl.assertQueryEquals(redApple, pivotTree, "Tree"); // // type/property ambiguity is resolved to type. // ocl.assertQueryInvalid(redApple, "self.oclAsType(Tree)"); // ocl.assertQueryEquals(aTree, ValuesUtil.createOrderedSetValue(null, redApple), // "self.oclAsType(Tree).fruits"); ocl.dispose(); }
/** Tests the nested name accesses */ @Test public void test_nested_names() throws InvocationTargetException { TestOCL ocl = createOCL(); initFruitPackage(ocl); MetamodelManagerInternal metamodelManager = ocl.getMetamodelManager(); IdResolver idResolver = ocl.getIdResolver(); org.eclipse.ocl.pivot.Class appleType = metamodelManager.getASOfEcore(org.eclipse.ocl.pivot.Class.class, apple); // // Simple model: appleTree contains redApple // EObject redApple = fruitEFactory.create(apple); redApple.eSet(fruit_color, color_red); redApple.eSet(fruit_name, "RedApple"); EObject appleTree = fruitEFactory.create(tree); appleTree.eSet(tree_name, "AppleTree"); @SuppressWarnings("unchecked") List<Object> treeFruits = (List<Object>) appleTree.eGet(tree_fruits); treeFruits.add(redApple); // ocl.assertQueryEquals(redApple, "RedApple", "self.name"); ocl.assertQueryEquals(redApple, "RedApple", "self.Fruit::name"); ocl.assertQueryEquals(redApple, "RedApple", "self.Apple::name"); ocl.assertValidationErrorQuery( appleType, "self.Tree::name", PivotMessages.ValidationConstraintIsNotSatisfied_ERROR_, PivotTables.STR_PropertyCallExp_c_c_NonStaticSourceTypeIsConformant, "self.name"); ocl.assertQueryEquals(redApple, redApple, "self.oclAsType(Apple)"); ocl.assertQueryEquals(redApple, redApple, "self.oclAsType(fruit::Apple)"); ocl.assertQueryEquals( redApple, idResolver.createSetOfEach(null, redApple), "self->oclAsType(Set(Fruit))"); ocl.assertQueryEquals( redApple, idResolver.createSetOfEach(null, redApple), "self->oclAsType(Set(fruit::Apple))"); ocl.assertSemanticErrorQuery( appleType, "self.oclAsType(fruit::fruit::Apple)", PivotMessagesInternal.UnresolvedNamespace_ERROR_, "", "fruit"); // Demonstrates Bug 353985 ocl.assertSemanticErrorQuery( appleType, "self->oclAsType(Set(fruit::apple::BadApple))", PivotMessagesInternal.UnresolvedType_ERROR_, "", "BadApple"); ocl.assertSemanticErrorQuery( appleType, "self->oclAsType(Set(fruit::apple::BadApple))", PivotMessagesInternal.UnresolvedType_ERROR_, "", "BadApple"); ocl.assertSemanticErrorQuery( appleType, "self->oclAsType(Set(fruit::badapple::BadApple))", PivotMessagesInternal.UnresolvedNamespace_ERROR_, "", "badapple"); ocl.assertSemanticErrorQuery( appleType, "self->oclAsType(Set(badfruit::badapple::BadApple))", PivotMessagesInternal.UnresolvedNamespace_ERROR_, "", "badfruit"); ocl.assertQueryInvalid(redApple, "self->oclAsType(Set(fruit::apple::EatingApple))"); ocl.assertQueryInvalid(redApple, "self->oclAsType(Set(fruit::Tree))"); // ocl.assertQueryEquals( redApple, idResolver.createSetOfEach(null, appleTree), "Tree.allInstances()"); ocl.assertQueryEquals( redApple, idResolver.createSetOfEach(null, appleTree), "fruit::Tree.allInstances()"); ocl.assertQueryEquals(null, ocl.getEmptySetValue(), "fruit::Tree.allInstances()"); // metamodelManager.addGlobalNamespace("zz", fruitPackage); ocl.assertQueryEquals( redApple, idResolver.createSetOfEach(null, appleTree), "zz::Tree.allInstances()"); // ocl.assertQueryEquals( redApple, idResolver.createBagOfEach(null, redApple), "Fruit.allInstances().oclAsType(Apple)"); ocl.assertQueryEquals( redApple, idResolver.createSetOfEach(null, redApple), "Fruit.allInstances()->oclAsType(Set(Apple))"); ocl.dispose(); }
/** * Executes the query for the specified <tt>target</tt> object. The result is the OCL evaluation * result which may be a Number, String, Collection or other object for normal returns or a * NullLiteralExp for null, or an InvalidLiteralExp for invalid. * * @param target the object on which to execute the query; this must be an instance of the context * with which the delegate was created * @param arguments a map of variable names to values; these must correspond to the variables with * which the delegate was created * @return the query's result * @throws InvocationTargetException in case of failure to prepare or execute the query, usually * because of an exception */ @Override public Object execute(@Nullable Object target, Map<String, ?> arguments) throws InvocationTargetException { @SuppressWarnings("null") @NonNull Map<String, ?> nonNullArguments = (arguments != null ? arguments : (Map<String, ?>) Collections.<String, Object>emptyMap()); try { if (specification == null) { prepare(); } @SuppressWarnings("null") @NonNull ExpressionInOCL nonNullSpecification = specification; OCL ocl = delegateDomain.getOCL(); IdResolver idResolver = ocl.getIdResolver(); Object targetValue = idResolver.boxedValueOf(target); org.eclipse.ocl.pivot.Class targetType = idResolver.getStaticTypeOf(targetValue); Type requiredType = nonNullSpecification.getOwnedContext().getType(); if ((requiredType == null) || !targetType.conformsTo(ocl.getStandardLibrary(), requiredType)) { String message = StringUtil.bind( PivotMessagesInternal.WrongContextClassifier_ERROR_, targetType, requiredType); throw new OCLDelegateException(new SemanticException(message)); } List<Variable> parameterVariables = nonNullSpecification.getOwnedParameters(); int argCount = arguments != null ? arguments.size() : 0; if (parameterVariables.size() != argCount) { String message = StringUtil.bind( PivotMessagesInternal.MismatchedArgumentCount_ERROR_, argCount, parameterVariables.size()); throw new OCLDelegateException(new SemanticException(message)); } Query query = ocl.createQuery(nonNullSpecification); EvaluationEnvironment env = query.getEvaluationEnvironment(target); for (Variable parameterVariable : parameterVariables) { // bind arguments to parameter names String name = parameterVariable.getName(); Object object = nonNullArguments.get(name); if ((object == null) && !nonNullArguments.containsKey(name)) { String message = StringUtil.bind( PivotMessagesInternal.EvaluationResultIsInvalid_ERROR_, nonNullSpecification.getBody()); throw new OCLDelegateException(new SemanticException(message)); } Object value = idResolver.boxedValueOf(object); targetType = idResolver.getStaticTypeOf(value); requiredType = ClassUtil.nonNullModel(parameterVariable.getType()); if (!targetType.conformsTo(ocl.getStandardLibrary(), requiredType)) { String message = StringUtil.bind( PivotMessagesInternal.MismatchedArgumentType_ERROR_, name, targetType, requiredType); throw new OCLDelegateException(new SemanticException(message)); } env.add(parameterVariable, value); } Object result = evaluate(query, target); // if (result.isInvalid()) { // String message = ClassUtil.bind(OCLMessages.EvaluationResultIsInvalid_ERROR_, // getOperationName()); // throw new OCLDelegateException(message); // } // if ((result == null) / * || ocl.isInvalid(result) * /) { // String message = ClassUtil.bind(OCLMessages.EvaluationResultIsNull_ERROR_, // getOperationName()); // throw new OCLDelegateException(message); // } // return converter.convert(ocl, result); // if (result == null) { // String message = NLS.bind(OCLMessages.EvaluationResultIsInvalid_ERROR_, // PivotUtil.getBody(specification)); // throw new InvocationTargetException(new OCLDelegateException(message)); // } return idResolver.ecoreValueOf(null, result); } catch (InvocationTargetException e) { throw e; } catch (EvaluationException e) { String message = StringUtil.bind( PivotMessagesInternal.EvaluationResultIsInvalid_ERROR_, specification.getBody()); throw new InvocationTargetException(new EvaluationException(message)); } catch (WrappedException e) { throw new InvocationTargetException(e.getCause()); } catch (Exception e) { throw new InvocationTargetException(e); } }