]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/Accessor.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / accessor / Accessor.java
1 /*******************************************************************************
2  *  Copyright (c) 2010 Association for Decentralized Information Management in
3  *  Industry THTH ry.
4  *  All rights reserved. This program and the accompanying materials
5  *  are made available under the terms of the Eclipse Public License v1.0
6  *  which accompanies this distribution, and is available at
7  *  http://www.eclipse.org/legal/epl-v10.html
8  *
9  *  Contributors:
10  *      VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.databoard.accessor;
13
14 import java.util.Collection;
15 import java.util.LinkedList;
16 import java.util.List;
17 import java.util.concurrent.Executor;
18
19 import org.simantics.databoard.Accessors;
20 import org.simantics.databoard.accessor.binary.BinaryObject;
21 import org.simantics.databoard.accessor.error.AccessorConstructionException;
22 import org.simantics.databoard.accessor.error.AccessorException;
23 import org.simantics.databoard.accessor.event.Event;
24 import org.simantics.databoard.accessor.event.InvalidatedEvent;
25 import org.simantics.databoard.accessor.impl.ChangeSet;
26 import org.simantics.databoard.accessor.interestset.InterestSet;
27 import org.simantics.databoard.accessor.java.JavaObject;
28 import org.simantics.databoard.accessor.reference.ChildReference;
29 import org.simantics.databoard.binding.Binding;
30 import org.simantics.databoard.binding.error.BindingException;
31 import org.simantics.databoard.type.Datatype;
32
33 /**
34  * Accessor is an interface to access, modify and monitor a data container.
35  * The actual storage format and location is implementation specific. 
36  * For instance, container could be: a bunch of bytes, a Java object, a file, 
37  * a folder with files, a network location, or direct memory of a simulation 
38  * experiment. <p> 
39  * 
40  * The structure is presentable with Databoard type system. The type can be 
41  * anything but a recursive structure.<p> 
42  * 
43  * The listening model allows placing of listener objects to accessors. 
44  * Each listener is associated with a InterestSet. It describes a sub-tree of 
45  * nodes to listen and aspects to monitor. Accessors emit Events on modifications  
46  * of structure and value. There is a reference in each event, and it is relative 
47  * to the accessor where the listener was placed. For instance, a listener, that is 
48  * interested in whole tree, is placed on a root accessor. A modification at a 
49  * leaf-node spawns an event with a reference path from the root to the leaf. 
50  * If the listener was placed directly on the leaf, there wouldn't be a path
51  * in the evenr object.<p> 
52  * 
53  * Multi-thread-usage is implementation dependent, read the documentation. <p>
54  * 
55  * Construction and destruction model is also implementation dependent.
56  * A rule of thumb in life management of objects is that, the party that 
57  * constructs an object must destroy it. Both construction and destruction of 
58  * the container are also outside the scope of the Accessor interface. <p> 
59  * 
60  * However, as general implementation contract, the data container is disposed
61  * as whole, individual nodes are not. While the container is alive, individual 
62  * nodes may be disposed using garbage collection mechanisms. Reference queue 
63  * mechanism is one implementatio strategy. More common strategy is usage of 
64  * weak references from parent to child. <p>
65  * 
66  * @see Accessors 
67  * @see JavaObject Accessor to Java Object container
68  * @see BinaryObject Accessor to a container in File or Memory  
69  * @see ArrayAccessor  
70  * @see BooleanAccessor 
71  * @see ByteAccessor 
72  * @see DoubleAccessor
73  * @see FloatAccessor
74  * @see IntegerAccessor
75  * @see LongAccessor
76  * @see MapAccessor
77  * @see OptionalAccessor
78  * @see RecordAccessor
79  * @see StringAccessor
80  * @see UnionAccessor
81  * @see VariantAccessor
82  * @author Toni Kalajainen (toni.kalajainen@iki.fi)
83  */
84 public interface Accessor {
85
86         /**
87          * Get a snapshot of the object as a single data value. <p>
88          * Accessor makes type adaption to users binding if possible. <p>
89          * 
90          * @param binding
91          * @return the value
92          * @throws AccessorException
93          */
94         Object getValue(Binding binding) throws AccessorException;
95
96         /**
97          * Read a copy of the accessor's object into the <tt>obj</tt> instance. <p>
98          * Accessor makes type adaption to users binding if possible. <p>
99          * 
100          * @param binding
101          * @param obj object to read the value to
102          * @throws AccessorException
103          */
104         void getValue(Binding binding, Object obj) throws AccessorException;
105         
106         /**
107          * Read value in <tt>path</tt> reference into an <tt>obj</tt> instance. <p>
108          * 
109          * @param path component reference path or <code>null</code> to return _this_ 
110          * @param binding
111          * @param obj
112          * @return true if value existed, false if not
113          * @throws AccessorException
114          */
115         boolean getValue(ChildReference path, Binding binding, Object obj) throws AccessorException;
116
117         /**
118          * Read value in <tt>path</tt> reference into an <tt>obj</tt> instance. <p>
119          * 
120          * @param path component reference path or <code>null</code> to return _this_ accessor
121          * @param binding
122          * @param obj
123          * @return the object or <tt>null</tt> if value doesn't exist
124          * @throws AccessorException
125          */
126         Object getValue(ChildReference path, Binding binding) throws AccessorException;
127         
128         /**
129          * Set a complete new value to the data container. 
130          * Accessor makes type adaption to users binding if possible. <p>
131          *
132          * If the new value removes old map entries, array entries, optional value, or 
133          * changes union or variant value type, it will disengage any existing 
134          * sub-accessors and send {@link InvalidatedEvent}. <p>
135          * 
136          * Writing the current value again may not emit an event. This is implementation
137          * specific. <p>
138          * 
139          * Write is durable, once a the method returns successfully the value has been
140          * stored in the implmentation. <p>
141          * 
142          * @param binding
143          * @param newValue
144          * @throws BindingException binding error
145          * @throws UnsupportedOperationException cannot set a new value
146          */
147         void setValue(Binding binding, Object newValue) throws AccessorException;
148
149         /**
150          * Set value to <tt>path</tt> reference.
151          * 
152          * @param path component reference path or <code>null</code> to return _this_ 
153          * @param binding
154          * @param obj
155          * @return true if value existed in the accessor, false if not
156          * @throws AccessorException
157          */
158         boolean setValue(ChildReference path, Binding binding, Object obj) throws AccessorException;
159         
160         /**
161          * Open an accessor to a child. If one already exists, the existing is returned, 
162          * otherwise a new is created. Child accessors are often remembered with 
163          * weak reference.<p> 
164          * 
165          * InvalidatedEvent is thrown from the accessor if it is unlinked from the
166          * parent hierarchy. <p> 
167          * 
168          * @param path component reference path or <code>null</code> to return _this_ accessor
169          * @return accessor
170          * @throws AccessorConstructionException
171          */
172         <T extends Accessor> T getComponent(ChildReference path) throws AccessorConstructionException;
173         
174         /**
175          * Apply a change set in a single transaction operation.
176          * 
177          * If rollback log is supplied, it is filled with reverse events. 
178          *  
179          * If the operation fails, rollback log can be applied to cancel changes.
180          * 
181          * @param changeSet
182          * @param rollback log to be filled with rollback events or <code>null</code>
183          * @throws AccessorException failed to apply change set
184          */
185         void apply(List<Event> changeSet, LinkedList<Event> rollback) throws AccessorException;
186         
187         /**
188          * Get structural represtentation of the accessor presented in databoard's
189          * type system. 
190          * 
191          * @return type description
192          */
193         Datatype type();
194         
195         /**
196          * Place a listener to an accessor node. The listener will be notified for changes
197          * in the node/node tree, depending on interest set.<p> 
198          * 
199          * When events are emited and in which thread processed is implementation
200          * specific. It is also implementation specific, whether the object can be mutated 
201          * in the listener or whether it has to be done afterwards. <p> 
202          * 
203          * In many implementations there is a pluggable event handling strategy 
204          * EventEmitter. The default behaviour is to emit events as they are
205          * spawned in the current thread.<p>
206          * 
207          * There is a reference in each event instance that describes the path from
208          * the accessor where listener was placed to the node to which the event 
209          * applies to. <p>
210          * 
211          * Listener is attached to the object that holds the value at the time at 
212          * the of the adding. 
213          * For example, If a listener is attached to an array of element at index 3, 
214          * and a new value is inserted at position 2, the listener still monitors the same
215          * container, which is now at index 4. The references of incoming the events 
216          * are modified to have the new index.<p>
217          * 
218          * Also, if a new value is assigned to the parent of an object that is listened,
219          * the listener keeps on monitoring the new value at the same reference.
220          * This doesn't apply when a new value is set to a union of different tag,
221          * to a variant with a new type, or value is removed from Optional type. 
222          * In these two cases the listener is invalidated.<p>   
223          * 
224          * See {@link ChangeSet} is an implementation that collects events.
225          * 
226          * Executor argument determines the thread where the onEvents method is 
227          * handled. <tt>null</tt> argument denotes current thread. 
228          * 
229          * @param listener
230          * @param interestSet
231          * @param pathPrefix path to the accessor or <code>null</code>. This is used in the events the accessor produces
232          * @param executor 
233          * @see ChangeSet collects events 
234          */
235         void addListener(Listener listener, InterestSet interestSet, ChildReference pathPrefix, Executor executor) throws AccessorException;
236         
237         /**
238          * Remove a listener. If the listener is added multiple times, the last 
239          * one added is removed. 
240          * 
241          * @param listener
242          * @throws AccessorException
243          */
244         void removeListener(Listener listener) throws AccessorException;
245         
246         /**
247          * Accessor listener. 
248          *
249          * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
250          */
251         public static interface Listener {
252
253                 /**
254                  * Notify the listener on a new event 
255                  * 
256                  * @param events
257                  */
258                 void onEvents(Collection<Event> events);
259                 
260         }
261         
262 }
263