alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  
* <tr> * <tr> * <tr> * <tr> * </table> * @param className the className to get the abbreviated name for, may be {@code null} * @param len the desired length of the abbreviated name * @return the abbreviated name or an empty string * @throws IllegalArgumentException if len <= 0 * @since 3.4 */ public static String getAbbreviatedName(String className, int len) { if (len <= 0) { throw new IllegalArgumentException("len must be > 0"); } if (className == null) { return StringUtils.EMPTY; } int availableSpace = len; int packageLevels = StringUtils.countMatches(className, '.'); String[] output = new String[packageLevels + 1]; int endIndex = className.length() - 1; for (int level = packageLevels; level >= 0; level--) { int startIndex = className.lastIndexOf('.', endIndex); String part = className.substring(startIndex + 1, endIndex + 1); availableSpace -= part.length(); if (level > 0) { // all elements except top level require an additional char space availableSpace--; } if (level == packageLevels) { // ClassName is always complete output[level] = part; } else { if (availableSpace > 0) { output[level] = part; } else { // if no space is left still the first char is used output[level] = part.substring(0, 1); } } endIndex = startIndex - 1; } return StringUtils.join(output, '.'); } // Superclasses/Superinterfaces // ---------------------------------------------------------------------- /** * <p>Gets a {@code List} of superclasses for the given class.

* * @param cls the class to look up, may be {@code null} * @return the {@code List} of superclasses in order going up from this one * {@code null} if null input */ public static List<Class getAllSuperclasses(final Class cls) { if (cls == null) { return null; } final List<Class classes = new ArrayList>(); Class<?> superclass = cls.getSuperclass(); while (superclass != null) { classes.add(superclass); superclass = superclass.getSuperclass(); } return classes; } /** * <p>Gets a {@code List} of all interfaces implemented by the given * class and its superclasses.</p> * * <p>The order is determined by looking through each interface in turn as * declared in the source file and following its hierarchy up. Then each * superclass is considered in the same way. Later duplicates are ignored, * so the order is maintained.</p> * * @param cls the class to look up, may be {@code null} * @return the {@code List} of interfaces in order, * {@code null} if null input */ public static List<Class getAllInterfaces(final Class cls) { if (cls == null) { return null; } final LinkedHashSet<Class interfacesFound = new LinkedHashSet>(); getAllInterfaces(cls, interfacesFound); return new ArrayList<Class(interfacesFound); } /** * Get the interfaces for the specified class. * * @param cls the class to look up, may be {@code null} * @param interfacesFound the {@code Set} of interfaces for the class */ private static void getAllInterfaces(Class<?> cls, final HashSet> interfacesFound) { while (cls != null) { final Class<?>[] interfaces = cls.getInterfaces(); for (final Class<?> i : interfaces) { if (interfacesFound.add(i)) { getAllInterfaces(i, interfacesFound); } } cls = cls.getSuperclass(); } } // Convert list // ---------------------------------------------------------------------- /** * <p>Given a {@code List} of class names, this method converts them into classes.

* * <p>A new {@code List} is returned. If the class name cannot be found, {@code null} * is stored in the {@code List}. If the class name in the {@code List} is * {@code null}, {@code null} is stored in the output {@code List}.</p> * * @param classNames the classNames to change * @return a {@code List} of Class objects corresponding to the class names, * {@code null} if null input * @throws ClassCastException if classNames contains a non String entry */ public static List<Class convertClassNamesToClasses(final List classNames) { if (classNames == null) { return null; } final List<Class classes = new ArrayList>(classNames.size()); for (final String className : classNames) { try { classes.add(Class.forName(className)); } catch (final Exception ex) { classes.add(null); } } return classes; } /** * <p>Given a {@code List} of {@code Class} objects, this method converts * them into class names.</p> * * <p>A new {@code List} is returned. {@code null} objects will be copied into * the returned list as {@code null}.</p> * * @param classes the classes to change * @return a {@code List} of class names corresponding to the Class objects, * {@code null} if null input * @throws ClassCastException if {@code classes} contains a non-{@code Class} entry */ public static List<String> convertClassesToClassNames(final List> classes) { if (classes == null) { return null; } final List<String> classNames = new ArrayList(classes.size()); for (final Class<?> cls : classes) { if (cls == null) { classNames.add(null); } else { classNames.add(cls.getName()); } } return classNames; } // Is assignable // ---------------------------------------------------------------------- /** * <p>Checks if an array of Classes can be assigned to another array of Classes.

* * <p>This method calls {@link #isAssignable(Class, Class) isAssignable} for each * Class pair in the input arrays. It can be used to check if a set of arguments * (the first parameter) are suitably compatible with a set of method parameter types * (the second parameter).</p> * * <p>Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, this * method takes into account widenings of primitive classes and * {@code null}s.</p> * * <p>Primitive widenings allow an int to be assigned to a {@code long}, * {@code float} or {@code double}. This method returns the correct * result for these cases.</p> * * <p>{@code Null} may be assigned to any reference type. This method will * return {@code true} if {@code null} is passed in and the toClass is * non-primitive.</p> * * <p>Specifically, this method tests whether the type represented by the * specified {@code Class} parameter can be converted to the type * represented by this {@code Class} object via an identity conversion * widening primitive or widening reference conversion. See * <em>The Java Language Specification, * sections 5.1.1, 5.1.2 and 5.1.4 for details.</p> * * <p>Since Lang 3.0, this method will default behavior for * calculating assignability between primitive and wrapper types <em>corresponding * to the running Java version</em>; i.e. autoboxing will be the default * behavior in VMs running Java versions > 1.5.</p> * * @param classArray the array of Classes to check, may be {@code null} * @param toClassArray the array of Classes to try to assign into, may be {@code null} * @return {@code true} if assignment possible */ public static boolean isAssignable(final Class<?>[] classArray, final Class... toClassArray) { return isAssignable(classArray, toClassArray, SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_5)); } /** * <p>Checks if an array of Classes can be assigned to another array of Classes.

* * <p>This method calls {@link #isAssignable(Class, Class) isAssignable} for each * Class pair in the input arrays. It can be used to check if a set of arguments * (the first parameter) are suitably compatible with a set of method parameter types * (the second parameter).</p> * * <p>Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, this * method takes into account widenings of primitive classes and * {@code null}s.</p> * * <p>Primitive widenings allow an int to be assigned to a {@code long}, * {@code float} or {@code double}. This method returns the correct * result for these cases.</p> * * <p>{@code Null} may be assigned to any reference type. This method will * return {@code true} if {@code null} is passed in and the toClass is * non-primitive.</p> * * <p>Specifically, this method tests whether the type represented by the * specified {@code Class} parameter can be converted to the type * represented by this {@code Class} object via an identity conversion * widening primitive or widening reference conversion. See * <em>The Java Language Specification, * sections 5.1.1, 5.1.2 and 5.1.4 for details.</p> * * @param classArray the array of Classes to check, may be {@code null} * @param toClassArray the array of Classes to try to assign into, may be {@code null} * @param autoboxing whether to use implicit autoboxing/unboxing between primitives and wrappers * @return {@code true} if assignment possible */ public static boolean isAssignable(Class<?>[] classArray, Class[] toClassArray, final boolean autoboxing) { if (ArrayUtils.isSameLength(classArray, toClassArray) == false) { return false; } if (classArray == null) { classArray = ArrayUtils.EMPTY_CLASS_ARRAY; } if (toClassArray == null) { toClassArray = ArrayUtils.EMPTY_CLASS_ARRAY; } for (int i = 0; i < classArray.length; i++) { if (isAssignable(classArray[i], toClassArray[i], autoboxing) == false) { return false; } } return true; } /** * Returns whether the given {@code type} is a primitive or primitive wrapper ({@link Boolean}, {@link Byte}, {@link Character}, * {@link Short}, {@link Integer}, {@link Long}, {@link Double}, {@link Float}). * * @param type * The class to query or null. * @return true if the given {@code type} is a primitive or primitive wrapper ({@link Boolean}, {@link Byte}, {@link Character}, * {@link Short}, {@link Integer}, {@link Long}, {@link Double}, {@link Float}). * @since 3.1 */ public static boolean isPrimitiveOrWrapper(final Class<?> type) { if (type == null) { return false; } return type.isPrimitive() || isPrimitiveWrapper(type); } /** * Returns whether the given {@code type} is a primitive wrapper ({@link Boolean}, {@link Byte}, {@link Character}, {@link Short}, * {@link Integer}, {@link Long}, {@link Double}, {@link Float}). * * @param type * The class to query or null. * @return true if the given {@code type} is a primitive wrapper ({@link Boolean}, {@link Byte}, {@link Character}, {@link Short}, * {@link Integer}, {@link Long}, {@link Double}, {@link Float}). * @since 3.1 */ public static boolean isPrimitiveWrapper(final Class<?> type) { return wrapperPrimitiveMap.containsKey(type); } /** * <p>Checks if one {@code Class} can be assigned to a variable of * another {@code Class}.</p> * * <p>Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, * this method takes into account widenings of primitive classes and * {@code null}s.</p> * * <p>Primitive widenings allow an int to be assigned to a long, float or * double. This method returns the correct result for these cases.</p> * * <p>{@code Null} may be assigned to any reference type. This method * will return {@code true} if {@code null} is passed in and the * toClass is non-primitive.</p> * * <p>Specifically, this method tests whether the type represented by the * specified {@code Class} parameter can be converted to the type * represented by this {@code Class} object via an identity conversion * widening primitive or widening reference conversion. See * <em>The Java Language Specification, * sections 5.1.1, 5.1.2 and 5.1.4 for details.</p> * * <p>Since Lang 3.0, this method will default behavior for * calculating assignability between primitive and wrapper types <em>corresponding * to the running Java version</em>; i.e. autoboxing will be the default * behavior in VMs running Java versions > 1.5.</p> * * @param cls the Class to check, may be null * @param toClass the Class to try to assign into, returns false if null * @return {@code true} if assignment possible */ public static boolean isAssignable(final Class<?> cls, final Class toClass) { return isAssignable(cls, toClass, SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_5)); } /** * <p>Checks if one {@code Class} can be assigned to a variable of * another {@code Class}.</p> * * <p>Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, * this method takes into account widenings of primitive classes and * {@code null}s.</p> * * <p>Primitive widenings allow an int to be assigned to a long, float or * double. This method returns the correct result for these cases.</p> * * <p>{@code Null} may be assigned to any reference type. This method * will return {@code true} if {@code null} is passed in and the * toClass is non-primitive.</p> * * <p>Specifically, this method tests whether the type represented by the * specified {@code Class} parameter can be converted to the type * represented by this {@code Class} object via an identity conversion * widening primitive or widening reference conversion. See * <em>The Java Language Specification, * sections 5.1.1, 5.1.2 and 5.1.4 for details.</p> * * @param cls the Class to check, may be null * @param toClass the Class to try to assign into, returns false if null * @param autoboxing whether to use implicit autoboxing/unboxing between primitives and wrappers * @return {@code true} if assignment possible */ public static boolean isAssignable(Class<?> cls, final Class toClass, final boolean autoboxing) { if (toClass == null) { return false; } // have to check for null, as isAssignableFrom doesn't if (cls == null) { return !toClass.isPrimitive(); } //autoboxing: if (autoboxing) { if (cls.isPrimitive() && !toClass.isPrimitive()) { cls = primitiveToWrapper(cls); if (cls == null) { return false; } } if (toClass.isPrimitive() && !cls.isPrimitive()) { cls = wrapperToPrimitive(cls); if (cls == null) { return false; } } } if (cls.equals(toClass)) { return true; } if (cls.isPrimitive()) { if (toClass.isPrimitive() == false) { return false; } if (Integer.TYPE.equals(cls)) { return Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); } if (Long.TYPE.equals(cls)) { return Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); } if (Boolean.TYPE.equals(cls)) { return false; } if (Double.TYPE.equals(cls)) { return false; } if (Float.TYPE.equals(cls)) { return Double.TYPE.equals(toClass); } if (Character.TYPE.equals(cls)) { return Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); } if (Short.TYPE.equals(cls)) { return Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); } if (Byte.TYPE.equals(cls)) { return Short.TYPE.equals(toClass) || Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); } // should never get here return false; } return toClass.isAssignableFrom(cls); } /** * <p>Converts the specified primitive Class object to its corresponding * wrapper Class object.</p> * * <p>NOTE: From v2.2, this method handles {@code Void.TYPE}, * returning {@code Void.TYPE}.</p> * * @param cls the class to convert, may be null * @return the wrapper class for {@code cls} or {@code cls} if * {@code cls} is not a primitive. {@code null} if null input. * @since 2.1 */ public static Class<?> primitiveToWrapper(final Class cls) { Class<?> convertedClass = cls; if (cls != null && cls.isPrimitive()) { convertedClass = primitiveWrapperMap.get(cls); } return convertedClass; } /** * <p>Converts the specified array of primitive Class objects to an array of * its corresponding wrapper Class objects.</p> * * @param classes the class array to convert, may be null or empty * @return an array which contains for each given class, the wrapper class or * the original class if class is not a primitive. {@code null} if null input. * Empty array if an empty array passed in. * @since 2.1 */ public static Class<?>[] primitivesToWrappers(final Class... classes) { if (classes == null) { return null; } if (classes.length == 0) { return classes; } final Class<?>[] convertedClasses = new Class[classes.length]; for (int i = 0; i < classes.length; i++) { convertedClasses[i] = primitiveToWrapper(classes[i]); } return convertedClasses; } /** * <p>Converts the specified wrapper class to its corresponding primitive * class.</p> * * <p>This method is the counter part of {@code primitiveToWrapper()}. * If the passed in class is a wrapper class for a primitive type, this * primitive type will be returned (e.g. {@code Integer.TYPE} for * {@code Integer.class}). For other classes, or if the parameter is * <b>null, the return value is null.

* * @param cls the class to convert, may be <b>null * @return the corresponding primitive type if {@code cls} is a * wrapper class, <b>null otherwise * @see #primitiveToWrapper(Class) * @since 2.4 */ public static Class<?> wrapperToPrimitive(final Class cls) { return wrapperPrimitiveMap.get(cls); } /** * <p>Converts the specified array of wrapper Class objects to an array of * its corresponding primitive Class objects.</p> * * <p>This method invokes {@code wrapperToPrimitive()} for each element * of the passed in array.</p> * * @param classes the class array to convert, may be null or empty * @return an array which contains for each given class, the primitive class or * <b>null if the original class is not a wrapper class. {@code null} if null input. * Empty array if an empty array passed in. * @see #wrapperToPrimitive(Class) * @since 2.4 */ public static Class<?>[] wrappersToPrimitives(final Class... classes) { if (classes == null) { return null; } if (classes.length == 0) { return classes; } final Class<?>[] convertedClasses = new Class[classes.length]; for (int i = 0; i < classes.length; i++) { convertedClasses[i] = wrapperToPrimitive(classes[i]); } return convertedClasses; } // Inner class // ---------------------------------------------------------------------- /** * <p>Is the specified class an inner class or static nested class.

* * @param cls the class to check, may be null * @return {@code true} if the class is an inner or static nested class, * false if not or {@code null} */ public static boolean isInnerClass(final Class<?> cls) { return cls != null && cls.getEnclosingClass() != null; } // Class loading // ---------------------------------------------------------------------- /** * Returns the class represented by {@code className} using the * {@code classLoader}. This implementation supports the syntaxes * "{@code java.util.Map.Entry[]}", "{@code java.util.Map$Entry[]}", * "{@code [Ljava.util.Map.Entry;}", and "{@code [Ljava.util.Map$Entry;}". * * @param classLoader the class loader to use to load the class * @param className the class name * @param initialize whether the class must be initialized * @return the class represented by {@code className} using the {@code classLoader} * @throws ClassNotFoundException if the class is not found */ public static Class<?> getClass( final ClassLoader classLoader, final String className, final boolean initialize) throws ClassNotFoundException { try { Class<?> clazz; if (abbreviationMap.containsKey(className)) { final String clsName = "[" + abbreviationMap.get(className); clazz = Class.forName(clsName, initialize, classLoader).getComponentType(); } else { clazz = Class.forName(toCanonicalName(className), initialize, classLoader); } return clazz; } catch (final ClassNotFoundException ex) { // allow path separators (.) as inner class name separators final int lastDotIndex = className.lastIndexOf(PACKAGE_SEPARATOR_CHAR); if (lastDotIndex != -1) { try { return getClass(classLoader, className.substring(0, lastDotIndex) + INNER_CLASS_SEPARATOR_CHAR + className.substring(lastDotIndex + 1), initialize); } catch (final ClassNotFoundException ex2) { // NOPMD // ignore exception } } throw ex; } } /** * Returns the (initialized) class represented by {@code className} * using the {@code classLoader}. This implementation supports * the syntaxes "{@code java.util.Map.Entry[]}", * "{@code java.util.Map$Entry[]}", "{@code [Ljava.util.Map.Entry;}", * and "{@code [Ljava.util.Map$Entry;}". * * @param classLoader the class loader to use to load the class * @param className the class name * @return the class represented by {@code className} using the {@code classLoader} * @throws ClassNotFoundException if the class is not found */ public static Class<?> getClass(final ClassLoader classLoader, final String className) throws ClassNotFoundException { return getClass(classLoader, className, true); } /** * Returns the (initialized) class represented by {@code className} * using the current thread's context class loader. This implementation * supports the syntaxes "{@code java.util.Map.Entry[]}", * "{@code java.util.Map$Entry[]}", "{@code [Ljava.util.Map.Entry;}", * and "{@code [Ljava.util.Map$Entry;}". * * @param className the class name * @return the class represented by {@code className} using the current thread's context class loader * @throws ClassNotFoundException if the class is not found */ public static Class<?> getClass(final String className) throws ClassNotFoundException { return getClass(className, true); } /** * Returns the class represented by {@code className} using the * current thread's context class loader. This implementation supports the * syntaxes "{@code java.util.Map.Entry[]}", "{@code java.util.Map$Entry[]}", * "{@code [Ljava.util.Map.Entry;}", and "{@code [Ljava.util.Map$Entry;}". * * @param className the class name * @param initialize whether the class must be initialized * @return the class represented by {@code className} using the current thread's context class loader * @throws ClassNotFoundException if the class is not found */ public static Class<?> getClass(final String className, final boolean initialize) throws ClassNotFoundException { final ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); final ClassLoader loader = contextCL == null ? ClassUtils.class.getClassLoader() : contextCL; return getClass(loader, className, initialize); } // Public method // ---------------------------------------------------------------------- /** * <p>Returns the desired Method much like {@code Class.getMethod}, however * it ensures that the returned Method is from a public class or interface and not * from an anonymous inner class. This means that the Method is invokable and * doesn't fall foul of Java bug * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957">4071957).

* * <pre> * <code>Set set = Collections.unmodifiableSet(...); * Method method = ClassUtils.getPublicMethod(set.getClass(), "isEmpty", new Class[0]); * Object result = method.invoke(set, new Object[]);</code> * </pre> * * @param cls the class to check, not null * @param methodName the name of the method * @param parameterTypes the list of parameters * @return the method * @throws NullPointerException if the class is null * @throws SecurityException if a security violation occurred * @throws NoSuchMethodException if the method is not found in the given class * or if the method doesn't conform with the requirements */ public static Method getPublicMethod(final Class<?> cls, final String methodName, final Class... parameterTypes) throws SecurityException, NoSuchMethodException { final Method declaredMethod = cls.getMethod(methodName, parameterTypes); if (Modifier.isPublic(declaredMethod.getDeclaringClass().getModifiers())) { return declaredMethod; } final List<Class candidateClasses = new ArrayList>(); candidateClasses.addAll(getAllInterfaces(cls)); candidateClasses.addAll(getAllSuperclasses(cls)); for (final Class<?> candidateClass : candidateClasses) { if (!Modifier.isPublic(candidateClass.getModifiers())) { continue; } Method candidateMethod; try { candidateMethod = candidateClass.getMethod(methodName, parameterTypes); } catch (final NoSuchMethodException ex) { continue; } if (Modifier.isPublic(candidateMethod.getDeclaringClass().getModifiers())) { return candidateMethod; } } throw new NoSuchMethodException("Can't find a public method for " + methodName + " " + ArrayUtils.toString(parameterTypes)); } // ---------------------------------------------------------------------- /** * Converts a class name to a JLS style class name. * * @param className the class name * @return the converted name */ private static String toCanonicalName(String className) { className = StringUtils.deleteWhitespace(className); if (className == null) { throw new NullPointerException("className must not be null."); } else if (className.endsWith("[]")) { final StringBuilder classNameBuffer = new StringBuilder(); while (className.endsWith("[]")) { className = className.substring(0, className.length() - 2); classNameBuffer.append("["); } final String abbreviation = abbreviationMap.get(className); if (abbreviation != null) { classNameBuffer.append(abbreviation); } else { classNameBuffer.append("L").append(className).append(";"); } className = classNameBuffer.toString(); } return className; } /** * <p>Converts an array of {@code Object} in to an array of {@code Class} objects. * If any of these objects is null, a null element will be inserted into the array.</p> * * <p>This method returns {@code null} for a {@code null} input array.

* * @param array an {@code Object} array * @return a {@code Class} array, {@code null} if null array input * @since 2.4 */ public static Class<?>[] toClass(final Object... array) { if (array == null) { return null; } else if (array.length == 0) { return ArrayUtils.EMPTY_CLASS_ARRAY; } final Class<?>[] classes = new Class[array.length]; for (int i = 0; i < array.length; i++) { classes[i] = array[i] == null ? null : array[i].getClass(); } return classes; } // Short canonical name // ---------------------------------------------------------------------- /** * <p>Gets the canonical name minus the package name for an {@code Object}.

* * @param object the class to get the short name for, may be null * @param valueIfNull the value to return if null * @return the canonical name of the object without the package name, or the null value * @since 2.4 */ public static String getShortCanonicalName(final Object object, final String valueIfNull) { if (object == null) { return valueIfNull; } return getShortCanonicalName(object.getClass().getName()); } /** * <p>Gets the canonical name minus the package name from a {@code Class}.

* * @param cls the class to get the short name for. * @return the canonical name without the package name or an empty string * @since 2.4 */ public static String getShortCanonicalName(final Class<?> cls) { if (cls == null) { return StringUtils.EMPTY; } return getShortCanonicalName(cls.getName()); } /** * <p>Gets the canonical name minus the package name from a String.

* * <p>The string passed in is assumed to be a canonical name - it is not checked.

* * @param canonicalName the class name to get the short name for * @return the canonical name of the class without the package name or an empty string * @since 2.4 */ public static String getShortCanonicalName(final String canonicalName) { return ClassUtils.getShortClassName(getCanonicalName(canonicalName)); } // Package name // ---------------------------------------------------------------------- /** * <p>Gets the package name from the canonical name of an {@code Object}.

* * @param object the class to get the package name for, may be null * @param valueIfNull the value to return if null * @return the package name of the object, or the null value * @since 2.4 */ public static String getPackageCanonicalName(final Object object, final String valueIfNull) { if (object == null) { return valueIfNull; } return getPackageCanonicalName(object.getClass().getName()); } /** * <p>Gets the package name from the canonical name of a {@code Class}.

* * @param cls the class to get the package name for, may be {@code null}. * @return the package name or an empty string * @since 2.4 */ public static String getPackageCanonicalName(final Class<?> cls) { if (cls == null) { return StringUtils.EMPTY; } return getPackageCanonicalName(cls.getName()); } /** * <p>Gets the package name from the canonical name.

* * <p>The string passed in is assumed to be a canonical name - it is not checked.

* <p>If the class is unpackaged, return an empty string.

* * @param canonicalName the canonical name to get the package name for, may be {@code null} * @return the package name or an empty string * @since 2.4 */ public static String getPackageCanonicalName(final String canonicalName) { return ClassUtils.getPackageName(getCanonicalName(canonicalName)); } /** * <p>Converts a given name of class into canonical format. * If name of class is not a name of array class it returns * unchanged name.</p> * <p>Example: * <ul> * <li>{@code getCanonicalName("[I") = "int[]"} * <li>{@code getCanonicalName("[Ljava.lang.String;") = "java.lang.String[]"} * <li>{@code getCanonicalName("java.lang.String") = "java.lang.String"} * </ul> * </p> * * @param className the name of class * @return canonical form of class name * @since 2.4 */ private static String getCanonicalName(String className) { className = StringUtils.deleteWhitespace(className); if (className == null) { return null; } int dim = 0; while (className.startsWith("[")) { dim++; className = className.substring(1); } if (dim < 1) { return className; } if (className.startsWith("L")) { className = className.substring( 1, className.endsWith(";") ? className.length() - 1 : className.length()); } else { if (className.length() > 0) { className = reverseAbbreviationMap.get(className.substring(0, 1)); } } final StringBuilder canonicalClassNameBuffer = new StringBuilder(className); for (int i = 0; i < dim; i++) { canonicalClassNameBuffer.append("[]"); } return canonicalClassNameBuffer.toString(); } /** * Get an {@link Iterable} that can iterate over a class hierarchy in ascending (subclass to superclass) order, * excluding interfaces. * * @param type the type to get the class hierarchy from * @return Iterable an Iterable over the class hierarchy of the given class * @since 3.2 */ public static Iterable<Class hierarchy(final Class type) { return hierarchy(type, Interfaces.EXCLUDE); } /** * Get an {@link Iterable} that can iterate over a class hierarchy in ascending (subclass to superclass) order. * * @param type the type to get the class hierarchy from * @param interfacesBehavior switch indicating whether to include or exclude interfaces * @return Iterable an Iterable over the class hierarchy of the given class * @since 3.2 */ public static Iterable<Class hierarchy(final Class type, final Interfaces interfacesBehavior) { final Iterable<Class classes = new Iterable>() { @Override public Iterator<Class iterator() { final MutableObject<Class next = new MutableObject>(type); return new Iterator<Class() { @Override public boolean hasNext() { return next.getValue() != null; } @Override public Class<?> next() { final Class<?> result = next.getValue(); next.setValue(result.getSuperclass()); return result; } @Override public void remove() { throw new UnsupportedOperationException(); } }; } }; if (interfacesBehavior != Interfaces.INCLUDE) { return classes; } return new Iterable<Class() { @Override public Iterator<Class iterator() { final Set<Class seenInterfaces = new HashSet>(); final Iterator<Class wrapped = classes.iterator(); return new Iterator<Class() { Iterator<Class interfaces = Collections.> emptySet().iterator(); @Override public boolean hasNext() { return interfaces.hasNext() || wrapped.hasNext(); } @Override public Class<?> next() { if (interfaces.hasNext()) { final Class<?> nextInterface = interfaces.next(); seenInterfaces.add(nextInterface); return nextInterface; } final Class<?> nextSuperclass = wrapped.next(); final Set<Class currentInterfaces = new LinkedHashSet>(); walkInterfaces(currentInterfaces, nextSuperclass); interfaces = currentInterfaces.iterator(); return nextSuperclass; } private void walkInterfaces(final Set<Class addTo, final Class c) { for (final Class<?> iface : c.getInterfaces()) { if (!seenInterfaces.contains(iface)) { addTo.add(iface); } walkInterfaces(addTo, iface); } } @Override public void remove() { throw new UnsupportedOperationException(); } }; } }; } }

Other Java examples (source code examples)

Here is a short list of links related to this Java ClassUtils.java source code file:

Java example source code file (ClassUtils.java)

This example Java source code file (ClassUtils.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

class, classloader, classnotfoundexception, hashmap, inner_class_separator_char, iterable, iterator, list, map, object, override, reflection, set, string, stringbuilder, util

The ClassUtils.java Java example source code

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.commons.lang3;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.mutable.MutableObject;

/**
 * <p>Operates on classes without using reflection.

* * <p>This class handles invalid {@code null} inputs as best it can. * Each method documents its behaviour in more detail.</p> * * <p>The notion of a {@code canonical name} includes the human * readable name for the type, for example {@code int[]}. The * non-canonical method variants work with the JVM names, such as * {@code [I}. </p> * * @since 2.0 */ public class ClassUtils { /** * Inclusivity literals for {@link #hierarchy(Class, Interfaces)}. * @since 3.2 */ public enum Interfaces { INCLUDE, EXCLUDE } /** * The package separator character: <code>'.' == {@value}. */ public static final char PACKAGE_SEPARATOR_CHAR = '.'; /** * The package separator String: <code>".". */ public static final String PACKAGE_SEPARATOR = String.valueOf(PACKAGE_SEPARATOR_CHAR); /** * The inner class separator character: <code>'$' == {@value}. */ public static final char INNER_CLASS_SEPARATOR_CHAR = '$'; /** * The inner class separator String: {@code "$"}. */ public static final String INNER_CLASS_SEPARATOR = String.valueOf(INNER_CLASS_SEPARATOR_CHAR); /** * Maps primitive {@code Class}es to their corresponding wrapper {@code Class}. */ private static final Map<Class> primitiveWrapperMap = new HashMap, Class>(); static { primitiveWrapperMap.put(Boolean.TYPE, Boolean.class); primitiveWrapperMap.put(Byte.TYPE, Byte.class); primitiveWrapperMap.put(Character.TYPE, Character.class); primitiveWrapperMap.put(Short.TYPE, Short.class); primitiveWrapperMap.put(Integer.TYPE, Integer.class); primitiveWrapperMap.put(Long.TYPE, Long.class); primitiveWrapperMap.put(Double.TYPE, Double.class); primitiveWrapperMap.put(Float.TYPE, Float.class); primitiveWrapperMap.put(Void.TYPE, Void.TYPE); } /** * Maps wrapper {@code Class}es to their corresponding primitive types. */ private static final Map<Class> wrapperPrimitiveMap = new HashMap, Class>(); static { for (final Map.Entry<Class> entry : primitiveWrapperMap.entrySet()) { final Class<?> primitiveClass = entry.getKey(); final Class<?> wrapperClass = entry.getValue(); if (!primitiveClass.equals(wrapperClass)) { wrapperPrimitiveMap.put(wrapperClass, primitiveClass); } } } /** * Maps a primitive class name to its corresponding abbreviation used in array class names. */ private static final Map<String, String> abbreviationMap; /** * Maps an abbreviation used in array class names to corresponding primitive class name. */ private static final Map<String, String> reverseAbbreviationMap; /** * Feed abbreviation maps */ static { final Map<String, String> m = new HashMap(); m.put("int", "I"); m.put("boolean", "Z"); m.put("float", "F"); m.put("long", "J"); m.put("short", "S"); m.put("byte", "B"); m.put("double", "D"); m.put("char", "C"); m.put("void", "V"); final Map<String, String> r = new HashMap(); for (final Map.Entry<String, String> e : m.entrySet()) { r.put(e.getValue(), e.getKey()); } abbreviationMap = Collections.unmodifiableMap(m); reverseAbbreviationMap = Collections.unmodifiableMap(r); } /** * <p>ClassUtils instances should NOT be constructed in standard programming. * Instead, the class should be used as * {@code ClassUtils.getShortClassName(cls)}.</p> * * <p>This constructor is public to permit tools that require a JavaBean * instance to operate.</p> */ public ClassUtils() { super(); } // Short class name // ---------------------------------------------------------------------- /** * <p>Gets the class name minus the package name for an {@code Object}.

* * @param object the class to get the short name for, may be null * @param valueIfNull the value to return if null * @return the class name of the object without the package name, or the null value */ public static String getShortClassName(final Object object, final String valueIfNull) { if (object == null) { return valueIfNull; } return getShortClassName(object.getClass()); } /** * <p>Gets the class name minus the package name from a {@code Class}.

* * <p>Consider using the Java 5 API {@link Class#getSimpleName()} instead. * The one known difference is that this code will return {@code "Map.Entry"} while * the {@code java.lang.Class} variant will simply return {@code "Entry"}. </p> * * @param cls the class to get the short name for. * @return the class name without the package name or an empty string */ public static String getShortClassName(final Class<?> cls) { if (cls == null) { return StringUtils.EMPTY; } return getShortClassName(cls.getName()); } /** * <p>Gets the class name minus the package name from a String.

* * <p>The string passed in is assumed to be a class name - it is not checked.

* <p>Note that this method differs from Class.getSimpleName() in that this will * return {@code "Map.Entry"} whilst the {@code java.lang.Class} variant will simply * return {@code "Entry"}. </p> * * @param className the className to get the short name for * @return the class name of the class without the package name or an empty string */ public static String getShortClassName(String className) { if (StringUtils.isEmpty(className)) { return StringUtils.EMPTY; } final StringBuilder arrayPrefix = new StringBuilder(); // Handle array encoding if (className.startsWith("[")) { while (className.charAt(0) == '[') { className = className.substring(1); arrayPrefix.append("[]"); } // Strip Object type encoding if (className.charAt(0) == 'L' && className.charAt(className.length() - 1) == ';') { className = className.substring(1, className.length() - 1); } if (reverseAbbreviationMap.containsKey(className)) { className = reverseAbbreviationMap.get(className); } } final int lastDotIdx = className.lastIndexOf(PACKAGE_SEPARATOR_CHAR); final int innerIdx = className.indexOf( INNER_CLASS_SEPARATOR_CHAR, lastDotIdx == -1 ? 0 : lastDotIdx + 1); String out = className.substring(lastDotIdx + 1); if (innerIdx != -1) { out = out.replace(INNER_CLASS_SEPARATOR_CHAR, PACKAGE_SEPARATOR_CHAR); } return out + arrayPrefix; } /** * <p>Null-safe version of aClass.getSimpleName()

* * @param cls the class for which to get the simple name. * @return the simple class name. * @since 3.0 * @see Class#getSimpleName() */ public static String getSimpleName(final Class<?> cls) { if (cls == null) { return StringUtils.EMPTY; } return cls.getSimpleName(); } /** * <p>Null-safe version of aClass.getSimpleName()

* * @param object the object for which to get the simple class name. * @param valueIfNull the value to return if <code>object is null * @return the simple class name. * @since 3.0 * @see Class#getSimpleName() */ public static String getSimpleName(final Object object, final String valueIfNull) { if (object == null) { return valueIfNull; } return getSimpleName(object.getClass()); } // Package name // ---------------------------------------------------------------------- /** * <p>Gets the package name of an {@code Object}.

* * @param object the class to get the package name for, may be null * @param valueIfNull the value to return if null * @return the package name of the object, or the null value */ public static String getPackageName(final Object object, final String valueIfNull) { if (object == null) { return valueIfNull; } return getPackageName(object.getClass()); } /** * <p>Gets the package name of a {@code Class}.

* * @param cls the class to get the package name for, may be {@code null}. * @return the package name or an empty string */ public static String getPackageName(final Class<?> cls) { if (cls == null) { return StringUtils.EMPTY; } return getPackageName(cls.getName()); } /** * <p>Gets the package name from a {@code String}.

* * <p>The string passed in is assumed to be a class name - it is not checked.

* <p>If the class is unpackaged, return an empty string.

* * @param className the className to get the package name for, may be {@code null} * @return the package name or an empty string */ public static String getPackageName(String className) { if (StringUtils.isEmpty(className)) { return StringUtils.EMPTY; } // Strip array encoding while (className.charAt(0) == '[') { className = className.substring(1); } // Strip Object type encoding if (className.charAt(0) == 'L' && className.charAt(className.length() - 1) == ';') { className = className.substring(1); } final int i = className.lastIndexOf(PACKAGE_SEPARATOR_CHAR); if (i == -1) { return StringUtils.EMPTY; } return className.substring(0, i); } // Abbreviated name // ---------------------------------------------------------------------- /** * <p>Gets the abbreviated name of a {@code Class}.

* * @param cls the class to get the abbreviated name for, may be {@code null} * @param len the desired length of the abbreviated name * @return the abbreviated name or an empty string * @throws IllegalArgumentException if len <= 0 * @see #getAbbreviatedName(String, int) * @since 3.4 */ public static String getAbbreviatedName(final Class<?> cls, int len) { if (cls == null) { return StringUtils.EMPTY; } return getAbbreviatedName(cls.getName(), len); } /** * <p>Gets the abbreviated class name from a {@code String}.

* * <p>The string passed in is assumed to be a class name - it is not checked.

* * <p>The abbreviation algorithm will shorten the class name, usually without * significant loss of meaning.</p> * <p>The abbreviated class name will always include the complete package hierarchy. * If enough space is available, rightmost sub-packages will be displayed in full * length.</p> * * <p>The following table illustrates the algorithm:

* <table summary="abbreviation examples"> * <tr>
classNamelenreturn
null 1""
"java.lang.String" 5"j.l.String"
"java.lang.String"15"j.lang.String"
"java.lang.String"30"java.lang.String"
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.