Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Test if EMF object is loading?
Test if EMF object is loading? [message #1755301] Thu, 02 March 2017 08:54 Go to next message
Jim 20100 is currently offline Jim 20100Friend
Messages: 69
Registered: June 2016
Member
Hello,

At several place, I have absolutely to detect if an EMF object is loading or not.

Example 1: in business method
The following method cannot work during loading, because property1 is maybe not correctly set. When running of course, it works.

@Override
public void setProperty2(Double property2) {

if (getProperty1()="toto")
return;

.....

}

Example 2: in TotalObserver

I use this code to prevent my observer to react to each change. Is it a correct way to do?

public TotalObserver(MyObject theObservedObject) {
super();

this.theObservedObject = theObservedObject;
setAdapter(new EContentAdapter() {
public void notifyChanged(Notification notification) {
super.notifyChanged(notification);

Resource resource = eResource();
if (resource==null)
return;
if (resource != null && ((Resource.Internal) resource).isLoading()){
System.out.println("We are loading");
return;
}
if (resource != null && ((Resource.Internal) resource).isLoaded()){
System.out.println("Resource is loaded");
}


Thx for your help

Rgds
Jim
Re: Test if EMF object is loading? [message #1755319 is a reply to message #1755301] Thu, 02 March 2017 10:25 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 29318
Registered: July 2009
Senior Member
In terms of your derived setter, it's probably just a bad design. The behavior of course generally depends on the order in which setProperty1 and setProperty2 are called. That just doesn't seem good because any code written against this API will behave unexpectedly. I also wonder about the == test on a string, but likely that's just an artifact of a synthetic example. And in the end, I don't see why loading matters. If you serialized property2, it should be set as it was serialized. If property1 has some special value, then that was serialized too, but how can the serialization be in a state where on deserializing you really want to ignore setting the value, even though if you did it programmatically you won't ignore it. I just don't get it...

For example 2, I also don't understand the problem being solved. E.g., it seems simple not to attach the observer until you've loaded the resource. When/where are you attaching this observer? Perhaps using org.eclipse.emf.ecore.xmi.XMLResource.OPTION_DEFER_ATTACHMENT so that the object isn't attached to the resource until it's fully loaded would avoid the whole issue? But it's still a question of, when are you adding the adapter?...
Re: Test if EMF object is loading? [message #1755435 is a reply to message #1755319] Fri, 03 March 2017 10:50 Go to previous messageGo to next message
Jim 20100 is currently offline Jim 20100Friend
Messages: 69
Registered: June 2016
Member
Example 1:
I don't get your explanation fully.
I ignore the setting value of property 2, only when the end user wants to set it.
During loading, I don't want to make such test because as you said it depends on the order in which setProperty1 and setProperty2 are called. if property1 is not yet set, then you can imagine that the property 2 will not be set.
Remark: For the == test, of course it is just an artifact.
****************************
Example 2:
I set my observer as an instance variable for EACH of my EMF objects, so during the construction.
So Maybe I should set it at another place. Can you give me an advice, cause I use a total observer in each EMF class?

// example of my EMF object
public class BuildingImpl extends PriceParentImpl implements Building {

TotalObserver totalObserver = new TotalObserver(this);

private class TotalObserver {
private EContentAdapter adapter;
private BuildingImpl theObservedObject;

public TotalObserver(BuildingImpl theObservedObject) {
super();
this.theObservedObject = theObservedObject;
setAdapter(new EContentAdapter() {
public void notifyChanged(Notification notification) {
...
Re: Test if EMF object is loading? [message #1755455 is a reply to message #1755435] Fri, 03 March 2017 13:44 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 29318
Registered: July 2009
Senior Member
For example 1, you did this in the generated implementation class. I'm not sure your definition of an end user. Is a programmer using the APIs in their code an end user? If this is something that's supposed to happen in the IDE when some user is editing the model, it would be better to specialize the in the generated item provider to prevent the user from editing the value in this case rather than ignoring any change, even programmatic ones. You might create a derived org.eclipse.emf.edit.provider.ItemPropertyDescriptor for this property and override canSetProperty(Object) to return for property2 when property1 has a certain value.

For example 2, I don't know the purpose of this observer (content adapter), but it seems fishy to me that you need to do this in the model itself. I have to wonder what happens when you call EcoreUtil.copy() on this object. I.e., what would this observer do while the copy is being constructed (which is quite similar to what happens when an instance is created during resource loading)... Of course in this case there is no containing resource for the created copy.

I can't give advice proper without knowing the purpose of this observer...
Re: Test if EMF object is loading? [message #1755476 is a reply to message #1755455] Fri, 03 March 2017 15:13 Go to previous messageGo to next message
Jim 20100 is currently offline Jim 20100Friend
Messages: 69
Registered: June 2016
Member
Example 1:
end user = ide user.
What I cannot get is why I cannot implement such code in my implementation class, because I consider my implementation class as my business class, where my business logic must be.
I cannot understand that I have to implement my business logic in the ItemPropertyDescriptor.

My business logic rule is: if you have set a production plant = "DIEKIRCH", you cannot set anymore a Unit Cost.

***************
Example 2

I use a lot of Observers, because each node of my EMF tree is dependent from their children.
Ex: Node unit cost = Sum(children total cost)

So with my observers, I detect all changes, if one child node is changed, all parents above needs to be updated.
I detect children property changes but as well as children addition or removal.

Regards
Jim
Re: Test if EMF object is loading? [message #1755488 is a reply to message #1755476] Fri, 03 March 2017 17:29 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 29318
Registered: July 2009
Senior Member
You can obviously do whatever you like, but anyone using the API to set a value will be surprised that setting a value is just ignored. The end user of a UI would also be better off to see the property be read-only rather than setting it and having it be ignored. But that's just my opinion. It's clear this is already causing difficulties. It's also clear that one could set the cost, and then set the production plant afterward, and I'm not sure you've also implemented special logic to unset the cost in that case as well. A different approach would be to define constraints on the model so that this is validated as an invalid state. In the generated editor, with live decoration, this would be displayed to the end user as soon as they've done something to put the model into an invalid state.

So the observer is used to keep derived feature values up-to-date. You could more simply compute the value on-demand instead. In any case, the value isn't needed until you've asked for it, so as an alternative, you could attach the observer only when a derived feature's value is requested. Presumably the derived features are marked as derived in the model (so EcoreUtil.copy doesn't copy them), and are also marked as transient (so they're not serialized). This avoids the whole problem of having to know something about how the model is being constructed by a deserializer or a copier.
Re: Test if EMF object is loading? [message #1755603 is a reply to message #1755488] Mon, 06 March 2017 09:41 Go to previous messageGo to next message
Jim 20100 is currently offline Jim 20100Friend
Messages: 69
Registered: June 2016
Member
Example 1:
I don't want to manage additional invalid states. I just have to be sure that my business methods (for me = implementation class) respect my business rules.
Of course I disable some fields on EMF forms for my end users as well. But additionally I am not sure that I can disable the "Property View" where a user can set each property as he wants (that is why I think that the business logic must be kept in the implementation class).

Solution: I still don't have? Another suggestion? Wink

Example 2:
It is not on demand, it is always displayed. The TreeViewer of my EMF objects must be refreshed each time you change a value on a children.
And I am very profesional, I don't refresh all the treeviewer, but I detect each line/property I have to refresh, that is quite complicated.
Moreover again, I cannot use derived properties because some values can be overridden on a node. Ex: you can force the Unit Cost on a level (so I have a changeable unit cost property), so it will not calculate anymore the sum of the children unit cost.
And even with derived values, you have to send event to tell the TreeViewer to refresh parent lines because a child was changed.

Solution: The only solution is maybe not to attach the observers as I do on each instance. But It must be done after the complete loading but I don't know how exactly I can detect that the loading is finished?
Re: Test if EMF object is loading? [message #1755605 is a reply to message #1755603] Mon, 06 March 2017 10:04 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 5834
Registered: July 2009
Senior Member
Hi

As you observe, derived properties cannot be overridden, but in practice they can be; you just define that the value of myDerivedProperty is determined by computeMyDerivedProperty() and override computeMyDerivedProperty() as appropriate. If you're happy to hack the Java a bit, you can override getMyDerivedProperty() directly so long as you understand when basicGetMyDerivedProperty() rather than getMyDerivedProperty() is used.

If you really want to do something after loading has completed, but before any usage occurs, I suggest that you ensure that MyResourceImpl.createXMLLoad() creates a MyXMILoadImpl where you can intercept a variety of load activities. (I have never tried this for Load, but I regularly use a derived XMISaveImpl to ensure that model elements are structured in a way that gives a valid standard XMI serialization.)

Never do anything smart until loading is complete or you will chase the numerous transient inconsistent states that occur during XML loading.

Regards

Ed Willink
Re: Test if EMF object is loading? [message #1755705 is a reply to message #1755605] Tue, 07 March 2017 06:45 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 29318
Registered: July 2009
Senior Member
For example 1, I did already explain how you can disable properties in the properties view by specializing the item property descriptor's canSetProperty method.

For example 2, the value is displayed based on calling the getter on the implementation class. So no computation needs to be done until the getter is called the first time. You can specialize the getter code. Here's a simple example
  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public String getNameGen()
  {
    return name;
  }

  public String getName()
  {
    String name = getNameGen();
    if (StringUtil.isEmpty(name))
    {
      String version = getVersion();
      if (!StringUtil.isEmpty(version))
      {
        return "JRE for " + version;
      }

      return null;
    }

    return name;
  }
Note the addition of "Gen" to the generated method. It's not so important in this case, but the body of this method will still be generated and it can be called from the overriding implementation of the getter. In this case, I'm essentially computing a default value for the feature if it's not been explicitly set.

I'm suggesting that the getter might well be the best place to do any initial computation and to attach adapters to keep that computation up-to-date.

The option org.eclipse.emf.ecore.xmi.XMLResource.OPTION_RESOURCE_HANDLER can be used to perform actions before/after load/save.
Previous Topic:Duplicate Content Instances in Eclipse Runtime Application
Next Topic:UML to comments ?
Goto Forum:
  


Current Time: Sun Apr 22 13:00:23 GMT 2018

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

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