X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Faccessor%2Fwire%2FWireClient.java;fp=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Faccessor%2Fwire%2FWireClient.java;h=35b7951e87446d8306220689a39b52f1f661b05e;hp=0fcafe1ce105350b4a018d7f5dbe9d48bda10ed8;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/wire/WireClient.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/wire/WireClient.java index 0fcafe1ce..35b7951e8 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/wire/WireClient.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/wire/WireClient.java @@ -1,1302 +1,1302 @@ -/******************************************************************************* - * 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.wire; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Executor; - -import org.simantics.databoard.Bindings; -import org.simantics.databoard.Datatypes; -import org.simantics.databoard.Methods; -import org.simantics.databoard.accessor.Accessor; -import org.simantics.databoard.accessor.ArrayAccessor; -import org.simantics.databoard.accessor.BooleanAccessor; -import org.simantics.databoard.accessor.ByteAccessor; -import org.simantics.databoard.accessor.CloseableAccessor; -import org.simantics.databoard.accessor.DoubleAccessor; -import org.simantics.databoard.accessor.FloatAccessor; -import org.simantics.databoard.accessor.IntegerAccessor; -import org.simantics.databoard.accessor.LongAccessor; -import org.simantics.databoard.accessor.MapAccessor; -import org.simantics.databoard.accessor.OptionalAccessor; -import org.simantics.databoard.accessor.RecordAccessor; -import org.simantics.databoard.accessor.StringAccessor; -import org.simantics.databoard.accessor.UnionAccessor; -import org.simantics.databoard.accessor.VariantAccessor; -import org.simantics.databoard.accessor.error.AccessorConstructionException; -import org.simantics.databoard.accessor.error.AccessorException; -import org.simantics.databoard.accessor.error.ReferenceException; -import org.simantics.databoard.accessor.event.ArrayElementRemoved; -import org.simantics.databoard.accessor.event.Event; -import org.simantics.databoard.accessor.event.MapEntryAdded; -import org.simantics.databoard.accessor.event.MapEntryRemoved; -import org.simantics.databoard.accessor.event.OptionalValueAssigned; -import org.simantics.databoard.accessor.event.OptionalValueRemoved; -import org.simantics.databoard.accessor.event.ValueAssigned; -import org.simantics.databoard.accessor.impl.ListenerEntry; -import org.simantics.databoard.accessor.interestset.InterestSet; -import org.simantics.databoard.accessor.reference.ChildReference; -import org.simantics.databoard.accessor.reference.ComponentReference; -import org.simantics.databoard.accessor.reference.IndexReference; -import org.simantics.databoard.accessor.reference.KeyReference; -import org.simantics.databoard.accessor.reference.NameReference; -import org.simantics.databoard.accessor.wire.IWireServer.AccessorInfo; -import org.simantics.databoard.accessor.wire.IWireServer.ApplyResult; -import org.simantics.databoard.adapter.AdaptException; -import org.simantics.databoard.binding.ArrayBinding; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.MapBinding; -import org.simantics.databoard.binding.error.BindingConstructionException; -import org.simantics.databoard.binding.error.BindingException; -import org.simantics.databoard.binding.impl.ArrayListBinding; -import org.simantics.databoard.binding.impl.ObjectArrayBinding; -import org.simantics.databoard.binding.impl.TreeMapBinding; -import org.simantics.databoard.binding.mutable.MutableVariant; -import org.simantics.databoard.method.MethodInterface; -import org.simantics.databoard.type.ArrayType; -import org.simantics.databoard.type.BooleanType; -import org.simantics.databoard.type.ByteType; -import org.simantics.databoard.type.Datatype; -import org.simantics.databoard.type.DoubleType; -import org.simantics.databoard.type.FloatType; -import org.simantics.databoard.type.IntegerType; -import org.simantics.databoard.type.LongType; -import org.simantics.databoard.type.MapType; -import org.simantics.databoard.type.OptionalType; -import org.simantics.databoard.type.RecordType; -import org.simantics.databoard.type.StringType; -import org.simantics.databoard.type.UnionType; -import org.simantics.databoard.type.VariantType; -import org.simantics.databoard.util.BijectionMap; - -/** - * WireAccessor provides an accessor over TCP/IP connection. - * - * All method invocation is blocking. WireAccessor may be accessed from - * simultanous threads. - * - * - * @author Toni Kalajainen - */ -public class WireClient implements IWireClient { - - /** A queue of released accessors */ - ReferenceQueue releaseQueue = new ReferenceQueue(); - Map subAccessorMap = new HashMap(); - -// Map accessorMap = new HashMap(); - BijectionMap listenerMap = new BijectionMap(); - - MethodInterface serverMi; - MethodInterface clientMi; - IWireServer server; - WireAccessor root; - - public WireClient() { - try { - this.clientMi = Methods.bindInterface(IWireClient.class, this); - } catch (BindingConstructionException e) { - throw new RuntimeException(e); - } - } - - public void setServerMethodInterface(MethodInterface serverMi) { - try { - this.serverMi = serverMi; - this.server = Methods.createProxy(IWireServer.class, serverMi); - } catch (BindingConstructionException e) { - throw new RuntimeException(e); - } - } - - public MethodInterface getServerMethodInterface() { - return serverMi; - } - - public MethodInterface getClientMethodInterface() { - return clientMi; - } - - public void close() { - try { - closeReleasedAccessors(); - } catch (WireException e) { - e.printStackTrace(); - } - - } - - /** - * Create an accessor. Does not dispose or add to cache, use getAccessor instead - * @param ref - * @return - * @throws WireException - */ - WireAccessor createAccessor(ChildReference ref) throws WireException { - AccessorInfo ai = server.openAccessor(ref); - if (ai.type instanceof BooleanType) { - return new WireBoolean(ai.accessorId, ai.type, ref); - } else - if (ai.type instanceof ByteType) { - return new WireByte(ai.accessorId, ai.type, ref); - } else - if (ai.type instanceof IntegerType) { - return new WireInteger(ai.accessorId, ai.type, ref); - } else - if (ai.type instanceof LongType) { - return new WireLong(ai.accessorId, ai.type, ref); - } else - if (ai.type instanceof FloatType) { - return new WireFloat(ai.accessorId, ai.type, ref); - } else - if (ai.type instanceof DoubleType) { - return new WireDouble(ai.accessorId, ai.type, ref); - } else - if (ai.type instanceof StringType) { - return new WireByte(ai.accessorId, ai.type, ref); - } else - if (ai.type instanceof MapType) { - return new WireMap(ai.accessorId, ai.type, ref); - } else - if (ai.type instanceof OptionalType) { - return new WireOptional(ai.accessorId, ai.type, ref); - } else - if (ai.type instanceof RecordType) { - return new WireRecord(ai.accessorId, ai.type, ref); - } else - if (ai.type instanceof UnionType) { - return new WireUnion(ai.accessorId, ai.type, ref); - } else - if (ai.type instanceof VariantType) { - return new WireVariant(ai.accessorId, ai.type, ref); - } - throw new WireException("error, unknown data type "+ai.type); - } - - /** - * Create or get wire accessor - * @param ref path from root - * @return wire accessor - * @throws WireException - */ - public WireAccessor getAccessor(ChildReference ref) throws WireException { - synchronized(subAccessorMap) { - // Rseult Check cache - closeReleasedAccessors(); - WireAccessorReference war = subAccessorMap.get(ref); - WireAccessor result = war == null ? null : war.get(); - if (result != null) return result; - - result = createAccessor(ref); - war = new WireAccessorReference(result); - subAccessorMap.put(ref, war); - - return result; - } - } - - /** - * Close garbage collected accessors - * @throws WireException - */ - void closeReleasedAccessors() throws WireException { - if (releaseQueue.poll()==null) return; - ArrayList ids = new ArrayList(); - while (releaseQueue.poll() != null) { - try { - WireAccessorReference ref = (WireAccessorReference) releaseQueue.remove(); - ids.add( ref.accId ); - } catch (InterruptedException e) { - } - } - // Close accessors - server.closeAccessors( ids.toArray(new Integer[ids.size()]) ); - } - - @Override - public int onEvents(int lisId, Event[] events) { - ListenerEntry listener = null; - synchronized(listenerMap) { - listener = listenerMap.getRight(lisId); - } - if (listener==null) return 0; - - List list = new CopyOnWriteArrayList(events); - listener.emitEvents(list); - - return 0; - } - - class WireAccessorReference extends WeakReference { - - int accId; - - public WireAccessorReference(WireAccessor referent) { - super(referent, releaseQueue); - this.accId = referent.accId; - } - - } - - abstract class WireAccessor implements Accessor, CloseableAccessor { - int accId; - ChildReference ref; - Datatype type; - - WireAccessor(int accId, Datatype type, ChildReference ref) { - this.accId = accId; - this.type = type; - this.ref = ref; - } - - @Override - public Object getValue(Binding binding) throws AccessorException { - try { - MutableVariant value = server.getValue(accId); - return value.getValue(binding); - } catch (WireException e) { - throw new AccessorException(e); - } catch (AdaptException e) { - throw new AccessorException(e); - } - } - - @Override - public void getValue(Binding binding, Object obj) - throws AccessorException { - try { - MutableVariant value= server.getValue(accId); - binding.readFrom(value.getBinding(), value.getValue(), obj); - } catch ( WireException e ) { - throw new AccessorException(e); - } catch ( BindingException e ) { - throw new AccessorException(e); - } - } - - @Override - public boolean getValue(ChildReference path, Binding binding, Object obj) throws AccessorException { - try { - Accessor a = getComponent(path); - a.getValue(binding, obj); - return true; - } catch (ReferenceException re) { - return false; - } catch (AccessorConstructionException e) { - throw new AccessorException(e); - } - } - - public Object getValue(ChildReference path, Binding binding) throws AccessorException { - try { - Accessor a = getComponent(path); - return a.getValue(binding); - } catch (ReferenceException re) { - return null; - } catch (AccessorConstructionException e) { - throw new AccessorException(e); - } - } - - - void applyEvent(Event...events) throws AccessorException { - ApplyResult result = server.apply(accId, events, false); - if (result.error != null) throw new AccessorException( result.error ); - } - - @Override - public void setValue(Binding binding, Object newValue) throws AccessorException { - applyEvent( new ValueAssigned(binding, newValue) ); - } - - public boolean setValue(ChildReference path, Binding binding, Object obj) throws AccessorException { - try { - Accessor a = getComponent(path); - a.setValue(binding, obj); - return true; - } catch (ReferenceException re) { - return false; - } catch (AccessorConstructionException e) { - throw new AccessorException(e); - } - } - - @SuppressWarnings("unchecked") - @Override - public T getComponent(ChildReference reference) - throws AccessorConstructionException { - try { - // Create a reference from the root - ChildReference r = ChildReference.concatenate(ref, reference); - return (T) WireClient.this.getAccessor( r ); - } catch (WireException e) { - throw new AccessorConstructionException( e ); - } - } - - @Override - public void apply(List changeSet, LinkedList rollback) - throws AccessorException { - - ApplyResult result = server.apply(accId, changeSet.toArray(new Event[changeSet.size()]), rollback!=null); - if (rollback!=null && result.rollbackLog!=null) - rollback.addAll( result.rollbackLog ); - if (result.error != null) throw new AccessorException( result.error ); - - } - - @Override - public Datatype type() { - return type; - } - - @Override - public void addListener(Listener listener, InterestSet interestSet, - ChildReference pathPrefix, Executor executor) throws AccessorException { - try { - ListenerEntry le = new ListenerEntry(listener, interestSet, pathPrefix, executor); - int lisId = server.addListener(accId, interestSet, pathPrefix); - synchronized(listenerMap) { - listenerMap.map(lisId, le); - } - } catch (WireException e) { - throw new AccessorException(e); - } - } - - @Override - public void removeListener(Listener listener) throws AccessorException { - Integer lisId = null; - synchronized(listenerMap) { - for (Entry e : listenerMap.getEntries()) { - if (e.getValue().listener == listener) { - lisId = e.getKey(); - break; - } - } - if (lisId==null) return; - listenerMap.removeWithLeft(lisId); - } - try { - server.removeListener(lisId); - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - public void close() throws AccessorException { - try { - server.closeAccessors( new Integer[] {accId} ); - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - } - - class WireBoolean extends WireAccessor implements BooleanAccessor { - - WireBoolean(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public BooleanType type() { - return (BooleanType) type; - } - - @Override - public boolean getValue() throws AccessorException { - try { - MutableVariant value = server.getValue(accId); - return (Boolean) value.getValue( Bindings.BOOLEAN ); - } catch (WireException e) { - throw new AccessorException( e ); - } catch (AdaptException e) { - throw new AccessorException( e ); - } - } - - @Override - public void setValue(boolean value) throws AccessorException { - Event e = new ValueAssigned(null, Bindings.BOOLEAN, value); - Event[] list = new Event[] {e}; - ApplyResult result = server.apply(accId, list, false); - if (result.error != null) throw new AccessorException( result.error ); - } - } - - class WireByte extends WireAccessor implements ByteAccessor { - - WireByte(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public ByteType type() { - return (ByteType) type; - } - - @Override - public byte getValue() throws AccessorException { - try { - MutableVariant value = server.getValue(accId); - return (Byte) value.getValue( Bindings.BYTE ); - } catch (WireException e) { - throw new AccessorException( e ); - } catch (AdaptException e) { - throw new AccessorException( e ); - } - } - - @Override - public void setValue(byte value) throws AccessorException { - Event e = new ValueAssigned(null, Bindings.BYTE, value); - Event[] list = new Event[] {e}; - ApplyResult result = server.apply(accId, list, false); - if (result.error != null) throw new AccessorException( result.error ); - } - } - - class WireInteger extends WireAccessor implements IntegerAccessor { - - WireInteger(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public IntegerType type() { - return (IntegerType) type; - } - - @Override - public int getValue() throws AccessorException { - try { - MutableVariant value = server.getValue(accId); - return (Integer) value.getValue( Bindings.INTEGER ); - } catch (WireException e) { - throw new AccessorException( e ); - } catch (AdaptException e) { - throw new AccessorException( e ); - } - } - - @Override - public void setValue(int value) throws AccessorException { - Event e = new ValueAssigned(Bindings.INTEGER, value); - Event[] list = new Event[] {e}; - ApplyResult result = server.apply(accId, list, false); - if (result.error != null) throw new AccessorException( result.error ); - } - - } - - class WireLong extends WireAccessor implements LongAccessor { - - WireLong(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public LongType type() { - return (LongType) type; - } - - @Override - public long getValue() throws AccessorException { - try { - MutableVariant value = server.getValue(accId); - return (Long) value.getValue( Bindings.LONG ); - } catch (WireException e) { - throw new AccessorException( e ); - } catch (AdaptException e) { - throw new AccessorException( e ); - } - } - - @Override - public void setValue(long value) throws AccessorException { - Event e = new ValueAssigned(Bindings.LONG, value); - Event[] list = new Event[] {e}; - ApplyResult result = server.apply(accId, list, false); - if (result.error != null) throw new AccessorException( result.error ); - } - - } - - class WireFloat extends WireAccessor implements FloatAccessor { - - WireFloat(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public FloatType type() { - return (FloatType) type; - } - - @Override - public float getValue() throws AccessorException { - try { - MutableVariant value = server.getValue(accId); - return (Float) value.getValue( Bindings.FLOAT ); - } catch (WireException e) { - throw new AccessorException( e ); - } catch (AdaptException e) { - throw new AccessorException( e ); - } - } - - @Override - public void setValue(float value) throws AccessorException { - Event e = new ValueAssigned(Bindings.FLOAT, value); - Event[] list = new Event[] {e}; - ApplyResult result = server.apply(accId, list, false); - if (result.error != null) throw new AccessorException( result.error ); - } - - } - - class WireDouble extends WireAccessor implements DoubleAccessor { - - WireDouble(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public DoubleType type() { - return (DoubleType) type; - } - - @Override - public double getValue() throws AccessorException { - try { - MutableVariant value = server.getValue(accId); - return (Double) value.getValue( Bindings.DOUBLE ); - } catch (WireException e) { - throw new AccessorException( e ); - } catch (AdaptException e) { - throw new AccessorException( e ); - } - } - - @Override - public void setValue(double value) throws AccessorException { - Event e = new ValueAssigned(Bindings.DOUBLE, value); - Event[] list = new Event[] {e}; - ApplyResult result = server.apply(accId, list, false); - if (result.error != null) throw new AccessorException( result.error ); - } - - } - - class WireArray extends WireAccessor implements ArrayAccessor { - - WireArray(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public ArrayType type() { - return (ArrayType) type; - } - - @Override - public void add(Binding binding, Object value) throws AccessorException { - try { - server.addAll(accId, -1, new MutableVariant(binding, value)); - } catch (WireException e) { - throw new AccessorException(e); - } - } - - @Override - public void addAll(Binding binding, Object[] values) throws AccessorException { - try { - ArrayBinding ab = new ObjectArrayBinding(new ArrayType(binding.type()), binding); - MutableVariant array = new MutableVariant(ab, values); - server.addAll(accId, -1, array); - } catch (WireException e) { - throw new AccessorException(e); - } - } - - @Override - public void addAll(int index, Binding binding, Object[] values) - throws AccessorException { - try { - ArrayBinding ab = new ObjectArrayBinding(new ArrayType(binding.type()), binding); - MutableVariant array = new MutableVariant(ab, values); - server.addAll(accId, index, array); - } catch (WireException e) { - throw new AccessorException(e); - } - } - - @Override - public void add(int index, Binding binding, Object value) throws AccessorException { - try { - server.addAll(accId, index, new MutableVariant(binding, value)); - } catch (WireException e) { - throw new AccessorException(e); - } - } - - @Override - public void set(int index, Binding binding, Object value) - throws AccessorException { - applyEvent(new ValueAssigned(new IndexReference(index), binding, value)); - } - - @Override - public void remove(int index, int count) throws AccessorException { - applyEvent(new ArrayElementRemoved(index)); - } - - @SuppressWarnings("unchecked") - @Override - public T getAccessor(int index) - throws AccessorConstructionException { - return (T) getComponent(new IndexReference(index)); - } - - @Override - public Object get(int index, Binding valueBinding) - throws AccessorException { - try { - MutableVariant v = server.getArrayElement(accId, index); - return v.getValue(valueBinding); - } catch (WireException e) { - throw new AccessorException(e); - } catch (AdaptException e) { - throw new AccessorException(e); - } - } - - @Override - public void get(int index, Binding valueBinding, Object dst) - throws AccessorException { - try { - MutableVariant v = server.getArrayElement(accId, index); - valueBinding.readFrom(v.getBinding(), v.getValue(), v); - } catch (WireException e) { - throw new AccessorException(e); - } catch (BindingException e) { - throw new AccessorException(e); - } - } - - @Override - public void getAll(Binding valueBinding, Object[] array) - throws AccessorException { - ObjectArrayBinding arrayBinding = new ObjectArrayBinding(type(), valueBinding); - Object[] a2 = (Object[]) getValue(arrayBinding); - System.arraycopy(a2, 0, array, 0, a2.length); - } - - @Override - public void getAll(Binding valueBinding, Collection values) - throws AccessorException { - ArrayListBinding arrayBinding = new ArrayListBinding(type(), valueBinding); - ArrayList a2 = (ArrayList) getValue(arrayBinding); - values.addAll(a2); - } - - @Override - public void setSize(int newSize) throws AccessorException { - throw new AccessorException("Not implemented"); - } - - @Override - public int size() throws AccessorException { - try { - return server.size(accId); - } catch (WireException e) { - throw new AccessorException( e ); - } - } - } - - class WireMap extends WireAccessor implements MapAccessor { - - WireMap(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public MapType type() { - return (MapType) type; - } - - @Override - public int size() throws AccessorException { - try { - return server.size(accId); - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - @Override - public Object get(Binding keyBinding, Object key, Binding valueBinding) - throws AccessorException { - try { - MutableVariant value = server.getMapValue(accId, new MutableVariant(keyBinding, key)); - if (value.type().equals(Datatypes.VOID)) return null; - return value.getValue(valueBinding); - } catch (WireException e) { - throw new AccessorException( e ); - } catch (AdaptException e) { - throw new AccessorException( e ); - } - } - - @Override - public boolean containsKey(Binding keyBinding, Object key) - throws AccessorException { - try { - return server.containsKey(accId, new MutableVariant(keyBinding, key)); - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - @Override - public boolean containsValue(Binding valueBinding, Object value) - throws AccessorException { - try { - return server.containsValue(accId, new MutableVariant(valueBinding, value)); - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - @Override - public void put(Binding keyBinding, Object key, Binding valueBinding, - Object value) throws AccessorException { - applyEvent( new MapEntryAdded(new MutableVariant(keyBinding, key), new MutableVariant(valueBinding, value)) ); - } - - @Override - public void remove(Binding keyBinding, Object key) - throws AccessorException { - applyEvent( new MapEntryRemoved(new MutableVariant(keyBinding, key)) ); - } - - @Override - public void clear() throws AccessorException { - try { - server.clear(accId); - } catch (WireException e) { - throw new AccessorException(e); - } - } - - @Override - public void putAll(Binding keyBinding, Binding valueBinding, - Map from) throws AccessorException { - - int count = from.size(); - Event events[] = new Event[ count ]; - int i = 0; - for (Entry e : from.entrySet()) { - MutableVariant key = new MutableVariant( keyBinding, e.getKey() ); - MutableVariant value = new MutableVariant( valueBinding, e.getValue() ); - events[i] = new MapEntryAdded( key, value ); - ++i; - } - applyEvent( events ); - } - - @Override - public void putAll(Binding keyBinding, Binding valueBinding, - Object[] keys, Object[] values) throws AccessorException { - if (keys.length != values.length) throw new AccessorException("bad args"); - int count = keys.length; - Event events[] = new Event[ count ]; - for (int i=0; i to) throws AccessorException { - MapBinding binding = new TreeMapBinding(keyBinding, valueBinding); - TreeMap v = (TreeMap) getValue(binding); - to.putAll(v); - } - - @SuppressWarnings("unchecked") - @Override - public void getAll(Binding keyBinding, Binding valueBinding, - Object[] keys, Object[] values) throws AccessorException { - MapBinding binding = new TreeMapBinding(keyBinding, valueBinding); - TreeMap v = (TreeMap) getValue(binding); - int i=0; - for (Entry e : v.entrySet()) { - keys[i] = e.getKey(); - values[i] = e.getValue(); - ++i; - } - } - - @Override - public Object[] getKeys(Binding keyBinding) throws AccessorException { - try { - MutableVariant array = server.getMapKeys(accId); - ArrayBinding binding = new ObjectArrayBinding( keyBinding ); - return (Object[]) array.getValue(binding); - } catch (WireException e) { - throw new AccessorException( e ); - } catch (AdaptException e) { - throw new AccessorException( e ); - } - } - - @Override - public int count(Binding keyBinding, Object from, - boolean fromInclusive, Object end, boolean endInclusive) - throws AccessorException { - throw new AccessorException("Not implemented"); - } - - @Override - public int getEntries(Binding keyBinding, Object from, - boolean fromInclusive, Object end, boolean endInclusive, - ArrayBinding keyArrayBinding, Object dstKeys, - ArrayBinding valueArrayBinding, Object dstValues, int limit) - throws AccessorException { - throw new AccessorException("Not implemented"); - } - - - @Override - public Object[] getValues(Binding valueBinding) - throws AccessorException { - try { - MutableVariant array = server.getMapValues(accId); - ArrayBinding binding = new ObjectArrayBinding( valueBinding ); - return (Object[]) array.getValue(binding); - } catch (WireException e) { - throw new AccessorException( e ); - } catch (AdaptException e) { - throw new AccessorException( e ); - } - } - - @SuppressWarnings("unchecked") - @Override - public T getValueAccessor(Binding keyBinding, Object key) throws AccessorConstructionException { - return (T) getComponent( new KeyReference(keyBinding, key) ); - } - - @Override - public Object getFirstKey(Binding keyBinding) throws AccessorException { - try { - MutableVariant result = server.getFirstKey(accId); - if (result.type().equals(Datatypes.VOID)) return null; - return result.getValue(keyBinding); - } catch (WireException e) { - throw new AccessorException(e); - } catch (AdaptException e) { - throw new AccessorException(e); - } - } - - @Override - public Object getLastKey(Binding keyBinding) throws AccessorException { - try { - MutableVariant result = server.getLastKey(accId); - if (result.type().equals(Datatypes.VOID)) return null; - return result.getValue(keyBinding); - } catch (WireException e) { - throw new AccessorException(e); - } catch (AdaptException e) { - throw new AccessorException(e); - } - } - - @Override - public Object getLowerKey(Binding keyBinding, Object key) - throws AccessorException { - try { - MutableVariant result = server.getLowerKey(accId, new MutableVariant(keyBinding, key)); - if (result.type().equals(Datatypes.VOID)) return null; - return result.getValue(keyBinding); - } catch (WireException e) { - throw new AccessorException(e); - } catch (AdaptException e) { - throw new AccessorException(e); - } - } - - @Override - public Object getFloorKey(Binding keyBinding, Object key) - throws AccessorException { - try { - MutableVariant result = server.getFloorKey(accId, new MutableVariant(keyBinding, key)); - if (result.type() == Datatypes.VOID) return null; - return result.getValue(keyBinding); - } catch (WireException e) { - throw new AccessorException(e); - } catch (AdaptException e) { - throw new AccessorException(e); - } - } - - @Override - public Object getCeilingKey(Binding keyBinding, Object key) - throws AccessorException { - try { - MutableVariant result = server.getCeilingKey(accId, new MutableVariant(keyBinding, key)); - if (result.type().equals(Datatypes.VOID)) return null; - return result.getValue(keyBinding); - } catch (WireException e) { - throw new AccessorException(e); - } catch (AdaptException e) { - throw new AccessorException(e); - } - } - - @Override - public Object getHigherKey(Binding keyBinding, Object key) - throws AccessorException { - try { - MutableVariant result = server.getHigherKey(accId, new MutableVariant(keyBinding, key)); - if (result.type().equals(Datatypes.VOID)) return null; - return result.getValue(keyBinding); - } catch (WireException e) { - throw new AccessorException(e); - } catch (AdaptException e) { - throw new AccessorException(e); - } - } - - } - - class WireOptional extends WireAccessor implements OptionalAccessor { - - WireOptional(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public OptionalType type() { - return (OptionalType) type; - } - - @Override - public void setNoValue() throws AccessorException { - applyEvent( new OptionalValueRemoved() ); - } - - @Override - public boolean hasValue() throws AccessorException { - try { - return server.hasValue(accId); - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - @Override - public Object getComponentValue(Binding componentBinding) - throws AccessorException { - try { - WireAccessor sa = createAccessor( new ComponentReference() ); - try { - return sa.getValue(componentBinding); - } finally { - sa.close(); - } - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - @Override - public void setComponentValue(Binding binding, Object value) - throws AccessorException { - applyEvent(new OptionalValueAssigned(binding, value)); - } - - @SuppressWarnings("unchecked") - @Override - public T getComponentAccessor() - throws AccessorConstructionException { - return (T) getComponent( new ComponentReference() ); - } - - } - - class WireRecord extends WireAccessor implements RecordAccessor { - - WireRecord(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public RecordType type() { - return (RecordType) type; - } - - @Override - public int count() throws AccessorException { - try { - return server.size(accId); - } catch (WireException e) { - throw new AccessorException(e); - } - } - - @SuppressWarnings("unchecked") - @Override - public T getFieldAccessor(int index) - throws AccessorConstructionException { - return (T) getComponent( new IndexReference(index) ); - } - - @SuppressWarnings("unchecked") - @Override - public T getFieldAccessor(String fieldName) - throws AccessorConstructionException { - return (T) getComponent( new NameReference( fieldName ) ); - } - - @Override - public Object getFieldValue(String fieldName, Binding fieldBinding) - throws AccessorException { - int fieldIndex = type().getComponentIndex(fieldName); - if (fieldIndex<0) throw new AccessorException("Field "+fieldName+" does not exist"); - return getFieldValue(fieldIndex, fieldBinding); - } - - @Override - public Object getFieldValue(int index, Binding fieldBinding) - throws AccessorException { - try { - WireAccessor sa = createAccessor( new IndexReference(index) ); - try { - return sa.getValue(fieldBinding); - } finally { - sa.close(); - } - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - public void setFieldValue(String fieldName, Binding fieldBinding, Object value) throws AccessorException { - int fieldIndex = type().getComponentIndex(fieldName); - if (fieldIndex<0) throw new AccessorException("Field "+fieldName+" does not exist"); - setFieldValue(fieldIndex, fieldBinding, value); - }; - - @Override - public void setFieldValue(int index, Binding fieldBinding, Object value) - throws AccessorException { - try { - WireAccessor sa = createAccessor( new IndexReference(index) ); - try { - sa.setValue(fieldBinding, value); - } finally { - sa.close(); - } - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - } - - class WireString extends WireAccessor implements StringAccessor { - - WireString(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public StringType type() { - return (StringType) type; - } - - @Override - public String getValue() throws AccessorException { - try { - MutableVariant value = server.getValue(accId); - return (String) value.getValue( Bindings.STRING ); - } catch (WireException e) { - throw new AccessorException( e ); - } catch (AdaptException e) { - throw new AccessorException( e ); - } - } - - @Override - public void setValue(String newValue) throws AccessorException { - Event e = new ValueAssigned( Bindings.STRING, newValue); - Event[] list = new Event[] {e}; - ApplyResult result = server.apply(accId, list, false); - if (result.error != null) throw new AccessorException( result.error ); - } - - } - - class WireUnion extends WireAccessor implements UnionAccessor { - - WireUnion(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public UnionType type() { - return (UnionType) type; - } - - @Override - public int count() throws AccessorException { - try { - return server.size(accId); - } catch (WireException e) { - throw new AccessorException(e); - } - } - - @Override - public int getTag() throws AccessorException { - try { - return server.getTag(accId); - } catch (WireException e) { - throw new AccessorException(e); - } - } - - @SuppressWarnings("unchecked") - @Override - public T getComponentAccessor() - throws AccessorConstructionException { - return (T) getComponent(new ComponentReference()); - } - - @Override - public Object getComponentValue(Binding componentBinding) - throws AccessorException { - try { - WireAccessor sa = createAccessor( new ComponentReference() ); - try { - return sa.getValue(componentBinding); - } finally { - sa.close(); - } - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - @Override - public void setComponentValue(int tag, Binding componentBinding, - Object componentValue) throws AccessorException { - try { - WireAccessor sa = createAccessor( new ComponentReference() ); - try { - sa.setValue(componentBinding, componentValue); - } finally { - sa.close(); - } - } catch (WireException e) { - throw new AccessorException( e ); - } - - } - - } - - class WireVariant extends WireAccessor implements VariantAccessor { - - WireVariant(int accId, Datatype type, ChildReference ref) { - super(accId, type, ref); - } - - @Override - public VariantType type() { - return (VariantType) type; - } - - @SuppressWarnings("unchecked") - @Override - public T getContentAccessor() - throws AccessorConstructionException { - return (T) getComponent(new ComponentReference()); - } - - @Override - public void setContentValue(Binding valueBinding, Object value) - throws AccessorException { - try { - WireAccessor sa = createAccessor( new ComponentReference() ); - try { - sa.setValue(valueBinding, value); - } finally { - sa.close(); - } - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - @Override - public Object getContentValue(Binding contentBinding) - throws AccessorException { - try { - WireAccessor sa = createAccessor( new ComponentReference() ); - try { - return sa.getValue(contentBinding); - } finally { - sa.close(); - } - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - @Override - public Datatype getContentType() throws AccessorException { - try { - WireAccessor sa = createAccessor( new ComponentReference() ); - try { - return sa.type(); - } finally { - sa.close(); - } - } catch (WireException e) { - throw new AccessorException( e ); - } - } - - } - - -} - +/******************************************************************************* + * 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.wire; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executor; + +import org.simantics.databoard.Bindings; +import org.simantics.databoard.Datatypes; +import org.simantics.databoard.Methods; +import org.simantics.databoard.accessor.Accessor; +import org.simantics.databoard.accessor.ArrayAccessor; +import org.simantics.databoard.accessor.BooleanAccessor; +import org.simantics.databoard.accessor.ByteAccessor; +import org.simantics.databoard.accessor.CloseableAccessor; +import org.simantics.databoard.accessor.DoubleAccessor; +import org.simantics.databoard.accessor.FloatAccessor; +import org.simantics.databoard.accessor.IntegerAccessor; +import org.simantics.databoard.accessor.LongAccessor; +import org.simantics.databoard.accessor.MapAccessor; +import org.simantics.databoard.accessor.OptionalAccessor; +import org.simantics.databoard.accessor.RecordAccessor; +import org.simantics.databoard.accessor.StringAccessor; +import org.simantics.databoard.accessor.UnionAccessor; +import org.simantics.databoard.accessor.VariantAccessor; +import org.simantics.databoard.accessor.error.AccessorConstructionException; +import org.simantics.databoard.accessor.error.AccessorException; +import org.simantics.databoard.accessor.error.ReferenceException; +import org.simantics.databoard.accessor.event.ArrayElementRemoved; +import org.simantics.databoard.accessor.event.Event; +import org.simantics.databoard.accessor.event.MapEntryAdded; +import org.simantics.databoard.accessor.event.MapEntryRemoved; +import org.simantics.databoard.accessor.event.OptionalValueAssigned; +import org.simantics.databoard.accessor.event.OptionalValueRemoved; +import org.simantics.databoard.accessor.event.ValueAssigned; +import org.simantics.databoard.accessor.impl.ListenerEntry; +import org.simantics.databoard.accessor.interestset.InterestSet; +import org.simantics.databoard.accessor.reference.ChildReference; +import org.simantics.databoard.accessor.reference.ComponentReference; +import org.simantics.databoard.accessor.reference.IndexReference; +import org.simantics.databoard.accessor.reference.KeyReference; +import org.simantics.databoard.accessor.reference.NameReference; +import org.simantics.databoard.accessor.wire.IWireServer.AccessorInfo; +import org.simantics.databoard.accessor.wire.IWireServer.ApplyResult; +import org.simantics.databoard.adapter.AdaptException; +import org.simantics.databoard.binding.ArrayBinding; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.MapBinding; +import org.simantics.databoard.binding.error.BindingConstructionException; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.binding.impl.ArrayListBinding; +import org.simantics.databoard.binding.impl.ObjectArrayBinding; +import org.simantics.databoard.binding.impl.TreeMapBinding; +import org.simantics.databoard.binding.mutable.MutableVariant; +import org.simantics.databoard.method.MethodInterface; +import org.simantics.databoard.type.ArrayType; +import org.simantics.databoard.type.BooleanType; +import org.simantics.databoard.type.ByteType; +import org.simantics.databoard.type.Datatype; +import org.simantics.databoard.type.DoubleType; +import org.simantics.databoard.type.FloatType; +import org.simantics.databoard.type.IntegerType; +import org.simantics.databoard.type.LongType; +import org.simantics.databoard.type.MapType; +import org.simantics.databoard.type.OptionalType; +import org.simantics.databoard.type.RecordType; +import org.simantics.databoard.type.StringType; +import org.simantics.databoard.type.UnionType; +import org.simantics.databoard.type.VariantType; +import org.simantics.databoard.util.BijectionMap; + +/** + * WireAccessor provides an accessor over TCP/IP connection. + * + * All method invocation is blocking. WireAccessor may be accessed from + * simultanous threads. + * + * + * @author Toni Kalajainen + */ +public class WireClient implements IWireClient { + + /** A queue of released accessors */ + ReferenceQueue releaseQueue = new ReferenceQueue(); + Map subAccessorMap = new HashMap(); + +// Map accessorMap = new HashMap(); + BijectionMap listenerMap = new BijectionMap(); + + MethodInterface serverMi; + MethodInterface clientMi; + IWireServer server; + WireAccessor root; + + public WireClient() { + try { + this.clientMi = Methods.bindInterface(IWireClient.class, this); + } catch (BindingConstructionException e) { + throw new RuntimeException(e); + } + } + + public void setServerMethodInterface(MethodInterface serverMi) { + try { + this.serverMi = serverMi; + this.server = Methods.createProxy(IWireServer.class, serverMi); + } catch (BindingConstructionException e) { + throw new RuntimeException(e); + } + } + + public MethodInterface getServerMethodInterface() { + return serverMi; + } + + public MethodInterface getClientMethodInterface() { + return clientMi; + } + + public void close() { + try { + closeReleasedAccessors(); + } catch (WireException e) { + e.printStackTrace(); + } + + } + + /** + * Create an accessor. Does not dispose or add to cache, use getAccessor instead + * @param ref + * @return + * @throws WireException + */ + WireAccessor createAccessor(ChildReference ref) throws WireException { + AccessorInfo ai = server.openAccessor(ref); + if (ai.type instanceof BooleanType) { + return new WireBoolean(ai.accessorId, ai.type, ref); + } else + if (ai.type instanceof ByteType) { + return new WireByte(ai.accessorId, ai.type, ref); + } else + if (ai.type instanceof IntegerType) { + return new WireInteger(ai.accessorId, ai.type, ref); + } else + if (ai.type instanceof LongType) { + return new WireLong(ai.accessorId, ai.type, ref); + } else + if (ai.type instanceof FloatType) { + return new WireFloat(ai.accessorId, ai.type, ref); + } else + if (ai.type instanceof DoubleType) { + return new WireDouble(ai.accessorId, ai.type, ref); + } else + if (ai.type instanceof StringType) { + return new WireByte(ai.accessorId, ai.type, ref); + } else + if (ai.type instanceof MapType) { + return new WireMap(ai.accessorId, ai.type, ref); + } else + if (ai.type instanceof OptionalType) { + return new WireOptional(ai.accessorId, ai.type, ref); + } else + if (ai.type instanceof RecordType) { + return new WireRecord(ai.accessorId, ai.type, ref); + } else + if (ai.type instanceof UnionType) { + return new WireUnion(ai.accessorId, ai.type, ref); + } else + if (ai.type instanceof VariantType) { + return new WireVariant(ai.accessorId, ai.type, ref); + } + throw new WireException("error, unknown data type "+ai.type); + } + + /** + * Create or get wire accessor + * @param ref path from root + * @return wire accessor + * @throws WireException + */ + public WireAccessor getAccessor(ChildReference ref) throws WireException { + synchronized(subAccessorMap) { + // Rseult Check cache + closeReleasedAccessors(); + WireAccessorReference war = subAccessorMap.get(ref); + WireAccessor result = war == null ? null : war.get(); + if (result != null) return result; + + result = createAccessor(ref); + war = new WireAccessorReference(result); + subAccessorMap.put(ref, war); + + return result; + } + } + + /** + * Close garbage collected accessors + * @throws WireException + */ + void closeReleasedAccessors() throws WireException { + if (releaseQueue.poll()==null) return; + ArrayList ids = new ArrayList(); + while (releaseQueue.poll() != null) { + try { + WireAccessorReference ref = (WireAccessorReference) releaseQueue.remove(); + ids.add( ref.accId ); + } catch (InterruptedException e) { + } + } + // Close accessors + server.closeAccessors( ids.toArray(new Integer[ids.size()]) ); + } + + @Override + public int onEvents(int lisId, Event[] events) { + ListenerEntry listener = null; + synchronized(listenerMap) { + listener = listenerMap.getRight(lisId); + } + if (listener==null) return 0; + + List list = new CopyOnWriteArrayList(events); + listener.emitEvents(list); + + return 0; + } + + class WireAccessorReference extends WeakReference { + + int accId; + + public WireAccessorReference(WireAccessor referent) { + super(referent, releaseQueue); + this.accId = referent.accId; + } + + } + + abstract class WireAccessor implements Accessor, CloseableAccessor { + int accId; + ChildReference ref; + Datatype type; + + WireAccessor(int accId, Datatype type, ChildReference ref) { + this.accId = accId; + this.type = type; + this.ref = ref; + } + + @Override + public Object getValue(Binding binding) throws AccessorException { + try { + MutableVariant value = server.getValue(accId); + return value.getValue(binding); + } catch (WireException e) { + throw new AccessorException(e); + } catch (AdaptException e) { + throw new AccessorException(e); + } + } + + @Override + public void getValue(Binding binding, Object obj) + throws AccessorException { + try { + MutableVariant value= server.getValue(accId); + binding.readFrom(value.getBinding(), value.getValue(), obj); + } catch ( WireException e ) { + throw new AccessorException(e); + } catch ( BindingException e ) { + throw new AccessorException(e); + } + } + + @Override + public boolean getValue(ChildReference path, Binding binding, Object obj) throws AccessorException { + try { + Accessor a = getComponent(path); + a.getValue(binding, obj); + return true; + } catch (ReferenceException re) { + return false; + } catch (AccessorConstructionException e) { + throw new AccessorException(e); + } + } + + public Object getValue(ChildReference path, Binding binding) throws AccessorException { + try { + Accessor a = getComponent(path); + return a.getValue(binding); + } catch (ReferenceException re) { + return null; + } catch (AccessorConstructionException e) { + throw new AccessorException(e); + } + } + + + void applyEvent(Event...events) throws AccessorException { + ApplyResult result = server.apply(accId, events, false); + if (result.error != null) throw new AccessorException( result.error ); + } + + @Override + public void setValue(Binding binding, Object newValue) throws AccessorException { + applyEvent( new ValueAssigned(binding, newValue) ); + } + + public boolean setValue(ChildReference path, Binding binding, Object obj) throws AccessorException { + try { + Accessor a = getComponent(path); + a.setValue(binding, obj); + return true; + } catch (ReferenceException re) { + return false; + } catch (AccessorConstructionException e) { + throw new AccessorException(e); + } + } + + @SuppressWarnings("unchecked") + @Override + public T getComponent(ChildReference reference) + throws AccessorConstructionException { + try { + // Create a reference from the root + ChildReference r = ChildReference.concatenate(ref, reference); + return (T) WireClient.this.getAccessor( r ); + } catch (WireException e) { + throw new AccessorConstructionException( e ); + } + } + + @Override + public void apply(List changeSet, LinkedList rollback) + throws AccessorException { + + ApplyResult result = server.apply(accId, changeSet.toArray(new Event[changeSet.size()]), rollback!=null); + if (rollback!=null && result.rollbackLog!=null) + rollback.addAll( result.rollbackLog ); + if (result.error != null) throw new AccessorException( result.error ); + + } + + @Override + public Datatype type() { + return type; + } + + @Override + public void addListener(Listener listener, InterestSet interestSet, + ChildReference pathPrefix, Executor executor) throws AccessorException { + try { + ListenerEntry le = new ListenerEntry(listener, interestSet, pathPrefix, executor); + int lisId = server.addListener(accId, interestSet, pathPrefix); + synchronized(listenerMap) { + listenerMap.map(lisId, le); + } + } catch (WireException e) { + throw new AccessorException(e); + } + } + + @Override + public void removeListener(Listener listener) throws AccessorException { + Integer lisId = null; + synchronized(listenerMap) { + for (Entry e : listenerMap.getEntries()) { + if (e.getValue().listener == listener) { + lisId = e.getKey(); + break; + } + } + if (lisId==null) return; + listenerMap.removeWithLeft(lisId); + } + try { + server.removeListener(lisId); + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + public void close() throws AccessorException { + try { + server.closeAccessors( new Integer[] {accId} ); + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + } + + class WireBoolean extends WireAccessor implements BooleanAccessor { + + WireBoolean(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public BooleanType type() { + return (BooleanType) type; + } + + @Override + public boolean getValue() throws AccessorException { + try { + MutableVariant value = server.getValue(accId); + return (Boolean) value.getValue( Bindings.BOOLEAN ); + } catch (WireException e) { + throw new AccessorException( e ); + } catch (AdaptException e) { + throw new AccessorException( e ); + } + } + + @Override + public void setValue(boolean value) throws AccessorException { + Event e = new ValueAssigned(null, Bindings.BOOLEAN, value); + Event[] list = new Event[] {e}; + ApplyResult result = server.apply(accId, list, false); + if (result.error != null) throw new AccessorException( result.error ); + } + } + + class WireByte extends WireAccessor implements ByteAccessor { + + WireByte(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public ByteType type() { + return (ByteType) type; + } + + @Override + public byte getValue() throws AccessorException { + try { + MutableVariant value = server.getValue(accId); + return (Byte) value.getValue( Bindings.BYTE ); + } catch (WireException e) { + throw new AccessorException( e ); + } catch (AdaptException e) { + throw new AccessorException( e ); + } + } + + @Override + public void setValue(byte value) throws AccessorException { + Event e = new ValueAssigned(null, Bindings.BYTE, value); + Event[] list = new Event[] {e}; + ApplyResult result = server.apply(accId, list, false); + if (result.error != null) throw new AccessorException( result.error ); + } + } + + class WireInteger extends WireAccessor implements IntegerAccessor { + + WireInteger(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public IntegerType type() { + return (IntegerType) type; + } + + @Override + public int getValue() throws AccessorException { + try { + MutableVariant value = server.getValue(accId); + return (Integer) value.getValue( Bindings.INTEGER ); + } catch (WireException e) { + throw new AccessorException( e ); + } catch (AdaptException e) { + throw new AccessorException( e ); + } + } + + @Override + public void setValue(int value) throws AccessorException { + Event e = new ValueAssigned(Bindings.INTEGER, value); + Event[] list = new Event[] {e}; + ApplyResult result = server.apply(accId, list, false); + if (result.error != null) throw new AccessorException( result.error ); + } + + } + + class WireLong extends WireAccessor implements LongAccessor { + + WireLong(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public LongType type() { + return (LongType) type; + } + + @Override + public long getValue() throws AccessorException { + try { + MutableVariant value = server.getValue(accId); + return (Long) value.getValue( Bindings.LONG ); + } catch (WireException e) { + throw new AccessorException( e ); + } catch (AdaptException e) { + throw new AccessorException( e ); + } + } + + @Override + public void setValue(long value) throws AccessorException { + Event e = new ValueAssigned(Bindings.LONG, value); + Event[] list = new Event[] {e}; + ApplyResult result = server.apply(accId, list, false); + if (result.error != null) throw new AccessorException( result.error ); + } + + } + + class WireFloat extends WireAccessor implements FloatAccessor { + + WireFloat(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public FloatType type() { + return (FloatType) type; + } + + @Override + public float getValue() throws AccessorException { + try { + MutableVariant value = server.getValue(accId); + return (Float) value.getValue( Bindings.FLOAT ); + } catch (WireException e) { + throw new AccessorException( e ); + } catch (AdaptException e) { + throw new AccessorException( e ); + } + } + + @Override + public void setValue(float value) throws AccessorException { + Event e = new ValueAssigned(Bindings.FLOAT, value); + Event[] list = new Event[] {e}; + ApplyResult result = server.apply(accId, list, false); + if (result.error != null) throw new AccessorException( result.error ); + } + + } + + class WireDouble extends WireAccessor implements DoubleAccessor { + + WireDouble(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public DoubleType type() { + return (DoubleType) type; + } + + @Override + public double getValue() throws AccessorException { + try { + MutableVariant value = server.getValue(accId); + return (Double) value.getValue( Bindings.DOUBLE ); + } catch (WireException e) { + throw new AccessorException( e ); + } catch (AdaptException e) { + throw new AccessorException( e ); + } + } + + @Override + public void setValue(double value) throws AccessorException { + Event e = new ValueAssigned(Bindings.DOUBLE, value); + Event[] list = new Event[] {e}; + ApplyResult result = server.apply(accId, list, false); + if (result.error != null) throw new AccessorException( result.error ); + } + + } + + class WireArray extends WireAccessor implements ArrayAccessor { + + WireArray(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public ArrayType type() { + return (ArrayType) type; + } + + @Override + public void add(Binding binding, Object value) throws AccessorException { + try { + server.addAll(accId, -1, new MutableVariant(binding, value)); + } catch (WireException e) { + throw new AccessorException(e); + } + } + + @Override + public void addAll(Binding binding, Object[] values) throws AccessorException { + try { + ArrayBinding ab = new ObjectArrayBinding(new ArrayType(binding.type()), binding); + MutableVariant array = new MutableVariant(ab, values); + server.addAll(accId, -1, array); + } catch (WireException e) { + throw new AccessorException(e); + } + } + + @Override + public void addAll(int index, Binding binding, Object[] values) + throws AccessorException { + try { + ArrayBinding ab = new ObjectArrayBinding(new ArrayType(binding.type()), binding); + MutableVariant array = new MutableVariant(ab, values); + server.addAll(accId, index, array); + } catch (WireException e) { + throw new AccessorException(e); + } + } + + @Override + public void add(int index, Binding binding, Object value) throws AccessorException { + try { + server.addAll(accId, index, new MutableVariant(binding, value)); + } catch (WireException e) { + throw new AccessorException(e); + } + } + + @Override + public void set(int index, Binding binding, Object value) + throws AccessorException { + applyEvent(new ValueAssigned(new IndexReference(index), binding, value)); + } + + @Override + public void remove(int index, int count) throws AccessorException { + applyEvent(new ArrayElementRemoved(index)); + } + + @SuppressWarnings("unchecked") + @Override + public T getAccessor(int index) + throws AccessorConstructionException { + return (T) getComponent(new IndexReference(index)); + } + + @Override + public Object get(int index, Binding valueBinding) + throws AccessorException { + try { + MutableVariant v = server.getArrayElement(accId, index); + return v.getValue(valueBinding); + } catch (WireException e) { + throw new AccessorException(e); + } catch (AdaptException e) { + throw new AccessorException(e); + } + } + + @Override + public void get(int index, Binding valueBinding, Object dst) + throws AccessorException { + try { + MutableVariant v = server.getArrayElement(accId, index); + valueBinding.readFrom(v.getBinding(), v.getValue(), v); + } catch (WireException e) { + throw new AccessorException(e); + } catch (BindingException e) { + throw new AccessorException(e); + } + } + + @Override + public void getAll(Binding valueBinding, Object[] array) + throws AccessorException { + ObjectArrayBinding arrayBinding = new ObjectArrayBinding(type(), valueBinding); + Object[] a2 = (Object[]) getValue(arrayBinding); + System.arraycopy(a2, 0, array, 0, a2.length); + } + + @Override + public void getAll(Binding valueBinding, Collection values) + throws AccessorException { + ArrayListBinding arrayBinding = new ArrayListBinding(type(), valueBinding); + ArrayList a2 = (ArrayList) getValue(arrayBinding); + values.addAll(a2); + } + + @Override + public void setSize(int newSize) throws AccessorException { + throw new AccessorException("Not implemented"); + } + + @Override + public int size() throws AccessorException { + try { + return server.size(accId); + } catch (WireException e) { + throw new AccessorException( e ); + } + } + } + + class WireMap extends WireAccessor implements MapAccessor { + + WireMap(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public MapType type() { + return (MapType) type; + } + + @Override + public int size() throws AccessorException { + try { + return server.size(accId); + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + @Override + public Object get(Binding keyBinding, Object key, Binding valueBinding) + throws AccessorException { + try { + MutableVariant value = server.getMapValue(accId, new MutableVariant(keyBinding, key)); + if (value.type().equals(Datatypes.VOID)) return null; + return value.getValue(valueBinding); + } catch (WireException e) { + throw new AccessorException( e ); + } catch (AdaptException e) { + throw new AccessorException( e ); + } + } + + @Override + public boolean containsKey(Binding keyBinding, Object key) + throws AccessorException { + try { + return server.containsKey(accId, new MutableVariant(keyBinding, key)); + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + @Override + public boolean containsValue(Binding valueBinding, Object value) + throws AccessorException { + try { + return server.containsValue(accId, new MutableVariant(valueBinding, value)); + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + @Override + public void put(Binding keyBinding, Object key, Binding valueBinding, + Object value) throws AccessorException { + applyEvent( new MapEntryAdded(new MutableVariant(keyBinding, key), new MutableVariant(valueBinding, value)) ); + } + + @Override + public void remove(Binding keyBinding, Object key) + throws AccessorException { + applyEvent( new MapEntryRemoved(new MutableVariant(keyBinding, key)) ); + } + + @Override + public void clear() throws AccessorException { + try { + server.clear(accId); + } catch (WireException e) { + throw new AccessorException(e); + } + } + + @Override + public void putAll(Binding keyBinding, Binding valueBinding, + Map from) throws AccessorException { + + int count = from.size(); + Event events[] = new Event[ count ]; + int i = 0; + for (Entry e : from.entrySet()) { + MutableVariant key = new MutableVariant( keyBinding, e.getKey() ); + MutableVariant value = new MutableVariant( valueBinding, e.getValue() ); + events[i] = new MapEntryAdded( key, value ); + ++i; + } + applyEvent( events ); + } + + @Override + public void putAll(Binding keyBinding, Binding valueBinding, + Object[] keys, Object[] values) throws AccessorException { + if (keys.length != values.length) throw new AccessorException("bad args"); + int count = keys.length; + Event events[] = new Event[ count ]; + for (int i=0; i to) throws AccessorException { + MapBinding binding = new TreeMapBinding(keyBinding, valueBinding); + TreeMap v = (TreeMap) getValue(binding); + to.putAll(v); + } + + @SuppressWarnings("unchecked") + @Override + public void getAll(Binding keyBinding, Binding valueBinding, + Object[] keys, Object[] values) throws AccessorException { + MapBinding binding = new TreeMapBinding(keyBinding, valueBinding); + TreeMap v = (TreeMap) getValue(binding); + int i=0; + for (Entry e : v.entrySet()) { + keys[i] = e.getKey(); + values[i] = e.getValue(); + ++i; + } + } + + @Override + public Object[] getKeys(Binding keyBinding) throws AccessorException { + try { + MutableVariant array = server.getMapKeys(accId); + ArrayBinding binding = new ObjectArrayBinding( keyBinding ); + return (Object[]) array.getValue(binding); + } catch (WireException e) { + throw new AccessorException( e ); + } catch (AdaptException e) { + throw new AccessorException( e ); + } + } + + @Override + public int count(Binding keyBinding, Object from, + boolean fromInclusive, Object end, boolean endInclusive) + throws AccessorException { + throw new AccessorException("Not implemented"); + } + + @Override + public int getEntries(Binding keyBinding, Object from, + boolean fromInclusive, Object end, boolean endInclusive, + ArrayBinding keyArrayBinding, Object dstKeys, + ArrayBinding valueArrayBinding, Object dstValues, int limit) + throws AccessorException { + throw new AccessorException("Not implemented"); + } + + + @Override + public Object[] getValues(Binding valueBinding) + throws AccessorException { + try { + MutableVariant array = server.getMapValues(accId); + ArrayBinding binding = new ObjectArrayBinding( valueBinding ); + return (Object[]) array.getValue(binding); + } catch (WireException e) { + throw new AccessorException( e ); + } catch (AdaptException e) { + throw new AccessorException( e ); + } + } + + @SuppressWarnings("unchecked") + @Override + public T getValueAccessor(Binding keyBinding, Object key) throws AccessorConstructionException { + return (T) getComponent( new KeyReference(keyBinding, key) ); + } + + @Override + public Object getFirstKey(Binding keyBinding) throws AccessorException { + try { + MutableVariant result = server.getFirstKey(accId); + if (result.type().equals(Datatypes.VOID)) return null; + return result.getValue(keyBinding); + } catch (WireException e) { + throw new AccessorException(e); + } catch (AdaptException e) { + throw new AccessorException(e); + } + } + + @Override + public Object getLastKey(Binding keyBinding) throws AccessorException { + try { + MutableVariant result = server.getLastKey(accId); + if (result.type().equals(Datatypes.VOID)) return null; + return result.getValue(keyBinding); + } catch (WireException e) { + throw new AccessorException(e); + } catch (AdaptException e) { + throw new AccessorException(e); + } + } + + @Override + public Object getLowerKey(Binding keyBinding, Object key) + throws AccessorException { + try { + MutableVariant result = server.getLowerKey(accId, new MutableVariant(keyBinding, key)); + if (result.type().equals(Datatypes.VOID)) return null; + return result.getValue(keyBinding); + } catch (WireException e) { + throw new AccessorException(e); + } catch (AdaptException e) { + throw new AccessorException(e); + } + } + + @Override + public Object getFloorKey(Binding keyBinding, Object key) + throws AccessorException { + try { + MutableVariant result = server.getFloorKey(accId, new MutableVariant(keyBinding, key)); + if (result.type() == Datatypes.VOID) return null; + return result.getValue(keyBinding); + } catch (WireException e) { + throw new AccessorException(e); + } catch (AdaptException e) { + throw new AccessorException(e); + } + } + + @Override + public Object getCeilingKey(Binding keyBinding, Object key) + throws AccessorException { + try { + MutableVariant result = server.getCeilingKey(accId, new MutableVariant(keyBinding, key)); + if (result.type().equals(Datatypes.VOID)) return null; + return result.getValue(keyBinding); + } catch (WireException e) { + throw new AccessorException(e); + } catch (AdaptException e) { + throw new AccessorException(e); + } + } + + @Override + public Object getHigherKey(Binding keyBinding, Object key) + throws AccessorException { + try { + MutableVariant result = server.getHigherKey(accId, new MutableVariant(keyBinding, key)); + if (result.type().equals(Datatypes.VOID)) return null; + return result.getValue(keyBinding); + } catch (WireException e) { + throw new AccessorException(e); + } catch (AdaptException e) { + throw new AccessorException(e); + } + } + + } + + class WireOptional extends WireAccessor implements OptionalAccessor { + + WireOptional(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public OptionalType type() { + return (OptionalType) type; + } + + @Override + public void setNoValue() throws AccessorException { + applyEvent( new OptionalValueRemoved() ); + } + + @Override + public boolean hasValue() throws AccessorException { + try { + return server.hasValue(accId); + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + @Override + public Object getComponentValue(Binding componentBinding) + throws AccessorException { + try { + WireAccessor sa = createAccessor( new ComponentReference() ); + try { + return sa.getValue(componentBinding); + } finally { + sa.close(); + } + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + @Override + public void setComponentValue(Binding binding, Object value) + throws AccessorException { + applyEvent(new OptionalValueAssigned(binding, value)); + } + + @SuppressWarnings("unchecked") + @Override + public T getComponentAccessor() + throws AccessorConstructionException { + return (T) getComponent( new ComponentReference() ); + } + + } + + class WireRecord extends WireAccessor implements RecordAccessor { + + WireRecord(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public RecordType type() { + return (RecordType) type; + } + + @Override + public int count() throws AccessorException { + try { + return server.size(accId); + } catch (WireException e) { + throw new AccessorException(e); + } + } + + @SuppressWarnings("unchecked") + @Override + public T getFieldAccessor(int index) + throws AccessorConstructionException { + return (T) getComponent( new IndexReference(index) ); + } + + @SuppressWarnings("unchecked") + @Override + public T getFieldAccessor(String fieldName) + throws AccessorConstructionException { + return (T) getComponent( new NameReference( fieldName ) ); + } + + @Override + public Object getFieldValue(String fieldName, Binding fieldBinding) + throws AccessorException { + int fieldIndex = type().getComponentIndex(fieldName); + if (fieldIndex<0) throw new AccessorException("Field "+fieldName+" does not exist"); + return getFieldValue(fieldIndex, fieldBinding); + } + + @Override + public Object getFieldValue(int index, Binding fieldBinding) + throws AccessorException { + try { + WireAccessor sa = createAccessor( new IndexReference(index) ); + try { + return sa.getValue(fieldBinding); + } finally { + sa.close(); + } + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + public void setFieldValue(String fieldName, Binding fieldBinding, Object value) throws AccessorException { + int fieldIndex = type().getComponentIndex(fieldName); + if (fieldIndex<0) throw new AccessorException("Field "+fieldName+" does not exist"); + setFieldValue(fieldIndex, fieldBinding, value); + }; + + @Override + public void setFieldValue(int index, Binding fieldBinding, Object value) + throws AccessorException { + try { + WireAccessor sa = createAccessor( new IndexReference(index) ); + try { + sa.setValue(fieldBinding, value); + } finally { + sa.close(); + } + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + } + + class WireString extends WireAccessor implements StringAccessor { + + WireString(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public StringType type() { + return (StringType) type; + } + + @Override + public String getValue() throws AccessorException { + try { + MutableVariant value = server.getValue(accId); + return (String) value.getValue( Bindings.STRING ); + } catch (WireException e) { + throw new AccessorException( e ); + } catch (AdaptException e) { + throw new AccessorException( e ); + } + } + + @Override + public void setValue(String newValue) throws AccessorException { + Event e = new ValueAssigned( Bindings.STRING, newValue); + Event[] list = new Event[] {e}; + ApplyResult result = server.apply(accId, list, false); + if (result.error != null) throw new AccessorException( result.error ); + } + + } + + class WireUnion extends WireAccessor implements UnionAccessor { + + WireUnion(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public UnionType type() { + return (UnionType) type; + } + + @Override + public int count() throws AccessorException { + try { + return server.size(accId); + } catch (WireException e) { + throw new AccessorException(e); + } + } + + @Override + public int getTag() throws AccessorException { + try { + return server.getTag(accId); + } catch (WireException e) { + throw new AccessorException(e); + } + } + + @SuppressWarnings("unchecked") + @Override + public T getComponentAccessor() + throws AccessorConstructionException { + return (T) getComponent(new ComponentReference()); + } + + @Override + public Object getComponentValue(Binding componentBinding) + throws AccessorException { + try { + WireAccessor sa = createAccessor( new ComponentReference() ); + try { + return sa.getValue(componentBinding); + } finally { + sa.close(); + } + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + @Override + public void setComponentValue(int tag, Binding componentBinding, + Object componentValue) throws AccessorException { + try { + WireAccessor sa = createAccessor( new ComponentReference() ); + try { + sa.setValue(componentBinding, componentValue); + } finally { + sa.close(); + } + } catch (WireException e) { + throw new AccessorException( e ); + } + + } + + } + + class WireVariant extends WireAccessor implements VariantAccessor { + + WireVariant(int accId, Datatype type, ChildReference ref) { + super(accId, type, ref); + } + + @Override + public VariantType type() { + return (VariantType) type; + } + + @SuppressWarnings("unchecked") + @Override + public T getContentAccessor() + throws AccessorConstructionException { + return (T) getComponent(new ComponentReference()); + } + + @Override + public void setContentValue(Binding valueBinding, Object value) + throws AccessorException { + try { + WireAccessor sa = createAccessor( new ComponentReference() ); + try { + sa.setValue(valueBinding, value); + } finally { + sa.close(); + } + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + @Override + public Object getContentValue(Binding contentBinding) + throws AccessorException { + try { + WireAccessor sa = createAccessor( new ComponentReference() ); + try { + return sa.getValue(contentBinding); + } finally { + sa.close(); + } + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + @Override + public Datatype getContentType() throws AccessorException { + try { + WireAccessor sa = createAccessor( new ComponentReference() ); + try { + return sa.type(); + } finally { + sa.close(); + } + } catch (WireException e) { + throw new AccessorException( e ); + } + } + + } + + +} +