Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Eclipse EMF Model Transaction Development Guide
Previous Page Home Next Page


Package org.eclipse.emf.transaction

Definition of the API for a transactional editing domain.

See:
           Description

Interface Summary
ExceptionHandler An interface for client objects that handle exceptions occurring in the interaction with an editing domain's command stack.
ResourceSetListener Listener interface for batched notification of changes to a resource set.
ResourceSetListener.Internal An interface for communication of internal life-cycle events to the listener.
RunnableWithResult<T> Extends the core Java Runnable interface with the ability to return a result.
Transaction Specification of a transaction in a TransactionalEditingDomain.
Transaction.OptionMetadata An interface that allows clients to query certain meta-data about transaction options.
Transaction.OptionMetadata.Registry A registry of metadata describing transaction options.
TransactionalCommandStack Extension of the basic CommandStack API providing additional control over (and feed-back from) the transactions used to execute commands.
TransactionalEditingDomain An extension of the EditingDomain API that applies transactional semantics to reading and writing the contents of an EMF ResourceSet.
TransactionalEditingDomain.DefaultOptions Adapter interface provided by TransactionalEditingDomains that support the notion of default transaction options.
TransactionalEditingDomain.Factory Interface defining the protocol for creating transactional editing domains.
TransactionalEditingDomain.Lifecycle Adapter interface provided by TransactionalEditingDomains that support notification of life-cycle events to TransactionalEditingDomainListeners.
TransactionalEditingDomain.Registry An ID-based registry of shareable TransactionalEditingDomain instances.
TransactionalEditingDomainListener A listener interface providing notifications of changes to a transactional editing domain.
TransactionChangeDescription A specialized change description that may not be able to apply itself, especially in the case where it includes non-EMF changes that are not reversible.
 

Class Summary
DemultiplexingListener A convenient superclass for post-commit listeners to process Notifications one at a time.
NotificationFilter A filter that determines which Notifications will be passed to ResourceSetListeners.
NotificationFilter.Custom A custom notification filter, implementing user-defined selection criteria.
RecordingCommand A partial Command implementation that records the changes made by a subclass's direct manipulation of objects via the metamodel's API.
ResourceSetChangeEvent Event object describing the nature of changes in a resource set to ResourceSetListeners.
ResourceSetListenerImpl Default implementation of a resource-set listener, useful for extending to implement only the callbacks of interest to the client.
RunnableWithResult.Impl<T> A convenient partial implementation of the RunnableWithResult interface that implements a settable result field and commit status.
TransactionalEditingDomainEvent An event object indicating a change in the state of a TransactionalEditingDomain, usually in some #getTransaction() life-cycle event.
TransactionalEditingDomainListenerImpl A default implementation of the TransactionalEditingDomainListener interface that does nothing in response to those call-backs, but which is useful for subclassing to handle just the interesting events.
TriggerListener A convenient superclass for listeners that implement "triggers" to process Notifications one at a time, generating a command for each that will make dependent updates to the model.
 

Exception Summary
RollbackException Exception indicating that a transaction was automatically rolled back on attempting to commit.
 

Package org.eclipse.emf.transaction Description

Definition of the API for a transactional editing domain.

Package Specification

Creating an Editing Domain

The following snippet illustrates the creation of a transactional editing domain:

TransactionalEditingDomain domain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain();
ResourceSet rset = domain.getResourceSet();

// or, create our own resource set and initialize the domain with it
rset = new MyResourceSetImpl();
domain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(rset);

To share a named editing domain with other applications, the editing domain registry can be used to obtain domains by ID, creating them if necessary. Editing domain IDs are configured on an extension point providing the factory implementation that the registry uses to initialize them:

<!-- In the plugin.xml -->
<extension point="org.eclipse.emf.transaction.editingDomains">
    <editingDomain
        id="com.example.MyEditingDomain"
        factory="com.example.MyEditingDomainFactory"/>
</extension>

// in code, access the registered editing domain by:

TransactionalEditingDomain myDomain = TransactionalEditingDomain.Registry.INSTANCE.getEditingDomain(
    "com.example.MyEditingDomain");

Reading a Resource Set

All work in an editing domain is done within the context of a transaction. This applies to both reading the model and writing it, as well as creating, loading, saving, and unloading resources. To load and read a resource:

Runnable read = new RunnableWithResult.Impl() {
        public void run() {
            Resource res = rset.getResource(
                URI.createFileURI("/tmp/my.xmi"),
                true);

            setResult(new Integer(res.getContents().size()));
        }
    };

// execute the read operation as a read-only transaction
int size = ((Integer) domain.runExclusive(read)).intValue();

Modifying a Resource Set

Modifications to a resource require read-write transactions, implemented as commands:

