X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2FMethods.java;fp=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2FMethods.java;h=44c0bcd1ebf90c0c59bf109f5910383b3af51c49;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git 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 index 000000000..44c0bcd1e --- /dev/null +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/Methods.java @@ -0,0 +1,264 @@ +/******************************************************************************* + * 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; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import org.simantics.databoard.binding.error.BindingConstructionException; +import org.simantics.databoard.binding.error.DatatypeConstructionException; +import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; +import org.simantics.databoard.method.Interface; +import org.simantics.databoard.method.MethodInterface; +import org.simantics.databoard.method.MethodInterfaceUtil; +import org.simantics.databoard.method.MethodNotSupportedException; +import org.simantics.databoard.method.MethodReflectionBinding; +import org.simantics.databoard.method.MethodType; +import org.simantics.databoard.method.MethodTypeBinding; +import org.simantics.databoard.method.MethodTypeDefinition; + +/** + * This is a facade class for method services. + * + * @author Toni Kalajainen + */ +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 obj 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.

+ * + * 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.

+ * + * @param interfaze interface to inspect methods from + * @param obj implementing object + * @return method interface implementation + * @throws BindingConstructionException + */ + public static MethodInterface bindInterface(Class interfaze, final T obj) throws BindingConstructionException + { + return MethodInterfaceUtil.bindInterface(interfaze, obj); + } + + /** + * Creates a proxy implementation that implements all methods of the + * interface. The interface binding ib 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 createProxy(Class 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 map = new HashMap(); + 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; + } + +} + +