/* * Copyright 2010, 2011 Christopher Pheby * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jadira.bindings.core.utils.reflection; import java.util.HashMap; import java.util.Map; import org.jadira.bindings.core.utils.string.StringUtils; /** * Holds utility methods for obtaining a class from a symbolic representation * The result of {@link #determineQualifiedName(String)} is equivalent in format to the result of {@link Class#getName()} */ public final class ClassUtils { public static final char PACKAGE_SEPARATOR_CHARACTER = '.'; public static final char INNER_CLASS_SEPARATOR_CHAR = '$'; private static final Map<String, String> PRIMITIVE_MAPPING = new HashMap<String, String>(); static { PRIMITIVE_MAPPING.put("int", "I"); PRIMITIVE_MAPPING.put("boolean", "Z"); PRIMITIVE_MAPPING.put("float", "F"); PRIMITIVE_MAPPING.put("long", "J"); PRIMITIVE_MAPPING.put("short", "S"); PRIMITIVE_MAPPING.put("byte", "B"); PRIMITIVE_MAPPING.put("double", "D"); PRIMITIVE_MAPPING.put("char", "C"); } private ClassUtils() { } /** * Attempt to load the class matching the given qualified name. * Uses the current Thread's class loader, or if unavailable, the classloader * this class was loaded from. * @param qualifiedName The qualified name to use * @throws IllegalArgumentException If the class cannot be loaded * @return The {@link Class} representing the given class */ public static Class<?> getClass(String qualifiedName) { return getClass(ClassLoaderUtils.getClassLoader(), qualifiedName); } /** * Attempt to load the class matching the given qualified name * @param classLoader Classloader to use * @param className The classname to use * @throws IllegalArgumentException If the class cannot be loaded * @return The {@link Class} representing the given class */ public static Class<?> getClass(ClassLoader classLoader, String className) { try { final Class<?> clazz; if (PRIMITIVE_MAPPING.containsKey(className)) { String qualifiedName = "[" + PRIMITIVE_MAPPING.get(className); clazz = Class.forName(qualifiedName, true, classLoader).getComponentType(); } else { clazz = Class.forName(determineQualifiedName(className), true, classLoader); } return clazz; } catch (ClassNotFoundException ex) { int lastSeparatorIndex = className.lastIndexOf(PACKAGE_SEPARATOR_CHARACTER); if (lastSeparatorIndex != -1) { return getClass(classLoader, className.substring(0, lastSeparatorIndex) + INNER_CLASS_SEPARATOR_CHAR + className.substring(lastSeparatorIndex + 1)); } throw new IllegalArgumentException("Unable to unmarshall String to Class: " + className); } } /** * Given a readable class name determine the JVM Qualified Name * @param className The name to convert * @return The JVM Qualified representation */ public static String determineQualifiedName(String className) { String readableClassName = StringUtils.removeWhitespace(className); if (readableClassName == null) { throw new IllegalArgumentException("readableClassName must not be null."); } else if (readableClassName.endsWith("[]")) { StringBuilder classNameBuffer = new StringBuilder(); while (readableClassName.endsWith("[]")) { readableClassName = readableClassName.substring(0, readableClassName.length() - 2); classNameBuffer.append("["); } String abbreviation = PRIMITIVE_MAPPING.get(readableClassName); if (abbreviation == null) { classNameBuffer.append("L").append(readableClassName).append(";"); } else { classNameBuffer.append(abbreviation); } readableClassName = classNameBuffer.toString(); } return readableClassName; } /** * Given a JVM Qualified Name produce a readable classname * @param qualifiedName The Qualified Name * @return The readable classname */ public static String determineReadableClassName(String qualifiedName) { String readableClassName = StringUtils.removeWhitespace(qualifiedName); if (readableClassName == null) { throw new IllegalArgumentException("qualifiedName must not be null."); } else if (readableClassName.startsWith("[")) { StringBuilder classNameBuffer = new StringBuilder(); while (readableClassName.startsWith("[")) { classNameBuffer.append("[]"); readableClassName = readableClassName.substring(1); } if (PRIMITIVE_MAPPING.containsValue(readableClassName)) { for (Map.Entry<String,String> next : PRIMITIVE_MAPPING.entrySet()) { if (next.getValue().equals(readableClassName)) { readableClassName = next.getKey() + classNameBuffer.toString(); break; } } } else if (readableClassName.startsWith("L") && readableClassName.endsWith(";")) { readableClassName = readableClassName.substring(1, readableClassName.length() - 1) + classNameBuffer.toString(); } else { throw new IllegalArgumentException("qualifiedName was invalid {" + readableClassName + "}"); } } else if (readableClassName.endsWith("]")) { throw new IllegalArgumentException("qualifiedName was invalid {" + readableClassName + "}"); } return readableClassName; } }