Command cmd = new RecordingCommand("Create Library") {
        protected void doExecute() {
            Library library = LibraryFactory.eINSTANCE.createLibrary();

            // these modifications require a write transaction in this editing domain
            res.getContents().add(library);
            library.setName("Main Branch");
        }
    };

try {
    ((TransactionalCommandStack) domain.getCommandStack()).execute(cmd, null); // default options
} catch (RollbackException rbe) {
    ErrorDialog.openError(
        getWorkbench().getShell(), "Transaction Rollback",
        "Transaction rolled back due to validation errors.", rbe.getStatus());
}

Listening for Model Changes

Listeners can be added to the editing domain to find out about changes that occur (directly and indirectly) in the resource set and its contents. There are two call-backs supported by the editing domain: transactionAboutToCommit (pre-commit) calls notify the listener of what changes a command has performed before it completes (commits) them, and resourceSetChanged (post-commit) indicates what changes a command has committed after it has completed normally (or what changes occurred during reading the resource set).

ResourceSetListener listener = new ResourceSetListenerImpl() {
        protected void resourceSetChanged(ResourceSetChangeEvent event) {
            // analyze the complete list of notifications that occurred during
            //    execution of the command to figure out how the model has changed
            analyzeChanges(event.getNotifications());
        }
    });
    
// attach the listener to the editing domain
domain.addResourceSetListener(listener);

The resource set listener can make changes to the resource set, but these are chained onto the current command and are not executed until after all other notifications have been processed:

// notify only on additions to the contents of a resource
NotificationFilter filter = NotificationFilter.createFeatureFilter(
        EcorePackage.eINSTANCE.getEResource(),
        Resource.RESOURCE__CONTENTS).and(
    NotifierFilter.createEventTypeFilter(
            Notification.ADD, Notification.ADD_MANY)
));

// create a new listener with this filter
ResourceSetListener listener = new ResourceSetListenerImpl(filter) {
        protected Command aboutToCompleteCommand(ResourceSetChangeEvent event) {
            // create a command to follow-up the changes that we observed
            Command cmd = analyzeChanges(event.getNotifications());
            
            // the command will be executed by the command stack
            return cmd;
        }
    });
    
// attach the listener to the editing domain
domain.addResourceSetListener(listener);

Notice two things about the previous example: first, the listener's pre-commit call-back method returns a command for future execution. The stack executes this command after completing the round of call-backs. It cannot simply "piggy-back" on the current command's transaction because it is closing. Secondly, it declares a filter to restrict the notifications that it will receive. The filter is a composite of two filters, stipulating that only ADD or ADD_MANY notifications are wanted, and these only from the contents lists of resources. If when a command completes, no notifications match the filter, then this listener is not invoked at all. Otherwise, only the notifications that do match are provided to the listener.

Listeners can also force rollback of the currently executing command if it must not be permitted to commit its changes. This is accomplished by throwing a RollbackException:

ResourceSetListener listener = new ResourceSetListenerImpl() {
        protected Command transactionAboutToCommit(ResourceSetChangeEvent) throws RollbackException {
            // validate the changes and force rollback if not acceptable
            if (!analyzeChanges(getNotifications())) {
                throw new RollbackException("Didn't like the changes.");
            }
            
            return null;  // no need to perform further changes
        }
    });

ResourceSetListeners can also be declared on an extension point, to be loaded on creation of an editing domain. This approach has the advantage of automatically attaching the listener to an editing domain before the client has been activated. The extension can specify one or more unique identifiers of editing domains to listen to; these are mapped to editing domain instances in the shared TransactionalEditingDomain.Registry. The listener class implementing this extension should initialize itself with an appropriate filter.

<extension point="org.eclipse.emf.transaction.listeners">
    <listener class="com.example.MyResourceSetListener">
        <editingDomain id="com.example.MyEditingDomain"/>
    </listener>
</extension>    

Undoing Model Changes

Transactions (commands) are undone via the command stack, as usual:

Command cmd = SomeCommand();

try {
    ((TransactionalCommandStack) domain.getCommandStack()).execute(cmd, null); // default options
} catch (RollbackException rbe) {
    ErrorDialog.openError(
        getWorkbench().getShell(), "Transaction Rollback",
        "Transaction rolled back due to validation errors.", rbe.getStatus());
}

// undo the last executed transaction
domain.getCommandStack().undo();

// redo it
domain.getCommandStack().redo();

See Also:
TransactionalEditingDomain, TransactionalCommandStack, RecordingCommand, RunnableWithResult, ResourceSetListener

Copyright 2002, 2007 IBM Corporation and others.
All Rights Reserved.


 
 
  Published under the terms of the Eclipse Public License Version 1.0 ("EPL") Design by Interspire