mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 00:38:56 +00:00
[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:
parent
17057231ae
commit
2aefc97350
3 changed files with 85 additions and 10 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue