Subversion Repositories bacoAlunos

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1878 jmachado 1
package com.owlike.genson.convert;
2
 
3
import java.lang.annotation.Annotation;
4
import java.lang.reflect.Type;
5
import java.util.Iterator;
6
import java.util.List;
7
import java.util.Map;
8
 
9
import com.owlike.genson.Context;
10
import com.owlike.genson.Converter;
11
import com.owlike.genson.Deserializer;
12
import com.owlike.genson.Factory;
13
import com.owlike.genson.Genson;
14
import com.owlike.genson.Operations;
15
import com.owlike.genson.Serializer;
16
import com.owlike.genson.Wrapper;
17
import com.owlike.genson.reflect.BeanDescriptorProvider;
18
import com.owlike.genson.reflect.TypeUtil;
19
import com.owlike.genson.stream.ObjectReader;
20
import com.owlike.genson.stream.ObjectWriter;
21
 
22
/**
23
 * This is the base factory that will create converters based on the default ones and on custom
24
 * Serializer, Deserializer and Converter. But it also uses factories (default and custom) and
25
 * {@link com.owlike.genson.reflect.BeanDescriptorProvider BeanDescriptorProvider} that is
26
 * responsible of creating bean converters.
27
 * <p/>
28
 * When you ask for a Converter it will
29
 * <ul>
30
 * <ol>
31
 * <li>Lookup in the registered Serializers for one that is parameterized with the current type, if
32
 * found we finished (it takes the first one, so the order matters).</li>
33
 * <li>Else we will try the factories by searching the ones that can create and instance of
34
 * Serializer&lt;CurrentType&gt; (again the order is very important). We continue while they return
35
 * null.</li>
36
 * <li>If no factory could create an instance we will use BeanDescriptorProvider.</li>
37
 * </ol>
38
 * </li>
39
 * <li>We apply all the same logic a second time for Deserializer.</li>
40
 * <li>If they are both an instance of Converter then we return one of them</li>
41
 * <li>Otherwise we will wrap both into a Converter.</li>
42
 * </ul>
43
 * <p/>
44
 * Note that the create method from the registered factories will only be called if the type with
45
 * which they are parameterized is assignable from the current type. For example, if we look for a
46
 * serializer of Integer then Factory&lt;Converter&lt;Integer>> and Factory&lt;Serializer&lt;Object>> match
47
 * both, the first registered will be used.
48
 *
49
 * @author eugen
50
 */
