[storage] allow nullable URIs. E.g. ReferenceDescription containerEObjectURI might be null if the reference is in a root eobject.

Change-Id: I25a354ca8d05a97c24be34c65170167f37f5128e
This commit is contained in:
Sven Efftinge 2015-02-13 08:49:34 +01:00
parent 17057231ae
commit 2aefc97350
3 changed files with 85 additions and 10 deletions

View file

@ -21,7 +21,7 @@ import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.xtend.lib.annotations.Data
import org.eclipse.xtext.naming.QualifiedName
import org.eclipse.xtext.resource.IEObjectDescription
import org.eclipse.xtext.resource.IResourceServiceProvider
import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider
import org.eclipse.xtext.scoping.IGlobalScopeProvider
/**
@ -45,9 +45,8 @@ class PortableURIs {
public static val PORTABLE_SCHEME = "portable"
@Inject IGlobalScopeProvider globalScopeProvider
// @Inject LazyURIEncoder lazyURIencoder
@Inject EPackage.Registry packageRegistry
@Inject IResourceServiceProvider.Registry resourceServiceProviderRegistry
@Inject ResourceDescriptionsProvider resourceDescriptionsProvider
/**
* @return whether the given string is a portable URI fragment
@ -89,9 +88,12 @@ class PortableURIs {
*/
def URI toPortableURI(StorageAwareResource sourceResource, URI targetURI) {
val to = sourceResource.resourceSet.getResource(targetURI.trimFragment, false)?.getEObject(targetURI.fragment)
val result = toPortableURI(sourceResource, to);
if (result != null) {
return result
// if it points to some registered ecore, there's no resourceSet and the result is not portable
if (to == null || to.eResource.resourceSet != null) {
val result = toPortableURI(sourceResource, to);
if (result != null) {
return result
}
}
return null
}
@ -121,8 +123,8 @@ class PortableURIs {
* @return a portable URI fragment, or <code>null</code> if the give EObject isn't itself or is not contained in an exported EObjectDescription
*/
protected def String getPortableURIFragment(EObject obj) {
val serviceProvider = resourceServiceProviderRegistry.getResourceServiceProvider(EcoreUtil.getURI(obj))
val desc = serviceProvider?.resourceDescriptionManager?.getResourceDescription(obj.eResource)
val descriptions = resourceDescriptionsProvider.getResourceDescriptions(obj.eResource)
val desc = descriptions.getResourceDescription(obj.eResource.URI)
if (desc == null) {
return null
}

View file

@ -242,11 +242,19 @@ package class SerializationExtensions {
}
def static URI readURI(ObjectInput in) {
return URI::createURI(in.readUTF)
val stringRep = in.readUTF
if (stringRep == "NULL") {
return null
}
return URI::createURI(stringRep)
}
def static void writeURI(ObjectOutput out, URI uri) {
out.writeUTF(uri.toString)
if (uri == null) {
out.writeUTF("NULL")
} else {
out.writeUTF(uri.toString)
}
}
def static QualifiedName readQualifiedName(ObjectInput in) {

View file

@ -62,6 +62,11 @@ class SerializableResourceDescriptionTest {
objectOut.writeObject(before)
val in = new ObjectInputStream(new ByteArrayInputStream(bout.toByteArray))
val after = in.readObject as SerializableResourceDescription
assertDescriptionsEqual(before, after)
}
def void assertDescriptionsEqual(SerializableResourceDescription before, SerializableResourceDescription after) {
assertEquals(before.URI, after.URI)
assertEquals(before.importedNames, after.importedNames)
@ -86,4 +91,64 @@ class SerializableResourceDescriptionTest {
assertEquals(beforeDesc.EObjectURI, afterDesc.EObjectURI)
}
}
@Test def void testNullSafeSerialization() {
val uri = URI::createURI("file:/foo/bar.baz.foo")
val before = new SerializableResourceDescription => [
URI = uri
references = #[
new SerializableReferenceDescription => [
sourceEObjectUri = uri.appendFragment('foo')
targetEObjectUri = null
containerEObjectURI = uri.appendFragment('baz')
EReference = EcorePackage.eINSTANCE.EAnnotation_Contents
indexInList = 1
],
new SerializableReferenceDescription => [
sourceEObjectUri = null
targetEObjectUri = uri.appendFragment('hubble2')
containerEObjectURI = uri.appendFragment('baz2')
EReference = EcorePackage.eINSTANCE.EAnnotation_Contents
indexInList = 2
],
new SerializableReferenceDescription => [
sourceEObjectUri = uri.appendFragment('foo')
targetEObjectUri = uri.appendFragment('hubble2')
containerEObjectURI = null
EReference = EcorePackage.eINSTANCE.EAnnotation_Contents
indexInList = 2
],
new SerializableReferenceDescription => [
sourceEObjectUri = uri.appendFragment('foo')
targetEObjectUri = null
containerEObjectURI = null
EReference = EcorePackage.eINSTANCE.EAnnotation_Contents
indexInList = 2
],
new SerializableReferenceDescription => [
sourceEObjectUri = null
targetEObjectUri = null
containerEObjectURI = null
EReference = EcorePackage.eINSTANCE.EAnnotation_Contents
indexInList = 2
]
]
descriptions = #[
new SerializableEObjectDescription => [
EObjectURI = uri.appendFragment('baz')
qualifiedName = QualifiedName.create('foo','baz')
EClass = EcorePackage.eINSTANCE.EAttribute
userData = newHashMap('myKey' -> 'myValue')
]
]
importedNames = #[QualifiedName.create('foo'), QualifiedName.create('foo','bar')]
]
val bout = new ByteArrayOutputStream()
val objectOut = new ObjectOutputStream(bout)
objectOut.writeObject(before)
val in = new ObjectInputStream(new ByteArrayInputStream(bout.toByteArray))
val after = in.readObject as SerializableResourceDescription
assertDescriptionsEqual(before, after)
}
}