This example Java source code file (Annotations.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.
/**
* Copyright (C) 2006 Google Inc.
*
* 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 com.google.inject.internal;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Joiner.MapJoiner;
import com.google.common.base.Preconditions;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.inject.BindingAnnotation;
import com.google.inject.Key;
import com.google.inject.ScopeAnnotation;
import com.google.inject.TypeLiteral;
import com.google.inject.internal.util.Classes;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import javax.inject.Qualifier;
/**
* Annotation utilities.
*
* @author crazybob@google.com (Bob Lee)
*/
public class Annotations {
/**
* Returns {@code true} if the given annotation type has no attributes.
*/
public static boolean isMarker(Class<? extends Annotation> annotationType) {
return annotationType.getDeclaredMethods().length == 0;
}
public static boolean isAllDefaultMethods(Class<? extends Annotation> annotationType) {
boolean hasMethods = false;
for (Method m : annotationType.getDeclaredMethods()) {
hasMethods = true;
if (m.getDefaultValue() == null) {
return false;
}
}
return hasMethods;
}
private static final LoadingCache<Class cache =
CacheBuilder.newBuilder().weakKeys().build(
new CacheLoader<Class() {
@Override
public Annotation load(Class<? extends Annotation> input) {
return generateAnnotationImpl(input);
}
});
/**
* Generates an Annotation for the annotation class. Requires that the annotation is all
* optionals.
*/
public static <T extends Annotation> T generateAnnotation(Class annotationType) {
Preconditions.checkState(
isAllDefaultMethods(annotationType), "%s is not all default methods", annotationType);
return (T)cache.getUnchecked(annotationType);
}
private static <T extends Annotation> T generateAnnotationImpl(final Class annotationType) {
final Map<String, Object> members = resolveMembers(annotationType);
return annotationType.cast(Proxy.newProxyInstance(
annotationType.getClassLoader(),
new Class<?>[] { annotationType },
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
String name = method.getName();
if (name.equals("annotationType")) {
return annotationType;
} else if (name.equals("toString")) {
return annotationToString(annotationType, members);
} else if (name.equals("hashCode")) {
return annotationHashCode(annotationType, members);
} else if (name.equals("equals")) {
return annotationEquals(annotationType, members, args[0]);
} else {
return members.get(name);
}
}
}));
}
private static ImmutableMap<String, Object> resolveMembers(
Class<? extends Annotation> annotationType) {
ImmutableMap.Builder<String, Object> result = ImmutableMap.builder();
for (Method method : annotationType.getDeclaredMethods()) {
result.put(method.getName(), method.getDefaultValue());
}
return result.build();
}
/** Implements {@link Annotation#equals}. */
private static boolean annotationEquals(Class<? extends Annotation> type,
Map<String, Object> members, Object other) throws Exception {
if (!type.isInstance(other)) {
return false;
}
for (Method method : type.getDeclaredMethods()) {
String name = method.getName();
if (!Arrays.deepEquals(
new Object[] {method.invoke(other)}, new Object[] {members.get(name)})) {
return false;
}
}
return true;
}
/** Implements {@link Annotation#hashCode}. */
private static int annotationHashCode(Class<? extends Annotation> type,
Map<String, Object> members) throws Exception {
int result = 0;
for (Method method : type.getDeclaredMethods()) {
String name = method.getName();
Object value = members.get(name);
result += (127 * name.hashCode()) ^ (Arrays.deepHashCode(new Object[] {value}) - 31);
}
return result;
}
private static final MapJoiner JOINER = Joiner.on(", ").withKeyValueSeparator("=");
private static final Function<Object, String> DEEP_TO_STRING_FN = new Function
Other Java examples (source code examples)
Here is a short list of links related to this Java Annotations.java source code file: