Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortle2008-02-03 16:40:54 +0000
committertle2008-02-03 16:40:54 +0000
commit7f7b20a5d66bf69e88734ead5036e4d6664aa381 (patch)
tree97dacecfda81e183389ab1c0adb3a83b953823ad /jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java
parent145c144380950bd4b49fd4597a1a0695cf7c8b7b (diff)
downloadwebtools.dali-7f7b20a5d66bf69e88734ead5036e4d6664aa381.tar.gz
webtools.dali-7f7b20a5d66bf69e88734ead5036e4d6664aa381.tar.xz
webtools.dali-7f7b20a5d66bf69e88734ead5036e4d6664aa381.zip
Merged jpt_2_0_exp branch into Head.v20080202_Merged
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java')
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java284
1 files changed, 228 insertions, 56 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java
index 409dd1db3c..c2b7c55f88 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 Oracle. All rights reserved.
+ * Copyright (c) 2005, 2008 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0, which accompanies this distribution
* and is available at http://www.eclipse.org/legal/epl-v10.html.
@@ -42,11 +42,13 @@ public final class ClassTools {
public static final char NESTED_CLASS_NAME_SEPARATOR = '$';
public static final char ARRAY_INDICATOR = '[';
+ public static final char TYPE_DECLARATION_ARRAY_OPEN = '[';
+ public static final char TYPE_DECLARATION_ARRAY_CLOSE = ']';
public static final char REFERENCE_CLASS_CODE = 'L';
public static final char REFERENCE_CLASS_NAME_DELIMITER = ';';
- private static PrimitiveClassCode[] PRIMITIVE_CLASS_CODES; // pseudo 'final' - lazy-initialized
+ private static Primitive[] PRIMITIVES; // pseudo-'final' - lazy-initialized
public static final char BYTE_CODE = 'B';
public static final char CHAR_CODE = 'C';
public static final char DOUBLE_CODE = 'D';
@@ -56,8 +58,11 @@ public final class ClassTools {
public static final char SHORT_CODE = 'S';
public static final char BOOLEAN_CODE = 'Z';
public static final char VOID_CODE = 'V';
-
- private static int MAX_PRIMITIVE_CLASS_NAME_LENGTH = -1; // pseudo 'final' - lazy-initialized
+ private static int MAX_PRIMITIVE_CLASS_NAME_LENGTH = -1; // pseudo-'final' - lazy-initialized
+ private static int MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH = -1; // pseudo-'final' - lazy-initialized
+
+ public static final String VOID_CLASS_NAME = void.class.getName();
+ public static final String VOID_WRAPPER_CLASS_NAME = java.lang.Void.class.getName();
/**
@@ -391,14 +396,14 @@ public final class ClassTools {
return field(object.getClass(), fieldName);
}
- /**
+ /*
* Return a string representation of the specified constructor.
*/
private static String fullyQualifiedConstructorSignature(Class<?> javaClass, Class<?>[] parameterTypes) {
return fullyQualifiedMethodSignature(javaClass, null, parameterTypes);
}
- /**
+ /*
* Return a string representation of the specified field.
*/
private static String fullyQualifiedFieldName(Class<?> javaClass, String fieldName) {
@@ -409,14 +414,14 @@ public final class ClassTools {
return sb.toString();
}
- /**
+ /*
* Return a string representation of the specified field.
*/
private static String fullyQualifiedFieldName(Object object, String fieldName) {
return fullyQualifiedFieldName(object.getClass(), fieldName);
}
- /**
+ /*
* Return a string representation of the specified method.
*/
private static String fullyQualifiedMethodSignature(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) {
@@ -441,7 +446,7 @@ public final class ClassTools {
return sb.toString();
}
- /**
+ /*
* Return a string representation of the specified method.
*/
private static String fullyQualifiedMethodSignature(Object receiver, String methodName, Class<?>[] parameterTypes) {
@@ -454,7 +459,7 @@ public final class ClassTools {
* Useful for accessing private, package, or protected fields.
* Object#getFieldValue(String fieldName)
*/
- public static Object getFieldValue(Object object, String fieldName) {
+ public static Object fieldValue(Object object, String fieldName) {
try {
return attemptToGetFieldValue(object, fieldName);
} catch (NoSuchFieldException nsfe) {
@@ -468,7 +473,7 @@ public final class ClassTools {
* Useful for accessing private, package, or protected fields.
* Class#getStaticFieldValue(String fieldName)
*/
- public static Object getStaticFieldValue(Class<?> javaClass, String fieldName) {
+ public static Object staticFieldValue(Class<?> javaClass, String fieldName) {
try {
return attemptToGetStaticFieldValue(javaClass, fieldName);
} catch (NoSuchFieldException nsfe) {
@@ -830,7 +835,7 @@ public final class ClassTools {
return newInstance(Class.forName(className, false, classLoader), parameterType, parameter);
}
- /**
+ /*
* Push the declared fields for the specified class
* onto the top of the stack.
*/
@@ -841,7 +846,7 @@ public final class ClassTools {
}
}
- /**
+ /*
* Push the declared methods for the specified class
* onto the top of the stack.
*/
@@ -1263,21 +1268,25 @@ public final class ClassTools {
/**
* Return whether the specified class is a "reference"
- * class (i.e. not void or one of the primitives).
+ * class (i.e. neither 'void' nor one of the primitive variable classes,
+ * ['boolean', 'int', 'float', etc.]).
+ * NB: void.class.isPrimitive() == true
*/
public static boolean classNamedIsReference(String className) {
- return ! classNamedIsNonReference(className);
+ return ! classNamedIsPrimitive(className);
}
/**
- * Return whether the specified class is a "non-reference"
- * class (i.e. void or one of the primitives).
+ * Return whether the specified class is a primitive
+ * class (i.e. 'void' or one of the primitive variable classes,
+ * ['boolean', 'int', 'float', etc.]).
+ * NB: void.class.isPrimitive() == true
*/
- public static boolean classNamedIsNonReference(String className) {
+ public static boolean classNamedIsPrimitive(String className) {
if (classNamedIsArray(className) || (className.length() > maxPrimitiveClassNameLength())) {
return false; // performance tweak
}
- PrimitiveClassCode[] codes = primitiveClassCodes();
+ Primitive[] codes = primitives();
for (int i = codes.length; i-- > 0; ) {
if (codes[i].javaClass.getName().equals(className)) {
return true;
@@ -1287,6 +1296,74 @@ public final class ClassTools {
}
/**
+ * Return whether the specified class is a "variable" primitive
+ * class (i.e. 'boolean', 'int', 'float', etc., but not 'void').
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classNamedIsVariablePrimitive(String className) {
+ return classNamedIsPrimitive(className)
+ && ( ! className.equals(VOID_CLASS_NAME));
+ }
+
+ /**
+ * Return whether the specified class is a primitive wrapper
+ * class (i.e. 'java.lang.Void' or one of the primitive variable wrapper classes,
+ * ['java.lang.Boolean', 'java.lang.Integer', 'java.lang.Float', etc.]).
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classNamedIsPrimitiveWrapperClass(String className) {
+ if (classNamedIsArray(className) || (className.length() > maxPrimitiveWrapperClassNameLength())) {
+ return false; // performance tweak
+ }
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ if (codes[i].wrapperClass.getName().equals(className)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return whether the specified class is a "variable" primitive
+ * class (i.e. 'boolean', 'int', 'float', etc., but not 'void').
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classNamedIsVariablePrimitiveWrapperClass(String className) {
+ return classNamedIsPrimitiveWrapperClass(className)
+ && ( ! className.equals(VOID_WRAPPER_CLASS_NAME));
+ }
+
+ /**
+ * Return whether the specified class is a primitive wrapper
+ * class (i.e. 'java.lang.Void' or one of the primitive variable wrapper classes,
+ * ['java.lang.Boolean', 'java.lang.Integer', 'java.lang.Float', etc.]).
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classIsPrimitiveWrapperClass(Class<?> javaClass) {
+ if (javaClass.isArray() || (javaClass.getName().length() > maxPrimitiveWrapperClassNameLength())) {
+ return false; // performance tweak
+ }
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ if (codes[i].wrapperClass == javaClass) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return whether the specified class is a "variable" primitive
+ * class (i.e. 'boolean', 'int', 'float', etc., but not 'void').
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classIsVariablePrimitiveWrapperClass(Class<?> javaClass) {
+ return classIsPrimitiveWrapperClass(javaClass)
+ && (javaClass != java.lang.Void.class);
+ }
+
+ /**
* Return the class name for the specified class code.
* @see java.lang.Class#getName()
*/
@@ -1307,7 +1384,7 @@ public final class ClassTools {
* @see java.lang.Class#getName()
*/
public static Class<?> classForCode(char classCode) {
- PrimitiveClassCode[] codes = primitiveClassCodes();
+ Primitive[] codes = primitives();
for (int i = codes.length; i-- > 0; ) {
if (codes[i].code == classCode) {
return codes[i].javaClass;
@@ -1330,7 +1407,7 @@ public final class ClassTools {
*/
public static char codeForClass(Class<?> javaClass) {
if (( ! javaClass.isArray()) && (javaClass.getName().length() <= maxPrimitiveClassNameLength())) {
- PrimitiveClassCode[] codes = primitiveClassCodes();
+ Primitive[] codes = primitives();
for (int i = codes.length; i-- > 0; ) {
if (codes[i].javaClass == javaClass) {
return codes[i].code;
@@ -1346,7 +1423,7 @@ public final class ClassTools {
*/
public static char codeForClassNamed(String className) {
if (( ! classNamedIsArray(className)) && (className.length() <= maxPrimitiveClassNameLength())) {
- PrimitiveClassCode[] codes = primitiveClassCodes();
+ Primitive[] codes = primitives();
for (int i = codes.length; i-- > 0; ) {
if (codes[i].javaClass.getName().equals(className)) {
return codes[i].code;
@@ -1357,23 +1434,46 @@ public final class ClassTools {
}
/**
- * Return the class for specified "type declaration".
+ * Return the class for the specified "type declaration".
+ */
+ public static Class<?> classForTypeDeclaration(String typeDeclaration) throws ClassNotFoundException {
+ return classForTypeDeclaration(typeDeclaration, ClassTools.class.getClassLoader());
+ }
+
+ /**
+ * Return the class for the specified "type declaration",
+ * using the specified class loader.
+ */
+ public static Class<?> classForTypeDeclaration(String typeDeclaration, ClassLoader classLoader) throws ClassNotFoundException {
+ TypeDeclaration td = typeDeclaration(typeDeclaration);
+ return classForTypeDeclaration(td.elementTypeName, td.arrayDepth);
+ }
+
+ private static TypeDeclaration typeDeclaration(String typeDeclaration) {
+ typeDeclaration = StringTools.removeAllWhitespace(typeDeclaration);
+ int arrayDepth = arrayDepthForTypeDeclaration_(typeDeclaration);
+ String elementTypeName = typeDeclaration.substring(0, typeDeclaration.length() - (arrayDepth * 2));
+ return new TypeDeclaration(elementTypeName, arrayDepth);
+ }
+
+ /**
+ * Return the class for the specified "type declaration".
*/
public static Class<?> classForTypeDeclaration(String elementTypeName, int arrayDepth) throws ClassNotFoundException {
return classForTypeDeclaration(elementTypeName, arrayDepth, null);
}
/**
- * Return the class for specified "type declaration",
+ * Return the class for the specified "type declaration",
* using the specified class loader.
*/
// see the "Evaluation" of jdk bug 6446627 for a discussion of loading classes
public static Class<?> classForTypeDeclaration(String elementTypeName, int arrayDepth, ClassLoader classLoader) throws ClassNotFoundException {
// primitives cannot be loaded via Class#forName(),
// so check for a primitive class name first
- PrimitiveClassCode pcc = null;
+ Primitive pcc = null;
if (elementTypeName.length() <= maxPrimitiveClassNameLength()) { // performance tweak
- PrimitiveClassCode[] codes = primitiveClassCodes();
+ Primitive[] codes = primitives();
for (int i = codes.length; i-- > 0; ) {
if (codes[i].javaClass.getName().equals(elementTypeName)) {
pcc = codes[i];
@@ -1403,7 +1503,44 @@ public final class ClassTools {
}
/**
- * Return the class name for specified "type declaration".
+ * Return the class name for the specified "type declaration"; e.g.
+ * "int[]" -> "[I"
+ * @see java.lang.Class#getName()
+ */
+ public static String classNameForTypeDeclaration(String typeDeclaration) {
+ TypeDeclaration td = typeDeclaration(typeDeclaration);
+ return classNameForTypeDeclaration(td.elementTypeName, td.arrayDepth);
+ }
+
+ /**
+ * Return the array depth for the specified "type declaration"; e.g.
+ * "int[]" -> 1
+ */
+ public static int arrayDepthForTypeDeclaration(String typeDeclaration) {
+ return arrayDepthForTypeDeclaration_(StringTools.removeAllWhitespace(typeDeclaration));
+ }
+
+ /*
+ * Assume no whitespace in the type declaration.
+ */
+ private static int arrayDepthForTypeDeclaration_(String typeDeclaration) {
+ int last = typeDeclaration.length() - 1;
+ int depth = 0;
+ int close = last;
+ while (typeDeclaration.charAt(close) == TYPE_DECLARATION_ARRAY_CLOSE) {
+ if (typeDeclaration.charAt(close - 1) == TYPE_DECLARATION_ARRAY_OPEN) {
+ depth++;
+ } else {
+ throw new IllegalArgumentException("invalid type declaration: " + typeDeclaration);
+ }
+ close = last - (depth * 2);
+ }
+ return depth;
+ }
+
+ /**
+ * Return the class name for the specified "type declaration".
+ * @see java.lang.Class#getName()
*/
public static String classNameForTypeDeclaration(String elementTypeName, int arrayDepth) {
// non-array
@@ -1411,8 +1548,8 @@ public final class ClassTools {
return elementTypeName;
}
- if (elementTypeName.equals(void.class.getName())) {
- throw new IllegalArgumentException("'void' must have an array depth of zero: " + arrayDepth + '.');
+ if (elementTypeName.equals(VOID_CLASS_NAME)) {
+ throw new IllegalArgumentException("'" + VOID_CLASS_NAME + "' must have an array depth of zero: " + arrayDepth + '.');
}
// array
StringBuilder sb = new StringBuilder(100);
@@ -1421,9 +1558,9 @@ public final class ClassTools {
}
// look for a primitive first
- PrimitiveClassCode pcc = null;
+ Primitive pcc = null;
if (elementTypeName.length() <= maxPrimitiveClassNameLength()) { // performance tweak
- PrimitiveClassCode[] codes = primitiveClassCodes();
+ Primitive[] codes = primitives();
for (int i = codes.length; i-- > 0; ) {
if (codes[i].javaClass.getName().equals(elementTypeName)) {
pcc = codes[i];
@@ -1452,7 +1589,7 @@ public final class ClassTools {
private static int calculateMaxPrimitiveClassNameLength() {
int max = -1;
- PrimitiveClassCode[] codes = primitiveClassCodes();
+ Primitive[] codes = primitives();
for (int i = codes.length; i-- > 0; ) {
int len = codes[i].javaClass.getName().length();
if (len > max) {
@@ -1462,24 +1599,46 @@ public final class ClassTools {
return max;
}
- private static PrimitiveClassCode[] primitiveClassCodes() {
- if (PRIMITIVE_CLASS_CODES == null) {
- PRIMITIVE_CLASS_CODES = buildPrimitiveClassCodes();
- }
- return PRIMITIVE_CLASS_CODES;
- }
-
- private static PrimitiveClassCode[] buildPrimitiveClassCodes() {
- PrimitiveClassCode[] result = new PrimitiveClassCode[9];
- result[0] = new PrimitiveClassCode(BYTE_CODE, byte.class);
- result[1] = new PrimitiveClassCode(CHAR_CODE, char.class);
- result[2] = new PrimitiveClassCode(DOUBLE_CODE, double.class);
- result[3] = new PrimitiveClassCode(FLOAT_CODE, float.class);
- result[4] = new PrimitiveClassCode(INT_CODE, int.class);
- result[5] = new PrimitiveClassCode(LONG_CODE, long.class);
- result[6] = new PrimitiveClassCode(SHORT_CODE, short.class);
- result[7] = new PrimitiveClassCode(BOOLEAN_CODE, boolean.class);
- result[8] = new PrimitiveClassCode(VOID_CODE, void.class);
+ private static int maxPrimitiveWrapperClassNameLength() {
+ if (MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH == -1) {
+ MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH = calculateMaxPrimitiveWrapperClassNameLength();
+ }
+ return MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH;
+ }
+
+ private static int calculateMaxPrimitiveWrapperClassNameLength() {
+ int max = -1;
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ int len = codes[i].wrapperClass.getName().length();
+ if (len > max) {
+ max = len;
+ }
+ }
+ return max;
+ }
+
+ private static Primitive[] primitives() {
+ if (PRIMITIVES == null) {
+ PRIMITIVES = buildPrimitives();
+ }
+ return PRIMITIVES;
+ }
+
+ /**
+ * NB: void.class.isPrimitive() == true
+ */
+ private static Primitive[] buildPrimitives() {
+ Primitive[] result = new Primitive[9];
+ result[0] = new Primitive(BYTE_CODE, java.lang.Byte.class);
+ result[1] = new Primitive(CHAR_CODE, java.lang.Character.class);
+ result[2] = new Primitive(DOUBLE_CODE, java.lang.Double.class);
+ result[3] = new Primitive(FLOAT_CODE, java.lang.Float.class);
+ result[4] = new Primitive(INT_CODE, java.lang.Integer.class);
+ result[5] = new Primitive(LONG_CODE, java.lang.Long.class);
+ result[6] = new Primitive(SHORT_CODE, java.lang.Short.class);
+ result[7] = new Primitive(BOOLEAN_CODE, java.lang.Boolean.class);
+ result[8] = new Primitive(VOID_CODE, java.lang.Void.class);
return result;
}
@@ -1492,14 +1651,27 @@ public final class ClassTools {
}
- // ********** member class **********
+ // ********** member classes **********
- private static class PrimitiveClassCode {
- char code;
- Class<?> javaClass;
- PrimitiveClassCode(char code, Class<?> javaClass) {
+ private static class Primitive {
+ final char code;
+ final Class<?> javaClass;
+ final Class<?> wrapperClass;
+ private static final String WRAPPER_CLASS_TYPE_FIELD_NAME = "TYPE";
+ // e.g. java.lang.Boolean.TYPE => boolean.class
+ Primitive(char code, Class<?> wrapperClass) {
this.code = code;
- this.javaClass = javaClass;
+ this.wrapperClass = wrapperClass;
+ this.javaClass = (Class<?>) staticFieldValue(wrapperClass, WRAPPER_CLASS_TYPE_FIELD_NAME);
+ }
+ }
+
+ private static class TypeDeclaration {
+ final String elementTypeName;
+ final int arrayDepth;
+ TypeDeclaration(String elementTypeName, int arrayDepth) {
+ this.elementTypeName = elementTypeName;
+ this.arrayDepth = arrayDepth;
}
}

Back to the top