diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageFacade.xtend b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageFacade.xtend index f4809d066..2c572b55b 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageFacade.xtend +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageFacade.xtend @@ -9,15 +9,15 @@ package org.eclipse.xtext.resource.persistence import com.google.inject.Inject import com.google.inject.Provider -import org.eclipse.xtext.generator.AbstractFileSystemAccess2 -import org.eclipse.xtext.generator.IContextualOutputConfigurationProvider +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream import java.io.InputStream import java.io.OutputStream -import org.eclipse.xtext.generator.IFileSystemAccessExtension3 -import java.io.ByteArrayOutputStream -import java.io.ByteArrayInputStream import org.eclipse.emf.common.util.URI import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl +import org.eclipse.xtext.generator.AbstractFileSystemAccess2 +import org.eclipse.xtext.generator.IContextualOutputConfigurationProvider +import org.eclipse.xtext.generator.IFileSystemAccessExtension3 /** * @author Sven Efftinge - Initial contribution and API diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageLoadable.xtend b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageLoadable.xtend index 2b0b7f869..15fc58fcf 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageLoadable.xtend +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageLoadable.xtend @@ -9,11 +9,11 @@ package org.eclipse.xtext.resource.persistence import java.io.IOException import java.io.InputStream +import java.io.ObjectInputStream import java.util.zip.ZipInputStream import org.apache.log4j.Logger import org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl import org.eclipse.xtend.lib.annotations.Data -import java.io.ObjectInputStream /** * @author Sven Efftinge - Initial contribution and API diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageWritable.xtend b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageWritable.xtend index 35a4c4ada..e3c30fc90 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageWritable.xtend +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/ResourceStorageWritable.xtend @@ -71,7 +71,8 @@ import org.eclipse.xtend.lib.annotations.Data protected def void writeResourceDescription(StorageAwareResource resource, ZipOutputStream zipOut) { zipOut.putNextEntry(new ZipEntry("resource-description")) val description = resource.resourceServiceProvider.resourceDescriptionManager.getResourceDescription(resource); - val serializableDescription = SerializableResourceDescription.createCopy(description) + val serializableDescription = SerializableResourceDescription.createCopy(description) + convertExternalURIsToPortableURIs(serializableDescription, resource) val out = new ObjectOutputStream(zipOut); try { out.writeObject(serializableDescription); @@ -80,4 +81,13 @@ import org.eclipse.xtend.lib.annotations.Data } zipOut.closeEntry } + + def protected void convertExternalURIsToPortableURIs(SerializableResourceDescription description, StorageAwareResource resource) { + for (ref : description.referenceDescriptions) { + if (ref.targetEObjectUri.trimFragment != resource.URI) { + (ref as SerializableReferenceDescription).targetEObjectUri = resource.portableURIs.toPortableURI(resource, ref.targetEObjectUri) + } + } + } + } \ No newline at end of file diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/SerializableResourceDescription.xtend b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/SerializableResourceDescription.xtend index 8101f4480..02aaf3dc7 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/SerializableResourceDescription.xtend +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/resource/persistence/SerializableResourceDescription.xtend @@ -75,10 +75,13 @@ import static extension org.eclipse.xtext.resource.persistence.SerializationExte URI uRI def void updateResourceURI(URI uri) { - this.uRI = uri + for (ref : references) { + ref.updateResourceURI(uri, this.uRI) + } for (desc : descriptions) { desc.updateResourceURI(uri) } + this.uRI = uri } override protected computeExportedObjects() { @@ -100,12 +103,11 @@ import static extension org.eclipse.xtext.resource.persistence.SerializationExte for (i : 0 ..< descriptionsSize) { descriptions.add(in.readCastedObject) } - //reference descriptions are not portable atm. -// val referencesSize = in.readInt -// references = new ArrayList(referencesSize); -// for (i : 0 ..< referencesSize) { -// references.add(in.readCastedObject) -// } + val referencesSize = in.readInt + references = new ArrayList(referencesSize); + for (i : 0 ..< referencesSize) { + references.add(in.readCastedObject) + } val importedNamesSize = in.readInt importedNames = new ArrayList(importedNamesSize) for (i : 0 ..< importedNamesSize) { @@ -119,11 +121,10 @@ import static extension org.eclipse.xtext.resource.persistence.SerializationExte for (desc : descriptions) { out.writeObject(desc) } - //reference descriptions are not portable atm. -// out.writeInt(references.size) -// for (ref : references) { -// out.writeObject(ref) -// } + out.writeInt(references.size) + for (ref : references) { + out.writeObject(ref) + } out.writeInt(importedNames.size) for (name : importedNames) { out.writeQualifiedName(name) @@ -210,6 +211,13 @@ import static extension org.eclipse.xtext.resource.persistence.SerializationExte out.writeInt(indexInList) } + def void updateResourceURI(URI newURI, URI oldURI) { + sourceEObjectUri = newURI.appendFragment(sourceEObjectUri.fragment) + if (targetEObjectUri.trimFragment == oldURI) { + targetEObjectUri = newURI.appendFragment(targetEObjectUri.fragment) + } + } + } diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/linking/LangATestLanguageRuntimeModule.java b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/linking/LangATestLanguageRuntimeModule.java index 3441a0417..334a668f0 100644 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/linking/LangATestLanguageRuntimeModule.java +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/linking/LangATestLanguageRuntimeModule.java @@ -3,7 +3,11 @@ Generated with Xtext */ package org.eclipse.xtext.linking; +import org.eclipse.xtext.generator.AbstractFileSystemAccess2; +import org.eclipse.xtext.generator.JavaIoFileSystemAccess; import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.resource.persistence.IResourceStorageFacade; +import org.eclipse.xtext.resource.persistence.ResourceStorageFacade; import org.eclipse.xtext.resource.persistence.StorageAwareResource; import com.google.inject.Binder; @@ -24,4 +28,12 @@ public class LangATestLanguageRuntimeModule extends AbstractLangATestLanguageRun public Class bindXtextResource() { return StorageAwareResource.class; } + + public Class bindIResourceStorageFacade() { + return ResourceStorageFacade.class; + } + + public Class bindAbstractFileSystemAccess2() { + return JavaIoFileSystemAccess.class; + } } diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/resource/persistence/PortableURIsTest.xtend b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/resource/persistence/PortableURIsTest.xtend index 831110bab..9f3ed65a4 100644 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/resource/persistence/PortableURIsTest.xtend +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/resource/persistence/PortableURIsTest.xtend @@ -7,16 +7,18 @@ *******************************************************************************/ package org.eclipse.xtext.resource.persistence +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import org.eclipse.emf.common.util.URI import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.EcorePackage -import org.junit.Assert -import org.junit.Test +import org.eclipse.emf.ecore.util.EcoreUtil import org.eclipse.xtext.junit4.AbstractXtextTests import org.eclipse.xtext.linking.LangATestLanguageStandaloneSetup -import org.eclipse.xtext.resource.XtextResourceSet -import org.eclipse.emf.common.util.URI import org.eclipse.xtext.linking.langATestLanguage.Main -import org.eclipse.emf.ecore.util.EcoreUtil +import org.eclipse.xtext.resource.XtextResourceSet +import org.junit.Assert +import org.junit.Test /** * @author Sven Efftinge - Initial contribution and API @@ -48,6 +50,33 @@ class PortableURIsTest extends AbstractXtextTests { assertSame(extended, resourceA.getEObject(portableURI.fragment)) } + @Test def void testPortableReferenceDescriptions() { + val resourceSet = get(XtextResourceSet) + val resourceA = resourceSet.createResource(URI.createURI("hubba:/bubba.langatestlanguage")) as StorageAwareResource + val resourceB = resourceSet.createResource(URI.createURI("hubba:/bubba2.langatestlanguage")) as StorageAwareResource + resourceB.load(getAsStream(''' + type B + '''), null) + resourceA.load(getAsStream(''' + import 'hubba:/bubba2.langatestlanguage' + + type A extends B + '''), null) + val bout = new ByteArrayOutputStream + val writable = resourceA.resourceStorageFacade.createResourceStorageWritable(bout) + writable.writeResource(resourceA) + + val loadable = resourceA.resourceStorageFacade.createResourceStorageLoadable(new ByteArrayInputStream(bout.toByteArray)) + + val resourceC = resourceSet.createResource(URI.createURI("hubba:/bubba3.langatestlanguage")) as StorageAwareResource + resourceC.load(loadable) + + val refDesc = resourceC.resourceDescription.referenceDescriptions.head + assertSame((resourceB.contents.head as Main).types.head, resourceSet.getEObject(refDesc.targetEObjectUri, false)) + assertSame((resourceC.contents.head as Main).types.head, resourceSet.getEObject(refDesc.sourceEObjectUri, false)) + } + + @Test def void testEObjectRelativeFragments() { checkFragmentBothDirections(EcorePackage.eINSTANCE, EcorePackage.eINSTANCE.EAnnotation_Details) checkFragmentBothDirections(EcorePackage.eINSTANCE.EAttribute_EAttributeType, EcorePackage.eINSTANCE.EAttribute_EAttributeType) diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/resource/persistence/SerializableResourceDescriptionTest.xtend b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/resource/persistence/SerializableResourceDescriptionTest.xtend index 781db16bb..66d96da15 100644 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/resource/persistence/SerializableResourceDescriptionTest.xtend +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/resource/persistence/SerializableResourceDescriptionTest.xtend @@ -64,17 +64,17 @@ class SerializableResourceDescriptionTest { val after = in.readObject as SerializableResourceDescription assertEquals(before.URI, after.URI) assertEquals(before.importedNames, after.importedNames) - //TODO references are not yet persisted -// assertEquals(before.references.size, after.references.size) -// for (int i : 0..