51
public class BasicConvertersFactory implements Factory<Converter<?>> {
52
  private final Map<Type, Serializer<?>> serializersMap;
53
  private final Map<Type, Deserializer<?>> deserializersMap;
54
  private final List<Factory<?>> factories;
55
  private final BeanDescriptorProvider beanDescriptorProvider;
56
 
57
  public BasicConvertersFactory(Map<Type, Serializer<?>> serializersMap,
58
                                Map<Type, Deserializer<?>> deserializersMap, List<Factory<?>> factories,
59
                                BeanDescriptorProvider beanDescriptorProvider) {
60
    this.serializersMap = serializersMap;
61
    this.deserializersMap = deserializersMap;
62
    this.factories = factories;
63
    this.beanDescriptorProvider = beanDescriptorProvider;
64
  }
65
 
66
  @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings({"unchecked", "rawtypes"})
67
  public Converter<?> create(1.5.0/docs/api/java/lang/reflect/Type.html">Type type, Genson genson) {
68
    Converter<?> converter;
69
    Serializer<?> serializer = provide(Serializer.class, type, serializersMap, genson);
70
    Deserializer<?> deserializer = provide(Deserializer.class, type, deserializersMap, genson);
71
    if (serializer instanceof Converter && deserializer instanceof Converter) {
72
      converter = (Converter<?>) deserializer;
73
    } else {
74
      converter = new DelegatedConverter(serializer, deserializer);
75
    }
76
    return converter;
77
  }
78
 
79
  @1.5.0/docs/api/java/lang/SuppressWarnings.html">SuppressWarnings("unchecked")
80
  protected <T> T provide(Class<T> forClass, 1.5.0/docs/api/java/lang/reflect/Type.html">Type withParameterType,
81
                          Map<Type, ? extends T> fromTypeMap, Genson genson) {
82
    if (fromTypeMap.containsKey(withParameterType)) return fromTypeMap.get(withParameterType);
83
 
84
    1.5.0/docs/api/java/lang/reflect/Type.html">Type wrappedParameterType = withParameterType;
85
    if (withParameterType instanceof Class<?> && ((Class<?>) withParameterType).isPrimitive())
86
      wrappedParameterType = TypeUtil.wrap((Class<?>) withParameterType);
87
 
88
    for (Iterator<Factory<?>> it = factories.iterator(); it.hasNext(); ) {
89
      Factory<?> factory = it.next();
90
      5+0%2Fdocs%2Fapi+Object">Object object;
91
      1.5.0/docs/api/java/lang/reflect/Type.html">Type factoryType = TypeUtil.lookupGenericType(Factory.class, factory.getClass());
92
      factoryType = TypeUtil.expandType(factoryType, factory.getClass());
93
      // it is a parameterized type and we want the parameter corresponding to Serializer from
94
      // Factory<Serializer<?>>
95
      factoryType = TypeUtil.typeOf(0, factoryType);
96
      1.5.0/docs/api/java/lang/reflect/Type.html">Type factoryParameter = TypeUtil.typeOf(0, factoryType);
97
      if (forClass.isAssignableFrom(TypeUtil.getRawClass(factoryType))
98
        && TypeUtil.match(wrappedParameterType, factoryParameter, false)
99
        && (object = factory.create(withParameterType, genson)) != null) {
100
        return forClass.cast(object);
101
      }
102
    }
103
 
104
    return (T) beanDescriptorProvider.provide(TypeUtil.getRawClass(withParameterType),
105
      withParameterType, genson);
106
  }
107
 
108
  private class DelegatedConverter<T> extends Wrapper<Converter<T>> implements Converter<T> {
109
    private final Serializer<T> serializer;
110
    private final Deserializer<T> deserializer;
111
 
112
    public DelegatedConverter(Serializer<T> serializer, Deserializer<T> deserializer) {
113
      this.serializer = serializer;
114
      this.deserializer = deserializer;
115
    }
116
 
117
    public void serialize(T obj, ObjectWriter writer, 5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
118
      serializer.serialize(obj, writer, ctx);
119
    }
120
 
121
    public T deserialize(ObjectReader reader, 5+0%2Fdocs%2Fapi+Context">Context ctx) throws 1.5.0/docs/api/java/lang/Exception.html">Exception {
122
      return deserializer.deserialize(reader, ctx);
123
    }
124
 
125
    @1.5.0/docs/api/java/lang/Override.html">Override
126
    public <A extends Annotation> A getAnnotation(Class<A> aClass) {
127
      A a = null;
128
      if (serializer != null) a = toAnnotatedElement(serializer).getAnnotation(aClass);
129
      if (deserializer != null && a == null)
130
        a = toAnnotatedElement(deserializer).getAnnotation(aClass);
131
      return a;
132
    }
133
 
134
    @1.5.0/docs/api/java/lang/Override.html">Override
135
    public 5+0%2Fdocs%2Fapi+Annotation">Annotation[] getAnnotations() {
136
      if (serializer != null && deserializer != null)
137
        return Operations.union(5+0%2Fdocs%2Fapi+Annotation">Annotation[].class, toAnnotatedElement(serializer)
138
          .getAnnotations(), toAnnotatedElement(deserializer).getAnnotations());
139
      if (serializer != null) return toAnnotatedElement(serializer).getAnnotations();
140
      if (deserializer != null) return toAnnotatedElement(deserializer).getAnnotations();
141
 
142
      return new 5+0%2Fdocs%2Fapi+Annotation">Annotation[0];
143
    }
144
 
145
    @1.5.0/docs/api/java/lang/Override.html">Override
146
    public 5+0%2Fdocs%2Fapi+Annotation">Annotation[] getDeclaredAnnotations() {
147
      if (serializer != null && deserializer != null)
148
        return Operations.union(5+0%2Fdocs%2Fapi+Annotation">Annotation[].class, toAnnotatedElement(serializer)
149
          .getDeclaredAnnotations(), toAnnotatedElement(deserializer)
150
          .getDeclaredAnnotations());
151
      if (serializer != null) return toAnnotatedElement(serializer).getDeclaredAnnotations();
152
      if (deserializer != null)
153
        return toAnnotatedElement(deserializer).getDeclaredAnnotations();
154
 
155
      return new 5+0%2Fdocs%2Fapi+Annotation">Annotation[0];
156
    }
157
 
158
    @1.5.0/docs/api/java/lang/Override.html">Override
159
    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
160
      if (serializer != null)
161
        return toAnnotatedElement(serializer).isAnnotationPresent(annotationClass);
162
      if (deserializer != null)
163
        return toAnnotatedElement(deserializer).isAnnotationPresent(annotationClass);
164
      return false;
165
    }
166
  }
167
}