1 /*******************************************************************************
\r
2 * Copyright (c) 2010- Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.databoard.accessor.wire;
\r
14 import java.lang.ref.ReferenceQueue;
\r
15 import java.lang.ref.WeakReference;
\r
16 import java.util.ArrayList;
\r
17 import java.util.Collection;
\r
18 import java.util.HashMap;
\r
19 import java.util.LinkedList;
\r
20 import java.util.List;
\r
21 import java.util.Map;
\r
22 import java.util.Map.Entry;
\r
23 import java.util.TreeMap;
\r
24 import java.util.concurrent.CopyOnWriteArrayList;
\r
25 import java.util.concurrent.Executor;
\r
27 import org.simantics.databoard.Bindings;
\r
28 import org.simantics.databoard.Datatypes;
\r
29 import org.simantics.databoard.Methods;
\r
30 import org.simantics.databoard.accessor.Accessor;
\r
31 import org.simantics.databoard.accessor.ArrayAccessor;
\r
32 import org.simantics.databoard.accessor.BooleanAccessor;
\r
33 import org.simantics.databoard.accessor.ByteAccessor;
\r
34 import org.simantics.databoard.accessor.CloseableAccessor;
\r
35 import org.simantics.databoard.accessor.DoubleAccessor;
\r
36 import org.simantics.databoard.accessor.FloatAccessor;
\r
37 import org.simantics.databoard.accessor.IntegerAccessor;
\r
38 import org.simantics.databoard.accessor.LongAccessor;
\r
39 import org.simantics.databoard.accessor.MapAccessor;
\r
40 import org.simantics.databoard.accessor.OptionalAccessor;
\r
41 import org.simantics.databoard.accessor.RecordAccessor;
\r
42 import org.simantics.databoard.accessor.StringAccessor;
\r
43 import org.simantics.databoard.accessor.UnionAccessor;
\r
44 import org.simantics.databoard.accessor.VariantAccessor;
\r
45 import org.simantics.databoard.accessor.error.AccessorConstructionException;
\r
46 import org.simantics.databoard.accessor.error.AccessorException;
\r
47 import org.simantics.databoard.accessor.error.ReferenceException;
\r
48 import org.simantics.databoard.accessor.event.ArrayElementRemoved;
\r
49 import org.simantics.databoard.accessor.event.Event;
\r
50 import org.simantics.databoard.accessor.event.MapEntryAdded;
\r
51 import org.simantics.databoard.accessor.event.MapEntryRemoved;
\r
52 import org.simantics.databoard.accessor.event.OptionalValueAssigned;
\r
53 import org.simantics.databoard.accessor.event.OptionalValueRemoved;
\r
54 import org.simantics.databoard.accessor.event.ValueAssigned;
\r
55 import org.simantics.databoard.accessor.impl.ListenerEntry;
\r
56 import org.simantics.databoard.accessor.interestset.InterestSet;
\r
57 import org.simantics.databoard.accessor.reference.ChildReference;
\r
58 import org.simantics.databoard.accessor.reference.ComponentReference;
\r
59 import org.simantics.databoard.accessor.reference.IndexReference;
\r
60 import org.simantics.databoard.accessor.reference.KeyReference;
\r
61 import org.simantics.databoard.accessor.reference.NameReference;
\r
62 import org.simantics.databoard.accessor.wire.IWireServer.AccessorInfo;
\r
63 import org.simantics.databoard.accessor.wire.IWireServer.ApplyResult;
\r
64 import org.simantics.databoard.adapter.AdaptException;
\r
65 import org.simantics.databoard.binding.ArrayBinding;
\r
66 import org.simantics.databoard.binding.Binding;
\r
67 import org.simantics.databoard.binding.MapBinding;
\r
68 import org.simantics.databoard.binding.error.BindingConstructionException;
\r
69 import org.simantics.databoard.binding.error.BindingException;
\r
70 import org.simantics.databoard.binding.impl.ArrayListBinding;
\r
71 import org.simantics.databoard.binding.impl.ObjectArrayBinding;
\r
72 import org.simantics.databoard.binding.impl.TreeMapBinding;
\r
73 import org.simantics.databoard.binding.mutable.MutableVariant;
\r
74 import org.simantics.databoard.method.MethodInterface;
\r
75 import org.simantics.databoard.type.ArrayType;
\r
76 import org.simantics.databoard.type.BooleanType;
\r
77 import org.simantics.databoard.type.ByteType;
\r
78 import org.simantics.databoard.type.Datatype;
\r
79 import org.simantics.databoard.type.DoubleType;
\r
80 import org.simantics.databoard.type.FloatType;
\r
81 import org.simantics.databoard.type.IntegerType;
\r
82 import org.simantics.databoard.type.LongType;
\r
83 import org.simantics.databoard.type.MapType;
\r
84 import org.simantics.databoard.type.OptionalType;
\r
85 import org.simantics.databoard.type.RecordType;
\r
86 import org.simantics.databoard.type.StringType;
\r
87 import org.simantics.databoard.type.UnionType;
\r
88 import org.simantics.databoard.type.VariantType;
\r
89 import org.simantics.databoard.util.BijectionMap;
\r
92 * WireAccessor provides an accessor over TCP/IP connection.
\r
94 * All method invocation is blocking. WireAccessor may be accessed from
\r
95 * simultanous threads.
\r
98 * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
\r
100 public class WireClient implements IWireClient {
\r
102 /** A queue of released accessors */
\r
103 ReferenceQueue<WireAccessor> releaseQueue = new ReferenceQueue<WireAccessor>();
\r
104 Map<ChildReference, WireAccessorReference> subAccessorMap = new HashMap<ChildReference, WireAccessorReference>();
\r
106 // Map<Integer, Accessor> accessorMap = new HashMap<Integer, Accessor>();
\r
107 BijectionMap<Integer, ListenerEntry> listenerMap = new BijectionMap<Integer, ListenerEntry>();
\r
109 MethodInterface serverMi;
\r
110 MethodInterface clientMi;
\r
111 IWireServer server;
\r
114 public WireClient() {
\r
116 this.clientMi = Methods.bindInterface(IWireClient.class, this);
\r
117 } catch (BindingConstructionException e) {
\r
118 throw new RuntimeException(e);
\r
122 public void setServerMethodInterface(MethodInterface serverMi) {
\r
124 this.serverMi = serverMi;
\r
125 this.server = Methods.createProxy(IWireServer.class, serverMi);
\r
126 } catch (BindingConstructionException e) {
\r
127 throw new RuntimeException(e);
\r
131 public MethodInterface getServerMethodInterface() {
\r
135 public MethodInterface getClientMethodInterface() {
\r
139 public void close() {
\r
141 closeReleasedAccessors();
\r
142 } catch (WireException e) {
\r
143 e.printStackTrace();
\r
149 * Create an accessor. Does not dispose or add to cache, use getAccessor instead
\r
152 * @throws WireException
\r
154 WireAccessor createAccessor(ChildReference ref) throws WireException {
\r
155 AccessorInfo ai = server.openAccessor(ref);
\r
156 if (ai.type instanceof BooleanType) {
\r
157 return new WireBoolean(ai.accessorId, ai.type, ref);
\r
159 if (ai.type instanceof ByteType) {
\r
160 return new WireByte(ai.accessorId, ai.type, ref);
\r
162 if (ai.type instanceof IntegerType) {
\r
163 return new WireInteger(ai.accessorId, ai.type, ref);
\r
165 if (ai.type instanceof LongType) {
\r
166 return new WireLong(ai.accessorId, ai.type, ref);
\r
168 if (ai.type instanceof FloatType) {
\r
169 return new WireFloat(ai.accessorId, ai.type, ref);
\r
171 if (ai.type instanceof DoubleType) {
\r
172 return new WireDouble(ai.accessorId, ai.type, ref);
\r
174 if (ai.type instanceof StringType) {
\r
175 return new WireByte(ai.accessorId, ai.type, ref);
\r
177 if (ai.type instanceof MapType) {
\r
178 return new WireMap(ai.accessorId, ai.type, ref);
\r
180 if (ai.type instanceof OptionalType) {
\r
181 return new WireOptional(ai.accessorId, ai.type, ref);
\r
183 if (ai.type instanceof RecordType) {
\r
184 return new WireRecord(ai.accessorId, ai.type, ref);
\r
186 if (ai.type instanceof UnionType) {
\r
187 return new WireUnion(ai.accessorId, ai.type, ref);
\r
189 if (ai.type instanceof VariantType) {
\r
190 return new WireVariant(ai.accessorId, ai.type, ref);
\r
192 throw new WireException("error, unknown data type "+ai.type);
\r
196 * Create or get wire accessor
\r
197 * @param ref path from root
\r
198 * @return wire accessor
\r
199 * @throws WireException
\r
201 public WireAccessor getAccessor(ChildReference ref) throws WireException {
\r
202 synchronized(subAccessorMap) {
\r
203 // Rseult Check cache
\r
204 closeReleasedAccessors();
\r
205 WireAccessorReference war = subAccessorMap.get(ref);
\r
206 WireAccessor result = war == null ? null : war.get();
\r
207 if (result != null) return result;
\r
209 result = createAccessor(ref);
\r
210 war = new WireAccessorReference(result);
\r
211 subAccessorMap.put(ref, war);
\r
218 * Close garbage collected accessors
\r
219 * @throws WireException
\r
221 void closeReleasedAccessors() throws WireException {
\r
222 if (releaseQueue.poll()==null) return;
\r
223 ArrayList<Integer> ids = new ArrayList<Integer>();
\r
224 while (releaseQueue.poll() != null) {
\r
226 WireAccessorReference ref = (WireAccessorReference) releaseQueue.remove();
\r
227 ids.add( ref.accId );
\r
228 } catch (InterruptedException e) {
\r
232 server.closeAccessors( ids.toArray(new Integer[ids.size()]) );
\r
236 public int onEvents(int lisId, Event[] events) {
\r
237 ListenerEntry listener = null;
\r
238 synchronized(listenerMap) {
\r
239 listener = listenerMap.getRight(lisId);
\r
241 if (listener==null) return 0;
\r
243 List<Event> list = new CopyOnWriteArrayList<Event>(events);
\r
244 listener.emitEvents(list);
\r
249 class WireAccessorReference extends WeakReference<WireAccessor> {
\r
253 public WireAccessorReference(WireAccessor referent) {
\r
254 super(referent, releaseQueue);
\r
255 this.accId = referent.accId;
\r
260 abstract class WireAccessor implements Accessor, CloseableAccessor {
\r
262 ChildReference ref;
\r
265 WireAccessor(int accId, Datatype type, ChildReference ref) {
\r
266 this.accId = accId;
\r
272 public Object getValue(Binding binding) throws AccessorException {
\r
274 MutableVariant value = server.getValue(accId);
\r
275 return value.getValue(binding);
\r
276 } catch (WireException e) {
\r
277 throw new AccessorException(e);
\r
278 } catch (AdaptException e) {
\r
279 throw new AccessorException(e);
\r
284 public void getValue(Binding binding, Object obj)
\r
285 throws AccessorException {
\r
287 MutableVariant value= server.getValue(accId);
\r
288 binding.readFrom(value.getBinding(), value.getValue(), obj);
\r
289 } catch ( WireException e ) {
\r
290 throw new AccessorException(e);
\r
291 } catch ( BindingException e ) {
\r
292 throw new AccessorException(e);
\r
297 public boolean getValue(ChildReference path, Binding binding, Object obj) throws AccessorException {
\r
299 Accessor a = getComponent(path);
\r
300 a.getValue(binding, obj);
\r
302 } catch (ReferenceException re) {
\r
304 } catch (AccessorConstructionException e) {
\r
305 throw new AccessorException(e);
\r
309 public Object getValue(ChildReference path, Binding binding) throws AccessorException {
\r
311 Accessor a = getComponent(path);
\r
312 return a.getValue(binding);
\r
313 } catch (ReferenceException re) {
\r
315 } catch (AccessorConstructionException e) {
\r
316 throw new AccessorException(e);
\r
321 void applyEvent(Event...events) throws AccessorException {
\r
322 ApplyResult result = server.apply(accId, events, false);
\r
323 if (result.error != null) throw new AccessorException( result.error );
\r
327 public void setValue(Binding binding, Object newValue) throws AccessorException {
\r
328 applyEvent( new ValueAssigned(binding, newValue) );
\r
331 public boolean setValue(ChildReference path, Binding binding, Object obj) throws AccessorException {
\r
333 Accessor a = getComponent(path);
\r
334 a.setValue(binding, obj);
\r
336 } catch (ReferenceException re) {
\r
338 } catch (AccessorConstructionException e) {
\r
339 throw new AccessorException(e);
\r
343 @SuppressWarnings("unchecked")
\r
345 public <T extends Accessor> T getComponent(ChildReference reference)
\r
346 throws AccessorConstructionException {
\r
348 // Create a reference from the root
\r
349 ChildReference r = ChildReference.concatenate(ref, reference);
\r
350 return (T) WireClient.this.getAccessor( r );
\r
351 } catch (WireException e) {
\r
352 throw new AccessorConstructionException( e );
\r
357 public void apply(List<Event> changeSet, LinkedList<Event> rollback)
\r
358 throws AccessorException {
\r
360 ApplyResult result = server.apply(accId, changeSet.toArray(new Event[changeSet.size()]), rollback!=null);
\r
361 if (rollback!=null && result.rollbackLog!=null)
\r
362 rollback.addAll( result.rollbackLog );
\r
363 if (result.error != null) throw new AccessorException( result.error );
\r
368 public Datatype type() {
\r
373 public void addListener(Listener listener, InterestSet interestSet,
\r
374 ChildReference pathPrefix, Executor executor) throws AccessorException {
\r
376 ListenerEntry le = new ListenerEntry(listener, interestSet, pathPrefix, executor);
\r
377 int lisId = server.addListener(accId, interestSet, pathPrefix);
\r
378 synchronized(listenerMap) {
\r
379 listenerMap.map(lisId, le);
\r
381 } catch (WireException e) {
\r
382 throw new AccessorException(e);
\r
387 public void removeListener(Listener listener) throws AccessorException {
\r
388 Integer lisId = null;
\r
389 synchronized(listenerMap) {
\r
390 for (Entry<Integer, ListenerEntry> e : listenerMap.getEntries()) {
\r
391 if (e.getValue().listener == listener) {
\r
392 lisId = e.getKey();
\r
396 if (lisId==null) return;
\r
397 listenerMap.removeWithLeft(lisId);
\r
400 server.removeListener(lisId);
\r
401 } catch (WireException e) {
\r
402 throw new AccessorException( e );
\r
406 public void close() throws AccessorException {
\r
408 server.closeAccessors( new Integer[] {accId} );
\r
409 } catch (WireException e) {
\r
410 throw new AccessorException( e );
\r
416 class WireBoolean extends WireAccessor implements BooleanAccessor {
\r
418 WireBoolean(int accId, Datatype type, ChildReference ref) {
\r
419 super(accId, type, ref);
\r
423 public BooleanType type() {
\r
424 return (BooleanType) type;
\r
428 public boolean getValue() throws AccessorException {
\r
430 MutableVariant value = server.getValue(accId);
\r
431 return (Boolean) value.getValue( Bindings.BOOLEAN );
\r
432 } catch (WireException e) {
\r
433 throw new AccessorException( e );
\r
434 } catch (AdaptException e) {
\r
435 throw new AccessorException( e );
\r
440 public void setValue(boolean value) throws AccessorException {
\r
441 Event e = new ValueAssigned(null, Bindings.BOOLEAN, value);
\r
442 Event[] list = new Event[] {e};
\r
443 ApplyResult result = server.apply(accId, list, false);
\r
444 if (result.error != null) throw new AccessorException( result.error );
\r
448 class WireByte extends WireAccessor implements ByteAccessor {
\r
450 WireByte(int accId, Datatype type, ChildReference ref) {
\r
451 super(accId, type, ref);
\r
455 public ByteType type() {
\r
456 return (ByteType) type;
\r
460 public byte getValue() throws AccessorException {
\r
462 MutableVariant value = server.getValue(accId);
\r
463 return (Byte) value.getValue( Bindings.BYTE );
\r
464 } catch (WireException e) {
\r
465 throw new AccessorException( e );
\r
466 } catch (AdaptException e) {
\r
467 throw new AccessorException( e );
\r
472 public void setValue(byte value) throws AccessorException {
\r
473 Event e = new ValueAssigned(null, Bindings.BYTE, value);
\r
474 Event[] list = new Event[] {e};
\r
475 ApplyResult result = server.apply(accId, list, false);
\r
476 if (result.error != null) throw new AccessorException( result.error );
\r
480 class WireInteger extends WireAccessor implements IntegerAccessor {
\r
482 WireInteger(int accId, Datatype type, ChildReference ref) {
\r
483 super(accId, type, ref);
\r
487 public IntegerType type() {
\r
488 return (IntegerType) type;
\r
492 public int getValue() throws AccessorException {
\r
494 MutableVariant value = server.getValue(accId);
\r
495 return (Integer) value.getValue( Bindings.INTEGER );
\r
496 } catch (WireException e) {
\r
497 throw new AccessorException( e );
\r
498 } catch (AdaptException e) {
\r
499 throw new AccessorException( e );
\r
504 public void setValue(int value) throws AccessorException {
\r
505 Event e = new ValueAssigned(Bindings.INTEGER, value);
\r
506 Event[] list = new Event[] {e};
\r
507 ApplyResult result = server.apply(accId, list, false);
\r
508 if (result.error != null) throw new AccessorException( result.error );
\r
513 class WireLong extends WireAccessor implements LongAccessor {
\r
515 WireLong(int accId, Datatype type, ChildReference ref) {
\r
516 super(accId, type, ref);
\r
520 public LongType type() {
\r
521 return (LongType) type;
\r
525 public long getValue() throws AccessorException {
\r
527 MutableVariant value = server.getValue(accId);
\r
528 return (Long) value.getValue( Bindings.LONG );
\r
529 } catch (WireException e) {
\r
530 throw new AccessorException( e );
\r
531 } catch (AdaptException e) {
\r
532 throw new AccessorException( e );
\r
537 public void setValue(long value) throws AccessorException {
\r
538 Event e = new ValueAssigned(Bindings.LONG, value);
\r
539 Event[] list = new Event[] {e};
\r
540 ApplyResult result = server.apply(accId, list, false);
\r
541 if (result.error != null) throw new AccessorException( result.error );
\r
546 class WireFloat extends WireAccessor implements FloatAccessor {
\r
548 WireFloat(int accId, Datatype type, ChildReference ref) {
\r
549 super(accId, type, ref);
\r
553 public FloatType type() {
\r
554 return (FloatType) type;
\r
558 public float getValue() throws AccessorException {
\r
560 MutableVariant value = server.getValue(accId);
\r
561 return (Float) value.getValue( Bindings.FLOAT );
\r
562 } catch (WireException e) {
\r
563 throw new AccessorException( e );
\r
564 } catch (AdaptException e) {
\r
565 throw new AccessorException( e );
\r
570 public void setValue(float value) throws AccessorException {
\r
571 Event e = new ValueAssigned(Bindings.FLOAT, value);
\r
572 Event[] list = new Event[] {e};
\r
573 ApplyResult result = server.apply(accId, list, false);
\r
574 if (result.error != null) throw new AccessorException( result.error );
\r
579 class WireDouble extends WireAccessor implements DoubleAccessor {
\r
581 WireDouble(int accId, Datatype type, ChildReference ref) {
\r
582 super(accId, type, ref);
\r
586 public DoubleType type() {
\r
587 return (DoubleType) type;
\r
591 public double getValue() throws AccessorException {
\r
593 MutableVariant value = server.getValue(accId);
\r
594 return (Double) value.getValue( Bindings.DOUBLE );
\r
595 } catch (WireException e) {
\r
596 throw new AccessorException( e );
\r
597 } catch (AdaptException e) {
\r
598 throw new AccessorException( e );
\r
603 public void setValue(double value) throws AccessorException {
\r
604 Event e = new ValueAssigned(Bindings.DOUBLE, value);
\r
605 Event[] list = new Event[] {e};
\r
606 ApplyResult result = server.apply(accId, list, false);
\r
607 if (result.error != null) throw new AccessorException( result.error );
\r
612 class WireArray extends WireAccessor implements ArrayAccessor {
\r
614 WireArray(int accId, Datatype type, ChildReference ref) {
\r
615 super(accId, type, ref);
\r
619 public ArrayType type() {
\r
620 return (ArrayType) type;
\r
624 public void add(Binding binding, Object value) throws AccessorException {
\r
626 server.addAll(accId, -1, new MutableVariant(binding, value));
\r
627 } catch (WireException e) {
\r
628 throw new AccessorException(e);
\r
633 public void addAll(Binding binding, Object[] values) throws AccessorException {
\r
635 ArrayBinding ab = new ObjectArrayBinding(new ArrayType(binding.type()), binding);
\r
636 MutableVariant array = new MutableVariant(ab, values);
\r
637 server.addAll(accId, -1, array);
\r
638 } catch (WireException e) {
\r
639 throw new AccessorException(e);
\r
644 public void addAll(int index, Binding binding, Object[] values)
\r
645 throws AccessorException {
\r
647 ArrayBinding ab = new ObjectArrayBinding(new ArrayType(binding.type()), binding);
\r
648 MutableVariant array = new MutableVariant(ab, values);
\r
649 server.addAll(accId, index, array);
\r
650 } catch (WireException e) {
\r
651 throw new AccessorException(e);
\r
656 public void add(int index, Binding binding, Object value) throws AccessorException {
\r
658 server.addAll(accId, index, new MutableVariant(binding, value));
\r
659 } catch (WireException e) {
\r
660 throw new AccessorException(e);
\r
665 public void set(int index, Binding binding, Object value)
\r
666 throws AccessorException {
\r
667 applyEvent(new ValueAssigned(new IndexReference(index), binding, value));
\r
671 public void remove(int index, int count) throws AccessorException {
\r
672 applyEvent(new ArrayElementRemoved(index));
\r
675 @SuppressWarnings("unchecked")
\r
677 public <T extends Accessor> T getAccessor(int index)
\r
678 throws AccessorConstructionException {
\r
679 return (T) getComponent(new IndexReference(index));
\r
683 public Object get(int index, Binding valueBinding)
\r
684 throws AccessorException {
\r
686 MutableVariant v = server.getArrayElement(accId, index);
\r
687 return v.getValue(valueBinding);
\r
688 } catch (WireException e) {
\r
689 throw new AccessorException(e);
\r
690 } catch (AdaptException e) {
\r
691 throw new AccessorException(e);
\r
696 public void get(int index, Binding valueBinding, Object dst)
\r
697 throws AccessorException {
\r
699 MutableVariant v = server.getArrayElement(accId, index);
\r
700 valueBinding.readFrom(v.getBinding(), v.getValue(), v);
\r
701 } catch (WireException e) {
\r
702 throw new AccessorException(e);
\r
703 } catch (BindingException e) {
\r
704 throw new AccessorException(e);
\r
709 public void getAll(Binding valueBinding, Object[] array)
\r
710 throws AccessorException {
\r
711 ObjectArrayBinding arrayBinding = new ObjectArrayBinding(type(), valueBinding);
\r
712 Object[] a2 = (Object[]) getValue(arrayBinding);
\r
713 System.arraycopy(a2, 0, array, 0, a2.length);
\r
717 public void getAll(Binding valueBinding, Collection<Object> values)
\r
718 throws AccessorException {
\r
719 ArrayListBinding arrayBinding = new ArrayListBinding(type(), valueBinding);
\r
720 ArrayList<?> a2 = (ArrayList<?>) getValue(arrayBinding);
\r
721 values.addAll(a2);
\r
725 public void setSize(int newSize) throws AccessorException {
\r
726 throw new AccessorException("Not implemented");
\r
730 public int size() throws AccessorException {
\r
732 return server.size(accId);
\r
733 } catch (WireException e) {
\r
734 throw new AccessorException( e );
\r
739 class WireMap extends WireAccessor implements MapAccessor {
\r
741 WireMap(int accId, Datatype type, ChildReference ref) {
\r
742 super(accId, type, ref);
\r
746 public MapType type() {
\r
747 return (MapType) type;
\r
751 public int size() throws AccessorException {
\r
753 return server.size(accId);
\r
754 } catch (WireException e) {
\r
755 throw new AccessorException( e );
\r
760 public Object get(Binding keyBinding, Object key, Binding valueBinding)
\r
761 throws AccessorException {
\r
763 MutableVariant value = server.getMapValue(accId, new MutableVariant(keyBinding, key));
\r
764 if (value.type().equals(Datatypes.VOID)) return null;
\r
765 return value.getValue(valueBinding);
\r
766 } catch (WireException e) {
\r
767 throw new AccessorException( e );
\r
768 } catch (AdaptException e) {
\r
769 throw new AccessorException( e );
\r
774 public boolean containsKey(Binding keyBinding, Object key)
\r
775 throws AccessorException {
\r
777 return server.containsKey(accId, new MutableVariant(keyBinding, key));
\r
778 } catch (WireException e) {
\r
779 throw new AccessorException( e );
\r
784 public boolean containsValue(Binding valueBinding, Object value)
\r
785 throws AccessorException {
\r
787 return server.containsValue(accId, new MutableVariant(valueBinding, value));
\r
788 } catch (WireException e) {
\r
789 throw new AccessorException( e );
\r
794 public void put(Binding keyBinding, Object key, Binding valueBinding,
\r
795 Object value) throws AccessorException {
\r
796 applyEvent( new MapEntryAdded(new MutableVariant(keyBinding, key), new MutableVariant(valueBinding, value)) );
\r
800 public void remove(Binding keyBinding, Object key)
\r
801 throws AccessorException {
\r
802 applyEvent( new MapEntryRemoved(new MutableVariant(keyBinding, key)) );
\r
806 public void clear() throws AccessorException {
\r
808 server.clear(accId);
\r
809 } catch (WireException e) {
\r
810 throw new AccessorException(e);
\r
815 public void putAll(Binding keyBinding, Binding valueBinding,
\r
816 Map<Object, Object> from) throws AccessorException {
\r
818 int count = from.size();
\r
819 Event events[] = new Event[ count ];
\r
821 for (Entry<Object, Object> e : from.entrySet()) {
\r
822 MutableVariant key = new MutableVariant( keyBinding, e.getKey() );
\r
823 MutableVariant value = new MutableVariant( valueBinding, e.getValue() );
\r
824 events[i] = new MapEntryAdded( key, value );
\r
827 applyEvent( events );
\r
831 public void putAll(Binding keyBinding, Binding valueBinding,
\r
832 Object[] keys, Object[] values) throws AccessorException {
\r
833 if (keys.length != values.length) throw new AccessorException("bad args");
\r
834 int count = keys.length;
\r
835 Event events[] = new Event[ count ];
\r
836 for (int i=0; i<count; i++) {
\r
837 events[i] = new MapEntryAdded( new MutableVariant(keyBinding, keys[i]), new MutableVariant(valueBinding, values[i]) );
\r
839 applyEvent( events );
\r
842 @SuppressWarnings("unchecked")
\r
844 public void getAll(Binding keyBinding, Binding valueBinding,
\r
845 Map<Object, Object> to) throws AccessorException {
\r
846 MapBinding binding = new TreeMapBinding(keyBinding, valueBinding);
\r
847 TreeMap<Object, Object> v = (TreeMap<Object, Object>) getValue(binding);
\r
851 @SuppressWarnings("unchecked")
\r
853 public void getAll(Binding keyBinding, Binding valueBinding,
\r
854 Object[] keys, Object[] values) throws AccessorException {
\r
855 MapBinding binding = new TreeMapBinding(keyBinding, valueBinding);
\r
856 TreeMap<Object, Object> v = (TreeMap<Object, Object>) getValue(binding);
\r
858 for (Entry<Object, Object> e : v.entrySet()) {
\r
859 keys[i] = e.getKey();
\r
860 values[i] = e.getValue();
\r
866 public Object[] getKeys(Binding keyBinding) throws AccessorException {
\r
868 MutableVariant array = server.getMapKeys(accId);
\r
869 ArrayBinding binding = new ObjectArrayBinding( keyBinding );
\r
870 return (Object[]) array.getValue(binding);
\r
871 } catch (WireException e) {
\r
872 throw new AccessorException( e );
\r
873 } catch (AdaptException e) {
\r
874 throw new AccessorException( e );
\r
879 public int count(Binding keyBinding, Object from,
\r
880 boolean fromInclusive, Object end, boolean endInclusive)
\r
881 throws AccessorException {
\r
882 throw new AccessorException("Not implemented");
\r
886 public int getEntries(Binding keyBinding, Object from,
\r
887 boolean fromInclusive, Object end, boolean endInclusive,
\r
888 ArrayBinding keyArrayBinding, Object dstKeys,
\r
889 ArrayBinding valueArrayBinding, Object dstValues, int limit)
\r
890 throws AccessorException {
\r
891 throw new AccessorException("Not implemented");
\r
896 public Object[] getValues(Binding valueBinding)
\r
897 throws AccessorException {
\r
899 MutableVariant array = server.getMapValues(accId);
\r
900 ArrayBinding binding = new ObjectArrayBinding( valueBinding );
\r
901 return (Object[]) array.getValue(binding);
\r
902 } catch (WireException e) {
\r
903 throw new AccessorException( e );
\r
904 } catch (AdaptException e) {
\r
905 throw new AccessorException( e );
\r
909 @SuppressWarnings("unchecked")
\r
911 public <T extends Accessor> T getValueAccessor(Binding keyBinding, Object key) throws AccessorConstructionException {
\r
912 return (T) getComponent( new KeyReference(keyBinding, key) );
\r
916 public Object getFirstKey(Binding keyBinding) throws AccessorException {
\r
918 MutableVariant result = server.getFirstKey(accId);
\r
919 if (result.type().equals(Datatypes.VOID)) return null;
\r
920 return result.getValue(keyBinding);
\r
921 } catch (WireException e) {
\r
922 throw new AccessorException(e);
\r
923 } catch (AdaptException e) {
\r
924 throw new AccessorException(e);
\r
929 public Object getLastKey(Binding keyBinding) throws AccessorException {
\r
931 MutableVariant result = server.getLastKey(accId);
\r
932 if (result.type().equals(Datatypes.VOID)) return null;
\r
933 return result.getValue(keyBinding);
\r
934 } catch (WireException e) {
\r
935 throw new AccessorException(e);
\r
936 } catch (AdaptException e) {
\r
937 throw new AccessorException(e);
\r
942 public Object getLowerKey(Binding keyBinding, Object key)
\r
943 throws AccessorException {
\r
945 MutableVariant result = server.getLowerKey(accId, new MutableVariant(keyBinding, key));
\r
946 if (result.type().equals(Datatypes.VOID)) return null;
\r
947 return result.getValue(keyBinding);
\r
948 } catch (WireException e) {
\r
949 throw new AccessorException(e);
\r
950 } catch (AdaptException e) {
\r
951 throw new AccessorException(e);
\r
956 public Object getFloorKey(Binding keyBinding, Object key)
\r
957 throws AccessorException {
\r
959 MutableVariant result = server.getFloorKey(accId, new MutableVariant(keyBinding, key));
\r
960 if (result.type() == Datatypes.VOID) return null;
\r
961 return result.getValue(keyBinding);
\r
962 } catch (WireException e) {
\r
963 throw new AccessorException(e);
\r
964 } catch (AdaptException e) {
\r
965 throw new AccessorException(e);
\r
970 public Object getCeilingKey(Binding keyBinding, Object key)
\r
971 throws AccessorException {
\r
973 MutableVariant result = server.getCeilingKey(accId, new MutableVariant(keyBinding, key));
\r
974 if (result.type().equals(Datatypes.VOID)) return null;
\r
975 return result.getValue(keyBinding);
\r
976 } catch (WireException e) {
\r
977 throw new AccessorException(e);
\r
978 } catch (AdaptException e) {
\r
979 throw new AccessorException(e);
\r
984 public Object getHigherKey(Binding keyBinding, Object key)
\r
985 throws AccessorException {
\r
987 MutableVariant result = server.getHigherKey(accId, new MutableVariant(keyBinding, key));
\r
988 if (result.type().equals(Datatypes.VOID)) return null;
\r
989 return result.getValue(keyBinding);
\r
990 } catch (WireException e) {
\r
991 throw new AccessorException(e);
\r
992 } catch (AdaptException e) {
\r
993 throw new AccessorException(e);
\r
999 class WireOptional extends WireAccessor implements OptionalAccessor {
\r
1001 WireOptional(int accId, Datatype type, ChildReference ref) {
\r
1002 super(accId, type, ref);
\r
1006 public OptionalType type() {
\r
1007 return (OptionalType) type;
\r
1011 public void setNoValue() throws AccessorException {
\r
1012 applyEvent( new OptionalValueRemoved() );
\r
1016 public boolean hasValue() throws AccessorException {
\r
1018 return server.hasValue(accId);
\r
1019 } catch (WireException e) {
\r
1020 throw new AccessorException( e );
\r
1025 public Object getComponentValue(Binding componentBinding)
\r
1026 throws AccessorException {
\r
1028 WireAccessor sa = createAccessor( new ComponentReference() );
\r
1030 return sa.getValue(componentBinding);
\r
1034 } catch (WireException e) {
\r
1035 throw new AccessorException( e );
\r
1040 public void setComponentValue(Binding binding, Object value)
\r
1041 throws AccessorException {
\r
1042 applyEvent(new OptionalValueAssigned(binding, value));
\r
1045 @SuppressWarnings("unchecked")
\r
1047 public <T extends Accessor> T getComponentAccessor()
\r
1048 throws AccessorConstructionException {
\r
1049 return (T) getComponent( new ComponentReference() );
\r
1054 class WireRecord extends WireAccessor implements RecordAccessor {
\r
1056 WireRecord(int accId, Datatype type, ChildReference ref) {
\r
1057 super(accId, type, ref);
\r
1061 public RecordType type() {
\r
1062 return (RecordType) type;
\r
1066 public int count() throws AccessorException {
\r
1068 return server.size(accId);
\r
1069 } catch (WireException e) {
\r
1070 throw new AccessorException(e);
\r
1074 @SuppressWarnings("unchecked")
\r
1076 public <T extends Accessor> T getFieldAccessor(int index)
\r
1077 throws AccessorConstructionException {
\r
1078 return (T) getComponent( new IndexReference(index) );
\r
1081 @SuppressWarnings("unchecked")
\r
1083 public <T extends Accessor> T getFieldAccessor(String fieldName)
\r
1084 throws AccessorConstructionException {
\r
1085 return (T) getComponent( new NameReference( fieldName ) );
\r
1089 public Object getFieldValue(String fieldName, Binding fieldBinding)
\r
1090 throws AccessorException {
\r
1091 int fieldIndex = type().getComponentIndex(fieldName);
\r
1092 if (fieldIndex<0) throw new AccessorException("Field "+fieldName+" does not exist");
\r
1093 return getFieldValue(fieldIndex, fieldBinding);
\r
1097 public Object getFieldValue(int index, Binding fieldBinding)
\r
1098 throws AccessorException {
\r
1100 WireAccessor sa = createAccessor( new IndexReference(index) );
\r
1102 return sa.getValue(fieldBinding);
\r
1106 } catch (WireException e) {
\r
1107 throw new AccessorException( e );
\r
1111 public void setFieldValue(String fieldName, Binding fieldBinding, Object value) throws AccessorException {
\r
1112 int fieldIndex = type().getComponentIndex(fieldName);
\r
1113 if (fieldIndex<0) throw new AccessorException("Field "+fieldName+" does not exist");
\r
1114 setFieldValue(fieldIndex, fieldBinding, value);
\r
1118 public void setFieldValue(int index, Binding fieldBinding, Object value)
\r
1119 throws AccessorException {
\r
1121 WireAccessor sa = createAccessor( new IndexReference(index) );
\r
1123 sa.setValue(fieldBinding, value);
\r
1127 } catch (WireException e) {
\r
1128 throw new AccessorException( e );
\r
1134 class WireString extends WireAccessor implements StringAccessor {
\r
1136 WireString(int accId, Datatype type, ChildReference ref) {
\r
1137 super(accId, type, ref);
\r
1141 public StringType type() {
\r
1142 return (StringType) type;
\r
1146 public String getValue() throws AccessorException {
\r
1148 MutableVariant value = server.getValue(accId);
\r
1149 return (String) value.getValue( Bindings.STRING );
\r
1150 } catch (WireException e) {
\r
1151 throw new AccessorException( e );
\r
1152 } catch (AdaptException e) {
\r
1153 throw new AccessorException( e );
\r
1158 public void setValue(String newValue) throws AccessorException {
\r
1159 Event e = new ValueAssigned( Bindings.STRING, newValue);
\r
1160 Event[] list = new Event[] {e};
\r
1161 ApplyResult result = server.apply(accId, list, false);
\r
1162 if (result.error != null) throw new AccessorException( result.error );
\r
1167 class WireUnion extends WireAccessor implements UnionAccessor {
\r
1169 WireUnion(int accId, Datatype type, ChildReference ref) {
\r
1170 super(accId, type, ref);
\r
1174 public UnionType type() {
\r
1175 return (UnionType) type;
\r
1179 public int count() throws AccessorException {
\r
1181 return server.size(accId);
\r
1182 } catch (WireException e) {
\r
1183 throw new AccessorException(e);
\r
1188 public int getTag() throws AccessorException {
\r
1190 return server.getTag(accId);
\r
1191 } catch (WireException e) {
\r
1192 throw new AccessorException(e);
\r
1196 @SuppressWarnings("unchecked")
\r
1198 public <T extends Accessor> T getComponentAccessor()
\r
1199 throws AccessorConstructionException {
\r
1200 return (T) getComponent(new ComponentReference());
\r
1204 public Object getComponentValue(Binding componentBinding)
\r
1205 throws AccessorException {
\r
1207 WireAccessor sa = createAccessor( new ComponentReference() );
\r
1209 return sa.getValue(componentBinding);
\r
1213 } catch (WireException e) {
\r
1214 throw new AccessorException( e );
\r
1219 public void setComponentValue(int tag, Binding componentBinding,
\r
1220 Object componentValue) throws AccessorException {
\r
1222 WireAccessor sa = createAccessor( new ComponentReference() );
\r
1224 sa.setValue(componentBinding, componentValue);
\r
1228 } catch (WireException e) {
\r
1229 throw new AccessorException( e );
\r
1236 class WireVariant extends WireAccessor implements VariantAccessor {
\r
1238 WireVariant(int accId, Datatype type, ChildReference ref) {
\r
1239 super(accId, type, ref);
\r
1243 public VariantType type() {
\r
1244 return (VariantType) type;
\r
1247 @SuppressWarnings("unchecked")
\r
1249 public <T extends Accessor> T getContentAccessor()
\r
1250 throws AccessorConstructionException {
\r
1251 return (T) getComponent(new ComponentReference());
\r
1255 public void setContentValue(Binding valueBinding, Object value)
\r
1256 throws AccessorException {
\r
1258 WireAccessor sa = createAccessor( new ComponentReference() );
\r
1260 sa.setValue(valueBinding, value);
\r
1264 } catch (WireException e) {
\r
1265 throw new AccessorException( e );
\r
1270 public Object getContentValue(Binding contentBinding)
\r
1271 throws AccessorException {
\r
1273 WireAccessor sa = createAccessor( new ComponentReference() );
\r
1275 return sa.getValue(contentBinding);
\r
1279 } catch (WireException e) {
\r
1280 throw new AccessorException( e );
\r
1285 public Datatype getContentType() throws AccessorException {
\r
1287 WireAccessor sa = createAccessor( new ComponentReference() );
\r
1293 } catch (WireException e) {
\r
1294 throw new AccessorException( e );
\r