Additional Javadoc; Remove IllegalArgumentException from throws clause

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1077892 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stephen Colebourne 2011-03-04 12:03:22 +00:00
parent ef3132ba09
commit ed69b85620
1 changed files with 47 additions and 31 deletions

View File

@ -25,11 +25,20 @@
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
/** /**
* Helper methods for working with {@link Annotation}s. * <p>Helper methods for working with {@link Annotation} instances.</p>
*
* <p>This contains various utility methods that make working with annotations simpler.</p>
*
* <p>#ThreadSafe#</p>
*
* @since 3.0 * @since 3.0
* @version $Id$ * @version $Id$
*/ */
public class AnnotationUtils { public class AnnotationUtils {
/**
* A style that prints annotations as recommended.
*/
private static final ToStringStyle TO_STRING_STYLE = new ToStringStyle() { private static final ToStringStyle TO_STRING_STYLE = new ToStringStyle() {
/** Serialization version */ /** Serialization version */
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -89,14 +98,17 @@ protected void appendDetail(StringBuffer buffer, String fieldName, Object value)
public AnnotationUtils() { public AnnotationUtils() {
} }
//-----------------------------------------------------------------------
/** /**
* Learn whether two annotations are equivalent; dynamically created * <p>Checks if two annotations are equal.</p>
* {@link Annotation} instances are always proxy objects which cannot be *
* depended upon to know how to implement {@link Annotation#equals(Object)} * <p>Dynamically created {@link Annotation} instances are always proxy
* per spec. * objects which cannot be depended upon to know how to implement
* @param a1 the first Annotation to compare * {@link Annotation#equals(Object)} correctly.</p>
* @param a2 the second Annotation to compare *
* @return Whether the two annotations are equal * @param a1 the first Annotation to compare, null returns false unless both are null
* @param a2 the second Annotation to compare, null returns false unless both are null
* @return true if the two annotations are equal or both null
*/ */
public static boolean equals(Annotation a1, Annotation a2) { public static boolean equals(Annotation a1, Annotation a2) {
if (a1 == a2) { if (a1 == a2) {
@ -132,26 +144,26 @@ && isValidAnnotationMemberType(m.getReturnType())) {
} }
/** /**
* Generate a hashcode for the given annotation; dynamically created * <p>Generate a hash code for the given annotation.</p>
* {@link Annotation} instances are always proxy objects which cannot be
* depended upon to know how to implement {@link Annotation#hashCode()} per
* spec.
* *
* @param a the Annotation for a hashcode calculation is desired * <p>Dynamically created {@link Annotation} instances are always proxy
* objects which cannot be depended upon to know how to implement
* {@link Annotation#hashCode()} correctly.</p>
*
* @param a the Annotation for a hash code calculation is desired, not null
* @return the calculated hash code * @return the calculated hash code
* @throws IllegalArgumentException * @throws IllegalAccessException if thrown during annotation access
* @throws IllegalAccessException * @throws InvocationTargetException if thrown during annotation access
* @throws InvocationTargetException
*/ */
public static int hashCode(Annotation a) throws IllegalArgumentException, public static int hashCode(Annotation a)
IllegalAccessException, InvocationTargetException { throws IllegalAccessException, InvocationTargetException {
int result = 0; int result = 0;
Class<? extends Annotation> type = a.annotationType(); Class<? extends Annotation> type = a.annotationType();
for (Method m : type.getDeclaredMethods()) { for (Method m : type.getDeclaredMethods()) {
Object value = m.invoke(a); Object value = m.invoke(a);
if (value == null) { if (value == null) {
throw new IllegalStateException(String.format("Annotation method %s returned null", throw new IllegalStateException(
m)); String.format("Annotation method %s returned null", m));
} }
result += hashMember(m.getName(), value); result += hashMember(m.getName(), value);
} }
@ -159,10 +171,11 @@ public static int hashCode(Annotation a) throws IllegalArgumentException,
} }
/** /**
* Generate a string representation of an Annotation, as suggested by * <p>Generate a string representation of an Annotation, as suggested by
* {@link Annotation#toString()}. * {@link Annotation#toString()}.</p>
*
* @param a the annotation of which a string representation is desired * @param a the annotation of which a string representation is desired
* @return String * @return the standard string representation of an annotation, not null
*/ */
public static String toString(final Annotation a) { public static String toString(final Annotation a) {
ToStringBuilder builder = new ToStringBuilder(a, TO_STRING_STYLE); ToStringBuilder builder = new ToStringBuilder(a, TO_STRING_STYLE);
@ -182,11 +195,14 @@ public static String toString(final Annotation a) {
} }
/** /**
* Learn whether the specified type is permitted as an annotation member. * <p>Checks if the specified type is permitted as an annotation member.</p>
* These include {@link String}, {@link Class}, primitive types, *
* {@link Annotation}s, {@link Enum}s, and arrays of same. * <p>The Java language specification only permits certain types to be used
* @param type to check * in annotations. These include {@link String}, {@link Class}, primitive types,
* @return boolean * {@link Annotation}, {@link Enum}, and arrays of these types.</p>
*
* @param type the type to check, null returns false
* @return true if the type is a valid type to use in an annotation
*/ */
public static boolean isValidAnnotationMemberType(Class<?> type) { public static boolean isValidAnnotationMemberType(Class<?> type) {
if (type == null) { if (type == null) {
@ -200,8 +216,8 @@ public static boolean isValidAnnotationMemberType(Class<?> type) {
} }
//besides modularity, this has the advantage of autoboxing primitives: //besides modularity, this has the advantage of autoboxing primitives:
private static int hashMember(String name, Object value) throws IllegalArgumentException, private static int hashMember(String name, Object value)
IllegalAccessException, InvocationTargetException { throws IllegalAccessException, InvocationTargetException {
int part1 = name.hashCode() * 127; int part1 = name.hashCode() * 127;
if (value.getClass().isArray()) { if (value.getClass().isArray()) {
return part1 ^ arrayMemberHash(value.getClass().getComponentType(), value); return part1 ^ arrayMemberHash(value.getClass().getComponentType(), value);