Subversion Repositories bacoAlunos

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1878 jmachado 1
package com.owlike.genson;
2
 
3
import java.lang.annotation.Annotation;
4
import java.lang.reflect.AnnotatedElement;
5
 
6
import com.owlike.genson.reflect.TypeUtil;
7
 
8
 
9
/**
10
 * Wrapper class must be extended by decorated converters that wrap other converters. This allows to
11
 * access merged class information of wrapped converter and the converter itself. So instead of
12
 * doing myObject.getClass().isAnnotationPresent(..) you will do myObject.isAnnotationPresent(..),
13
 * where myObject is an instance of Wrapper. For example to check if a converter (or any another
14
 * encapsulated converter and so on) has annotation @HandleNull you will do it that way:
15
 * <p/>
16
 * <pre>
17
 * Wrapper.toAnnotatedElement(converter).isAnnotationPresent(HandleNull.class);
18
 * </pre>
19
 * <p/>
20
 * In the future there may be other methods to access other kind of class information.
21
 *
22
 * @author eugen
23
 */
24
public abstract class Wrapper<T> implements 1.5.0/docs/api/java/lang/reflect/AnnotatedElement.html">AnnotatedElement {
25
  private 1.5.0/docs/api/java/lang/reflect/AnnotatedElement.html">AnnotatedElement wrappedElement;
26
  protected T wrapped;
27
 
28
  protected Wrapper() {
29
  }
30
 
31
  protected Wrapper(T wrappedObject) {
32
    if (wrappedObject == null)
33
      throw new 1.5.0/docs/api/java/lang/IllegalArgumentException.html">IllegalArgumentException("Null not allowed!");
34
    decorate(wrappedObject);
35
  }
36
 
37
  public 5+0%2Fdocs%2Fapi+Annotation">Annotation[] getAnnotations() {
38
    return Operations.union(5+0%2Fdocs%2Fapi+Annotation">Annotation[].class, wrappedElement.getAnnotations(), getClass()
39
      .getAnnotations());
40
  }
41
 
42
  public <A extends Annotation> A getAnnotation(Class<A> aClass) {
43
    A ann = wrappedElement.getAnnotation(aClass);
44
    return ann == null ? getClass().getAnnotation(aClass) : ann;
45
  }
46
 
47
  public 5+0%2Fdocs%2Fapi+Annotation">Annotation[] getDeclaredAnnotations() {
48
    return Operations.union(5+0%2Fdocs%2Fapi+Annotation">Annotation[].class, wrappedElement.getDeclaredAnnotations(),
49
      getClass().getDeclaredAnnotations());
50
  }
51
 
52
  public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
53
    return wrappedElement.isAnnotationPresent(annotationClass)
54
      || getClass().isAnnotationPresent(annotationClass);
55
  }
56
 
57
  // package visibility as a convenience for CircularClassReferenceConverter
58
  protected void decorate(T object) {
59
    if (wrappedElement != null)
60
      throw new 1.5.0/docs/api/java/lang/IllegalStateException.html">IllegalStateException("An object is already wrapped!");
61
    if (object instanceof 1.5.0/docs/api/java/lang/reflect/AnnotatedElement.html">AnnotatedElement)
62
      this.wrappedElement = (1.5.0/docs/api/java/lang/reflect/AnnotatedElement.html">AnnotatedElement) object;
63
    else
64
      this.wrappedElement = object.getClass();
65
    this.wrapped = object;
66
  }
67
 
68
  public T unwrap() {
69
    return wrapped;
70
  }
71
 
72
  /**
73
   * This method acts as an adapter to AnnotatedElement, use it when you need to work on a
74
   * converter annotations. In fact "object" argument will usually be of type converter. If this
75
   * class is a wrapper than it will cast it to annotatedElement (as Wrapper implements
76
   * AnnotatedElement). Otherwise we will return the class of this object.
77
   *
78
   * @param object may be an instance of converter for example
79
   * @return an annotatedElement that allows us to get annotations from this object and it's
80
   * wrapped classes if it is a Wrapper.
81
   */
82
  public static 1.5.0/docs/api/java/lang/reflect/AnnotatedElement.html">AnnotatedElement toAnnotatedElement(5+0%2Fdocs%2Fapi+Object">Object object) {
83
    if (object == null)
84
      return null;
85
    if (isWrapped(object))
86
      return (1.5.0/docs/api/java/lang/reflect/AnnotatedElement.html">AnnotatedElement) object;
87
    else
88
      return object.getClass();
89
  }
90
 
91
  public static boolean isWrapped(5+0%2Fdocs%2Fapi+Object">Object object) {
92
    return object instanceof Wrapper;
93
  }
94
 
95
  /**
96
   * @return true if this object or its wrapped object (if the object extends Wrapper) is of type clazz.
97
   */
98
  public static boolean isOfType(5+0%2Fdocs%2Fapi+Object">Object object, Class<?> clazz) {
99
    return TypeUtil.match(object.getClass(), clazz, false) ||
100
             (isWrapped(object) && Wrapper.isOfType(((Wrapper<?>) object).unwrap(), clazz));
101
  }
102
}