Skip to main content



      Home
Home » Modeling » TMF (Xtext) » Validation with the Check Language across multiple files
Validation with the Check Language across multiple files [message #647737] Sat, 08 January 2011 07:59 Go to next message
Eclipse UserFriend
hi folks,

how can I apply checks defined in a .chk file globally across multiple files?

I have a check, that checks for the uniqueness of model elements based on multiple attributes, but this check only works within a single file.

If there is a duplicate model element that is stored in another file, the uniqueness check does not indicate an error.

thanks & regards,

steven
Re: Validation with the Check Language across multiple files [message #647738 is a reply to message #647737] Sat, 08 January 2011 08:23 Go to previous messageGo to next message
Eclipse UserFriend
Hi,

without having posted you check it's hard to say why it does not work.

btw. i wouldnot do this with check but rather build something like
org.eclipse.xtext.validation.NamesAreUniqueValidator

~Christian

[Updated on: Sat, 08 January 2011 08:31] by Moderator

Re: Validation with the Check Language across multiple files [message #647769 is a reply to message #647737] Sat, 08 January 2011 14:40 Go to previous messageGo to next message
Eclipse UserFriend
hi,

my check looks like this:

context Model ERROR "Modules must be globally unique":
let modules = this.elements.typeSelect(Module):
modules.forAll(m | !modules.without({m}).exists(anotherM | anotherM.name == m.name && anotherM.env == m.env))
;

this check indicates an error if two modules within the same file are the same (name and env are the same). however, if these modules are stored in two different files, the check does not indicate an error.

why wouldn't you do this with check? Is it not possible or is it considered a bad practice?

regards,

steven
Re: Validation with the Check Language across multiple files [message #647774 is a reply to message #647769] Sat, 08 January 2011 15:27 Go to previous messageGo to next message
Eclipse UserFriend
Hi,

your check does not work across files as you explicitly test only the
modules within the model (the let clause). You could use a helper
function that actually collects all modules (probably not very performant).

What Christian is heading at (I think) is to make use of the global
index of visible model elements (although the NamesAreUniqueValidator
mentioned only checks names within the current resource and not all of
them). You would provide this index (via your own IResourceDescription
implementation) with enough information for identifying duplicates and
query the index in the validation process. All this assumes that you are
using current Xtext version.

Alex
Re: Validation with the Check Language across multiple files [message #647775 is a reply to message #647774] Sat, 08 January 2011 15:49 Go to previous messageGo to next message
Eclipse UserFriend
Hi,

here some quick and dirty code that das some kind of global uniqueness validation (this works only for objects that are exported and maybe not performant - maybe using a own impl of IResourceDescription.Manager might help when performance problems occur)

package org.xtext.example.mydsl.validation;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.IResourceDescription;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.validation.Check;
import org.xtext.example.mydsl.myDsl.Element;
import org.xtext.example.mydsl.myDsl.MyDslPackage;

import com.google.inject.Inject;
 

public class MyDslJavaValidator extends AbstractMyDslJavaValidator {
	
	@Inject
	IResourceDescriptions resourceDescriptions;

	@Check
	public void checkGreetingStartsWithCapital(Element element) {
		int count = 0;
		for (Element e : getAllElements()) {
			if (e.eIsProxy()) {
				e = (Element) EcoreUtil.resolve(e, element);
			}
			if (element.getName().equals(e.getName())) {
				count++;
			}
		}
		if ( count >1 ) {
			error("Nicht unique", MyDslPackage.ELEMENT);
		}
	}
	
	private List<Element> getAllElements() {
		List<Element> result = new ArrayList<Element>();
		for (IResourceDescription resourceDescription : resourceDescriptions.getAllResourceDescriptions()) {
			for (IEObjectDescription eobjectDescription : resourceDescription.getExportedObjects(MyDslPackage.eINSTANCE.getElement())) {
				result.add((Element) eobjectDescription.getEObjectOrProxy());
			}
		}
		return result;
	}

}



~Christian
Re: Validation with the Check Language across multiple files [message #647776 is a reply to message #647775] Sat, 08 January 2011 16:00 Go to previous messageGo to next message
Eclipse UserFriend
And here some sample code with resource descriptions
package org.xtext.example.mydsl;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.impl.DefaultResourceDescription;
import org.xtext.example.mydsl.myDsl.Element;

public class MyDslResourceDescription extends DefaultResourceDescription {

	public MyDslResourceDescription(Resource resource,
			IQualifiedNameProvider nameProvider) {
		super(resource, nameProvider);
	}
	
	
	@Override
	protected IEObjectDescription createIEObjectDescription(EObject from) {
		if (from instanceof Element) {
			if (getNameProvider() == null)
				return null;
			String qualifiedName = getNameProvider().getQualifiedName(from);
			if (qualifiedName != null) {
				Map<String, String> userData = new HashMap<String, String>();
				userData.put("name", ((Element)from).getName());
				return EObjectDescription.create(qualifiedName, from, userData );
			}
		}
		return super.createIEObjectDescription(from);
	}

}


package org.xtext.example.mydsl;

import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.resource.IResourceDescription;
import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionManager;

public class MyDslResourceDescriptionManager extends
		DefaultResourceDescriptionManager {
	
	@Override
	protected IResourceDescription internalGetResourceDescription(
			Resource resource, IQualifiedNameProvider nameProvider) {
		return new MyDslResourceDescription(resource, nameProvider);
	}

}


/*
 * generated by Xtext
 */
package org.xtext.example.mydsl;

import org.eclipse.xtext.resource.IResourceDescription;

/**
 * Use this class to register components to be used at runtime / without the Equinox extension registry.
 */
public class MyDslRuntimeModule extends org.xtext.example.mydsl.AbstractMyDslRuntimeModule {

	public Class<? extends IResourceDescription.Manager> bindIResourceDescriptionsManager() {
		return MyDslResourceDescriptionManager.class;
	}
	
}



package org.xtext.example.mydsl.validation;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.IResourceDescription;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.validation.Check;
import org.xtext.example.mydsl.myDsl.Element;
import org.xtext.example.mydsl.myDsl.MyDslPackage;

import com.google.inject.Inject;
 

public class MyDslJavaValidator extends AbstractMyDslJavaValidator {
	
	@Inject
	IResourceDescriptions resourceDescriptions;

	@Check
	public void checkGreetingStartsWithCapital(Element element) {
		int count = 0;
		for (String name : getAllElementNames()) {
			if (element.getName().equals(name)) {
				count++;
			}
		}
		if ( count >1 ) {
			error("Nicht unique", MyDslPackage.ELEMENT);
		}
	}
	
	private List<String> getAllElementNames() {
		List<String> result = new ArrayList<String>();
		for (IResourceDescription resourceDescription : resourceDescriptions.getAllResourceDescriptions()) {
			for (IEObjectDescription eobjectDescription : resourceDescription.getExportedObjects(MyDslPackage.eINSTANCE.getElement())) {
				result.add(eobjectDescription.getUserData("name"));
			}
		}
		return result;
	}

}


~Christian
Re: Validation with the Check Language across multiple files [message #647777 is a reply to message #647737] Sat, 08 January 2011 16:57 Go to previous messageGo to next message
Eclipse UserFriend
hi christian,

thanks for your quick answer!!

I tried your solution, but if
resourceDescriptions.getAllResourceDescriptions()


is called, it returns no objects. resourceDescriptions is injected - it is not null.


My project has Xtext nature.
Do I have to do any additional setup so the index can list my resources?


s

[Updated on: Sat, 08 January 2011 16:58] by Moderator

Re: Validation with the Check Language across multiple files [message #647781 is a reply to message #647777] Sat, 08 January 2011 17:51 Go to previous messageGo to next message
Eclipse UserFriend
Hi,

for me it works without nany further modification.(triggering the validation explicitely). please ensure that a builder run has taken place.
maybe you can file a bugzilla feature request to ease such global validations.

~Christian

[Updated on: Sat, 08 January 2011 17:55] by Moderator

Re: Validation with the Check Language across multiple files [message #647808 is a reply to message #647781] Sun, 09 January 2011 08:52 Go to previous messageGo to next message
Eclipse UserFriend
hi christian,

can you make your xtext project availbale such that I can use it to identity the reason why my project does not work as expected?

thanks,

steven
Re: Validation with the Check Language across multiple files [message #647809 is a reply to message #647808] Sun, 09 January 2011 08:58 Go to previous messageGo to next message
Eclipse UserFriend
Hi,

the only thing i did not post is the grammar:

Model:
    elements+=Element*;

Element: name=ID;


please note: you have to call the validator explicitely.
have a look to the problems view to see the errors
occur / disoccur.

Did you try to debug to find out where the problem is?

~Christian

[Updated on: Sun, 09 January 2011 09:18] by Moderator

Re: Validation with the Check Language across multiple files [message #869364 is a reply to message #647776] Thu, 03 May 2012 05:40 Go to previous messageGo to next message
Eclipse UserFriend
Hello Christian,

I tried to implement your resource descriptions example, however the current version of xtext has some differences with the arguments to internalGetResourceDescription.

protected IResourceDescription internalGetResourceDescription(Resource resource, IDefaultResourceDescriptionStrategy strategy) {
	return new DefaultResourceDescription(resource, strategy, cache);
}


As you probably are aware, it is now asking for an IDefaultResourceDescriptionStrategy instead of an IQualifiedNameProvider. It looks as though the indexing has been revamped to support the notion of a cached mechanism.

Would you mind updating your example to support the current version? I had some luck with your down'n'dirty example, but it is slow, and doesn't propagate the duplicate detection to all files including duplicates unless the files are saved, or a complete project build is executed. If I could get your resource descriptions example to work, I would be grateful.
Re: Validation with the Check Language across multiple files [message #869394 is a reply to message #869364] Thu, 03 May 2012 06:38 Go to previous message
Eclipse UserFriend
You do not have to customize the manager at all. Simply bind your
custom IDefaultResouceDescriptionStrategy
Previous Topic:content assist problem
Next Topic:Creating JSON from EObjects
Goto Forum:
  


Current Time: Sun Jul 06 11:38:01 EDT 2025

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

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

Back to the top