Overview | Package | Class | Use | Tree | Deprecated | Index | Help
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES

## Package org.modeshape.graph.observe

The Observation API provides several mechanisms for asynchronously observing changes to content.

See:
Description

Interface Summary
Observable | Interface used to register `listeners`.
ObservationBus | A simple `Observer` that is itself `Observable`.
Observer | The interface for an observer of graph changes.

Class Summary
ChangeObserver | Abstract class that is used to signal that a change set has occurred.
ChangeObservers | Reusable manager of change listeners, typically employed by another `Observable` implementation.
Changes | A set of changes that were made atomically.
LocalObservationBus | A simple `Observer` that is itself `Observable`.
NetChangeObserver | A specialized `Observer` that figures out the net changes made during a single `set of changes`.
NetChangeObserver.NetChange | A notification of changes to a node.
NetChangeObserver.NetChanges | A set of net changes that were made atomically.

Enum Summary
NetChangeObserver.ChangeType |

## Package org.modeshape.graph.observe Description

The Observation API provides several mechanisms for asynchronously observing changes to content.

Many event frameworks define the listeners and sources as interfaces. While this is often useful, it requires the implementations properly address the thread-safe semantics of managing and calling the listeners. This observation framework uses abstract or concrete classes to minimize the effort required for implementing `ChangeObserver` or `Observable`. The classes also allow the framework to implement a number of utility methods, such as the `unregister()` method on ChangeObserver, that also save effort and code.

However, one of the more important reasons for providing classes is that `ChangeObserver` uses `weak references` to track the `Observable` instances, and the `ChangeObservers` class uses weak references for the listeners. This means that if an observers do not prevent `Observable` instances from being garbage collected, nor do observers prevent `Observable` instances from being garbage collected.

### Observable

Any component that can have changes and be observed can implement the `Observable` interface. This interface allows Observers to register (or be registered) to receive notifications of the changes. However, a concrete and thread-safe implementation of this interface, called `ChangeObservers`, is available and should be used where possible, since it automatically manages the registered `ChangeObserver` instances and properly implements the register and unregister mechanisms.

### Observers

Components that are to recieve notifications of changes are called observers. To create an observer, simply extend the `ChangeObserver` abstract class and provide an implementation of the `ChangeObserver.notify(Changes)` method. Then, register the observer with an `Observable` using its `Observable.register(Observer)` method. The observer's `ChangeObserver.notify(Changes)` method will then be called with the changes that have been made to the Observable.

When an observer is no longer needed, it should be unregistered from all `Observable` instances with which it was registered. The `ChangeObserver` class automatically tracks which `Observable` instances it is registered with, and calling the observer's `ChangeObserver.unregister()` will unregister the observer from all of these Observables. Alternatively, an observer can be unregistered from a single Observable using the Observable's `Observable.unregister(Observer)` method.

### Changes

The `Changes` class represents the set of individual changes that have been made during a single, atomic operation. Each `Changes` instance has information about the source of the changes, the timestamp at which the changes occurred, and the individual changes that were made. These individual changes take the form of `ChangeRequest` objects, such as `CreateNodeRequest`, `DeleteBranchRequest`, etc. Each request is `frozen`, meaning it is immutable and will not change. Also none of the requests will be `cancelled`.

Using the actual `ChangeRequest` objects as the "events" has a number of advantages. First, there are already a number of existing `ChangeRequest` subclasses that describe various types of changes in quite a bit of detail; thus no need to duplicate the structure or come up with a generic event class.

Second, the requests have all the state required for an event, plus they often will have more. For example, the DeleteBranchRequest has the actual location of the branch that was delete (and in this way is not much different than a more generic event), but the CreateNodeRequest has the actual location of the created node along with the properties of that node. Additionally, the RemovePropertyRequest has the actual location of the node along with the name of the property that was removed. In many cases, these requests have all the information a more general event class might have but then hopefully enough information for many observers to use directly without having to read the graph to decide what actually changed.

Third, the requests that make up a `Changes` instance can actually be replayed. Consider the case of a cache that is backed by a `RepositorySource`, which might use an observer to keep the cache in sync. As the cache is notified of Changes, the cache can simply replay the changes against its source.

Overview | Package | Class | Use | Tree | Deprecated | Index | Help
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES

Copyright © 2008-2011 JBoss, a division of Red Hat. All Rights Reserved.