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