X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Faccessor%2FAccessor.java;h=b29083f74789f5be070b5fd5160bf242f2e2a0f3;hp=140c94aaac702ed2c0c1eb0fee59227a9af20195;hb=refs%2Fchanges%2F38%2F238%2F2;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/Accessor.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/Accessor.java index 140c94aaa..b29083f74 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/Accessor.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/Accessor.java @@ -1,263 +1,263 @@ -/******************************************************************************* - * Copyright (c) 2010 Association for Decentralized Information Management in - * Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.databoard.accessor; - -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.Executor; - -import org.simantics.databoard.Accessors; -import org.simantics.databoard.accessor.binary.BinaryObject; -import org.simantics.databoard.accessor.error.AccessorConstructionException; -import org.simantics.databoard.accessor.error.AccessorException; -import org.simantics.databoard.accessor.event.Event; -import org.simantics.databoard.accessor.event.InvalidatedEvent; -import org.simantics.databoard.accessor.impl.ChangeSet; -import org.simantics.databoard.accessor.interestset.InterestSet; -import org.simantics.databoard.accessor.java.JavaObject; -import org.simantics.databoard.accessor.reference.ChildReference; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.error.BindingException; -import org.simantics.databoard.type.Datatype; - -/** - * 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.

- * - * @see Accessors - * @see JavaObject Accessor to Java Object container - * @see BinaryObject Accessor to a container in File or Memory - * @see ArrayAccessor - * @see BooleanAccessor - * @see ByteAccessor - * @see DoubleAccessor - * @see FloatAccessor - * @see IntegerAccessor - * @see LongAccessor - * @see MapAccessor - * @see OptionalAccessor - * @see RecordAccessor - * @see StringAccessor - * @see UnionAccessor - * @see VariantAccessor - * @author Toni Kalajainen (toni.kalajainen@iki.fi) - */ -public interface Accessor { - - /** - * Get a snapshot of the object as a single data value.

- * Accessor makes type adaption to users binding if possible.

- * - * @param binding - * @return the value - * @throws AccessorException - */ - Object getValue(Binding binding) throws AccessorException; - - /** - * Read a copy of the accessor's object into the obj instance.

- * Accessor makes type adaption to users binding if possible.

- * - * @param binding - * @param obj object to read the value to - * @throws AccessorException - */ - void getValue(Binding binding, Object obj) throws AccessorException; - - /** - * Read value in path reference into an obj instance.

- * - * @param path component reference path or null to return _this_ - * @param binding - * @param obj - * @return true if value existed, false if not - * @throws AccessorException - */ - boolean getValue(ChildReference path, Binding binding, Object obj) throws AccessorException; - - /** - * Read value in path reference into an obj instance.

- * - * @param path component reference path or null to return _this_ accessor - * @param binding - * @param obj - * @return the object or null if value doesn't exist - * @throws AccessorException - */ - Object getValue(ChildReference path, Binding binding) throws AccessorException; - - /** - * Set a complete new value to the data container. - * Accessor makes type adaption to users binding if possible.

- * - * 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 {@link 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.

- * - * @param binding - * @param newValue - * @throws BindingException binding error - * @throws UnsupportedOperationException cannot set a new value - */ - void setValue(Binding binding, Object newValue) throws AccessorException; - - /** - * Set value to path reference. - * - * @param path component reference path or null to return _this_ - * @param binding - * @param obj - * @return true if value existed in the accessor, false if not - * @throws AccessorException - */ - boolean setValue(ChildReference path, Binding binding, Object obj) throws AccessorException; - - /** - * Open an accessor to a child. If one already exists, the existing is returned, - * otherwise a new is created. Child accessors are often remembered with - * weak reference.

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

- * - * @param path component reference path or null to return _this_ accessor - * @return accessor - * @throws AccessorConstructionException - */ - T getComponent(ChildReference path) throws AccessorConstructionException; - - /** - * 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. - * - * @param changeSet - * @param rollback log to be filled with rollback events or null - * @throws AccessorException failed to apply change set - */ - void apply(List changeSet, LinkedList rollback) throws AccessorException; - - /** - * Get structural represtentation of the accessor presented in databoard's - * type system. - * - * @return type description - */ - Datatype type(); - - /** - * 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 {@link ChangeSet} is an implementation that collects events. - * - * Executor argument determines the thread where the onEvents method is - * handled. null argument denotes current thread. - * - * @param listener - * @param interestSet - * @param pathPrefix path to the accessor or null. This is used in the events the accessor produces - * @param executor - * @see ChangeSet collects events - */ - void addListener(Listener listener, InterestSet interestSet, ChildReference pathPrefix, Executor executor) throws AccessorException; - - /** - * Remove a listener. If the listener is added multiple times, the last - * one added is removed. - * - * @param listener - * @throws AccessorException - */ - void removeListener(Listener listener) throws AccessorException; - - /** - * Accessor listener. - * - * @author Toni Kalajainen - */ - public static interface Listener { - - /** - * Notify the listener on a new event - * - * @param events - */ - void onEvents(Collection events); - - } - -} - +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.databoard.accessor; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.Executor; + +import org.simantics.databoard.Accessors; +import org.simantics.databoard.accessor.binary.BinaryObject; +import org.simantics.databoard.accessor.error.AccessorConstructionException; +import org.simantics.databoard.accessor.error.AccessorException; +import org.simantics.databoard.accessor.event.Event; +import org.simantics.databoard.accessor.event.InvalidatedEvent; +import org.simantics.databoard.accessor.impl.ChangeSet; +import org.simantics.databoard.accessor.interestset.InterestSet; +import org.simantics.databoard.accessor.java.JavaObject; +import org.simantics.databoard.accessor.reference.ChildReference; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.type.Datatype; + +/** + * 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.

+ * + * @see Accessors + * @see JavaObject Accessor to Java Object container + * @see BinaryObject Accessor to a container in File or Memory + * @see ArrayAccessor + * @see BooleanAccessor + * @see ByteAccessor + * @see DoubleAccessor + * @see FloatAccessor + * @see IntegerAccessor + * @see LongAccessor + * @see MapAccessor + * @see OptionalAccessor + * @see RecordAccessor + * @see StringAccessor + * @see UnionAccessor + * @see VariantAccessor + * @author Toni Kalajainen (toni.kalajainen@iki.fi) + */ +public interface Accessor { + + /** + * Get a snapshot of the object as a single data value.

+ * Accessor makes type adaption to users binding if possible.

+ * + * @param binding + * @return the value + * @throws AccessorException + */ + Object getValue(Binding binding) throws AccessorException; + + /** + * Read a copy of the accessor's object into the obj instance.

+ * Accessor makes type adaption to users binding if possible.

+ * + * @param binding + * @param obj object to read the value to + * @throws AccessorException + */ + void getValue(Binding binding, Object obj) throws AccessorException; + + /** + * Read value in path reference into an obj instance.

+ * + * @param path component reference path or null to return _this_ + * @param binding + * @param obj + * @return true if value existed, false if not + * @throws AccessorException + */ + boolean getValue(ChildReference path, Binding binding, Object obj) throws AccessorException; + + /** + * Read value in path reference into an obj instance.

+ * + * @param path component reference path or null to return _this_ accessor + * @param binding + * @param obj + * @return the object or null if value doesn't exist + * @throws AccessorException + */ + Object getValue(ChildReference path, Binding binding) throws AccessorException; + + /** + * Set a complete new value to the data container. + * Accessor makes type adaption to users binding if possible.

+ * + * 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 {@link 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.

+ * + * @param binding + * @param newValue + * @throws BindingException binding error + * @throws UnsupportedOperationException cannot set a new value + */ + void setValue(Binding binding, Object newValue) throws AccessorException; + + /** + * Set value to path reference. + * + * @param path component reference path or null to return _this_ + * @param binding + * @param obj + * @return true if value existed in the accessor, false if not + * @throws AccessorException + */ + boolean setValue(ChildReference path, Binding binding, Object obj) throws AccessorException; + + /** + * Open an accessor to a child. If one already exists, the existing is returned, + * otherwise a new is created. Child accessors are often remembered with + * weak reference.

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

+ * + * @param path component reference path or null to return _this_ accessor + * @return accessor + * @throws AccessorConstructionException + */ + T getComponent(ChildReference path) throws AccessorConstructionException; + + /** + * 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. + * + * @param changeSet + * @param rollback log to be filled with rollback events or null + * @throws AccessorException failed to apply change set + */ + void apply(List changeSet, LinkedList rollback) throws AccessorException; + + /** + * Get structural represtentation of the accessor presented in databoard's + * type system. + * + * @return type description + */ + Datatype type(); + + /** + * 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 {@link ChangeSet} is an implementation that collects events. + * + * Executor argument determines the thread where the onEvents method is + * handled. null argument denotes current thread. + * + * @param listener + * @param interestSet + * @param pathPrefix path to the accessor or null. This is used in the events the accessor produces + * @param executor + * @see ChangeSet collects events + */ + void addListener(Listener listener, InterestSet interestSet, ChildReference pathPrefix, Executor executor) throws AccessorException; + + /** + * Remove a listener. If the listener is added multiple times, the last + * one added is removed. + * + * @param listener + * @throws AccessorException + */ + void removeListener(Listener listener) throws AccessorException; + + /** + * Accessor listener. + * + * @author Toni Kalajainen + */ + public static interface Listener { + + /** + * Notify the listener on a new event + * + * @param events + */ + void onEvents(Collection events); + + } + +} +