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    }