Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Using the index with an hierarchically directory tree
Using the index with an hierarchically directory tree [message #902781] Mon, 20 August 2012 12:09 Go to next message
Tobias Mayer is currently offline Tobias MayerFriend
Messages: 8
Registered: August 2012
Junior Member
Hello everybody,

I have some questions about the index in xtext and how to use it correctly.

In my case, an element is referable if it is on the same level or above in the directory tree (not beside / not under).

Here is a little example to better describe my concern:

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

generate myDsl "..."

Model:
 greetings+=element*;

element:
   Greeting
 | RefGreetings
 
;

Greeting:
 'Hello' name=ID '!';
 
RefGreetings:
 'Ref' el = [Greeting];


The directory tree is as follows:

root
|---subdir---file2.mydsl
|
|---file1.mydsl


The file file1.mydsl contains the following code:
Hello test1!


The file file2.mydsl contains the following code:
Hello test2!


It shall be possible now to extend the file file2.mydsl to:
Hello test2!
Ref test1 


But it is not allowed to extend the file file1.mydsl to:
Hello test1!
Ref test2 


To get this behavior, I have extended the classes ResourceDescriptionsBasedContainer and SimpleResourceDescriptionsBasedContainerManager (the sourcecode is at the end of this topic). An IEObjectDescription and an IResourceDescription contain an URI. The code beneath uses a method "visible(URI candidate, URI base)" to determine whether an IEObjectDescription or an IResourceDescription is visible to the current regarded IResourceDescription.

I'm pretty sure that something is wrong with my solution because I will get the following message when testing the code:

An internal error occurred during: "Xtext validation".
java.lang.UnsupportedOperationException


My questions are:

Is this the right way to get the desired behavior?
Does anyone know how to do it correctly?

Best Regards,

Tobias



public class MySimpleResourceDescriptionsBasedContainerManager extends
		SimpleResourceDescriptionsBasedContainerManager {

	@Override 
	public IContainer getContainer(IResourceDescription desc, IResourceDescriptions resourceDescriptions) {
		MyResourceDescriptionsBasedContainer result = new MyResourceDescriptionsBasedContainer(desc, resourceDescriptions);
		result.setUriToDescriptionCacheEnabled(false);
		return result;
	}
	
	@Override
	public List<IContainer> getVisibleContainers(IResourceDescription desc, IResourceDescriptions resourceDescriptions) {
		return Collections.singletonList(this.getContainer(desc, resourceDescriptions));
	}
	
}






public class MyResourceDescriptionsBasedContainer extends ResourceDescriptionsBasedContainer {
	
	
	protected IResourceDescription desc;
	
	
	@Override
	public Iterable<IEObjectDescription> getExportedObjects() {
		
		List<IEObjectDescription> filtered = Collections.emptyList();
		
		for (IEObjectDescription od : super.getExportedObjects())
		{
			if (this.visible(od.getEObjectURI(), desc.getURI()))
			{
				filtered.add(od);
			}
		}
		
		return filtered;
	}
	
	@Override
	public Iterable<IEObjectDescription> getExportedObjectsByType(EClass type) {
		
		
		List<IEObjectDescription> filtered = Collections.emptyList();
		
		for (IEObjectDescription od : super.getExportedObjectsByType(type))
		{	
			if (this.visible(od.getEObjectURI(), desc.getURI()))
			{
				filtered.add(od);
			}
		}
		
		return filtered;
	}
	
	@Override
	public Iterable<IEObjectDescription> getExportedObjectsByObject(EObject object) {
	
		List<IEObjectDescription> filtered = Collections.emptyList();
		
		for (IEObjectDescription od : super.getExportedObjectsByObject(object))
		{
			if (this.visible(od.getEObjectURI(), desc.getURI()))
			{
				filtered.add(od);
			}
		}	
		
		return filtered;
	}
	
	@Override
	public Iterable<IEObjectDescription> getExportedObjects(EClass type, QualifiedName qualifiedName, boolean ignoreCase) {
	
		
		List<IEObjectDescription> filtered = Collections.emptyList();
		
		for (IEObjectDescription od : super.getExportedObjects(type, qualifiedName, ignoreCase))
		{
			if (this.visible(od.getEObjectURI(), desc.getURI()))
			{
				filtered.add(od);
			}
		}	
		return filtered;
	}
	
	
	public MyResourceDescriptionsBasedContainer(IResourceDescription desc, IResourceDescriptions descriptions) {
		super(descriptions);
		this.desc = desc;
	}
	
	@Override
	public Iterable<IResourceDescription> getResourceDescriptions() {
		List<IResourceDescription> result = Collections.emptyList(); 
		
		for (IResourceDescription element : getUriToDescription().values())
		{
			if (visible(element.getURI(), this.desc.getURI()))
			{
				result.add(element);
			}
		}
		
		return result;
	}
	
	
	@Override
	public int getResourceDescriptionCount() {
		int counter = 0;
		for (IResourceDescription element : getUriToDescription().values())
		{
			if (visible(element.getURI(), this.desc.getURI()))
				counter++;
		}
		
		return counter;
	
	}
	
	@Override
	public boolean hasResourceDescription(URI uri) {
		return visible(uri, this.desc.getURI());
	}
	
	@Override
	public IResourceDescription getResourceDescription(URI uri) {
		if (hasResourceDescription(uri)){
			return getUriToDescription().get(uri);
		}
	}
	
	
	/* Common Methods */
	protected boolean visible(URI candidate, URI base)
	{
		boolean result = false;
		List<String> uriBase = getMyDirectory(base);
		List<String> uriCandidate = getMyDirectory(candidate);
		
			if (uriCandidate.size() <= uriBase.size()) {
				int limit = uriCandidate.size();
				boolean equal = true;
				int i = 0;
				for (i = 0; i < limit && equal; i++) {
					String str1 = uriBase.get(i);
					String str2 = uriCandidate.get(i);
					equal = str1.equals(str2);
				}

				result = equal;
			
			}
			return result;
		}
			
	protected List<String> getMyDirectory(URI paramUri) {
	
		List<String> pathStr = paramUri.segmentsList().subList(0,
				paramUri.segmentsList().size() - 1);
		return pathStr;
	}	

}




[Updated on: Mon, 20 August 2012 12:19]

Report message to a moderator

Re: Using the index with an hierarchically directory tree [message #903082 is a reply to message #902781] Tue, 21 August 2012 20:47 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3107
Registered: July 2009
Senior Member
Hi Tobias,

I'd try to bind a custom IContainer.Manager to achieve the described
visibility rules, too. You're probably hit by
https://bugs.eclipse.org/bugs/show_bug.cgi?id=372041

Regards,
Sebastian
--
Looking for professional support for Xtext, Xtend or Eclipse Modeling?
Go visit: http://xtext.itemis.com

Am 20.08.12 14:09, schrieb Tobias Mayer:
> Hello everybody,
>
> I have some questions about the index in xtext and how to use it correctly.
> In my case, an element is referable if it is on the same level or above
> in the directory tree (not beside / not under).
>
> Here is a little example to better describe my concern:
>
>
> grammar org.xtext.example.mydsl.MyDsl with
> org.eclipse.xtext.common.Terminals
>
> generate myDsl "..."
>
> Model:
> greetings+=element*;
>
> element:
> Greeting
> | RefGreetings
>
> ;
>
> Greeting:
> 'Hello' name=ID '!';
>
> RefGreetings:
> 'Ref' el = [Greeting];
>
>
> root
> |---subdir---file2.mydsl
> |
> |---file1.mydsl
>
>
> The file file1.mydsl contains the following code:
> Hello test1!
>
> The file file2.mydsl contains the following code:
> Hello test2!
>
> It shall be possible now to extend the file file2.mydsl to:
>
> Hello test2!
> Ref test1
>
> But it is not allowed to extend the file file1.mydsl to:
>
> Hello test1!
> Ref test2
>
> To get this behavior, I have extended the classes
> ResourceDescriptionsBasedContainer and
> SimpleResourceDescriptionsBasedContainerManager (the sourcecode is at
> the end of this topic). An IEObjectDescription and an
> IResourceDescription contain an URI. The code beneath uses a method
> "visible(URI candidate, URI base)" to determine whether an
> IEObjectDescription or an IResourceDescription is visible to the current
> regarded IResourceDescription.
>
> I'm pretty sure that something is wrong with my solution because I will
> get the following message when testing the code:
>
> An internal error occurred during: "Xtext validation".
> java.lang.UnsupportedOperationException
>
>
> My questions are:
>
> Is this the right way to get the desired behavior?
> Does anyone know how to do it correctly?
>
> Best Regards,
>
> Tobias
Re: Using the index with an hierarchically directory tree [message #903096 is a reply to message #902781] Tue, 21 August 2012 21:28 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
You could also use fully qualified names and name things after their
location; sort of like java packages. That would be needed to tell two
otherwise equally named elements apart anyway.

Containers is a more physical thing IMO - although your language may not
support it, but you could allow two containers to be superposed so that
things that are in the same logical namespace is visible even if coming
from two containers.

Regards
- henrik


On 2012-20-08 14:09, Tobias Mayer wrote:
> Hello everybody,
>
> I have some questions about the index in xtext and how to use it correctly.
> In my case, an element is referable if it is on the same level or above
> in the directory tree (not beside / not under).
>
> Here is a little example to better describe my concern:
>
>
> grammar org.xtext.example.mydsl.MyDsl with
> org.eclipse.xtext.common.Terminals
>
> generate myDsl "..."
>
> Model:
> greetings+=element*;
>
> element:
> Greeting
> | RefGreetings
>
> ;
>
> Greeting:
> 'Hello' name=ID '!';
>
> RefGreetings:
> 'Ref' el = [Greeting];
>
>
> root
> |---subdir---file2.mydsl
> |
> |---file1.mydsl
>
>
> The file file1.mydsl contains the following code:
> Hello test1!
>
> The file file2.mydsl contains the following code:
> Hello test2!
>
> It shall be possible now to extend the file file2.mydsl to:
>
> Hello test2!
> Ref test1
>
> But it is not allowed to extend the file file1.mydsl to:
>
> Hello test1!
> Ref test2
>
> To get this behavior, I have extended the classes
> ResourceDescriptionsBasedContainer and
> SimpleResourceDescriptionsBasedContainerManager (the sourcecode is at
> the end of this topic). An IEObjectDescription and an
> IResourceDescription contain an URI. The code beneath uses a method
> "visible(URI candidate, URI base)" to determine whether an
> IEObjectDescription or an IResourceDescription is visible to the current
> regarded IResourceDescription.
>
> I'm pretty sure that something is wrong with my solution because I will
> get the following message when testing the code:
>
> An internal error occurred during: "Xtext validation".
> java.lang.UnsupportedOperationException
>
>
> My questions are:
>
> Is this the right way to get the desired behavior?
> Does anyone know how to do it correctly?
>
> Best Regards,
>
> Tobias
Re: Using the index with an hierarchically directory tree [message #903221 is a reply to message #902781] Wed, 22 August 2012 15:00 Go to previous message
Tobias Mayer is currently offline Tobias MayerFriend
Messages: 8
Registered: August 2012
Junior Member
Thank you for your answers!

I have found the mistake which leads to the error message "An internal error occurred during: Xtext validation. java.lang.UnsupportedOperationException".

When I replace the lines containing "Collections.emptyList()" with "ArrayList<IEObjectDescription>()", the error message disappears and the behavior of the editor is as desired. (For the line containing "public Iterable<IResourceDescription> getResourceDescriptions()" I have to replace with the string "new ArrayList<IResourceDescription>()".)

But in general, is this the right way to realize this behavior or not?

The method "getScope(...) of the interface "IGlobalScopeProvider" (http://download.eclipse.org/modeling/tmf/xtext/javadoc/2.3/org/eclipse/xtext/scoping/IGlobalScopeProvider.html) has the parameter "com.google.common.base.Predicate<IEObjectDescription> filter". The method "IScope getGlobalScope(final Resource context, final EReference reference)" of the class "AbstractGlobalScopeDelegatingScopeProvider" sets the filter to null. This method is called, when the language infrastructure is generated.

Is it better to override the method getGlobalScope and add a filter?

Best Regards,

Tobias
Previous Topic:Couldn't resolve reference
Next Topic:problem for define dsl
Goto Forum:
  


Current Time: Wed Feb 19 23:16:50 GMT 2020

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

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

Back to the top