1 /*******************************************************************************
\r
2 * Copyright (c) 2010 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.databoard;
14 import java.lang.reflect.Method;
\r
15 import java.util.HashMap;
\r
16 import java.util.Map;
\r
18 import org.simantics.databoard.binding.error.BindingConstructionException;
\r
19 import org.simantics.databoard.binding.error.DatatypeConstructionException;
\r
20 import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;
\r
21 import org.simantics.databoard.method.Interface;
\r
22 import org.simantics.databoard.method.MethodInterface;
\r
23 import org.simantics.databoard.method.MethodInterfaceUtil;
\r
24 import org.simantics.databoard.method.MethodNotSupportedException;
\r
25 import org.simantics.databoard.method.MethodReflectionBinding;
\r
26 import org.simantics.databoard.method.MethodType;
\r
27 import org.simantics.databoard.method.MethodTypeBinding;
\r
28 import org.simantics.databoard.method.MethodTypeDefinition;
\r
31 * This is a facade class for method services.
33 * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
35 public class Methods {
37 public static Interface NULL_INTERFACE = new Interface();
39 public static MethodReflectionBinding methodReflectionBinding = new MethodReflectionBinding();
41 public static MethodInterface adaptMethods(MethodInterface mi, final MethodTypeDefinition[] rangeMethods)
43 return MethodInterfaceUtil.adaptMethods(mi, rangeMethods);
47 * Bind an interface type to an instance. The <code>obj</code> must have all the
48 * methods described in the interface type.
50 * @param interfaceType interface type
52 * @return interface binding
53 * @throws BindingConstructionException
55 public static MethodInterface bindInterface(Interface interfaceType, Object obj) throws BindingConstructionException
57 return MethodInterfaceUtil.bindInterface(interfaceType, obj);
61 * Creates a InterfaceBinding implementation out of an object that
62 * implements an interface. All the methods of the interface are
63 * represented in the resulting InterfaceBinding. MethodTypeDefinitions are
64 * generated automatically. <p>
66 * There are restrictions to interface methods. Methods cannot have as
67 * argument, return type or as an exception anything {@link Datatypes#getDatatype(Class)}
68 * cannot create data type out of. In other perspective, all classes must
69 * be composed of simple array, record, union, and primitive types.<p>
71 * @param interfaze interface to inspect methods from
72 * @param obj implementing object
73 * @return method interface implementation
74 * @throws BindingConstructionException
76 public static <T> MethodInterface bindInterface(Class<T> interfaze, final T obj) throws BindingConstructionException
78 return MethodInterfaceUtil.bindInterface(interfaze, obj);
82 * Creates a proxy implementation that implements all methods of the
83 * <code>interface</code>. The interface binding <code>ib</code> must implement
86 * @param interfaze interface
87 * @param ib interface binding
88 * @return an implementation to interfaze
89 * @throws BindingConstructionException on construction error
91 public static <T> T createProxy(Class<T> interfaze, MethodInterface ib)
92 throws BindingConstructionException
94 return MethodInterfaceUtil.createProxy(interfaze, ib);
99 * Get method description
102 * @return method description
103 * @throws DatatypeConstructionException
105 public static MethodTypeDefinition getMethodDescription(Method m) throws DatatypeConstructionException
107 return methodReflectionBinding.getMethodDescription(m);
111 * Get method description
114 * @return method type
115 * @throws DatatypeConstructionException
117 public static MethodType getMethodType(Method m) throws DatatypeConstructionException
119 return methodReflectionBinding.getMethodType(m);
123 * Get method binding of a method.
124 * Method arguments are wrapped into an Object[].
125 * Throwables in an UnionType.
128 * @return method bindings
129 * @throws BindingConstructionException
131 public static MethodTypeBinding getMethodTypeBinding(Method m) throws BindingConstructionException
133 return methodReflectionBinding.getMethodBinding(m);
137 * Get method type bindings of all methods of an interface
140 * @return and array of method type bindings
142 public static MethodTypeBinding[] getMethodTypeBindingsUnchecked(Class<?> interfaze)
145 return methodReflectionBinding.getInterfaceBinding(interfaze);
146 } catch (BindingConstructionException e) {
147 throw new RuntimeBindingConstructionException(e);
152 * Get method bindings for all methods of an interface
155 * @return an array of methods type bindings
156 * @throws BindingConstructionException
158 public static MethodTypeBinding[] getMethodTypeBindings(Class<?> interfaze) throws BindingConstructionException
160 return methodReflectionBinding.getInterfaceBinding(interfaze);
163 public static Interface getInterfaceType(Class<?> interfaze) throws BindingConstructionException
165 return methodReflectionBinding.getInterfaceType(interfaze);
168 public static Interface getInterfaceTypeUnchecked(Class<?> interfaze)
171 return methodReflectionBinding.getInterfaceType(interfaze);
172 } catch (BindingConstructionException e) {
173 throw new RuntimeBindingConstructionException(e);
177 public static MethodInterface composeMethods(MethodInterface...interfaces)
178 throws IllegalArgumentException
180 return new MethodComposition(interfaces);
183 public static MethodInterface noMethods()
185 return NullMethods.INSTANCE;
191 class MethodComposition implements MethodInterface {
193 MethodInterface[] interfaces;
194 Map<MethodTypeDefinition, MethodInterface> map = new HashMap<MethodTypeDefinition, MethodInterface>();
195 Interface interfaceType;
197 public MethodComposition(MethodInterface ... interfaces)
199 this.interfaces = interfaces;
200 for (MethodInterface mi : interfaces)
202 for (MethodTypeDefinition md : mi.getInterface().getMethodDefinitions())
204 if (map.containsKey(md))
205 throw new IllegalArgumentException("Method ("+md+") cannot be shard over multiple MethodInterface");
209 MethodTypeDefinition[] methods = map.values().toArray(new MethodTypeDefinition[0]);
210 interfaceType = new Interface(methods);
214 public Method getMethod(MethodTypeDefinition description)
215 throws MethodNotSupportedException {
216 MethodInterface mi = map.get(description);
217 if (mi==null) throw new MethodNotSupportedException(description.getName());
218 return mi.getMethod(description);
222 public Method getMethod(MethodTypeBinding binding)
223 throws MethodNotSupportedException {
224 MethodInterface mi = map.get(binding.getMethodDefinition());
225 if (mi==null) throw new MethodNotSupportedException(binding.getMethodDefinition().getName());
226 return mi.getMethod(binding);
230 public Interface getInterface() {
231 return interfaceType;
237 * MethodInterface implementation that contains no methods.
239 class NullMethods implements MethodInterface {
241 public static final MethodInterface INSTANCE = new NullMethods();
243 Interface interfaceType = new Interface();;
246 public Method getMethod(MethodTypeDefinition description)
247 throws MethodNotSupportedException {
248 throw new MethodNotSupportedException(description.getName());
252 public Method getMethod(MethodTypeBinding binding)
253 throws MethodNotSupportedException {
254 throw new MethodNotSupportedException(binding.getMethodDefinition().getName());
258 public Interface getInterface() {
259 return interfaceType;