Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » how to verify object on object change(setter called)
how to verify object on object change(setter called) [message #625756] Wed, 22 September 2010 10:20 Go to next message
moritz du is currently offline moritz duFriend
Messages: 102
Registered: February 2010
Senior Member
i am using emf to read/ write xml based on a xsd. first i tried jaxb an it's generated code: the main problem was the lack of an (in Memory) object validation. It was very easy to validate on reading and writing the xml but no one could tell if the object is still consistent after a setter was called.

i need java code generated from xsd that behaves similar than hand crafted code: detecting misuse/errors as soon as possible. a hand crafted setter would validate the input and throws an Exception if input is in conflict with model/ didn't pass the check.

my question is how to get this behavior with emf-generated-code? Is it possible to get code that never allows an invalid object in memory? (i don't want a invalid value be set on any part of EObject)
i already read something about the Oberserver/Adapter thing in EMF. and i allready got some code that reads/writes xml. and thx to generated example code -- i' am also able to validate the content of a resource.
but how to get a "contentAdapter?" that throws an exception on setting an invalid value and resets the old value?

thx in advance
Re: how to verify object on object change(setter called) [message #627840 is a reply to message #625756] Thu, 23 September 2010 06:03 Go to previous messageGo to next message
Animesh Kumar is currently offline Animesh KumarFriend
Messages: 18
Registered: September 2010
Location: Bangalore
Junior Member
Hi,
As much as i could understand your problem statement, you wanted an EMF Generated code for validation in your model.
If that is what you required then you can create Constraints using Annotations in your model. You can then regenerate your code which will create a ModelValidator class in your util package. In the ModelValidator class you will have a method generated for your constraint.
In the method you will have a code snippet something like this:-
if (false) {
if (diagnostics != null) {
diagnostics.add(createDiagnostic(Diagnostic.ERROR,
DIAGNOSTIC_SOURCE, 0,
"_UI_GenericConstraint_diagnostic",
new Object[] {"ValidUrl", getObjectLabel(webSite, context) },
new Object[] { webSite }, context));
}

You will have to change false by a boolean value which specifies whether the constraint is satified or not.


You can either directly call the validation after setting the value or you can use adapters. Even a basic Adapter is sufficient and you would not require a ContentAdapter. You can call the validate method in the notifyChanged method of the Adapter.

About resetting the value. You will need Adapters for that. Whenever a notification is sent, the notification consists of both old value as well as the new value. You can validate and if the value is incorrect then you can reset it back to the old value.

I would like to know why do you need to reset the value back to previous state automatically. That is a error done by user who is using the application and user should only rectify it. You can just specify that there is an error and the user cannot proceed till the error is rectified.


Regards,
Animesh

[Updated on: Thu, 23 September 2010 06:04]

Report message to a moderator

Re: how to verify object on object change(setter called) [message #628064 is a reply to message #625756] Thu, 23 September 2010 08:58 Go to previous messageGo to next message
moritz du is currently offline moritz duFriend
Messages: 102
Registered: February 2010
Senior Member
thx,

but i already have constraints in my model. since my model is xsd there are tags like
<xs:restriction base="xs:string">
      <xs:pattern value="\d{38}_\d{2}_\d{10}"/>
    </xs:restriction>

i could use this constraints on reading xml files (from example code):
for (EObject eObject : resource.getContents()) {
						Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObject);
						if (diagnostic.getSeverity() != Diagnostic.OK) {
							printDiagnostic(diagnostic, "");
						}
					}

so if all is "ok" i know i have a valid object in memory. the problem is that every "setAttribute" on this Object could destroy consistency with underlying model. for example i set the value "12" for a field with the restriction - see above-. at this moment the generated code destroyed or allowed to destroy the consistency with underlying model.
the question is: how could i use the information about constraints (the information must be somewhere in generated code?!) as early as possible -- on changing the object. (as i stated earlier, in handwritten code this information would "enrich" the setter code - throwing an Exception if someone tries to pass an argument not valid in underlying model )
EDIT:
"I would like to know why do you need to reset the value back to previous state automatically. That is a error done by user who is using the application and user should only rectify it."
The point is i am writing an api that read/writes xml based on xsd. And such an api should throw exception if someone tries to pass invalid arguments (the xsd says what is invalid). thwrowing one single exception for all missused setters at the end/before writing the xml would be little late. and saying thats not the fault of the api but the fault of api user isn't really right, isn't it? my first try to write such an xsd-backed xml-api was jaxb but there was the lack of in memory object validation (the are one died project that does this). someone said use emf - now i am here and ask the same question Smile
Is it to difficult or not needed(why?) to write an code generator that adds the field validation directly to the setters?

[Updated on: Thu, 23 September 2010 09:15]

Report message to a moderator

Re: how to verify object on object change(setter called) [message #628244 is a reply to message #628064] Thu, 23 September 2010 10:40 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 30551
Registered: July 2009
Senior Member
You could use something like an EContentAdapter to listen to all changes
and invoke the validator whenever an object changes.

Keep in mind though that no matter what, you will have instances that
aren't valid. For example, a feature might be required to be set, or
contain at least one value, but until you set it, or add a value, it
won't be valid.


tanteanni@hotmail.com wrote:
> thx,
>
> but i already have constraints in my model. since my model is xsd
> there are tags like
>
> <xs:restriction base="xs:string">
> <xs:pattern value="\d{38}_\d{2}_\d{10}"/>
> </xs:restriction>
>
> i could use this constraints on reading xml files (from example code):
>
> for (EObject eObject : resource.getContents()) {
> Diagnostic diagnostic =
> Diagnostician.INSTANCE.validate(eObject);
> if (diagnostic.getSeverity() != Diagnostic.OK) {
> printDiagnostic(diagnostic, "");
> }
> }
>
> so if all is "ok" i know i have a valid object in memory. the problem
> is that every "setAttribute" on this Object could destroy consistency
> with underlying model. for example i set the value "12" for a field
> with the restriction - see above-. at this moment the generated code
> destroyed or allowed to destroy the consistency with underlying model.
> the question is: how could i use the information about constraints
> (the information must be somewhere in generated code?!) as early as
> possible -- on changing the object. (as i stated earlier, in
> handwritten code this information would "enrich" the setter code -
> throwing an Exception if someone tries to pass an argument not valid
> in underlying model )
Re: how to verify object on object change(setter called) [message #628273 is a reply to message #625756] Thu, 23 September 2010 11:27 Go to previous messageGo to next message
moritz du is currently offline moritz duFriend
Messages: 102
Registered: February 2010
Senior Member
thx for answering probably "noobish"-(emf) questions - but here come more:

" For example, a feature might be required to be set, or
contain at least one value, but until you set it, or add a value, it
won't be valid. "

that's a point. but this is no argument to ignore model constraints for generating setter code, isn't it? then we would have at least "good" setters (can't destroy consistency) but "bad" constructors (not able to construct valid object).

apart from that: "You could use something like an EContentAdapter to listen to all changes and invoke the validator whenever an object changes. "
is there any example code that does this? or can someone create a quick example based on generated classes like "MyModelValidator". (The problem is i don't know where to look for the classes i need and then let eclipse' autocompletion give me a hint what method probably to use.)

another question that slowly arises is: What is best or at least good Practice to write an xsd-backed-xml-api (using emf)? is it at all a bad idea to give immediate feedback (exception) on using a setter wrong?
if not what are alternatives to EContentAdapter/Validator? Write own (constraint sensitive) setters and rewrite/check/complete the on model change?


Re: how to verify object on object change(setter called) [message #628671 is a reply to message #628273] Thu, 23 September 2010 15:37 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 30551
Registered: July 2009
Senior Member
Comments below.

tanteanni@hotmail.com wrote:
> thx for answering probably "noobish"-(emf) questions - but here come
> more:
>
> " For example, a feature might be required to be set, or
> contain at least one value, but until you set it, or add a value, it
> won't be valid. "
>
> that's a point. but this is no argument to ignore model constraints
> for generating setter code, isn't it?
The fact that constraints can generally involve the values of many
features on many objects implies that a general approach must tolerate
invalid intermediate and initial states.
> then we would have at least "good" setters (can't destroy consistency)
> but "bad" constructors (not able to construct valid object).
>
> apart from that: "You could use something like an EContentAdapter to
> listen to all changes and invoke the validator whenever an object
> changes. "
> is there any example code that does this? or can someone create a
> quick example based on generated classes like "MyModelValidator". (The
> problem is i don't know where to look for the classes i need and then
> let eclipse' autocompletion give me a hint what method probably to use.)
Ctrl-Shift-T is great for finding any class.
>
> another question that slowly arises is: What is best or at least good
> Practice to write an xsd-backed-xml-api (using emf)? is it at all a
> bad idea to give immediate feedback (exception) on using a setter wrong?
It's not wrong, but it's much more common to invoke the validator after
a command is finished executing and not do it at the API level.
> if not what are alternatives to EContentAdapter/Validator? Write own
> (constraint sensitive) setters and rewrite/check/complete the on model
> change?
Another way to handle notifications internally is to specialize
eNotificationRequired to return true always, and to specialize eNotify
(calling super so the normal handling is done). In that eNotify
override, you can invoke the general validator, or handle the more
special case of validating the data value itself against constraints on
that EDataType. From the notification you'll know which feature's value
to check...
>
>
>
Re: how to verify object on object change(setter called) [message #628680 is a reply to message #628273] Thu, 23 September 2010 16:21 Go to previous message
Animesh Kumar is currently offline Animesh KumarFriend
Messages: 18
Registered: September 2010
Location: Bangalore
Junior Member
Use of EContentAdapters:
This Example is just to give an overview about how you can proceed.
1) Creating the adapter
private Company company=MyModelFactory.eINSTANCE.createCompany();
private ContentAdapter contentAdapter = new ContentAdapter(company);

2) Defining the ContentAdapter
public final class ContentAdapter extends EContentAdapter {
private Company company;
private boolean validCompanyName;
public ContentAdapter(Company company) {
this.company=company;
company.eAdapters().add(this);
}
public void notifyChanged(Notification notification) {
super.notifyChanged(notification);
MyModelValidator validator = MyModelValidator.INSTANCE;
BasicDiagnostic diagnostic = new BasicDiagnostic();
Map<Object, Object> context = new HashMap<Object, Object>();
validCompanyName = validator.validateCompany_ValidName(company, diagnostic,context);
//Resetting to old value on invalid entry
if(!validCompanyName){
company.setName(notification.getOldStringValue());
}
}
}

Whenever you try to set the name of the company, a call will automatically go to the ContentAdapter.
It would be better if you attach the adapter immediately after creating an instance of Company, so that it can listen to changes.


Regards,
Animesh

[Updated on: Thu, 23 September 2010 16:36]

Report message to a moderator

Previous Topic:Defining scpecific references?
Next Topic:how to solve ecore lib issue
Goto Forum:
  


Current Time: Sat Oct 19 10:33:18 GMT 2019

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

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

Back to the top