/******************************************************************************* * Copyright (c) 2010, 2015 Willink Transformations 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: * E.D.Willink - initial API and implementation *******************************************************************************/ package org.eclipse.ocl.examples.test.xtext; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.ocl.examples.xtext.tests.XtextTestCase; import org.eclipse.ocl.pivot.Annotation; import org.eclipse.ocl.pivot.AnyType; import org.eclipse.ocl.pivot.Comment; import org.eclipse.ocl.pivot.Constraint; import org.eclipse.ocl.pivot.Element; import org.eclipse.ocl.pivot.ExpressionInOCL; import org.eclipse.ocl.pivot.Feature; import org.eclipse.ocl.pivot.Library; import org.eclipse.ocl.pivot.Operation; import org.eclipse.ocl.pivot.TemplateParameter; import org.eclipse.ocl.pivot.Type; import org.eclipse.ocl.pivot.TypedElement; import org.eclipse.ocl.pivot.internal.complete.StandardLibraryInternal; import org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager; import org.eclipse.ocl.pivot.internal.utilities.AS2Moniker; import org.eclipse.ocl.pivot.internal.utilities.OCLInternal; import org.eclipse.ocl.pivot.library.LibraryFeature; import org.eclipse.ocl.pivot.model.OCLmetamodel; import org.eclipse.ocl.pivot.model.OCLstdlib; import org.eclipse.ocl.pivot.utilities.FeatureFilter; import org.eclipse.ocl.pivot.utilities.OCL; import org.eclipse.ocl.xtext.base.cs2as.CS2AS; import org.eclipse.ocl.xtext.base.utilities.BaseCSResource; import org.eclipse.ocl.xtext.oclstdlib.scoping.JavaClassScope; import com.google.common.collect.Iterables; /** * Tests. */ @SuppressWarnings("null") public class OCLstdlibTests extends XtextTestCase { public static class MonikeredComparator implements Comparator<Element> { public static final Comparator<? super Element> INSTANCE = new MonikeredComparator(); @Override public int compare(Element o1, Element o2) { String m1 = AS2Moniker.toString(o1); String m2 = AS2Moniker.toString(o2); return m1.compareTo(m2); } } // protected MetamodelManager metamodelManager = null; public Map<String, Element> computeMoniker2ASMap(Collection<? extends Resource> pivotResources) { Map<String, Element> map = new HashMap<String, Element>(); for (Resource asResource : pivotResources) { for (Iterator<EObject> it = asResource.getAllContents(); it.hasNext();) { EObject eObject = it.next(); assert eObject.eResource() == asResource; if ((eObject instanceof Element) && !(eObject instanceof TemplateParameter) && !(eObject instanceof Comment) /*&& (eObject != orphanagePackage)*/) { Element newElement = (Element) eObject; String moniker = AS2Moniker.toString(newElement); assert moniker != null; Element oldElement = map.get(moniker); if (oldElement == null) { map.put(moniker, newElement); } else { assert newElement.getClass() == oldElement.getClass(); } } } } return map; } protected Resource doLoadAS(@NonNull ResourceSet resourceSet, @NonNull URI libraryURI, @NonNull Resource javaResource, boolean validateMonikers) { Resource asResource = resourceSet.getResource(libraryURI, true); assertNoResourceErrors("Load failed", asResource); assertNoUnresolvedProxies("File Model", asResource); assertNoValidationErrors("File Model", asResource); // PivotAliasCreator.refreshPackageAliases(javaResource); assertNoResourceErrors("Java Model", javaResource); assertNoUnresolvedProxies("Java Model", javaResource); assertNoValidationErrors("Java Model", javaResource); if (!validateMonikers) { return asResource; } // // Check similar content // Map<String,Element> fileMoniker2asMap = computeMoniker2ASMap(Collections.singletonList(asResource)); // for (String moniker : fileMoniker2asMap.keySet()) { // System.out.println("File : " + moniker); // } Map<String,Element> javaMoniker2asMap = computeMoniker2ASMap(Collections.singletonList(javaResource)); // for (String moniker : javaMoniker2asMap.keySet()) { // System.out.println("Java : " + moniker); // } // assertEquals(fileMoniker2asMap.size(), javaMoniker2asMap.size()); for (String moniker : fileMoniker2asMap.keySet()) { Element fileElement = fileMoniker2asMap.get(moniker); Element javaElement = javaMoniker2asMap.get(moniker); if (javaElement == null) { boolean isExpression = false; for (EObject eObject = fileElement; eObject != null; eObject = eObject.eContainer()) { if ((eObject instanceof ExpressionInOCL) || (eObject instanceof Constraint) || (eObject instanceof Annotation)) { isExpression = true; // Embedded OCL not present in Java break; } } if (isExpression) { continue; } } assertNotNull("Missing java element for '" + moniker + "'", javaElement); // @SuppressWarnings("null") // Can be null and we'll have an NPE as the test failure. Class<? extends Element> javaElementClass = javaElement.getClass(); assertEquals(fileElement.getClass(), javaElementClass); if (fileElement instanceof TypedElement) { Type fileType = ((TypedElement)fileElement).getType(); Type javaType = ((TypedElement)javaElement).getType(); assertEquals(fileType.getClass(), javaType.getClass()); String fileMoniker = AS2Moniker.toString(fileType); String javaMoniker = AS2Moniker.toString(javaType); assertEquals(fileMoniker, javaMoniker); } if (fileElement instanceof Feature) { String fileClass = ((Feature)fileElement).getImplementationClass(); String javaClass = ((Feature)javaElement).getImplementationClass(); if (fileClass == null) { LibraryFeature implementation = ((Feature)fileElement).getImplementation(); if (implementation != null) { fileClass = implementation.getClass().getCanonicalName(); } } if (javaClass == null) { LibraryFeature implementation = ((Feature)javaElement).getImplementation(); if (implementation != null) { javaClass = implementation.getClass().getCanonicalName(); } } assertEquals(fileClass, javaClass); } if (fileElement instanceof org.eclipse.ocl.pivot.Class) { List<Element> fileTypes = new ArrayList<Element>(((org.eclipse.ocl.pivot.Class)fileElement).getSuperClasses()); List<Element> javaTypes = new ArrayList<Element>(((org.eclipse.ocl.pivot.Class)javaElement).getSuperClasses()); Collections.sort(fileTypes, MonikeredComparator.INSTANCE); Collections.sort(javaTypes, MonikeredComparator.INSTANCE); assertEquals(fileTypes.size(), javaTypes.size()); for (int i = 0; i < fileTypes.size(); i++) { Element fileType = fileTypes.get(i); Element javaType = javaTypes.get(i); String fileMoniker = AS2Moniker.toString(fileType); String javaMoniker = AS2Moniker.toString(javaType); assertEquals(fileMoniker, javaMoniker); } } } return asResource; } @Override protected void setUp() throws Exception { super.setUp(); // metamodelManager = OCL.createEnvironmentFactory(getProjectMap()).getMetamodelManager(); } @Override protected void tearDown() throws Exception { // EnvironmentFactoryResourceSetAdapter adapter = EnvironmentFactoryResourceSetAdapter.findAdapter(resourceSet); // if (adapter != null) { // MetamodelManager metamodelManager = adapter.getMetamodelManager(); // if (metamodelManager != null) { // metamodelManager.dispose(); // } // } // metamodelManager.dispose(); // metamodelManager = null; super.tearDown(); } public void testLoadAsString() throws Exception { OCL ocl = OCL.newInstance(getProjectMap()); String testFile = "library lib : lib = 'http://mylib'{\n"+ " type OclAny : AnyType {\n"+ " operation a(elem : Boolean) : Integer {\n"+ " post a: elem;\n"+ " }\n"+ " }\n"+ " type Bag(T) : BagType conformsTo Collection(T) {}\n"+ " type Class conformsTo OclAny {}\n"+ " type Boolean : PrimitiveType conformsTo OclAny {}\n"+ " type Collection(T) : CollectionType conformsTo OclAny {}\n"+ " type Enumeration conformsTo OclAny {}\n"+ " type Integer : PrimitiveType conformsTo Real {}\n"+ " type OclComparable conformsTo OclAny {\n"+ " operation compareTo(that : OclSelf) : Integer[1] => 'org.eclipse.ocl.pivot.library.oclany.OclComparableCompareToOperation';\n"+ " }\n"+ " type OclElement conformsTo OclAny {}\n"+ " type OclInvalid : InvalidType {}\n"+ " type OclSelf : SelfType conformsTo OclAny {}\n"+ " type OrderedCollection(T) : CollectionType conformsTo Collection(T) {}\n"+ " type OrderedSet(T) : OrderedSetType conformsTo Collection(T) {}\n"+ " type Real : PrimitiveType conformsTo OclComparable {}\n"+ " type Sequence(T) : SequenceType conformsTo Collection(T) {}\n"+ " type Set(T) : SetType conformsTo Collection(T) {}\n"+ " type String : PrimitiveType conformsTo OclAny {}\n"+ " type UniqueCollection(T) : CollectionType conformsTo Collection(T) {}\n"+ " type UnlimitedNatural : PrimitiveType conformsTo Integer {}\n"+ "}\n"; doLoadFromString(ocl, "string.oclstdlib", testFile); ocl.dispose(); } public void testImport() throws Exception { OCL ocl = OCL.newInstance(getProjectMap()); String testFile = "import 'minimal.oclstdlib';\n"+ "import 'minimal.oclstdlib';\n"+ "library lib : lib = 'http://minimal.oclstdlib'{\n"+ " type OclAny : AnyType {\n"+ " operation a(elem : Boolean) : Boolean {\n"+ " post a: result = elem;\n"+ " }\n"+ " }\n"+ "}\n"; Resource asResource = doLoadASResourceFromString(ocl, "string.oclstdlib", testFile); PivotMetamodelManager metamodelManager = PivotMetamodelManager.getAdapter(asResource.getResourceSet()); AnyType oclAnyType = metamodelManager.getStandardLibrary().getOclAnyType(); Iterable<Operation> ownedOperations = metamodelManager.getAllOperations(oclAnyType, FeatureFilter.SELECT_NON_STATIC); assertEquals(2, Iterables.size(ownedOperations)); // one from OclAny::= ocl.dispose(); } /** * Checks that the local oclstdlib.oclstdlib is the same as the pre-compiled * Java implementation. * * FIXME check the library/model version instead. */ public void testOCLstdlib() throws Exception { OCL ocl = OCL.newInstance(OCL.CLASS_PATH); // // Load OCL stdlib as a file. // ResourceSet resourceSet = ocl.getResourceSet(); getProjectMap().initializeResourceSet(resourceSet); URI libraryURI = URI.createPlatformResourceURI("org.eclipse.ocl.pivot/model/OCL-2.5.oclstdlib", true); BaseCSResource xtextResource = (BaseCSResource) resourceSet.createResource(libraryURI); JavaClassScope.getAdapter(xtextResource, getClass().getClassLoader()); ocl.getEnvironmentFactory().adapt(xtextResource); xtextResource.load(null); CS2AS cs2as = xtextResource.findCS2AS(); assertNoResourceErrors("Load failed", xtextResource); Resource fileResource = cs2as.getASResource(); assertNoResourceErrors("File Model", fileResource); assertNoUnresolvedProxies("File Model", fileResource); assertNoValidationErrors("File Model", fileResource); // // Load 'oclstdlib.oclstdlib' as pre-code-generated Java. // Resource javaResource = OCLstdlib.getDefault(); // PivotAliasCreator.refreshPackageAliases(javaResource); assertNoResourceErrors("Java Model", javaResource); assertNoUnresolvedProxies("Java Model", javaResource); assertNoValidationErrors("Java Model", javaResource); // // Check similar content // Map<String,Element> fileMoniker2asMap = computeMoniker2ASMap(Collections.singletonList(fileResource)); // for (String moniker : fileMoniker2asMap.keySet()) { // System.out.println("File : " + moniker); // } Map<String,Element> javaMoniker2asMap = computeMoniker2ASMap(Collections.singletonList(javaResource)); // for (String moniker : javaMoniker2asMap.keySet()) { // System.out.println("Java : " + moniker); // } // assertEquals(fileMoniker2asMap.size(), javaMoniker2asMap.size()); for (String moniker : fileMoniker2asMap.keySet()) { Element fileElement = fileMoniker2asMap.get(moniker); Element javaElement = javaMoniker2asMap.get(moniker); if (javaElement == null) { boolean isExpression = false; for (EObject eObject = fileElement; eObject != null; eObject = eObject.eContainer()) { if ((eObject instanceof ExpressionInOCL) || (eObject instanceof Constraint) || (eObject instanceof Annotation)) { isExpression = true; // Embedded OCL not present in Java break; } } if (isExpression) { continue; } } assertNotNull("Missing java element for '" + moniker + "'", javaElement); // @SuppressWarnings("null") // Can be null and we'll have an NPE as the test failure. Class<? extends Element> javaElementClass = javaElement.getClass(); assertEquals(fileElement.getClass(), javaElementClass); if (fileElement instanceof TypedElement) { Type fileType = ((TypedElement)fileElement).getType(); Type javaType = ((TypedElement)javaElement).getType(); assertEquals(fileType.getClass(), javaType.getClass()); String fileMoniker = AS2Moniker.toString(fileType); String javaMoniker = AS2Moniker.toString(javaType); assertEquals(fileMoniker, javaMoniker); } if (fileElement instanceof Feature) { String fileClass = ((Feature)fileElement).getImplementationClass(); String javaClass = ((Feature)javaElement).getImplementationClass(); if (fileClass == null) { LibraryFeature implementation = ((Feature)fileElement).getImplementation(); if (implementation != null) { fileClass = implementation.getClass().getCanonicalName(); } } if (javaClass == null) { LibraryFeature implementation = ((Feature)javaElement).getImplementation(); if (implementation != null) { javaClass = implementation.getClass().getCanonicalName(); } } assertEquals(fileClass, javaClass); } if (fileElement instanceof org.eclipse.ocl.pivot.Class) { List<Element> fileTypes = new ArrayList<Element>(((org.eclipse.ocl.pivot.Class)fileElement).getSuperClasses()); List<Element> javaTypes = new ArrayList<Element>(((org.eclipse.ocl.pivot.Class)javaElement).getSuperClasses()); Collections.sort(fileTypes, MonikeredComparator.INSTANCE); Collections.sort(javaTypes, MonikeredComparator.INSTANCE); assertEquals(fileTypes.size(), javaTypes.size()); for (int i = 0; i < fileTypes.size(); i++) { Element fileType = fileTypes.get(i); Element javaType = javaTypes.get(i); String fileMoniker = AS2Moniker.toString(fileType); String javaMoniker = AS2Moniker.toString(javaType); assertEquals(fileMoniker, javaMoniker); } } } ocl.dispose(); } /** * Checks that the OCL 2.5 AS model is the same as the pre-compiled * Java implementation. */ public void testOCLstdlib_AS() throws Exception { OCL ocl = OCL.newInstance(getProjectMap()); // // Load OCL stdlib as an AS file. // // ResourceSet resourceSet = ocl.getResourceSet(); // if (!EMFPlugin.IS_ECLIPSE_RUNNING) { // getProjectMap().initializeResourceSet(resourceSet); // } URI libraryURI = URI.createPlatformResourceURI("org.eclipse.ocl.pivot/model-gen/OCL-2.5.oclas", true); // // Load 'oclstdlib.oclstdlib' as pre-code-generated Java. // Resource javaResource = OCLstdlib.getDefault(); @SuppressWarnings("unused")Resource asResource = doLoadAS(ocl.getMetamodelManager().getASResourceSet(), libraryURI, javaResource, true); ocl.dispose(); } /** * Checks that the OCL 2.5 AS model is the same as the pre-compiled * Java implementation. */ public void testPivot_AS() throws Exception { OCLInternal ocl = OCLInternal.newInstance(getProjectMap(), null); // // Load OCL stdlib as an AS file. // // ResourceSet resourceSet = new ResourceSetImpl(); // getProjectMap().initializeResourceSet(resourceSet); // ASResourceFactoryRegistry.INSTANCE.configureResourceSet(resourceSet); URI pivotURI = URI.createPlatformResourceURI("org.eclipse.ocl.pivot/model-gen/Pivot.oclas", true); // // Load OCLmetamodel as pre-code-generated Java. // StandardLibraryInternal standardLibrary = ocl.getStandardLibrary(); Library asLibrary = (Library) standardLibrary.getPackage(); org.eclipse.ocl.pivot.Package oclMetamodel = OCLmetamodel.create(standardLibrary, asLibrary.getName(), asLibrary.getNsPrefix(), OCLmetamodel.PIVOT_URI); Resource javaResource = oclMetamodel.eResource(); @SuppressWarnings("unused") Resource asResource = doLoadAS(ocl.getMetamodelManager().getASResourceSet(), pivotURI, javaResource, false); // FIXME Contents are far from identical ocl.dispose(); } }