1 package org.logicalcobwebs.cglib.core; 2 3 import java.lang.reflect.Method ; 4 import java.util.*; 5 import org.logicalcobwebs.asm.Type; 6 7 public class TypeUtils { 8 private static final Map transforms = new HashMap(); 9 private static final Map rtransforms = new HashMap(); 10 11 private TypeUtils() { 12 } 13 14 static { 15 transforms.put("void", "V"); 16 transforms.put("byte", "B"); 17 transforms.put("char", "C"); 18 transforms.put("double", "D"); 19 transforms.put("float", "F"); 20 transforms.put("int", "I"); 21 transforms.put("long", "J"); 22 transforms.put("short", "S"); 23 transforms.put("boolean", "Z"); 24 25 CollectionUtils.reverse(transforms, rtransforms); 26 } 27 28 public static boolean isStatic(int access) { 29 return (Constants.ACC_STATIC & access) != 0; 30 } 31 32 public static boolean isAbstract(int access) { 33 return (Constants.ACC_ABSTRACT & access) != 0; 34 } 35 36 public static boolean isInterface(int access) { 37 return (Constants.ACC_INTERFACE & access) != 0; 38 } 39 40 41 public static String getPackageName(Type type) { 43 String name = getClassName(type); 44 int idx = name.lastIndexOf('.'); 45 return (idx < 0) ? "" : name.substring(0, idx); 46 } 47 48 public static String upperFirst(String s) { 49 if (s == null || s.length() == 0) { 50 return s; 51 } 52 return Character.toUpperCase(s.charAt(0)) + s.substring(1); 53 } 54 55 public static String getClassName(Type type) { 56 if (isPrimitive(type)) { 57 return (String )rtransforms.get(type.getDescriptor()); 58 } else if (isArray(type)) { 59 return getClassName(getComponentType(type)) + "[]"; 60 } else { 61 return type.getClassName(); 62 } 63 } 64 65 public static Type[] add(Type[] types, Type extra) { 66 if (types == null) { 67 return new Type[]{ extra }; 68 } else { 69 List list = Arrays.asList(types); 70 if (list.contains(extra)) { 71 return types; 72 } 73 Type[] copy = new Type[types.length + 1]; 74 System.arraycopy(types, 0, copy, 0, types.length); 75 copy[types.length] = extra; 76 return copy; 77 } 78 } 79 80 public static Type[] add(Type[] t1, Type[] t2) { 81 Type[] all = new Type[t1.length + t2.length]; 83 System.arraycopy(t1, 0, all, 0, t1.length); 84 System.arraycopy(t2, 0, all, t1.length, t2.length); 85 return all; 86 } 87 88 public static Type fromInternalName(String name) { 89 return Type.getType("L" + name + ";"); 91 } 92 93 public static Type[] fromInternalNames(String [] names) { 94 if (names == null) { 95 return null; 96 } 97 Type[] types = new Type[names.length]; 98 for (int i = 0; i < names.length; i++) { 99 types[i] = fromInternalName(names[i]); 100 } 101 return types; 102 } 103 104 public static int getStackSize(Type[] types) { 105 int size = 0; 106 for (int i = 0; i < types.length; i++) { 107 size += types[i].getSize(); 108 } 109 return size; 110 } 111 112 public static String [] toInternalNames(Type[] types) { 113 if (types == null) { 114 return null; 115 } 116 String [] names = new String [types.length]; 117 for (int i = 0; i < types.length; i++) { 118 names[i] = types[i].getInternalName(); 119 } 120 return names; 121 } 122 123 public static Signature parseSignature(String s) { 124 int space = s.indexOf(' '); 125 int lparen = s.indexOf('(', space); 126 int rparen = s.indexOf(')', lparen); 127 String returnType = s.substring(0, space); 128 String methodName = s.substring(space + 1, lparen); 129 StringBuffer sb = new StringBuffer (); 130 sb.append('('); 131 for (Iterator it = parseTypes(s, lparen + 1, rparen).iterator(); it.hasNext();) { 132 sb.append(it.next()); 133 } 134 sb.append(')'); 135 sb.append(map(returnType)); 136 return new Signature(methodName, sb.toString()); 137 } 138 139 public static Type parseType(String s) { 140 return Type.getType(map(s)); 141 } 142 143 public static Type[] parseTypes(String s) { 144 List names = parseTypes(s, 0, s.length()); 145 Type[] types = new Type[names.size()]; 146 for (int i = 0; i < types.length; i++) { 147 types[i] = Type.getType((String )names.get(i)); 148 } 149 return types; 150 } 151 152 public static Signature parseConstructor(Type[] types) { 153 StringBuffer sb = new StringBuffer (); 154 sb.append("("); 155 for (int i = 0; i < types.length; i++) { 156 sb.append(types[i].getDescriptor()); 157 } 158 sb.append(")"); 159 sb.append("V"); 160 return new Signature(Constants.CONSTRUCTOR_NAME, sb.toString()); 161 } 162 163 public static Signature parseConstructor(String sig) { 164 return parseSignature("void <init>(" + sig + ")"); } 166 167 private static List parseTypes(String s, int mark, int end) { 168 List types = new ArrayList(5); 169 for (;;) { 170 int next = s.indexOf(',', mark); 171 if (next < 0) { 172 break; 173 } 174 types.add(map(s.substring(mark, next).trim())); 175 mark = next + 1; 176 } 177 types.add(map(s.substring(mark, end).trim())); 178 return types; 179 } 180 181 private static String map(String type) { 182 if (type.equals("")) { 183 return type; 184 } 185 String t = (String )transforms.get(type); 186 if (t != null) { 187 return t; 188 } else if (type.indexOf('.') < 0) { 189 return map("java.lang." + type); 190 } else { 191 StringBuffer sb = new StringBuffer (); 192 int index = 0; 193 while ((index = type.indexOf("[]", index) + 1) > 0) { 194 sb.append('['); 195 } 196 type = type.substring(0, type.length() - sb.length() * 2); 197 sb.append('L').append(type.replace('.', '/')).append(';'); 198 return sb.toString(); 199 } 200 } 201 202 public static Type getBoxedType(Type type) { 203 switch (type.getSort()) { 204 case Type.CHAR: 205 return Constants.TYPE_CHARACTER; 206 case Type.BOOLEAN: 207 return Constants.TYPE_BOOLEAN; 208 case Type.DOUBLE: 209 return Constants.TYPE_DOUBLE; 210 case Type.FLOAT: 211 return Constants.TYPE_FLOAT; 212 case Type.LONG: 213 return Constants.TYPE_LONG; 214 case Type.INT: 215 return Constants.TYPE_INTEGER; 216 case Type.SHORT: 217 return Constants.TYPE_SHORT; 218 case Type.BYTE: 219 return Constants.TYPE_BYTE; 220 default: 221 return type; 222 } 223 } 224 225 public static Type getUnboxedType(Type type) { 226 if (Constants.TYPE_INTEGER.equals(type)) { 227 return Type.INT_TYPE; 228 } else if (Constants.TYPE_BOOLEAN.equals(type)) { 229 return Type.BOOLEAN_TYPE; 230 } else if (Constants.TYPE_DOUBLE.equals(type)) { 231 return Type.DOUBLE_TYPE; 232 } else if (Constants.TYPE_LONG.equals(type)) { 233 return Type.LONG_TYPE; 234 } else if (Constants.TYPE_CHARACTER.equals(type)) { 235 return Type.CHAR_TYPE; 236 } else if (Constants.TYPE_BYTE.equals(type)) { 237 return Type.BYTE_TYPE; 238 } else if (Constants.TYPE_FLOAT.equals(type)) { 239 return Type.FLOAT_TYPE; 240 } else if (Constants.TYPE_SHORT.equals(type)) { 241 return Type.SHORT_TYPE; 242 } else { 243 return type; 244 } 245 } 246 247 public static boolean isArray(Type type) { 248 return type.getSort() == Type.ARRAY; 249 } 250 251 public static Type getComponentType(Type type) { 252 if (!isArray(type)) { 253 throw new IllegalArgumentException ("Type " + type + " is not an array"); 254 } 255 return Type.getType(type.getDescriptor().substring(1)); 256 } 257 258 public static boolean isPrimitive(Type type) { 259 switch (type.getSort()) { 260 case Type.ARRAY: 261 case Type.OBJECT: 262 return false; 263 default: 264 return true; 265 } 266 } 267 268 public static String emulateClassGetName(Type type) { 269 if (isPrimitive(type) || isArray(type)) { 270 return type.getDescriptor().replace('/', '.'); 271 } else { 272 return type.getClassName(); 273 } 274 } 275 276 public static Type[] getTypes(Class [] classes) { 277 if (classes == null) { 278 return null; 279 } 280 Type[] types = new Type[classes.length]; 281 for (int i = 0; i < classes.length; i++) { 282 types[i] = Type.getType(classes[i]); 283 } 284 return types; 285 } 286 287 public static int ICONST(int value) { 288 switch (value) { 289 case -1: return Constants.ICONST_M1; 290 case 0: return Constants.ICONST_0; 291 case 1: return Constants.ICONST_1; 292 case 2: return Constants.ICONST_2; 293 case 3: return Constants.ICONST_3; 294 case 4: return Constants.ICONST_4; 295 case 5: return Constants.ICONST_5; 296 } 297 return -1; } 299 300 public static int LCONST(long value) { 301 if (value == 0L) { 302 return Constants.LCONST_0; 303 } else if (value == 1L) { 304 return Constants.LCONST_1; 305 } else { 306 return -1; } 308 } 309 310 public static int FCONST(float value) { 311 if (value == 0f) { 312 return Constants.FCONST_0; 313 } else if (value == 1f) { 314 return Constants.FCONST_1; 315 } else if (value == 2f) { 316 return Constants.FCONST_2; 317 } else { 318 return -1; } 320 } 321 322 public static int DCONST(double value) { 323 if (value == 0d) { 324 return Constants.DCONST_0; 325 } else if (value == 1d) { 326 return Constants.DCONST_1; 327 } else { 328 return -1; } 330 } 331 332 public static int NEWARRAY(Type type) { 333 switch (type.getSort()) { 334 case Type.BYTE: 335 return Constants.T_BYTE; 336 case Type.CHAR: 337 return Constants.T_CHAR; 338 case Type.DOUBLE: 339 return Constants.T_DOUBLE; 340 case Type.FLOAT: 341 return Constants.T_FLOAT; 342 case Type.INT: 343 return Constants.T_INT; 344 case Type.LONG: 345 return Constants.T_LONG; 346 case Type.SHORT: 347 return Constants.T_SHORT; 348 case Type.BOOLEAN: 349 return Constants.T_BOOLEAN; 350 default: 351 return -1; } 353 } 354 355 public static Signature getSignature(Method method) { 356 return new Signature(method.getName(), Type.getMethodDescriptor(method)); 357 } 358 } 359 | Popular Tags |