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