Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » UML2 » Resolving relative URI's in references(UML2 model load with relative element references between model fragments)
Resolving relative URI's in references [message #1701041] Wed, 08 July 2015 20:47 Go to next message
Andreas Henriksson is currently offline Andreas HenrikssonFriend
Messages: 6
Registered: April 2012
Junior Member
Hi,

I'm currently developing a model transform that operates on UML2 models and will produce various output formats such as custom XML and C code. My models are produced in RSA from IBM Rational and are therefor persisted in various emx and efx files (fragmented model).

Now, within my Eclipse model project where the model is developed we are forced to use linked resources for various historical reasons that ties us to a specific structure in the SCM system. This all works very well inside Eclipse/RSA when all files and paths are resolved through the Eclipse resource API and some other fairy dust. Outside of Eclipse my transform loads the complete model form the emx file through some special population of the URI map in the resource set that resolves the linked resource paths etc during load.
However once the logical file path in the project started deviating from the physical file path through the linked resources in the Eclipse project and some symbolic links in the file system, I'm noticing that element references between model fragments are not handled correctly. RSA persists these references as relative paths between the source and target model fragment,

I've done some extensive debugging and found that two things seems to be happening.

1. In the resource set URI converter, there is no workspace outside Eclipse so EMF defaults to create file URI's based on which for a relative URI becomes relative to the current working directory of the JVM.
2. In Eclipse/RSA there seems to be some RSA code that is handling the loading of models from disc and unlike the non-Eclipse case, all URI's that reach the resource set are platform:/resource based. So somewhere the relative URI is translated to a platform URI.

Now I'm wondering if there is any way to support the resolution of these relative URI's. I can't adress it in the resource set since I only have access to the target URI in there and not the context from which the reference is being resolved (source reference element and it's fragment URI). Therefor I have to "jack in" somewhere in the UML2 component form what I can discern.

Any pointers are greatly appreciated.


Thanks

Andreas
Re: Resolving relative URI's in references [message #1701115 is a reply to message #1701041] Thu, 09 July 2015 12:56 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. DamusFriend
Messages: 1176
Registered: July 2009
Location: Canada
Senior Member

Hi, Andreas,

What you don't have in your application is exactly what the EMF
run-time (and, by extension, RSA and other tools) rely on for
resolution of relative URIs: the context of the referencing resource.
You have to have the base URI on which to resolve a relative one,
ideally using the URI::resolve(...) API. You will only run into
trouble if you ever try to load a resource using a non-absolute URI.

I do recommend the approach of using platform:/resource URIs throughout
your code, relying on the URI map to normalize these to file: URIs
(which happens only when the resource set actually creates an input
stream to load a resource). If you just let the EMF run-time
implicitly resolve proxies as usual, then the context of the
referencing resource (for base URI) should always be available to
resolve the relative URIs. I don't understand how you would be losing
that context ...

HTH,

Christian

On 2015-07-08 20:47:55 +0000, Andreas Henriksson said:

