]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.databoard/src/org/simantics/databoard/Methods.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / Methods.java
diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/Methods.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/Methods.java
new file mode 100644 (file)
index 0000000..44c0bcd
--- /dev/null
@@ -0,0 +1,264 @@
+/*******************************************************************************\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;
+
+import java.lang.reflect.Method;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.simantics.databoard.binding.error.BindingConstructionException;\r
+import org.simantics.databoard.binding.error.DatatypeConstructionException;\r
+import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
+import org.simantics.databoard.method.Interface;\r
+import org.simantics.databoard.method.MethodInterface;\r
+import org.simantics.databoard.method.MethodInterfaceUtil;\r
+import org.simantics.databoard.method.MethodNotSupportedException;\r
+import org.simantics.databoard.method.MethodReflectionBinding;\r
+import org.simantics.databoard.method.MethodType;\r
+import org.simantics.databoard.method.MethodTypeBinding;\r
+import org.simantics.databoard.method.MethodTypeDefinition;\r
+
+/**
+ * This is a facade class for method services.
+ *
+ * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
+ */
+public class Methods {
+       
+       public static Interface NULL_INTERFACE = new Interface();
+       
+       public static MethodReflectionBinding methodReflectionBinding = new MethodReflectionBinding();
+
+       public static MethodInterface adaptMethods(MethodInterface mi, final MethodTypeDefinition[] rangeMethods)
+       {
+               return MethodInterfaceUtil.adaptMethods(mi, rangeMethods);
+       }
+       
+    /**
+     * Bind an interface type to an instance. The <code>obj</code> must have all the
+     * methods described in the interface type. 
+     * 
+     * @param interfaceType interface type
+     * @param obj instance
+     * @return interface binding
+     * @throws BindingConstructionException
+     */
+    public static MethodInterface bindInterface(Interface interfaceType, Object obj) throws BindingConstructionException
+    {
+       return MethodInterfaceUtil.bindInterface(interfaceType, obj);
+    }
+
+    /**
+     * Creates a InterfaceBinding implementation out of an object that 
+     * implements an interface. All the methods of the interface are 
+     * represented in the resulting InterfaceBinding. MethodTypeDefinitions are 
+     * generated automatically. <p>
+     * 
+     * There are restrictions to interface methods. Methods cannot have as
+     * argument, return type or as an exception anything {@link Datatypes#getDatatype(Class)}
+     * cannot create data type out of. In other perspective, all classes must 
+     * be composed of simple array, record, union, and primitive types.<p>    
+     * 
+     * @param interfaze interface to inspect methods from
+     * @param obj implementing object
+     * @return method interface implementation
+     * @throws BindingConstructionException 
+     */
+       public static <T> MethodInterface bindInterface(Class<T> interfaze, final T obj) throws BindingConstructionException
+    {
+       return MethodInterfaceUtil.bindInterface(interfaze, obj);
+    }
+    
+    /**
+     * Creates a proxy implementation that implements all methods of the 
+     * <code>interface</code>. The interface binding <code>ib</code> must implement
+     * all the methods. 
+     * 
+     * @param interfaze interface 
+     * @param ib interface binding
+     * @return an implementation to interfaze
+     * @throws BindingConstructionException on construction error
+     */
+       public static <T> T createProxy(Class<T> interfaze, MethodInterface ib)
+       throws BindingConstructionException
+       {
+               return MethodInterfaceUtil.createProxy(interfaze, ib);
+       }    
+        
+       
+    /**
+     * Get method description
+     * 
+     * @param m
+     * @return method description
+     * @throws DatatypeConstructionException 
+     */
+    public static MethodTypeDefinition getMethodDescription(Method m) throws DatatypeConstructionException
+    {
+       return methodReflectionBinding.getMethodDescription(m);
+    }
+    
+    /**
+     * Get method description
+     * 
+     * @param m
+     * @return method type
+     * @throws DatatypeConstructionException 
+     */
+    public static MethodType getMethodType(Method m) throws DatatypeConstructionException
+    {
+       return methodReflectionBinding.getMethodType(m);
+    }
+    
+    /**
+     * Get method binding of a method. 
+     * Method arguments are wrapped into an Object[].
+     * Throwables in an UnionType. 
+     * 
+     * @param m
+     * @return method bindings
+     * @throws BindingConstructionException 
+     */
+    public static MethodTypeBinding getMethodTypeBinding(Method m) throws BindingConstructionException
+    {
+       return methodReflectionBinding.getMethodBinding(m);
+    }
+
+    /**
+     * Get method type bindings of all methods of an interface
+     *  
+     * @param interfaze
+     * @return and array of method type bindings
+     */
+    public static MethodTypeBinding[] getMethodTypeBindingsUnchecked(Class<?> interfaze)
+    {
+       try {
+               return methodReflectionBinding.getInterfaceBinding(interfaze);
+       } catch (BindingConstructionException e) {
+               throw new RuntimeBindingConstructionException(e);
+       }       
+    }
+    
+    /**
+     * Get method bindings for all methods of an interface
+     * 
+     * @param interfaze
+     * @return an array of methods type bindings
+     * @throws BindingConstructionException
+     */
+    public static MethodTypeBinding[] getMethodTypeBindings(Class<?> interfaze) throws BindingConstructionException
+    {
+       return methodReflectionBinding.getInterfaceBinding(interfaze);
+    }
+    
+    public static Interface getInterfaceType(Class<?> interfaze) throws BindingConstructionException
+    {
+       return methodReflectionBinding.getInterfaceType(interfaze);
+    }
+    
+    public static Interface getInterfaceTypeUnchecked(Class<?> interfaze) 
+    {
+       try {
+               return methodReflectionBinding.getInterfaceType(interfaze);
+       } catch (BindingConstructionException e) {
+               throw new RuntimeBindingConstructionException(e);
+       }
+    }    
+        
+    public static MethodInterface composeMethods(MethodInterface...interfaces)
+    throws IllegalArgumentException
+    {
+       return new MethodComposition(interfaces);
+    }
+    
+    public static MethodInterface noMethods()
+    {
+       return NullMethods.INSTANCE;
+    }       
+       
+
+}
+
+class MethodComposition implements MethodInterface {
+       
+       MethodInterface[] interfaces;
+       Map<MethodTypeDefinition, MethodInterface> map = new HashMap<MethodTypeDefinition, MethodInterface>();
+       Interface interfaceType;
+       
+       public MethodComposition(MethodInterface ... interfaces)
+       {
+               this.interfaces = interfaces;
+               for (MethodInterface mi : interfaces)
+               {
+                       for (MethodTypeDefinition md : mi.getInterface().getMethodDefinitions())
+                       {
+                               if (map.containsKey(md))
+                                       throw new IllegalArgumentException("Method ("+md+") cannot be shard over multiple MethodInterface");
+                               map.put(md, mi);
+                       }
+               }
+               MethodTypeDefinition[] methods = map.values().toArray(new MethodTypeDefinition[0]);
+               interfaceType = new Interface(methods);
+       }
+
+       @Override
+       public Method getMethod(MethodTypeDefinition description)
+                       throws MethodNotSupportedException {
+               MethodInterface mi = map.get(description);
+               if (mi==null) throw new MethodNotSupportedException(description.getName());
+               return mi.getMethod(description);
+       }
+
+       @Override
+       public Method getMethod(MethodTypeBinding binding)
+                       throws MethodNotSupportedException {
+               MethodInterface mi = map.get(binding.getMethodDefinition());
+               if (mi==null) throw new MethodNotSupportedException(binding.getMethodDefinition().getName());
+               return mi.getMethod(binding);
+       }
+
+       @Override
+       public Interface getInterface() {
+               return interfaceType;
+       }
+       
+}
+
+/**
+ * MethodInterface implementation that contains no methods.
+ */
+class NullMethods implements MethodInterface {
+
+       public static final MethodInterface INSTANCE = new NullMethods();
+       
+       Interface interfaceType = new Interface();;
+       
+       @Override
+       public Method getMethod(MethodTypeDefinition description)
+                       throws MethodNotSupportedException {
+               throw new MethodNotSupportedException(description.getName());
+       }
+
+       @Override
+       public Method getMethod(MethodTypeBinding binding)
+                       throws MethodNotSupportedException {            
+               throw new MethodNotSupportedException(binding.getMethodDefinition().getName());
+       }
+
+       @Override
+       public Interface getInterface() {
+               return interfaceType;
+       }
+
+}
+
+