-/*******************************************************************************\r
- * Copyright (c) 2010 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.databoard.accessor;\r
-\r
-import java.util.Collection;\r
-import java.util.LinkedList;\r
-import java.util.List;\r
-import java.util.concurrent.Executor;\r
-\r
-import org.simantics.databoard.Accessors;\r
-import org.simantics.databoard.accessor.binary.BinaryObject;\r
-import org.simantics.databoard.accessor.error.AccessorConstructionException;\r
-import org.simantics.databoard.accessor.error.AccessorException;\r
-import org.simantics.databoard.accessor.event.Event;\r
-import org.simantics.databoard.accessor.event.InvalidatedEvent;\r
-import org.simantics.databoard.accessor.impl.ChangeSet;\r
-import org.simantics.databoard.accessor.interestset.InterestSet;\r
-import org.simantics.databoard.accessor.java.JavaObject;\r
-import org.simantics.databoard.accessor.reference.ChildReference;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.binding.error.BindingException;\r
-import org.simantics.databoard.type.Datatype;\r
-\r
-/**\r
- * Accessor is an interface to access, modify and monitor a data container.\r
- * The actual storage format and location is implementation specific. \r
- * For instance, container could be: a bunch of bytes, a Java object, a file, \r
- * a folder with files, a network location, or direct memory of a simulation \r
- * experiment. <p> \r
- * \r
- * The structure is presentable with Databoard type system. The type can be \r
- * anything but a recursive structure.<p> \r
- * \r
- * The listening model allows placing of listener objects to accessors. \r
- * Each listener is associated with a InterestSet. It describes a sub-tree of \r
- * nodes to listen and aspects to monitor. Accessors emit Events on modifications \r
- * of structure and value. There is a reference in each event, and it is relative \r
- * to the accessor where the listener was placed. For instance, a listener, that is \r
- * interested in whole tree, is placed on a root accessor. A modification at a \r
- * leaf-node spawns an event with a reference path from the root to the leaf. \r
- * If the listener was placed directly on the leaf, there wouldn't be a path\r
- * in the evenr object.<p> \r
- * \r
- * Multi-thread-usage is implementation dependent, read the documentation. <p>\r
- * \r
- * Construction and destruction model is also implementation dependent.\r
- * A rule of thumb in life management of objects is that, the party that \r
- * constructs an object must destroy it. Both construction and destruction of \r
- * the container are also outside the scope of the Accessor interface. <p> \r
- * \r
- * However, as general implementation contract, the data container is disposed\r
- * as whole, individual nodes are not. While the container is alive, individual \r
- * nodes may be disposed using garbage collection mechanisms. Reference queue \r
- * mechanism is one implementatio strategy. More common strategy is usage of \r
- * weak references from parent to child. <p>\r
- * \r
- * @see Accessors \r
- * @see JavaObject Accessor to Java Object container\r
- * @see BinaryObject Accessor to a container in File or Memory \r
- * @see ArrayAccessor \r
- * @see BooleanAccessor \r
- * @see ByteAccessor \r
- * @see DoubleAccessor\r
- * @see FloatAccessor\r
- * @see IntegerAccessor\r
- * @see LongAccessor\r
- * @see MapAccessor\r
- * @see OptionalAccessor\r
- * @see RecordAccessor\r
- * @see StringAccessor\r
- * @see UnionAccessor\r
- * @see VariantAccessor\r
- * @author Toni Kalajainen (toni.kalajainen@iki.fi)\r
- */\r
-public interface Accessor {\r
-\r
- /**\r
- * Get a snapshot of the object as a single data value. <p>\r
- * Accessor makes type adaption to users binding if possible. <p>\r
- * \r
- * @param binding\r
- * @return the value\r
- * @throws AccessorException\r
- */\r
- Object getValue(Binding binding) throws AccessorException;\r
-\r
- /**\r
- * Read a copy of the accessor's object into the <tt>obj</tt> instance. <p>\r
- * Accessor makes type adaption to users binding if possible. <p>\r
- * \r
- * @param binding\r
- * @param obj object to read the value to\r
- * @throws AccessorException\r
- */\r
- void getValue(Binding binding, Object obj) throws AccessorException;\r
- \r
- /**\r
- * Read value in <tt>path</tt> reference into an <tt>obj</tt> instance. <p>\r
- * \r
- * @param path component reference path or <code>null</code> to return _this_ \r
- * @param binding\r
- * @param obj\r
- * @return true if value existed, false if not\r
- * @throws AccessorException\r
- */\r
- boolean getValue(ChildReference path, Binding binding, Object obj) throws AccessorException;\r
-\r
- /**\r
- * Read value in <tt>path</tt> reference into an <tt>obj</tt> instance. <p>\r
- * \r
- * @param path component reference path or <code>null</code> to return _this_ accessor\r
- * @param binding\r
- * @param obj\r
- * @return the object or <tt>null</tt> if value doesn't exist\r
- * @throws AccessorException\r
- */\r
- Object getValue(ChildReference path, Binding binding) throws AccessorException;\r
- \r
- /**\r
- * Set a complete new value to the data container. \r
- * Accessor makes type adaption to users binding if possible. <p>\r
- *\r
- * If the new value removes old map entries, array entries, optional value, or \r
- * changes union or variant value type, it will disengage any existing \r
- * sub-accessors and send {@link InvalidatedEvent}. <p>\r
- * \r
- * Writing the current value again may not emit an event. This is implementation\r
- * specific. <p>\r
- * \r
- * Write is durable, once a the method returns successfully the value has been\r
- * stored in the implmentation. <p>\r
- * \r
- * @param binding\r
- * @param newValue\r
- * @throws BindingException binding error\r
- * @throws UnsupportedOperationException cannot set a new value\r
- */\r
- void setValue(Binding binding, Object newValue) throws AccessorException;\r
-\r
- /**\r
- * Set value to <tt>path</tt> reference.\r
- * \r
- * @param path component reference path or <code>null</code> to return _this_ \r
- * @param binding\r
- * @param obj\r
- * @return true if value existed in the accessor, false if not\r
- * @throws AccessorException\r
- */\r
- boolean setValue(ChildReference path, Binding binding, Object obj) throws AccessorException;\r
- \r
- /**\r
- * Open an accessor to a child. If one already exists, the existing is returned, \r
- * otherwise a new is created. Child accessors are often remembered with \r
- * weak reference.<p> \r
- * \r
- * InvalidatedEvent is thrown from the accessor if it is unlinked from the\r
- * parent hierarchy. <p> \r
- * \r
- * @param path component reference path or <code>null</code> to return _this_ accessor\r
- * @return accessor\r
- * @throws AccessorConstructionException\r
- */\r
- <T extends Accessor> T getComponent(ChildReference path) throws AccessorConstructionException;\r
- \r
- /**\r
- * Apply a change set in a single transaction operation.\r
- * \r
- * If rollback log is supplied, it is filled with reverse events. \r
- * \r
- * If the operation fails, rollback log can be applied to cancel changes.\r
- * \r
- * @param changeSet\r
- * @param rollback log to be filled with rollback events or <code>null</code>\r
- * @throws AccessorException failed to apply change set\r
- */\r
- void apply(List<Event> changeSet, LinkedList<Event> rollback) throws AccessorException;\r
- \r
- /**\r
- * Get structural represtentation of the accessor presented in databoard's\r
- * type system. \r
- * \r
- * @return type description\r
- */\r
- Datatype type();\r
- \r
- /**\r
- * Place a listener to an accessor node. The listener will be notified for changes\r
- * in the node/node tree, depending on interest set.<p> \r
- * \r
- * When events are emited and in which thread processed is implementation\r
- * specific. It is also implementation specific, whether the object can be mutated \r
- * in the listener or whether it has to be done afterwards. <p> \r
- * \r
- * In many implementations there is a pluggable event handling strategy \r
- * EventEmitter. The default behaviour is to emit events as they are\r
- * spawned in the current thread.<p>\r
- * \r
- * There is a reference in each event instance that describes the path from\r
- * the accessor where listener was placed to the node to which the event \r
- * applies to. <p>\r
- * \r
- * Listener is attached to the object that holds the value at the time at \r
- * the of the adding. \r
- * For example, If a listener is attached to an array of element at index 3, \r
- * and a new value is inserted at position 2, the listener still monitors the same\r
- * container, which is now at index 4. The references of incoming the events \r
- * are modified to have the new index.<p>\r
- * \r
- * Also, if a new value is assigned to the parent of an object that is listened,\r
- * the listener keeps on monitoring the new value at the same reference.\r
- * This doesn't apply when a new value is set to a union of different tag,\r
- * to a variant with a new type, or value is removed from Optional type. \r
- * In these two cases the listener is invalidated.<p> \r
- * \r
- * See {@link ChangeSet} is an implementation that collects events.\r
- * \r
- * Executor argument determines the thread where the onEvents method is \r
- * handled. <tt>null</tt> argument denotes current thread. \r
- * \r
- * @param listener\r
- * @param interestSet\r
- * @param pathPrefix path to the accessor or <code>null</code>. This is used in the events the accessor produces\r
- * @param executor \r
- * @see ChangeSet collects events \r
- */\r
- void addListener(Listener listener, InterestSet interestSet, ChildReference pathPrefix, Executor executor) throws AccessorException;\r
- \r
- /**\r
- * Remove a listener. If the listener is added multiple times, the last \r
- * one added is removed. \r
- * \r
- * @param listener\r
- * @throws AccessorException\r
- */\r
- void removeListener(Listener listener) throws AccessorException;\r
- \r
- /**\r
- * Accessor listener. \r
- *\r
- * @author Toni Kalajainen <toni.kalajainen@vtt.fi>\r
- */\r
- public static interface Listener {\r
-\r
- /**\r
- * Notify the listener on a new event \r
- * \r
- * @param events\r
- */\r
- void onEvents(Collection<Event> events);\r
- \r
- }\r
- \r
-}\r
-\r
+/*******************************************************************************
+ * 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. <p>
+ *
+ * The structure is presentable with Databoard type system. The type can be
+ * anything but a recursive structure.<p>
+ *
+ * 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.<p>
+ *
+ * Multi-thread-usage is implementation dependent, read the documentation. <p>
+ *
+ * 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. <p>
+ *
+ * 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. <p>
+ *
+ * @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. <p>
+ * Accessor makes type adaption to users binding if possible. <p>
+ *
+ * @param binding
+ * @return the value
+ * @throws AccessorException
+ */
+ Object getValue(Binding binding) throws AccessorException;
+
+ /**
+ * Read a copy of the accessor's object into the <tt>obj</tt> instance. <p>
+ * Accessor makes type adaption to users binding if possible. <p>
+ *
+ * @param binding
+ * @param obj object to read the value to
+ * @throws AccessorException
+ */
+ void getValue(Binding binding, Object obj) throws AccessorException;
+
+ /**
+ * Read value in <tt>path</tt> reference into an <tt>obj</tt> instance. <p>
+ *
+ * @param path component reference path or <code>null</code> 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 <tt>path</tt> reference into an <tt>obj</tt> instance. <p>
+ *
+ * @param path component reference path or <code>null</code> to return _this_ accessor
+ * @param binding
+ * @param obj
+ * @return the object or <tt>null</tt> 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. <p>
+ *
+ * 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}. <p>
+ *
+ * Writing the current value again may not emit an event. This is implementation
+ * specific. <p>
+ *
+ * Write is durable, once a the method returns successfully the value has been
+ * stored in the implmentation. <p>
+ *
+ * @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 <tt>path</tt> reference.
+ *
+ * @param path component reference path or <code>null</code> 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.<p>
+ *
+ * InvalidatedEvent is thrown from the accessor if it is unlinked from the
+ * parent hierarchy. <p>
+ *
+ * @param path component reference path or <code>null</code> to return _this_ accessor
+ * @return accessor
+ * @throws AccessorConstructionException
+ */
+ <T extends Accessor> 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 <code>null</code>
+ * @throws AccessorException failed to apply change set
+ */
+ void apply(List<Event> changeSet, LinkedList<Event> 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.<p>
+ *
+ * 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. <p>
+ *
+ * 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.<p>
+ *
+ * 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. <p>
+ *
+ * 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.<p>
+ *
+ * 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.<p>
+ *
+ * See {@link ChangeSet} is an implementation that collects events.
+ *
+ * Executor argument determines the thread where the onEvents method is
+ * handled. <tt>null</tt> argument denotes current thread.
+ *
+ * @param listener
+ * @param interestSet
+ * @param pathPrefix path to the accessor or <code>null</code>. 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 <toni.kalajainen@vtt.fi>
+ */
+ public static interface Listener {
+
+ /**
+ * Notify the listener on a new event
+ *
+ * @param events
+ */
+ void onEvents(Collection<Event> events);
+
+ }
+
+}
+