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.util; 032 033import java.lang.reflect.Constructor; 034import java.lang.reflect.ParameterizedType; 035import java.lang.reflect.Type; 036import java.lang.reflect.Method; 037import java.io.*; 038import java.lang.reflect.Array; 039import java.lang.reflect.GenericArrayType; 040import java.lang.reflect.TypeVariable; 041import java.lang.reflect.WildcardType; 042import java.nio.*; 043 044/** 045 * Miscellaneous utility methods. 046 * 047 * @author ochafik 048 */ 049public class Utils { 050 051 public static int getEnclosedConstructorParametersOffset(Constructor c) { 052 Class<?> enclosingClass = c.getDeclaringClass().getEnclosingClass(); 053 Class[] params = c.getParameterTypes(); 054 int overrideOffset = params.length > 0 && enclosingClass != null && enclosingClass == params[0] ? 1 : 0; 055 return overrideOffset; 056 } 057 058 public static boolean isDirect(Buffer b) { 059 if (b instanceof ByteBuffer) { 060 return ((ByteBuffer) b).isDirect(); 061 } 062 if (b instanceof IntBuffer) { 063 return ((IntBuffer) b).isDirect(); 064 } 065 if (b instanceof LongBuffer) { 066 return ((LongBuffer) b).isDirect(); 067 } 068 if (b instanceof DoubleBuffer) { 069 return ((DoubleBuffer) b).isDirect(); 070 } 071 if (b instanceof FloatBuffer) { 072 return ((FloatBuffer) b).isDirect(); 073 } 074 if (b instanceof ShortBuffer) { 075 return ((ShortBuffer) b).isDirect(); 076 } 077 if (b instanceof CharBuffer) { 078 return ((CharBuffer) b).isDirect(); 079 } 080 return false; 081 } 082 083 public static Object[] takeRight(Object[] array, int n) { 084 if (n == array.length) { 085 return array; 086 } else { 087 Object[] res = new Object[n]; 088 System.arraycopy(array, array.length - n, res, 0, n); 089 return res; 090 } 091 } 092 093 public static Object[] takeLeft(Object[] array, int n) { 094 if (n == array.length) { 095 return array; 096 } else { 097 Object[] res = new Object[n]; 098 System.arraycopy(array, 0, res, 0, n); 099 return res; 100 } 101 } 102 103 public static boolean isSignedIntegral(Type tpe) { 104 return tpe == int.class || tpe == Integer.class 105 || tpe == long.class || tpe == Long.class 106 || tpe == short.class || tpe == Short.class 107 || tpe == byte.class || tpe == Byte.class; 108 } 109 110 public static String toString(Type t) { 111 if (t == null) { 112 return "?"; 113 } 114 if (t instanceof Class) { 115 return ((Class) t).getName(); 116 } 117 return t.toString(); 118 } 119 120 public static String toString(Throwable th) { 121 if (th == null) 122 return "<no trace>"; 123 StringWriter sw = new StringWriter(); 124 PrintWriter pw = new PrintWriter(sw); 125 th.printStackTrace(pw); 126 return sw.toString(); 127 } 128 129 public static boolean eq(Object a, Object b) { 130 if ((a == null) != (b == null)) { 131 return false; 132 } 133 return !(a != null && !a.equals(b)); 134 } 135 136 public static boolean containsTypeVariables(Type type) { 137 if (type instanceof TypeVariable) { 138 return true; 139 } 140 if (type instanceof ParameterizedType) { 141 ParameterizedType pt = (ParameterizedType) type; 142 for (Type t : pt.getActualTypeArguments()) { 143 if (containsTypeVariables(t)) { 144 return true; 145 } 146 } 147 } 148 return false; 149 } 150 151 public static <T> Class<T> getClass(Type type) { 152 if (type == null) { 153 return null; 154 } 155 if (type instanceof Class<?>) { 156 return (Class<T>) type; 157 } 158 if (type instanceof ParameterizedType) { 159 return getClass(((ParameterizedType) type).getRawType()); 160 } 161 if (type instanceof GenericArrayType) { 162 return (Class) Array.newInstance(getClass(((GenericArrayType) type).getGenericComponentType()), 0).getClass(); 163 } 164 if (type instanceof WildcardType) { 165 return null; 166 } 167 if (type instanceof TypeVariable) { 168 Type[] bounds = ((TypeVariable) type).getBounds(); 169 return getClass(bounds[0]); 170 } 171 throw new UnsupportedOperationException("Cannot infer class from type " + type); 172 } 173 174 public static Type getParent(Type type) { 175 if (type instanceof Class) { 176 return ((Class) type).getSuperclass(); 177 } else // TODO handle templates !!! 178 { 179 return getParent(getClass(type)); 180 } 181 } 182 183 public static Class[] getClasses(Type[] types) { 184 int n = types.length; 185 Class[] ret = new Class[n]; 186 for (int i = 0; i < n; i++) { 187 ret[i] = getClass(types[i]); 188 } 189 return ret; 190 } 191 192 public static Type getUniqueParameterizedTypeParameter(Type type) { 193 return (type instanceof ParameterizedType) ? ((ParameterizedType) type).getActualTypeArguments()[0] : null; 194 } 195 196 public static boolean parametersComplyToSignature(Object[] values, Class[] parameterTypes) { 197 if (values.length != parameterTypes.length) { 198 return false; 199 } 200 for (int i = 0, n = values.length; i < n; i++) { 201 Object value = values[i]; 202 Class parameterType = parameterTypes[i]; 203 if (!parameterType.isInstance(value)) { 204 return false; 205 } 206 } 207 return true; 208 } 209}