All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javabits.yar.Ids Maven / Gradle / Ivy

There is a newer version: 3.0.1.RELEASE
Show newest version
package org.javabits.yar;

import com.google.common.reflect.TypeToken;

import javax.annotation.Nullable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import static java.util.Objects.requireNonNull;
import static org.javabits.yar.Annotations.checkRuntimeRetention;

/**
 * This class provides utility methods to construct and deal with {@link Id}.
 * This class provide 3 main ways to build {@code Id}:
 * 
    *
  • from {@code Class}
  • *
  • from {@code TypeToken}
  • *
  • from {@code Type}
  • *
* As follow: *

Class based construction:

*
 *     Ids.newId(MyInterface.class);
 *     Ids.newId(MyInterface.class, MyAnnotation.class);
 *     Ids.newId(MyInterface.class, Names.named("my-name"));
 * 
*

TypeToken based construction:

*
 *     Ids.newId(new TypeToken>(){});
 *     Ids.newId(new TypeToken>(){}, MyAnnotation.class);
 *     Ids.newId(new TypeToken>(){}, Names.named("my-name"));
 * 
*

Type based construction

*
 *     Ids.newId(aMethod.getGenericParameterTypes()[0]);
 *     Ids.newId(aMethod.getGenericParameterTypes()[0], MyAnnotation.class);
 *     Ids.newId(aMethod.getGenericParameterTypes()[0], Names.named("my-name"));
 * 
* * @author Romain Gilles */ public final class Ids { private Ids() { throw new AssertionError("Not for you!"); } /** * Returns a new {@link Id} for the given type. * * @param type the {@code Type} from which the {@code Id} must be constructed. * @param the type of the Id. * @return an new {@code Id} based on the given type. */ public static Id newId(final Class type) { return newId(TypeToken.of(type)); } /** * Returns a new {@link Id} which represents the {@code type} qualified by * the {@code annotationClass}. * * @param type the type to which the new id has to be associated. * @param annotationClass the qualifying annotation type. * @param the type of the id. * @return an new {@code Id} based on the given type and annotation type. */ public static Id newId(final Class type, final Class annotationClass) { return newId(TypeToken.of(type), annotationClass); } /** * Returns a new {@link Id} which represents the {@code type} qualified by * the {@code annotation} instance. * * @param type the type to which the new id has to be associated. * @param annotation the qualifying annotation. * @param the type of the id. * @return an new {@code Id} based on the given type and annotation. */ public static Id newId(final Class type, final Annotation annotation) { return newId(TypeToken.of(type), annotation); } /** * Returns a new {@link Id} which represents the {@code type}. * * @param type the type to which the new id has to be associated. * @param the type of the id. * @return an new {@code Id} based on the given type. */ public static Id newId(final TypeToken type) { return IdImpl.newId(type); } /** * Returns a new {@link Id} which represents the {@code type} qualified by * the {@code annotationClass}. * * @param type the type to which the new id has to be associated. * @param annotationClass the qualifying annotation type. * @param the type of the id. * @return an new {@code Id} based on the given type and annotation type. */ public static Id newId(final TypeToken type, final Class annotationClass) { return IdImpl.newId(type, annotationClass); } /** * Returns a new {@link Id} which represents the {@code type} qualified by * the {@code annotation} instance. * * @param type the type to which the new id has to be associated. * @param annotation the qualifying annotation. * @param the type of the id. * @return an new {@code Id} based on the given type and annotation. */ public static Id newId(final TypeToken type, final Annotation annotation) { return IdImpl.newId(type, annotation); } /** * Returns a new {@link Id} which represents the {@code type}. * * @param type the type to which the new id has to be associated. * @return an new {@code Id} based on the given type. */ public static Id newId(final Type type) { return newId(TypeToken.of(type)); } /** * Returns a new {@link Id} which represents the {@code type} qualified by * the {@code annotationClass}. * * @param type the type to which the new id has to be associated. * @param annotationClass the qualifying annotation type. * @return an new {@code Id} based on the given type and annotation type. */ public static Id newId(final Type type, final Class annotationClass) { return newId(TypeToken.of(type), annotationClass); } /** * Returns a new {@link Id} which represents the {@code type} qualified by * the {@code annotation} instance. * * @param type the type to which the new id has to be associated. * @param annotation the qualifying annotation. * @return an new {@code Id} based on the given type and annotation. */ public static Id newId(final Type type, final Annotation annotation) { return newId(TypeToken.of(type), annotation); } static final class IdImpl implements Id { private final TypeToken typeToken; private final AnnotationStrategy annotationStrategy; private final int hashCode; private IdImpl(TypeToken typeToken, AnnotationStrategy annotationStrategy) { this.typeToken = requireNonNull(typeToken, "typeToken"); this.annotationStrategy = requireNonNull(annotationStrategy, "annotationStrategy"); this.hashCode = computeHashCode(typeToken, annotationStrategy); } private static Id newId(final TypeToken type) { return new IdImpl<>(type, AbstractAnnotationStrategy.NULL_STRATEGY); } private static Id newId(final TypeToken type, final Class annotationClass) { return new IdImpl<>(type, AbstractAnnotationStrategy.strategyFor(annotationClass)); } private static Id newId(final TypeToken type, final Annotation annotation) { return new IdImpl<>(type, AbstractAnnotationStrategy.strategyFor(annotation)); } @Override public Type type() { return typeToken.getType(); } @Override public Class annotationType() { return annotationStrategy.getAnnotationType(); } @Override public Annotation annotation() { return annotationStrategy.getAnnotation(); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; IdImpl id = (IdImpl) o; return annotationStrategy.equals(id.annotationStrategy) && typeToken.equals(id.typeToken); } @Override public int hashCode() { return hashCode; } private int computeHashCode(TypeToken typeToken, AnnotationStrategy annotationStrategy) { int result = requireNonNull(typeToken, "typeToken").hashCode(); result = 31 * result + requireNonNull(annotationStrategy, "annotationStrategy").hashCode(); return result; } @Override public String toString() { return "Key[type=" + typeToken + ", annotation=" + annotationStrategy + "]"; } static interface AnnotationStrategy { @Nullable Annotation getAnnotation(); @Nullable Class getAnnotationType(); @Override public int hashCode(); @Override public boolean equals(Object o); } static abstract class AbstractAnnotationStrategy implements AnnotationStrategy { static final AnnotationStrategy NULL_STRATEGY = new NullAnnotationStrategy(); static AnnotationStrategy strategyFor(Class annotationClass) { return new TypeAnnotationStrategy(annotationClass); } public static AnnotationStrategy strategyFor(Annotation annotation) { if (Annotations.isMarker(annotation)) { return new TypeAnnotationStrategy(annotation.annotationType()); } return new InstanceAnnotationStrategy(annotation); } } static final class NullAnnotationStrategy extends AbstractAnnotationStrategy { NullAnnotationStrategy() { } @Nullable @Override public Annotation getAnnotation() { return null; } @Override public Class getAnnotationType() { return null; } @Override public String toString() { return "[none]"; } } static final class TypeAnnotationStrategy extends AbstractAnnotationStrategy { private final Class annotationClass; TypeAnnotationStrategy(Class annotationClass) { this.annotationClass = checkRuntimeRetention(annotationClass, "annotationClass"); } @Override public Annotation getAnnotation() { return null; } @Override public Class getAnnotationType() { return annotationClass; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; TypeAnnotationStrategy that = (TypeAnnotationStrategy) o; return annotationClass.equals(that.annotationClass); } @Override public int hashCode() { return annotationClass.hashCode(); } @Override public String toString() { return "@" + annotationClass.toString(); } } static final class InstanceAnnotationStrategy extends AbstractAnnotationStrategy { private final Annotation annotation; InstanceAnnotationStrategy(Annotation annotation) { this.annotation = annotation; } @Nullable @Override public Annotation getAnnotation() { return annotation; } @Override public Class getAnnotationType() { return annotation.annotationType(); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; InstanceAnnotationStrategy that = (InstanceAnnotationStrategy) o; return annotation.equals(that.annotation); } @Override public int hashCode() { return annotation.hashCode(); } @Override public String toString() { return annotation.toString(); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy