001/* 002 * BridJ - Dynamic and blazing-fast native interop for Java. 003 * http://bridj.googlecode.com/ 004 * 005 * Copyright (c) 2010-2013, Olivier Chafik (http://ochafik.com/) 006 * All rights reserved. 007 * 008 * Redistribution and use in source and binary forms, with or without 009 * modification, are permitted provided that the following conditions are met: 010 * 011 * * Redistributions of source code must retain the above copyright 012 * notice, this list of conditions and the following disclaimer. 013 * * Redistributions in binary form must reproduce the above copyright 014 * notice, this list of conditions and the following disclaimer in the 015 * documentation and/or other materials provided with the distribution. 016 * * Neither the name of Olivier Chafik nor the 017 * names of its contributors may be used to endorse or promote products 018 * derived from this software without specific prior written permission. 019 * 020 * THIS SOFTWARE IS PROVIDED BY OLIVIER CHAFIK AND CONTRIBUTORS ``AS IS'' AND ANY 021 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 023 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 024 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 027 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 030 */ 031package org.bridj; 032 033import java.lang.reflect.Constructor; 034import java.lang.reflect.Method; 035import java.lang.reflect.Type; 036import org.bridj.cpp.CPPRuntime; 037import org.bridj.util.Utils; 038 039/** 040 * Base class for implementation of runtimes 041 * 042 * @author Olivier 043 */ 044public abstract class AbstractBridJRuntime implements BridJRuntime { 045 //@Override 046 047 public void unregister(Type type) { 048 // TODO !!! 049 } 050 051 //@Override 052 public Type getType(NativeObject instance) { 053 if (instance == null) { 054 return null; 055 } 056 return Utils.getClass(instance.getClass()); 057 } 058 059 protected java.lang.reflect.Constructor findConstructor(Class<?> type, int constructorId, boolean onlyWithAnnotation) throws SecurityException, NoSuchMethodException { 060 for (java.lang.reflect.Constructor<?> c : type.getDeclaredConstructors()) { 061 org.bridj.ann.Constructor ca = c.getAnnotation(org.bridj.ann.Constructor.class); 062 if (ca == null) { 063 continue; 064 } 065 if (ca.value() == constructorId) { 066 return c; 067 } 068 } 069 if (constructorId < 0)// && args.length == 0) 070 { 071 return type.getConstructor(); 072 } 073 Class<?> sup = type.getSuperclass(); 074 if (sup != null) { 075 try { 076 java.lang.reflect.Constructor c = findConstructor(sup, constructorId, onlyWithAnnotation); 077 if (onlyWithAnnotation && c != null) { 078 return c; 079 } 080 081 Type[] params = c.getGenericParameterTypes(); 082 Constructor<?>[] ccs = type.getDeclaredConstructors(); 083 for (java.lang.reflect.Constructor cc : ccs) { 084 Type[] ccparams = cc.getGenericParameterTypes(); 085 int overrideOffset = Utils.getEnclosedConstructorParametersOffset(cc); 086 if (isOverridenSignature(params, ccparams, overrideOffset)) { 087 return cc; 088 } 089 } 090 } catch (Throwable th) { 091 th.printStackTrace(); 092 } 093 } 094 throw new NoSuchMethodException("Cannot find constructor with index " + constructorId); 095 } 096 097 public static boolean isOverridenSignature(Type[] parentSignature, Type[] overrideSignature, int overrideOffset) { 098 int n = parentSignature.length; 099 if (overrideSignature.length - overrideOffset != n) { 100 return false; 101 } 102 for (int i = 0; i < n; i++) { 103 if (!isOverride(parentSignature[i], overrideSignature[overrideOffset + i])) { 104 return false; 105 } 106 } 107 return true; 108 } 109 110 protected static boolean isOverride(Type parentSignature, Type overrideSignature) { 111 return Utils.getClass(parentSignature).isAssignableFrom(Utils.getClass(overrideSignature)); 112 } 113}