Home » Modeling » TMF (Xtext) » Problems lazy linking resources
Problems lazy linking resources [message #1432583] |
Sat, 27 September 2014 10:46 |
diego sevilla Messages: 11 Registered: June 2010 |
Junior Member |
|
|
Hello all:
I've been having problems lazy linking my external resources. I've been following the advice in these other forum posts to no avail: https://www.eclipse.org/forums/index.php/t/295656/
Simplifying, my grammar is something like this:
Box returns Box:
'Box' name=PathNameSpec '{'
...
('sub-boxes' boxes+=BoxReference (boxes+=BoxReference)*)?
BoxReference returns BoxReference:
box=[Box] name=EString;
Each ".box" file contains a Box definition, but by BoxReference, you can reference other boxes that are in the same directory, or in subdirectories.
So, say I have Box1 that has a subbox of type Box2. These Box1 and Box2 are in corresponding files with the grammar extension.
First of all, if I load in advance all the boxes, that is,
resourceSet.getResource(URI.createURI("Box1.box"), true);
resourceSet.getResource(URI.createURI("Box2.box"), true);
Then all the refernces are satisfied without any problem.
However, I have lots of different boxes, and it would be overkill to load them all in advance.
So, I've been playing with lazy resource loading, scoping and such, but I cannot find a way of make it working. As advertised in the linked posts, I do the following:
1. I install a Linking service in which I take into account the getLinkedObjects function:
@Override
public List<EObject> getLinkedObjects(EObject context, EReference ref,
INode node) throws IllegalNodeException
{
System.err.println("getLinkedObjects: " + node.getText());
List<EObject> list = super.getLinkedObjects(context, ref, node);
if (list != null && list.isEmpty())
{
ResourceSet set = context.eResource().getResourceSet();
Resource r = set.getResource(URI.createURI(node.getText()).appendFileExtension("boxd"), true);
// should I do this?
// context.eResource().getContents().add((EObject) r);
list = Collections.singletonList((EObject)r.getContents().get(0));
}
return list;
}
2. I install a LazyLinker to override beforeModelLinked, but I have no idea what to put there. Reading the posts, I think I should be searching for lazy linked resources and removing them, then the getLinkedObject can populate the not found references:
/* (non-Javadoc)
* @see org.eclipse.xtext.linking.impl.AbstractCleaningLinker#beforeModelLinked(org.eclipse.emf.ecore.EObject, org.eclipse.xtext.diagnostics.IDiagnosticConsumer)
*/
@Override
protected void beforeModelLinked(EObject model,
IDiagnosticConsumer diagnosticsConsumer) {
super.beforeModelLinked(model, diagnosticsConsumer);
// what to do here?
}
What would I like to accomplish?
Well, I don't even know if this is the right way of doing this, but what I would like to have is some mechanism that, when trying to resolve a missing box, say "Box2", I could instruct the ResourceSet to go find, parse and read the file Box2.box, that is readily available in the file system. By the way, the references are not added, and I get extrange (to me) errors loading the resource, something in the lines of:
org.eclipse.emf.common.util.WrappedException: org.eclipse.emf.ecore.resource.impl.ResourceSetImpl$1DiagnosticWrappedException: java.io.FileNotFoundException: /[some long path]/Box2.boxd (File not found)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:231)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.doResolveLazyCrossReference(LazyLinkingResource.java:191)
...
I get a file not found exception, *But* the file actually exists there exactly at the path shown. (Why cannot find it?)
Well, hope somebody can help me, and thanks in advance.
diego.
|
|
| |
Re: Problems lazy linking resources [message #1433173 is a reply to message #1433135] |
Sun, 28 September 2014 09:51 |
diego sevilla Messages: 11 Registered: June 2010 |
Junior Member |
|
|
Hi, Christian:
Thanks for your response. I think I tried something similar, even defining the scope_BoxReference_box() function, but the problem is that at Scope level I don't get the "node" textual information. That is, I have the context information (The BoxReference object), and I have the Reference information (I see it is looking for a "box" reference), but I only get the name of the BoxReference, but not the textual information that resolves to a reference to a Box object (that is, which box I'm searching for). This is given by a INode, as far as I know, and the only way that I know of obtaining this information is via getLinkedObjects().
On the other hand, I could load all the boxes, and offer that as a Scope, but this is precisely what I didn't want to do in the first place.
Please, correct me if I'm wrong.
Thanks,
diego.
|
|
|
Re: Problems lazy linking resources [message #1433198 is a reply to message #1433173] |
Sun, 28 September 2014 10:52 |
|
Hi,
can you please tell us your business rules for the scoping.
what i understand is
you have boxes and you reference them by name?!? don you ?!?
and you want to restrict the visible boxes by certain criteria (i understood the path of the model file)
this can ususally be done by scoping.
what i dont understand is why you want to access the node model (although it is quite easy using nodemodelutils)
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
Re: Problems lazy linking resources [message #1433238 is a reply to message #1433198] |
Sun, 28 September 2014 12:30 |
diego sevilla Messages: 11 Registered: June 2010 |
Junior Member |
|
|
Hi, Christian,
Sorry if I didn't explained myself well. I answer you inine.
Christian Dietrich wrote on Sun, 28 September 2014 06:52Hi,
can you please tell us your business rules for the scoping.
what i understand is
you have boxes and you reference them by name?!? don you ?!?
and you want to restrict the visible boxes by certain criteria (i understood the path of the model file)
Yes, I reference them by name. To put a specific example, say I have a box type BoxType1, I reference it as:
Box BoxTypeX {
...
sub-boxes
BoxType1 boxname1
BoxType2 boxname2
}
Each "BoxType" is in fact a file that defines a box type. When the parser sees "BoxType1", it does know that this must denote a box, but the fact is that this box is *not* loaded beforehand, has to be parsed lazily, because it is defined using the same grammar, so when the parses actually see "BoxType1", I have to trigger the loading of the model, that will live in the file "BoxType1.box", and have to be loaded as another Box object, and added to the ResourceSet, so that the cross references could be correctly realized.
So I think in my case is not just restricting which boxes I can use to resolve the Scoping, because these boxes are actually not loaded beforehand (I want them to be loaded on demand)
Quote:
this can ususally be done by scoping.
what i dont understand is why you want to access the node model (although it is quite easy using nodemodelutils)
Do you have an example in which a scope function can access nodemodelutils to get the actual "BoxType" string that I could use to load on demand the corresponding "BoxType.box" file?
Thanks again,
diego.
|
|
| |
Re: Problems lazy linking resources [message #1433287 is a reply to message #1433254] |
Sun, 28 September 2014 14:19 |
diego sevilla Messages: 11 Registered: June 2010 |
Junior Member |
|
|
Hi again, Christian:
Christian Dietrich wrote on Sun, 28 September 2014 09:03Hi,
xtexts by name linking is by default lazy so i still do not understand your problem.
if you use that grammar out of the box (+ maybe a proper adaption of the nameprovider - you did not post the relevant part of the grammar)
what of that default behaviour is wrong?
Xtext may be lazy, but the fact is that whenever I tried to access data from BoxType1 referenced, it showed me an error of BoxType1 not known. The grammar I showed above is enough to illustrate the problem. Whenever you reference a Box that has not been loaded previously in the ResourceSet, whenever I try to access the data through the BoxReference type I get an exception, the object not being effectively resolved:
BoxReference someBoxReference ... // Obtained from the model
someBoxReferente.getBox().getSomething(); // This causes the error, as the box object returned is lazy and has not been resolved
As I said before, I can solve all these problems if I load (using resourceSet.getResource("BoxTpe1.box") ), but I have a lot of boxes and I don't want to load (resolve) them beforehand.
Hope that explains better my problem. Once more: if I don't load a given box type explicitly it does not automatically resolved.
Regards,
diego.
|
|
| |
Re: Problems lazy linking resources [message #1433347 is a reply to message #1433287] |
Sun, 28 September 2014 16:33 |
Ed Willink Messages: 7670 Registered: July 2009 |
Senior Member |
|
|
Hi
I suspect that your knowledge that
resourceSet.getResource("BoxTpe1.box")
is a good thing to do is not shared by EMF. Probably there is a
misunderstanding about the paths. I suggest you investigate the proxy
resolution failure that occurs in EcoreUtil.resolve(EObject proxy,
ResourceSet resourceSet). Just step through the retry after the
exceoption is thrown.
Regards
Ed Willink
On 28/09/2014 16:19, diego sevilla wrote:
> Hi again, Christian:
>
> Christian Dietrich wrote on Sun, 28 September 2014 09:03
>> Hi,
>>
>> xtexts by name linking is by default lazy so i still do not understand
>> your problem.
>>
>> if you use that grammar out of the box (+ maybe a proper adaption of
>> the nameprovider - you did not post the relevant part of the grammar)
>> what of that default behaviour is wrong?
>
>
> Xtext may be lazy, but the fact is that whenever I tried to access data
> from BoxType1 referenced, it showed me an error of BoxType1 not known.
> The grammar I showed above is enough to illustrate the problem. Whenever
> you reference a Box that has not been loaded previously in the
> ResourceSet, whenever I try to access the data through the BoxReference
> type I get an exception, the object not being effectively resolved:
>
>
> BoxReference someBoxReference ... // Obtained from the model
> someBoxReferente.getBox().getSomething(); // This causes the error, as
> the box object returned is lazy and has not been resolved
>
>
> As I said before, I can solve all these problems if I load (using
> resourceSet.getResource("BoxTpe1.box") ), but I have a lot of boxes and
> I don't want to load (resolve) them beforehand.
>
> Hope that explains better my problem. Once more: if I don't load a given
> box type explicitly it does not automatically resolved.
>
> Regards,
> diego.
>
|
|
|
Re: Problems lazy linking resources [message #1433465 is a reply to message #1433347] |
Sun, 28 September 2014 21:11 |
diego sevilla Messages: 11 Registered: June 2010 |
Junior Member |
|
|
Ed Willink wrote on Sun, 28 September 2014 12:33Hi
I suspect that your knowledge that
resourceSet.getResource("BoxTpe1.box")
is a good thing to do is not shared by EMF. Probably there is a
misunderstanding about the paths. I suggest you investigate the proxy
resolution failure that occurs in EcoreUtil.resolve(EObject proxy,
ResourceSet resourceSet). Just step through the retry after the
exceoption is thrown.
Regards
Ed Willink
Ed,
Sorry, my bad. At last it resulted that the file was not really there, so the FileNotFound exception was expected. When I put the file in place, everything worked.
Just for the record, I may have misunderstood Christian, but the fact is that the resources are not automatically resolved unless I load them by hand using ResourceSet.getResource(). Once I do it inside getLinkedObjects, then everything works. But, I suspect that in this case, the Scoping is not enough, because even at the time of the Scoping, you have to provide a set of EObjects where to look at for the exact reference, and the only option I would have would be to create proxy objects to all the boxes in the file system, having to traverse it.
Anyway, it works now, thanks all for your help.
Regards,
diego.
|
|
|
Goto Forum:
Current Time: Fri Sep 20 07:44:54 GMT 2024
Powered by FUDForum. Page generated in 0.03724 seconds
|