> Hi,
>
> I'm currently developing a model transform that operates on UML2 models
> and will produce various output formats such as custom XML and C code.
> My models are produced in RSA from IBM Rational and are therefor
> persisted in various emx and efx files (fragmented model).
>
> Now, within my Eclipse model project where the model is developed we
> are forced to use linked resources for various historical reasons that
> ties us to a specific structure in the SCM system. This all works very
> well inside Eclipse/RSA when all files and paths are resolved through
> the Eclipse resource API and some other fairy dust. Outside of Eclipse
> my transform loads the complete model form the emx file through some
> special population of the URI map in the resource set that resolves the
> linked resource paths etc during load.
> However once the logical file path in the project started deviating
> from the physical file path through the linked resources in the Eclipse
> project and some symbolic links in the file system, I'm noticing that
> element references between model fragments are not handled correctly.
> RSA persists these references as relative paths between the source and
> target model fragment,
>
> I've done some extensive debugging and found that two things seems to
> be happening.
>
> 1. In the resource set URI converter, there is no workspace outside
> Eclipse so EMF defaults to create file URI's based on which for a
> relative URI becomes relative to the current working directory of the
> JVM.
> 2. In Eclipse/RSA there seems to be some RSA code that is handling the
> loading of models from disc and unlike the non-Eclipse case, all URI's
> that reach the resource set are platform:/resource based. So somewhere
> the relative URI is translated to a platform URI.
>
> Now I'm wondering if there is any way to support the resolution of
> these relative URI's. I can't adress it in the resource set since I
> only have access to the target URI in there and not the context from
> which the reference is being resolved (source reference element and
> it's fragment URI). Therefor I have to "jack in" somewhere in the UML2
> component form what I can discern.
>
> Any pointers are greatly appreciated.
>
>
> Thanks
>
> Andreas
Re: Resolving relative URI's in references [message #1701128 is a reply to message #1701115] Thu, 09 July 2015 13:18 Go to previous messageGo to next message
Andreas Henriksson is currently offline Andreas HenrikssonFriend
Messages: 6
Registered: April 2012
Junior Member
Hi Christian,

What I can't seem to understand is where I would "plugin" any code to enable myself to use platform URI's in my code or have a place to resolve the relative URI's. The only place I've found so far to make any customisations is the ResourceSet used and by extension and URIConverter used in the ResourceSet.
When the code reaches the resource set though, only the target URI is supplied and the context is unavailable to the resource set (but available earlier in the call chain where I fail to plug myself in).

It also seems like the actual loading of the model is done without platform URI's and it looks like RSA (or EMF in a workspace context?) is doing something during the deserialisation as the URI's that reaches the resource set in these cases are platform URI's while they are file URI's outside of Eclipse.

Are there any specialisation points in EMF or UML2 that one can implement and inject into the model handling for the non-Eclipse case since extension points are not possible outside Eclipse either?


Thanks

Andreas
Re: Resolving relative URI's in references [message #1701146 is a reply to message #1701128] Thu, 09 July 2015 14:02 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. DamusFriend
Messages: 1176
Registered: July 2009
Location: Canada
Senior Member

Hi, Andreas,

In RSA, the Eclipse Platform provides "native" support for the
platform: URL scheme, which means that EMF can use platform:/resource
URIs as a fully-normalized (primitive) scheme.

Outside of the Eclipse Platform, you need to populate EMF's URI map to
map platform:/resource/.../ folder paths to something for which your
host system provides URL scheme handlers, probably file: scheme.
Because the workspace's linked resources can map sub-folders to
logically unrelated folders in the file system, you will need to make
separate mappings for paths nested within other paths. This works
because, when EMF's URIConverter normalizes a URI, it always choose the
longest URI mapping that it can find.

But, you do still need to create resources in your ResourceSet using
the platform:/resource URIs exactly as you would in RSA, in order for
these mappings to work properly. As long as the mappings are complete,
creating resources, loading them, and resolving cross-reference proxies
should work seamlessly just as it does in RSA. The URIConverter will
use the mappings to translate the platform:/resource URIs to file: URIs
to create input streams for loading, but otherwise, everything just
operates on the abstract platform:/resource URIs.

The point in EMF/UML2 where you need to inject anything should only be
the resource's URIConverter's URI map. I think the problem you are
seeing is as a result of one or both of:

* incomplete URI mappings in the converter
* not specifying absolute platform:/resource/... URIs for the resources
in the resource set

With these two things in place, cross-reference proxies will always be
created with absolute platform:/resource URIs by EMF when deserializing
a resource.

HTH,

Christian


On 2015-07-09 13:18:29 +0000, Andreas Henriksson said:

> Hi Christian,
>
> What I can't seem to understand is where I would "plugin" any code to
> enable myself to use platform URI's in my code or have a place to
> resolve the relative URI's. The only place I've found so far to make
> any customisations is the ResourceSet used and by extension and
> URIConverter used in the ResourceSet. When the code reaches the
> resource set though, only the target URI is supplied and the context is
> unavailable to the resource set (but available earlier in the call
> chain where I fail to plug myself in).
>
> It also seems like the actual loading of the model is done without
> platform URI's and it looks like RSA (or EMF in a workspace context?)
> is doing something during the deserialisation as the URI's that reaches
> the resource set in these cases are platform URI's while they are file
> URI's outside of Eclipse.
>
> Are there any specialisation points in EMF or UML2 that one can
> implement and inject into the model handling for the non-Eclipse case
> since extension points are not possible outside Eclipse either?
>
> Thanks
>
> Andreas
Re: Resolving relative URI's in references [message #1701149 is a reply to message #1701146] Thu, 09 July 2015 14:13 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 6041
Registered: July 2009
Senior Member
HI

Getting the registrations right is hard. You may find

org.eclipse.ocl.pivot.internal.resource.StandaloneProjectMap

helpful. It does a more thorough job than EcorePlugin.ExtensionProcessor.

Regards

Ed Willink

On 09/07/2015 15:02, Christian W. Damus wrote:
> Hi, Andreas,
>
> In RSA, the Eclipse Platform provides "native" support for the
> platform: URL scheme, which means that EMF can use platform:/resource
> URIs as a fully-normalized (primitive) scheme.
>
> Outside of the Eclipse Platform, you need to populate EMF's URI map to
> map platform:/resource/.../ folder paths to something for which your
> host system provides URL scheme handlers, probably file: scheme.
> Because the workspace's linked resources can map sub-folders to
> logically unrelated folders in the file system, you will need to make
> separate mappings for paths nested within other paths. This works
> because, when EMF's URIConverter normalizes a URI, it always choose
> the longest URI mapping that it can find.
>
> But, you do still need to create resources in your ResourceSet using
> the platform:/resource URIs exactly as you would in RSA, in order for
> these mappings to work properly. As long as the mappings are
> complete, creating resources, loading them, and resolving
> cross-reference proxies should work seamlessly just as it does in
> RSA. The URIConverter will use the mappings to translate the
> platform:/resource URIs to file: URIs to create input streams for
> loading, but otherwise, everything just operates on the abstract
> platform:/resource URIs.
>
> The point in EMF/UML2 where you need to inject anything should only be
> the resource's URIConverter's URI map. I think the problem you are
> seeing is as a result of one or both of:
>
> * incomplete URI mappings in the converter
> * not specifying absolute platform:/resource/... URIs for the
> resources in the resource set
>
> With these two things in place, cross-reference proxies will always be
> created with absolute platform:/resource URIs by EMF when
> deserializing a resource.
>
> HTH,
>
> Christian
>
>
> On 2015-07-09 13:18:29 +0000, Andreas Henriksson said:
>
>> Hi Christian,
>>
>> What I can't seem to understand is where I would "plugin" any code to
>> enable myself to use platform URI's in my code or have a place to
>> resolve the relative URI's. The only place I've found so far to make
>> any customisations is the ResourceSet used and by extension and
>> URIConverter used in the ResourceSet. When the code reaches the
>> resource set though, only the target URI is supplied and the context
>> is unavailable to the resource set (but available earlier in the call
>> chain where I fail to plug myself in).
>>
>> It also seems like the actual loading of the model is done without
>> platform URI's and it looks like RSA (or EMF in a workspace context?)
>> is doing something during the deserialisation as the URI's that
>> reaches the resource set in these cases are platform URI's while they
>> are file URI's outside of Eclipse.
>>
>> Are there any specialisation points in EMF or UML2 that one can
>> implement and inject into the model handling for the non-Eclipse case
>> since extension points are not possible outside Eclipse either?
>>
>> Thanks
>>
>> Andreas
>
>
Re: Resolving relative URI's in references [message #1701152 is a reply to message #1701146] Thu, 09 July 2015 14:30 Go to previous messageGo to next message
Andreas Henriksson is currently offline Andreas HenrikssonFriend
Messages: 6
Registered: April 2012
Junior Member
Hi Christian,

Thanks for your time and guidance on this.

In my application outside Eclipse I am not creating any resources per se, I am only loading models from disc that are authored in RSA. The loading is done through a resource set instance into which I have registered the various path maps and UML2 packages and profiles.

I just realised that this initial call to getResource("absolute file uri", loadOnDemand==true) in the resource set is using an absolute file URI, but the model which is loaded and is constructed in RSA will have fragment references that are relative for project internal paths and platform:/resource based for cross project paths. The loading of these relative URIs that are triggered by the initial model load through the resource set.
It is these resource load calls that are part of the initial model load that I'm struggling to figure out how to adress since they are not initiated explicitly by me. Or will EMF somehow resolve them differently if the URI to the input model is a platform URI instead of a file URI?

An example even without the logical-physical file structures differing is this.

a/path is a Eclipse project root directory

a/path/model.emx
a/path/subdir1/fragment1.efx
a/path/subdir2/fragment2.efx

model.emx includes two packages that are stored in fragment1.efx and fragment2.efx and the href's in the .emx file will be "subdir1/fragment1.efx#..." and "subdir2/fragment2.efx#..." which are relative. A class in fragment1.efx contains an attribute whose type is defined in fragment2.efx and the reference will be "../subdir2/fragment2.efx#..." which is also relative.

So what I'm struggling with is how I can impact for example the loading uri's "subdir1/fragment1.efx#..." and "../subdir2/fragment2.efx#..." which are triggered by the loading of the model.emx resource.


Regards

Andreas
Re: Resolving relative URI's in references [message #1701165 is a reply to message #1701152] Thu, 09 July 2015 15:10 Go to previous messageGo to next message
Christian W. Damus is currently offline Christian W. DamusFriend
Messages: 1176
Registered: July 2009
Location: Canada
Senior Member

Hi, Andreas,

See some replies in-line, below.

HTH,

Christian


On 2015-07-09 14:30:12 +0000, Andreas Henriksson said:

> Hi Christian,
>
> Thanks for your time and guidance on this.
> In my application outside Eclipse I am not creating any resources per
> se, I am only loading models from disc that are authored in RSA. The
> loading is done through a resource set instance into which I have
> registered the various path maps and UML2 packages and profiles.

Right, sorry, what I meant by "creating a resource" is specifically
asking the ResourceSet to create a resource within it so that it may be
loaded. This is implicitly done by the getResource(URI, boolean) API
for a resource that isn't in the set, yet. I didn't mean actually
creating new resources in storage.


> I just realised that this initial call to getResource("absolute file
> uri", loadOnDemand==true) in the resource set is using an absolute file
> URI, but the model which is loaded and is constructed in RSA will have
> fragment references that are relative for project internal paths and
> platform:/resource based for cross project paths. The loading of these
> relative URIs that are triggered by the initial model load through the
> resource set.

Right, that's your problem. The cross-references between resources are
relative URIs assuming the workspace layout and platform:/resource
scheme. So, you need to specify the expected absolute
platform:/resource URIs initially when creating-for-loading the
resources in the ResourceSet. That is, the URI argument to
ResourceSet::getResource(URI, boolean) must be an absolute
platform:/resource URI.


> It is these resource load calls that are part of the initial model load
> that I'm struggling to figure out how to adress since they are not
> initiated explicitly by me.

Where are the URIs coming from that you use to load the initial set of
resources? If they are provided to your application as file: scheme
URIs, then you will have to denormalize them against your URI mappings
to determine the corresponding platform:/resource URIs.


> Or will EMF somehow resolve them differently if the URI to the input
> model is a platform URI instead of a file URI?

Right, if you start with platform:/resource URIs, then EMF will compute
all relative URI resolutions on that basis, and will have a consistent
view of the original RSA workspace layout of
projects/folders/resources. It will use the mappings to access the
file system when necessary for loading content.


> An example even without the logical-physical file structures differing is this.
>
> a/path is a Eclipse project root directory
>
> a/path/model.emx
> a/path/subdir1/fragment1.efx
> a/path/subdir2/fragment2.efx
>
> model.emx includes two packages that are stored in fragment1.efx and
> fragment2.efx and the href's in the .emx file will be
> "subdir1/fragment1.efx#..." and "subdir2/fragment2.efx#..." which are
> relative. A class in fragment1.efx contains an attribute whose type is
> defined in fragment2.efx and the reference will be
> "../subdir2/fragment2.efx#..." which is also relative.

In this simple case, it doesn't matter whether model.emx is loaded with
a file: or a platform: URI, because the relative paths are the same in
either scheme. But, you have to start with an absolute URI (of
whatever scheme) to load model.emx because EMF can't resolve the
relative references to the fragment resources if the base URI for
model.emx is also a relative URI.


> So what I'm struggling with is how I can impact for example the loading
> uri's "subdir1/fragment1.efx#..." and "../subdir2/fragment2.efx#..."
> which are triggered by the loading of the model.emx resource.

The only important thing here is that the model.emx resource have an
absolute URI. EMF takes care of the rest when resolving proxies
on-demand.


>
>
> Regards
>
> Andreas
Re: Resolving relative URI's in references [message #1701726 is a reply to message #1701165] Wed, 15 July 2015 09:22 Go to previous messageGo to next message
Andreas Henriksson is currently offline Andreas HenrikssonFriend
Messages: 6
Registered: April 2012
Junior Member
Christian,

I need to test using the platform:/resource URI to make some conclusions, but I'm still a bit doubtful about the relative references. Today I give an absolut file URI to the emx file when I invoke ResourceSet.getResource(uri, true). The relative type references are not resolved against this URI, or the particular parent fragment URI that the type reference is hosted in, but rather against the current working directory of the JVM. This tells med that EMF doesn't seem to be resolving the relative URI with a base from the URI of the containing resource.

Ed,

Thanks for the tip on the OCL pivot project. That code looks very complete. It seems to me that it does more than just setting up the URI maps and converters though. In particular I'm looking through the code and wondering how much the Adapter part is doing. How much of this code besides the URIMap and setting up the EcorePlugin.getPlatformResourceMap() are essential for a standalone environment?
I would prefer not to include parts of the OCL environment in my project, but if most code is essential I rather reuse your good work than mimic it.
Do the StandaloneProjectMap also handle virtual directories and linked resources? Currently I read the .project file and add these to the URI map since they will not be handled through the Eclipse resource framework. I would assume such a solution would otherwise be compatible with the StandaloneProjectMap.


Thanks again for the great insights and help.
Re: Resolving relative URI's in references [message #1703065 is a reply to message #1701726] Tue, 28 July 2015 12:14 Go to previous message
Christian W. Damus is currently offline Christian W. DamusFriend
Messages: 1176
Registered: July 2009
Location: Canada
Senior Member

Hi, Andreas,

I should be very surprised, indeed, to see EMF not using the correct
contextual resource URI for the resolution of HREFs. Every application
depends on this and the mechanism is quite reliable, assuming that the
resource set and resources are initially configured properly.

Is there any example code that you can share that demonstrates the
behaviour you're seeing? I think that in order to be of any further
help, I would need something that I can debug to identify where the
problem lies.

Cheers,

Christian


On 2015-07-15 09:22:57 +0000, Andreas Henriksson said:

> Christian,
>
> I need to test using the platform:/resource URI to make some
> conclusions, but I'm still a bit doubtful about the relative
> references. Today I give an absolut file URI to the emx file when I
> invoke ResourceSet.getResource(uri, true). The relative type references
> are not resolved against this URI, or the particular parent fragment
> URI that the type reference is hosted in, but rather against the
> current working directory of the JVM. This tells med that EMF doesn't
> seem to be resolving the relative URI with a base from the URI of the
> containing resource.
>
> Ed,
>
> Thanks for the tip on the OCL pivot project. That code looks very
> complete. It seems to me that it does more than just setting up the URI
> maps and converters though. In particular I'm looking through the code
> and wondering how much the Adapter part is doing. How much of this code
> besides the URIMap and setting up the
> EcorePlugin.getPlatformResourceMap() are essential for a standalone
> environment?
> I would prefer not to include parts of the OCL environment in my
> project, but if most code is essential I rather reuse your good work
> than mimic it.
> Do the StandaloneProjectMap also handle virtual directories and linked
> resources? Currently I read the .project file and add these to the URI
> map since they will not be handled through the Eclipse resource
> framework. I would assume such a solution would otherwise be compatible
> with the StandaloneProjectMap.
>
>
> Thanks again for the great insights and help.
Previous Topic:memberEnds not correctly ordered?
Next Topic:profile uml
Goto Forum:
  


Current Time: Sun Sep 23 21:03:47 GMT 2018

Powered by FUDForum. Page generated in 0.01865 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top