Skip to content

Commit

Permalink
Allow any level of subclassing of AnnotationLiteral and TypeLiteral
Browse files Browse the repository at this point in the history
git-svn-id: http://anonsvn.jboss.org/repos/weld/ri/trunk@143 1c488680-804c-0410-94cd-c6b725194a0e
  • Loading branch information
pmuir committed Oct 24, 2008
1 parent aca70ff commit 3e050cf
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 75 deletions.
73 changes: 31 additions & 42 deletions webbeans-api/src/main/java/javax/webbeans/AnnotationLiteral.java
Expand Up @@ -28,83 +28,72 @@
*/
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

// TODO Check members for equals, hashCode and toString()
public abstract class AnnotationLiteral<T extends Annotation> implements
Annotation
{

private Class<T> annotationType;

protected AnnotationLiteral()
{
if (!(getClass().getSuperclass() == AnnotationLiteral.class))
Class<?> annotationLiteralSubclass = getAnnotationLiteralSubclass(this.getClass());
if (annotationLiteralSubclass == null)
{
throw new RuntimeException(
"Not a direct subclass of AnnotationLiteral");
throw new RuntimeException(getClass() + "is not a subclass of AnnotationLiteral ");
}
if (!(getClass().getGenericSuperclass() instanceof ParameterizedType))
annotationType = getTypeParameter(annotationLiteralSubclass);
if (annotationType == null)
{
throw new RuntimeException(
"Missing type parameter in AnnotationLiteral");
throw new RuntimeException(getClass() + " is missing type parameter in AnnotationLiteral");

}
}

@SuppressWarnings("unchecked")
private static <T> Class<T> getAnnotationType(Class<?> clazz)
private static Class<?> getAnnotationLiteralSubclass(Class<?> clazz)
{
ParameterizedType parameterized = (ParameterizedType) clazz
.getGenericSuperclass();
return (Class<T>) parameterized.getActualTypeArguments()[0];
Class<?> superclass = clazz.getSuperclass();
if (superclass.equals(AnnotationLiteral.class))
{
return clazz;
}
else if (superclass.equals(Object.class))
{
return null;
}
else
{
return (getAnnotationLiteralSubclass(superclass));
}
}

/*
// Alternative impl of getAnnotationType
private static <T> Class<T> getAnnotationType(Class<?> clazz)
@SuppressWarnings("unchecked")
private static <T> Class<T> getTypeParameter(Class<?> annotationLiteralSuperclass)
{
Type type = clazz.getGenericSuperclass();
Class<T> annotationType = null;
Type type = annotationLiteralSuperclass.getGenericSuperclass();
if (type instanceof ParameterizedType)
{
ParameterizedType parameterizedType = (ParameterizedType) type;
if (parameterizedType.getActualTypeArguments().length == 1)
{
annotationType = (Class<T>) parameterizedType
return (Class<T>) parameterizedType
.getActualTypeArguments()[0];
}
}
if (annotationType == null && clazz != Object.class)
{
return getAnnotationType(clazz.getSuperclass());
} else
{
return annotationType;
}
return null;
}
*
*/

// TODO: equals(), hashCode()

private Class<T> annotationType;



public Class<? extends Annotation> annotationType()
{
annotationType = getAnnotationType(getClass());
if (annotationType == null)
{
throw new RuntimeException(
"Unable to determine type of annotation literal for " + getClass());
}
return annotationType;
}

@Override
public String toString()
{
String annotationName = "@" + annotationType().getName() + "()";
return annotationName;
return "@" + annotationType().getName() + "()";
}

@Override
Expand Down
77 changes: 63 additions & 14 deletions webbeans-api/src/main/java/javax/webbeans/TypeLiteral.java
Expand Up @@ -26,39 +26,88 @@
* with actual type parameters.
*
* @author Gavin King
* @author Pete Muir
*
* @param <T>
* the type, including all actual type parameters
*/
public abstract class TypeLiteral<T> {
public abstract class TypeLiteral<T>
{

protected TypeLiteral() {
if (!(getClass().getSuperclass() == TypeLiteral.class)) {
throw new RuntimeException("Not a direct subclass of TypeLiteral");
private Type actualType;

protected TypeLiteral()
{
Class<?> typeLiteralSubclass = getTypeLiteralSubclass(this.getClass());
if (typeLiteralSubclass == null)
{
throw new RuntimeException(getClass() + " is not a subclass of TypeLiteral");
}
if (!(getClass().getGenericSuperclass() instanceof ParameterizedType)) {
throw new RuntimeException("Missing type parameter in TypeLiteral");
actualType = getTypeParameter(typeLiteralSubclass);
if (actualType == null)
{
throw new RuntimeException(getClass() + " is missing type parameter in TypeLiteral");
}
}

public final Type getType() {
ParameterizedType parameterized = (ParameterizedType) getClass()
.getGenericSuperclass();
return parameterized.getActualTypeArguments()[0];
public final Type getType()
{
return actualType;
}

@SuppressWarnings("unchecked")
public final Class<T> getRawType() {
Type type = getType();
if (type instanceof Class) {
if (type instanceof Class)
{
return (Class<T>) type;
} else if (type instanceof ParameterizedType) {
}
else if (type instanceof ParameterizedType)
{
return (Class<T>) ((ParameterizedType) type).getRawType();
} else if (type instanceof GenericArrayType) {
}
else if (type instanceof GenericArrayType)
{
return (Class<T>) Object[].class;
} else {
}
else
{
throw new RuntimeException("Illegal type");
}
}

@SuppressWarnings("unchecked")
private static Class<?> getTypeLiteralSubclass(Class<?> clazz)
{
Class<?> superclass = clazz.getSuperclass();
if (superclass.equals(TypeLiteral.class))
{
return clazz;
}
else if (superclass.equals(Object.class))
{
return null;
}
else
{
return (getTypeLiteralSubclass(superclass));
}
}

@SuppressWarnings("unchecked")
private static Type getTypeParameter(Class<?> superclass)
{
Type type = superclass.getGenericSuperclass();
if (type instanceof ParameterizedType)
{
ParameterizedType parameterizedType = (ParameterizedType) type;
if (parameterizedType.getActualTypeArguments().length == 1)
{
return parameterizedType.getActualTypeArguments()[0];
}
}
return null;
}

// TODO: equals(), hashCode()
}
Expand Up @@ -48,22 +48,7 @@
public class SimpleComponentModelTest extends AbstractTest
{

private class NamedAnnotationLiteral extends AnnotationLiteral<Named> implements Named
{

private String value;

public NamedAnnotationLiteral(String value)
{
this.value = value;
}

public String value()
{
return value;
}

}
private abstract class NamedAnnotationLiteral extends AnnotationLiteral<Named> implements Named {}

// **** TESTS FOR DEPLOYMENT TYPE **** //

Expand Down Expand Up @@ -149,7 +134,14 @@ public void testDefaultNamed()
public void testDefaultXmlNamed()
{
Map<Class<? extends Annotation>, Annotation> annotations = new HashMap<Class<? extends Annotation>, Annotation>();
annotations.put(Named.class, new NamedAnnotationLiteral(""));
annotations.put(Named.class, new NamedAnnotationLiteral() {

public String value()
{
return "";
}

});
AnnotatedType<SeaBass> annotatedItem = new SimpleAnnotatedType<SeaBass>(SeaBass.class, annotations);
SimpleComponentModel<SeaBass> trout = new SimpleComponentModel<SeaBass>(new SimpleAnnotatedType<SeaBass>(SeaBass.class), annotatedItem, manager);

Expand All @@ -161,7 +153,14 @@ public void testDefaultXmlNamed()
public void testNonDefaultXmlNamed()
{
Map<Class<? extends Annotation>, Annotation> annotations = new HashMap<Class<? extends Annotation>, Annotation>();
annotations.put(Named.class, new NamedAnnotationLiteral("aTrout"));
annotations.put(Named.class, new NamedAnnotationLiteral(){

public String value()
{
return "aTrout";
}

});
AnnotatedType<SeaBass> annotatedItem = new SimpleAnnotatedType<SeaBass>(SeaBass.class, annotations);
SimpleComponentModel<SeaBass> trout = new SimpleComponentModel<SeaBass>(new SimpleAnnotatedType<SeaBass>(SeaBass.class), annotatedItem, manager);

Expand Down Expand Up @@ -192,7 +191,14 @@ public void testStereotypeDeclaredInXmlAndJava()
Map<Class<? extends Annotation>, Annotation> orderXmlAnnotations = new HashMap<Class<? extends Annotation>, Annotation>();
orderXmlAnnotations.put(Current.class, new CurrentAnnotationLiteral());
orderXmlAnnotations.put(Synchronous.class, new SynchronousAnnotationLiteral());
orderXmlAnnotations.put(Named.class, new NamedAnnotationLiteral ("currentSynchronousOrder"));
orderXmlAnnotations.put(Named.class, new NamedAnnotationLiteral (){

public String value()
{
return "currentSynchronousOrder";
}

});
AnnotatedType currentSynchronousOrderAnnotatedItem = new SimpleAnnotatedType(Order.class, orderXmlAnnotations);

SimpleComponentModel<Order> order = new SimpleComponentModel<Order>(new SimpleAnnotatedType(Order.class), currentSynchronousOrderAnnotatedItem, manager);
Expand Down

0 comments on commit 3e050cf

Please sign in to comment.