org.simantics.databoard.accessor
Interface Accessor

All Known Subinterfaces:
ArrayAccessor, BooleanAccessor, ByteAccessor, DoubleAccessor, FileAccessor, FileArrayAccessor, FileBooleanAccessor, FileByteAccessor, FileDoubleAccessor, FileFloatAccessor, FileIntegerAccessor, FileLongAccessor, FileMapAccessor, FileOptionalAccessor, FileRecordAccessor, FileStringAccessor, FileUnionAccessor, FileVariantAccessor, FloatAccessor, IntegerAccessor, LongAccessor, MapAccessor, OptionalAccessor, RecordAccessor, StringAccessor, UnionAccessor, VariantAccessor
All Known Implementing Classes:
BinaryArray, BinaryBoolean, BinaryByte, BinaryDouble, BinaryFloat, BinaryInteger, BinaryLong, BinaryMap, BinaryObject, BinaryOptional, BinaryRecord, BinaryString, BinaryUnion, BinaryVariant, ClosableCompositeRecord, CompositeRecord, DirectoryMap, JavaArray, JavaBoolean, JavaByte, JavaDouble, JavaFloat, JavaInteger, JavaLong, JavaMap, JavaObject, JavaOptional, JavaRecord, JavaString, JavaUnion, JavaVariant, StepwiseDatasourceAccessor

public interface Accessor

Accessor is an interface to access, modify and monitor a data container. The actual storage format and location is implementation specific. For instance, container could be: a bunch of bytes, a Java object, a file, a folder with files, a network location, or direct memory of a simulation experiment.

The structure is presentable with Databoard type system. The type can be anything but a recursive structure.

The listening model allows placing of listener objects to accessors. Each listener is associated with a InterestSet. It describes a sub-tree of nodes to listen and aspects to monitor. Accessors emit Events on modifications of structure and value. There is a reference in each event, and it is relative to the accessor where the listener was placed. For instance, a listener, that is interested in whole tree, is placed on a root accessor. A modification at a leaf-node spawns an event with a reference path from the root to the leaf. If the listener was placed directly on the leaf, there wouldn't be a path in the evenr object.

Multi-thread-usage is implementation dependent, read the documentation.

Construction and destruction model is also implementation dependent. A rule of thumb in life management of objects is that, the party that constructs an object must destroy it. Both construction and destruction of the container are also outside the scope of the Accessor interface.

However, as general implementation contract, the data container is disposed as whole, individual nodes are not. While the container is alive, individual nodes may be disposed using garbage collection mechanisms. Reference queue mechanism is one implementatio strategy. More common strategy is usage of weak references from parent to child.

Author:
Toni Kalajainen (toni.kalajainen@iki.fi)
See Also:
Accessors, Accessor to Java Object container, Accessor to a container in File or Memory, ArrayAcessor, BooleanAcessor, ByteAcessor, DoubleAcessor, FloatAcessor, IntegerAcessor, LongAcessor, MapAcessor, OptionalAcessor, RecordAcessor, StringAcessor, UnionAcessor, VariantAcessor

Nested Class Summary
static interface Accessor.Listener
           
 
Method Summary
 void addListener(Accessor.Listener listener, InterestSet interestSet, AccessorReference pathPrefix)
          Place a listener to an accessor node.
 void apply(java.util.List<Event> changeSet, java.util.LinkedList<Event> rollback)
          Apply a change set in a single transaction operation.
<T extends Accessor>
T
getAccessor(AccessorReference reference)
          Get an accessor to a sub-container.
 java.lang.Object getValue(Binding binding)
          Get a snapshot of the object model as a single data value.
 void removeListener(Accessor.Listener listener)
          Remove a listener.
 void setValue(Binding binding, java.lang.Object newValue)
          Set a complete new value to the data container.
 DataType type()
          Get structural represtentation of the accessor presented in databoard's type system.
 

Method Detail

getValue

java.lang.Object getValue(Binding binding)
                          throws AccessorException
Get a snapshot of the object model as a single data value.

Parameters:
binding -
Returns:
the value
Throws:
AccessorException

setValue

void setValue(Binding binding,
              java.lang.Object newValue)
              throws AccessorException
Set a complete new value to the data container. If the new value removes old map entries, array entries, optional value, or changes union or variant value type, it will disengage any existing sub-accessors and send InvalidatedEvent.

Writing the current value again may not emit an event. This is implementation specific.

Write is durable, once a the method returns successfully the value has been stored in the implmentation.

Parameters:
binding -
newValue -
Throws:
BindingException - binding error
java.lang.UnsupportedOperationException - cannot set a new value
AccessorException

getAccessor

<T extends Accessor> T getAccessor(AccessorReference reference)
                               throws AccessorConstructionException
Get an accessor to a sub-container. If one already exists, the same is returned, otherwise a new is created.

InvalidatedEvent is thrown from the accessor if it is unlinked from the parent hierarchy.

Parameters:
reference - component reference or null to return _this_ accessor
Returns:
accessor
Throws:
AccessorConstructionException

apply

void apply(java.util.List<Event> changeSet,
           java.util.LinkedList<Event> rollback)
           throws AccessorException
Apply a change set in a single transaction operation. If rollback log is supplied, it is filled with reverse events. If the operation fails, rollback log can be applied to cancel changes.

Parameters:
changeSet -
rollback - log to be filled with rollback events or null
Throws:
AccessorException - failed to apply change set

type

DataType type()
Get structural represtentation of the accessor presented in databoard's type system.

Returns:
type description

addListener

void addListener(Accessor.Listener listener,
                 InterestSet interestSet,
                 AccessorReference pathPrefix)
                 throws AccessorException
Place a listener to an accessor node. The listener will be notified for changes in the node/node tree, depending on interest set.

When events are emited and in which thread processed is implementation specific. It is also implementation specific, whether the object can be mutated in the listener or whether it has to be done afterwards.

In many implementations there is a pluggable event handling strategy EventEmitter. The default behaviour is to emit events as they are spawned in the current thread.

There is a reference in each event instance that describes the path from the accessor where listener was placed to the node to which the event applies to.

Listener is attached to the object that holds the value at the time at the of the adding. For example, If a listener is attached to an array of element at index 3, and a new value is inserted at position 2, the listener still monitors the same container, which is now at index 4. The references of incoming the events are modified to have the new index.

Also, if a new value is assigned to the parent of an object that is listened, the listener keeps on monitoring the new value at the same reference. This doesn't apply when a new value is set to a union of different tag, to a variant with a new type, or value is removed from Optional type. In these two cases the listener is invalidated.

See ChangeSet is an implementation that collects events.

Parameters:
listener -
interestSet -
pathPrefix - path to the accessor or null. This is used in the events the accessor produces
Throws:
AccessorException
See Also:
collects events

removeListener

void removeListener(Accessor.Listener listener)
                    throws AccessorException
Remove a listener. If the listener is added multiple times, the last one added is removed.

Parameters:
listener -
Throws:
AccessorException