From ec1738a677979928fddb03a4883b87db90d9795a Mon Sep 17 00:00:00 2001 From: Sven Efftinge Date: Wed, 3 Aug 2011 11:38:37 +0200 Subject: First bits of ResourceDescriptionStrategy --- .../META-INF/MANIFEST.MF | 4 +- .../scoping/LazyCreationProxyUriConverterTest.java | 85 ++++++++++++++++++++++ .../scoping/ResourceDescriptionManagerTest.java | 50 +++++++++++++ .../emf/ecore/xcore/XcoreRuntimeModule.java | 8 ++ .../scoping/LazyCreationProxyUriConverter.java | 85 ++++++++++++++++++++++ .../scoping/XcoreResourceDescriptionStrategy.java | 71 ++++++++++++++++++ 6 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/LazyCreationProxyUriConverterTest.java create mode 100644 org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/ResourceDescriptionManagerTest.java create mode 100644 org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/LazyCreationProxyUriConverter.java create mode 100644 org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreResourceDescriptionStrategy.java diff --git a/org.eclipse.emf.ecore.xcore.tests/META-INF/MANIFEST.MF b/org.eclipse.emf.ecore.xcore.tests/META-INF/MANIFEST.MF index 87a56862d..39536412c 100644 --- a/org.eclipse.emf.ecore.xcore.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.emf.ecore.xcore.tests/META-INF/MANIFEST.MF @@ -9,5 +9,7 @@ Require-Bundle: org.eclipse.emf.ecore.xcore, org.junit4;bundle-version="4.5.0", org.eclipse.ui;bundle-version="3.5.2";resolution:=optional, org.eclipse.core.runtime;bundle-version="3.5.0";resolution:=optional, - org.eclipse.xtext.junit4;bundle-version="2.0.0" + org.eclipse.xtext.junit4;bundle-version="2.0.0", + org.eclipse.emf.codegen.ecore;bundle-version="2.7.0", + org.eclipse.xtext.common.types;bundle-version="2.0.0" Import-Package: org.eclipse.xtext.junit diff --git a/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/LazyCreationProxyUriConverterTest.java b/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/LazyCreationProxyUriConverterTest.java new file mode 100644 index 000000000..7131ecb86 --- /dev/null +++ b/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/LazyCreationProxyUriConverterTest.java @@ -0,0 +1,85 @@ +package org.eclipse.emf.ecore.xcore.tests.scoping; + +import org.eclipse.emf.codegen.ecore.genmodel.GenClass; +import org.eclipse.emf.codegen.ecore.genmodel.GenModelFactory; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EOperation; +import org.eclipse.emf.ecore.EcoreFactory; +import org.eclipse.emf.ecore.xcore.scoping.LazyCreationProxyUriConverter; +import org.eclipse.xtext.common.types.JvmGenericType; +import org.eclipse.xtext.common.types.TypesFactory; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.util.Pair; +import org.junit.Test; + +import static junit.framework.Assert.*; + +public class LazyCreationProxyUriConverterTest { + + @Test + public void testUriConversion_1() throws Exception { + LazyCreationProxyUriConverter converter = new LazyCreationProxyUriConverter(); + + GenClass genClass = GenModelFactory.eINSTANCE.createGenClass(); + final QualifiedName name = QualifiedName.create("foo.bar","Baz"); + converter.installProxyURI(URI.createFileURI("foo.test"), genClass, name); + + Pair proxyInfo = converter.decodeProxy(genClass); + assertSame(genClass.eClass(), proxyInfo.getFirst()); + assertEquals(name.toString(), proxyInfo.getSecond().toString()); + } + + @Test + public void testUriConversion_2() throws Exception { + LazyCreationProxyUriConverter converter = new LazyCreationProxyUriConverter(); + + EClass eClass = EcoreFactory.eINSTANCE.createEClass(); + final QualifiedName name = QualifiedName.create("foo.bar","Baz"); + converter.installProxyURI(URI.createFileURI("foo.test"), eClass, name); + + Pair proxyInfo = converter.decodeProxy(eClass); + assertSame(eClass.eClass(), proxyInfo.getFirst()); + assertEquals(name.toString(), proxyInfo.getSecond().toString()); + } + + @Test + public void testUriConversion_3() throws Exception { + LazyCreationProxyUriConverter converter = new LazyCreationProxyUriConverter(); + + JvmGenericType genericType = TypesFactory.eINSTANCE.createJvmGenericType(); + final QualifiedName name = QualifiedName.create("foo.bar","Baz"); + converter.installProxyURI(URI.createFileURI("foo.test"), genericType, name); + + Pair proxyInfo = converter.decodeProxy(genericType); + assertSame(genericType.eClass(), proxyInfo.getFirst()); + assertEquals(name.toString(), proxyInfo.getSecond().toString()); + } + + @Test + public void testUriConversion_4() throws Exception { + LazyCreationProxyUriConverter converter = new LazyCreationProxyUriConverter(); + + EOperation op = EcoreFactory.eINSTANCE.createEOperation(); + final QualifiedName name = QualifiedName.create("foo.bar","Baz"); + try { + converter.installProxyURI(URI.createFileURI("foo.test"), op, name); + fail(); + } catch (IllegalArgumentException e) { + + } + } + + @Test + public void testUriConversion_5() throws Exception { + LazyCreationProxyUriConverter converter = new LazyCreationProxyUriConverter(); + + JvmGenericType genericType = TypesFactory.eINSTANCE.createJvmGenericType(); + try { + converter.decodeProxy(genericType); + fail(); + } catch (IllegalArgumentException e) { + + } + } +} diff --git a/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/ResourceDescriptionManagerTest.java b/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/ResourceDescriptionManagerTest.java new file mode 100644 index 000000000..548b4fabc --- /dev/null +++ b/org.eclipse.emf.ecore.xcore.tests/src/org/eclipse/emf/ecore/xcore/tests/scoping/ResourceDescriptionManagerTest.java @@ -0,0 +1,50 @@ +package org.eclipse.emf.ecore.xcore.tests.scoping; + +import java.util.Iterator; + +import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage; +import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.emf.ecore.xcore.XPackage; +import org.eclipse.emf.ecore.xcore.XcoreInjectorProvider; +import org.eclipse.xtext.common.types.TypesPackage; +import org.eclipse.xtext.junit4.InjectWith; +import org.eclipse.xtext.junit4.XtextRunner; +import org.eclipse.xtext.junit4.util.ParseHelper; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.resource.IResourceDescription; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.google.inject.Inject; + +import static org.junit.Assert.*; + +@RunWith(XtextRunner.class) +@InjectWith(XcoreInjectorProvider.class) +public class ResourceDescriptionManagerTest { + + @Inject + private ParseHelper parser; + + @Inject + private IResourceDescription.Manager descriptionManager; + + @Test + public void testCreateResourceDescription() throws Exception { + XPackage xcorePackage = parser.parse("package foo.bar class Baz {}"); + IResourceDescription resourceDescription = descriptionManager.getResourceDescription(xcorePackage.eResource()); + + Iterator eclass = resourceDescription.getExportedObjectsByType(EcorePackage.Literals.ECLASS).iterator(); + Iterator genclass = resourceDescription.getExportedObjectsByType(GenModelPackage.Literals.GEN_CLASS).iterator(); + Iterator jvmTypes = resourceDescription.getExportedObjectsByType(TypesPackage.Literals.JVM_GENERIC_TYPE).iterator(); + final String expected = "foo.bar.Baz"; + assertEquals(expected, eclass.next().getName().toString()); + assertFalse(eclass.hasNext()); + assertEquals(expected, genclass.next().getName().toString()); + assertFalse(genclass.hasNext()); + assertEquals(expected, jvmTypes.next().getName().toString()); + assertEquals(expected+"Impl", jvmTypes.next().getName().toString()); + assertFalse(genclass.hasNext()); + } + +} diff --git a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java index 13a337779..ee9e9b630 100644 --- a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java +++ b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/XcoreRuntimeModule.java @@ -4,7 +4,9 @@ package org.eclipse.emf.ecore.xcore; import org.eclipse.emf.ecore.xcore.linking.XcoreLazyLinker; +import org.eclipse.emf.ecore.xcore.scoping.XcoreResourceDescriptionStrategy; import org.eclipse.xtext.linking.ILinker; +import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; import org.eclipse.xtext.serializer.ISerializer; import org.eclipse.xtext.serializer.impl.Serializer; @@ -24,4 +26,10 @@ public class XcoreRuntimeModule extends org.eclipse.emf.ecore.xcore.AbstractXcor { return Serializer.class; } + + public Class bindIDefaultResourceDescriptionStrategy() + { + return XcoreResourceDescriptionStrategy.class; + } + } diff --git a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/LazyCreationProxyUriConverter.java b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/LazyCreationProxyUriConverter.java new file mode 100644 index 000000000..7d9fc6e1b --- /dev/null +++ b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/LazyCreationProxyUriConverter.java @@ -0,0 +1,85 @@ +package org.eclipse.emf.ecore.xcore.scoping; + +import java.util.Map; + +import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.xtext.common.types.TypesPackage; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.util.Pair; +import org.eclipse.xtext.util.Tuples; + +import static com.google.common.collect.Maps.*; + +public class LazyCreationProxyUriConverter { + + private Map types = newHashMap(); + { + EClass eclass = EcorePackage.Literals.ECLASS; + EClass genClass = GenModelPackage.Literals.GEN_CLASS; + EClass jvmGenericType = TypesPackage.Literals.JVM_GENERIC_TYPE; + types.put(eclass.getName(), eclass); + types.put(genClass.getName(), genClass); + types.put(jvmGenericType.getName(), jvmGenericType); + } + + public void installProxyURI(URI resourceURI, EObject eobject, QualifiedName name) { + URI proxyURI = getProxyURI(resourceURI, eobject, name); + ((InternalEObject) eobject).eSetProxyURI(proxyURI); + } + + public URI getProxyURI(URI resourceURI, EObject eObject, QualifiedName name) { + if (!isSupported(eObject)) { + throw new IllegalArgumentException("eObjects of type " + eObject.eClass().getName() + " are not supported."); + } + return resourceURI.appendFragment(encodeFragment(eObject.eClass(), name)); + } + + private boolean isSupported(EObject eObject) { + return types.containsValue(eObject.eClass()); + } + + public Pair decodeProxy(EObject obj) { + if (obj != null) { + URI proxyURI = ((InternalEObject) obj).eProxyURI(); + if (proxyURI != null) { + return decodeProxyUri(proxyURI); + } + } + throw new IllegalArgumentException("" + obj); + } + + public Pair decodeProxyUri(URI proxyUri) { + final String fragment = proxyUri.fragment(); + if (fragment != null) { + Pair fragmentInfo = decodeFragment(fragment); + if (fragmentInfo != null) { + return fragmentInfo; + } + } + throw new IllegalArgumentException("couldn't parse URI :'" + proxyUri); + } + + private final static String DELIM = "%"; + + protected String encodeFragment(EClass eclass, QualifiedName name) { + return eclass.getName() + DELIM + name.toString(); + } + + protected Pair decodeFragment(String fragment) { + String[] segments = fragment.split(DELIM); + if (segments.length == 2) { + String clazzName = segments[0]; + QualifiedName name = QualifiedName.create(segments[1]); + if (types.containsKey(clazzName)) { + return Tuples.create(types.get(clazzName), name); + } + } + return null; + } + +} diff --git a/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreResourceDescriptionStrategy.java b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreResourceDescriptionStrategy.java new file mode 100644 index 000000000..be932ed79 --- /dev/null +++ b/org.eclipse.emf.ecore.xcore/src/org/eclipse/emf/ecore/xcore/scoping/XcoreResourceDescriptionStrategy.java @@ -0,0 +1,71 @@ +package org.eclipse.emf.ecore.xcore.scoping; + +import org.eclipse.emf.codegen.ecore.genmodel.GenClass; +import org.eclipse.emf.codegen.ecore.genmodel.GenModelFactory; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EcoreFactory; +import org.eclipse.emf.ecore.xcore.XClass; +import org.eclipse.xtext.common.types.JvmGenericType; +import org.eclipse.xtext.common.types.TypesFactory; +import org.eclipse.xtext.naming.QualifiedName; +import org.eclipse.xtext.resource.EObjectDescription; +import org.eclipse.xtext.resource.IEObjectDescription; +import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionStrategy; +import org.eclipse.xtext.util.IAcceptor; + +import com.google.inject.Inject; + +public class XcoreResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy { + + @Inject(optional=true) + private TypesFactory typesFactory = TypesFactory.eINSTANCE; + + @Inject(optional=true) + private EcoreFactory ecoreFactory = EcoreFactory.eINSTANCE; + + @Inject(optional=true) + private GenModelFactory genFactory = GenModelFactory.eINSTANCE; + + @Inject + private LazyCreationProxyUriConverter proxyTool; + + @Override + public boolean createEObjectDescriptions(EObject eObject, IAcceptor acceptor) { + if (eObject instanceof XClass) { + final XClass clazz = (XClass) eObject; + String name = clazz.getName(); + String packageName = clazz.getPackage().getName(); + QualifiedName qn = QualifiedName.create(packageName,name); + createGenModelDescription(eObject, acceptor, qn); + createEcoreDescription(eObject, acceptor, qn); + createJvmTypesDescription(eObject, acceptor, qn); + return false; + } + return true; + } + + protected void createJvmTypesDescription(EObject eObject, IAcceptor acceptor, QualifiedName qn) { + JvmGenericType theInterface = typesFactory.createJvmGenericType(); + proxyTool.installProxyURI(eObject.eResource().getURI(), theInterface, qn); + acceptor.accept(EObjectDescription.create(qn, theInterface)); + + QualifiedName implClassName = QualifiedName.create(qn.toString()+"Impl"); + JvmGenericType theImplClass = typesFactory.createJvmGenericType(); + proxyTool.installProxyURI(eObject.eResource().getURI(), theImplClass, implClassName); + acceptor.accept(EObjectDescription.create(implClassName, theImplClass)); + } + + protected void createEcoreDescription(EObject eObject, IAcceptor acceptor, QualifiedName qn) { + EClass eclass = ecoreFactory.createEClass(); + proxyTool.installProxyURI(eObject.eResource().getURI(), eclass, qn); + acceptor.accept(EObjectDescription.create(qn, eclass)); + } + + protected void createGenModelDescription(EObject eObject, IAcceptor acceptor, QualifiedName qn) { + GenClass genClass = genFactory.createGenClass(); + proxyTool.installProxyURI(eObject.eResource().getURI(), genClass, qn); + acceptor.accept(EObjectDescription.create(qn, genClass)); + } + +} -- cgit v1.2.3