Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Track change notifications
Track change notifications [message #1863962] Fri, 08 March 2024 08:50 Go to next message
Klarise Hund is currently offline Klarise HundFriend
Messages: 24
Registered: October 2022
Junior Member
Hi,

From what I know it is possible in EMF to implement listeners that track changes made to a model .The idea is that I want to implement listeners on some attributes, references etc, and based on whether it was changed or not, trigger another action. Is there any available resource that helps with that? Should I modify any of the files generated for the editor or create new ones?

Thanks!
Re: Track change notifications [message #1863964 is a reply to message #1863962] Fri, 08 March 2024 10:06 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33143
Registered: July 2009
Senior Member
You can use eObject.eAdapters().add(...) to listen to an object's changes.

Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Track change notifications [message #1863966 is a reply to message #1863964] Fri, 08 March 2024 10:09 Go to previous messageGo to next message
Klarise Hund is currently offline Klarise HundFriend
Messages: 24
Registered: October 2022
Junior Member
Should I do that in any of the generated files or..?

Thanks!
Re: Track change notifications [message #1863968 is a reply to message #1863966] Fri, 08 March 2024 11:47 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33143
Registered: July 2009
Senior Member
Typically listeners are added by the application, not within the generated code. But you're goal to "trigger actions" is a bit vague. The generated item providers are adapters, added by the adapter factory, and they listen to changes to triggers calls to the viewer refresh methods...

Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Track change notifications [message #1863971 is a reply to message #1863968] Fri, 08 March 2024 12:29 Go to previous messageGo to next message
Klarise Hund is currently offline Klarise HundFriend
Messages: 24
Registered: October 2022
Junior Member
By trigger actions I mean, for instance, if a certain attribute is set to a certain value , then, the user will have readonly permissions on the name attribute of the same element ). for instance in the following I have made changes to the BookItemProvider, so that if the year attribute is set to "2007", the name attribute of that particular Book will be readonly. For other Books where the year is != 2007, the name attribute should be able to be edited.

@Override
	public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) {
	    if (itemPropertyDescriptors == null) {
	        super.getPropertyDescriptors(object);

	        // Dynamically determine if the name property should be read-only
	        boolean isNameReadOnly = false;
	        if (object instanceof Book) {
	            Book book = (Book) object;
	            if (book.getYear() == 2007) {
	                isNameReadOnly = true;
	            }
	        }

	        addNamePropertyDescriptor(object, isNameReadOnly);
	        addYearPropertyDescriptor(object);
	    }
	    return itemPropertyDescriptors;
	}

	// Updated to include dynamic read-only logic
	protected void addNamePropertyDescriptor(Object object, boolean isReadOnly) {
	    itemPropertyDescriptors.add(createItemPropertyDescriptor(
	            ((ComposeableAdapterFactory) adapterFactory).getRootAdapterFactory(),
	            getResourceLocator(), getString("_UI_Book_name_feature"),
	            getString("_UI_PropertyDescriptor_description", "_UI_Book_name_feature", "_UI_Book_type"),
	            LibraryProjectPackage.Literals.BOOK__NAME, true, false, isReadOnly,
	            ItemPropertyDescriptor.GENERIC_VALUE_IMAGE, null, null));
	}


	@Override
	public void notifyChanged(Notification notification) {
	    super.notifyChanged(notification);

	    if (notification.getFeatureID(Book.class) == LibraryProjectPackage.BOOK__YEAR) {
	        // Year has changed, so refresh property descriptors to potentially update read-only status
	        itemPropertyDescriptors = null;
	    }

	    switch (notification.getFeatureID(Book.class)) {
	        case LibraryProjectPackage.BOOK__NAME:
	        case LibraryProjectPackage.BOOK__YEAR:
	            fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
	            return;
	    }
	}
Re: Track change notifications [message #1863972 is a reply to message #1863971] Fri, 08 March 2024 13:22 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33143
Registered: July 2009
Senior Member
FYI, something you might not have noticed/realized is that the item providers are by default singletons, I.e., the factory creates one adapter per type of object. In the *.genmodel you can select a GenClass and look at the Properties view where you can change from Singleton to Stateful and regenerate so that the factory creates an item provider per instance object. I mention this because forcing the property descriptors to be recomputed is fine and good, but the same cached list will be used for all objects which is not going to work well for what I see above. You might instead consider creating derived property descriptors so that youc an specialize the org.eclipse.emf.edit.provider.ItemPropertyDescriptor.canSetProperty(Object) method. To make the descriptor read-only depending on the object and doing that only when the descriptor is actually being used.

Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Track change notifications [message #1863973 is a reply to message #1863972] Fri, 08 March 2024 13:23 Go to previous message
Klarise Hund is currently offline Klarise HundFriend
Messages: 24
Registered: October 2022
Junior Member
I made the following changes, and it seems to be working. At least for now :)

@Override
	public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) {
	    // Always clear the old descriptors to ensure they are re-evaluated for the current object state
	    itemPropertyDescriptors = null;
	    super.getPropertyDescriptors(object);

	    // Note: We do not need to pass isReadOnly flag here anymore
	    addNamePropertyDescriptor(object); // Adjust this method to evaluate read-only condition internally
	    addYearPropertyDescriptor(object);
	    
	    return itemPropertyDescriptors;
	}

	// Adjusted to evaluate read-only condition internally
	protected void addNamePropertyDescriptor(Object object) {
	    boolean editName = true;
	    if (object instanceof Book) {
	        Book book = (Book) object;
	        if (book.getYear() == 2007) {
	            editName = false;
	        }
	    }
	    
	    itemPropertyDescriptors.add(createItemPropertyDescriptor(
	            ((ComposeableAdapterFactory) adapterFactory).getRootAdapterFactory(),
	            getResourceLocator(), getString("_UI_Book_name_feature"),
	            getString("_UI_PropertyDescriptor_description", "_UI_Book_name_feature", "_UI_Book_type"),
	            LibraryProjectPackage.Literals.BOOK__NAME, editName, false, false,
	            ItemPropertyDescriptor.GENERIC_VALUE_IMAGE, null, null));
	}
Previous Topic:Why Enumerators save the Literal into the file
Next Topic:[CDO] EmbeddedRepositoryExample is not working
Goto Forum:
  


Current Time: Thu May 02 10:12:33 GMT 2024

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

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

Back to the top