001 /*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005
006 package org.bridj;
007
008 import java.lang.reflect.Constructor;
009 import java.lang.reflect.Method;
010 import java.lang.reflect.Type;
011 import org.bridj.cpp.CPPRuntime;
012 import org.bridj.util.Utils;
013
014 /**
015 * Base class for implementation of runtimes
016 * @author Olivier
017 */
018 public abstract class AbstractBridJRuntime implements BridJRuntime {
019 //@Override
020 public void unregister(Type type) {
021 // TODO !!!
022 }
023
024 //@Override
025 public Type getType(NativeObject instance) {
026 if (instance == null)
027 return null;
028 return Utils.getClass(instance.getClass());
029 }
030
031 protected java.lang.reflect.Constructor findConstructor(Class<?> type, int constructorId, boolean onlyWithAnnotation) throws SecurityException, NoSuchMethodException {
032 for (java.lang.reflect.Constructor<?> c : type.getDeclaredConstructors()) {
033 org.bridj.ann.Constructor ca = c.getAnnotation(org.bridj.ann.Constructor.class);
034 if (ca == null)
035 continue;
036 if (ca.value() == constructorId)
037 return c;
038 }
039 if (constructorId < 0)// && args.length == 0)
040 return type.getConstructor();
041 Class<?> sup = type.getSuperclass();
042 if (sup != null) {
043 try {
044 java.lang.reflect.Constructor c = findConstructor(sup, constructorId, onlyWithAnnotation);
045 if (onlyWithAnnotation && c != null)
046 return c;
047
048 Type[] params = c.getGenericParameterTypes();
049 Constructor<?>[] ccs = type.getDeclaredConstructors();
050 for (java.lang.reflect.Constructor cc : ccs) {
051 Type[] ccparams = cc.getGenericParameterTypes();
052 int overrideOffset = Utils.getEnclosedConstructorParametersOffset(cc);
053 if (isOverridenSignature(params, ccparams, overrideOffset))
054 return cc;
055 }
056 } catch (Throwable th) {
057 th.printStackTrace();
058 }
059 }
060 throw new NoSuchMethodException("Cannot find constructor with index " + constructorId);
061 }
062 public static boolean isOverridenSignature(Type[] parentSignature, Type[] overrideSignature, int overrideOffset) {
063 int n = parentSignature.length;
064 if (overrideSignature.length - overrideOffset != n)
065 return false;
066 for (int i = 0; i < n; i++)
067 if (!isOverride(parentSignature[i], overrideSignature[overrideOffset + i]))
068 return false;
069 return true;
070 }
071 protected static boolean isOverride(Type parentSignature, Type overrideSignature) {
072 return Utils.getClass(parentSignature).isAssignableFrom(Utils.getClass(overrideSignature));
073 }
074
075 }