Skip to main content



      Home
Home » Modeling » TMF (Xtext) » [Xtext 2.1] property databinding in own dsl
[Xtext 2.1] property databinding in own dsl [message #757800] Mon, 21 November 2011 13:00 Go to next message
Eclipse UserFriend
Hey,

in case of the domainmodel example: What would be the best approach to realise a databinding in a custom dsl?
With databinding I mean typing a (nested) property in some view input's attribute so that it can be read and written in different states of the application like e.g. in JSF, Flex etc..
entity.referenceA.referenceB

Is there some extension point in xbase for this case?

regards,
Max

[Updated on: Wed, 23 November 2011 20:57] by Moderator

Re: property databinding in own dsl [message #758268 is a reply to message #757800] Tue, 22 November 2011 09:12 Go to previous messageGo to next message
Eclipse UserFriend
Shameless plug nr. 37 this year of: http://dslmeinte.wordpress.com/2010/08/16/path-expressions-in-entity-models/ Wink
(Note: it's not directly compatible with the Domainmodel Example in Xtext 2.x anymore. I still have to do the port of the original to Xtext 2.x, as promised in a comment somewhere. However, it's definitely useable for adaptation.)

[Updated on: Tue, 22 November 2011 09:14] by Moderator

Re: property databinding in own dsl [message #758278 is a reply to message #758268] Tue, 22 November 2011 09:35 Go to previous messageGo to next message
Eclipse UserFriend
Thanks a lot for the link.
Re: property databinding in own dsl [message #758635 is a reply to message #758268] Wed, 23 November 2011 20:53 Go to previous messageGo to next message
Eclipse UserFriend
Hey,

I've found a shorter solution using xbase by writing an own XMemberFeatureCall rule which does not offer method calls:
grammar org.company.lang with org.eclipse.xtext.xbase.Xbase

generate lang "http://www.company.org/lang/Lang"

import "http://www.eclipse.org/xtext/xbase/Xbase" as xbase
import "http://www.eclipse.org/xtext/common/JavaVMTypes" as types

...

Input:
	'input' binding=DataBinding;

DataBinding returns xbase::XExpression:
	XFeatureCall
	({xbase::XMemberFeatureCall.memberCallTarget=current} '.'
		feature=[types::JvmIdentifiableElement|ValidID])*;


Now, I'm able to write sth like this assuming the root scope contains the entity variable a:
input a.name

XMemberFeatureCalls are already handled by the XbaseScopeProvider.

I do not want method calls, blocks and control flow statements. Just a simple property binding / property path.

Now, it works so far that I cannot write:
input a.name.substring(0, 1)
because this is not defined in the syntax but I can write:
input a.name.substring

Although the syntax is correct the method has no arguments and that's what is displayed in the IDE.
I may modify the scope to forbid method calls or override the error message in a validator - Is it possible to override other error messages like this one?

regards,
Max

[Updated on: Wed, 23 November 2011 21:26] by Moderator

Re: property databinding in own dsl [message #758667 is a reply to message #758635] Thu, 24 November 2011 02:47 Go to previous messageGo to next message
Eclipse UserFriend
I'd customize (override) the scope provider to give you only what you want, which is probably much less than the full set of JvmIdentifiableElements.
Re: property databinding in own dsl [message #758887 is a reply to message #758667] Thu, 24 November 2011 23:52 Go to previous messageGo to next message
Eclipse UserFriend
I've implemented this validator method to solve my problem:
	@Check
	def checkInputBinding(Input input) {
		val binding = input.getBinding() as XMemberFeatureCall;
		val feature = binding.getFeature();
		
		try {
			// retrieve expression's return type
			val method = feature as JvmOperation;
			val exprReturnTypeName = binding.getType(true).getType().identifier
			val getterPrefix = if (exprReturnTypeName.toLowerCase == "java.lang.boolean") "is" else "get" 
			
			// transform to setter method name if current method's name matches getter signature
			val methodName = method.identifier
			val regex = "^(.*?\\.)" + getterPrefix + "([A-Z][\\w]*)\\(\\)$"
			val setterName = methodName.replaceFirst(regex, "$1set$2(" + exprReturnTypeName + ")")
			
			if (methodName != setterName) { // if method is getter
				val callTarget = binding.getMemberCallTarget();
				val featuresAvailable = callTarget.getType(true).getType().eContents();
				val methodsAvailable = featuresAvailable.filter(typeof(JvmOperation))

				for (m : methodsAvailable)
					if (m.identifier.startsWith(setterName))
						return; // if setter is also available
			}
		} catch(ClassCastException e) { }
		
		// else: is not a property binding
		error("Valid property binding required. Please register a property with getter and setter.", UclPackage$Literals::INPUT__BINDING)
	}


But a I agree with you: Extending the scope provider would be better.
Where is the best position to filter the possible XMemberFeatureCalls in the scope?
Thought about sth like:
if (call.eContainingFeature() == UclPackage.Literals.INPUT__BINDING)
	// ... {do filter} ...

But where to put it?
Maybe the best solution would be to extend FilteredDelegatingScope and overwrite the filtering Predicate.apply() method but how to inject it?

regards,
Max

[Updated on: Fri, 25 November 2011 01:12] by Moderator

Re: property databinding in own dsl [message #758902 is a reply to message #758887] Fri, 25 November 2011 01:59 Go to previous message
Eclipse UserFriend
Finally, after reading some other posts I realised, that in this case it is better to use a validator: The user sees the scope he expects and gets a message that informs him about the required property binding.

However, I had another problem where I wanted to hide every method of a boundary class in the scope because I generate methods from expressions in a view language. Inside a expression several view properties should be visible but not my generated methods. Also the problem targeted with this thread should be solved by a custom implementation of VisibilityService and binding in MyLangRuntimeModule:
public class UclVisibilityService extends VisibilityService {

	@Inject
	private IJvmModelAssociations associations;
	
	@Override
	public boolean isVisible(final JvmMember jvmMember, JvmDeclaredType contextType) {
		final EObject o = associations.getPrimarySourceElement(jvmMember.eContainer());
		
		if (o instanceof View && jvmMember instanceof JvmOperation)
				return false;

		return super.isVisible(jvmMember, contextType);
	}
	
}


regards,
Max

[Updated on: Fri, 25 November 2011 02:00] by Moderator

Previous Topic:[Xtend2] Problem Creating JvmTypeReference to Existing Classes
Next Topic:Plugin Deployment Problem
Goto Forum:
  


Current Time: Wed Jul 23 16:32:17 EDT 2025

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

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

Back to the top