View Javadoc

1   package com.atlassian.plugins.rest.common.json;
2   
3   import org.codehaus.jackson.Version;
4   import org.codehaus.jackson.map.BeanDescription;
5   import org.codehaus.jackson.map.BeanProperty;
6   import org.codehaus.jackson.map.JsonMappingException;
7   import org.codehaus.jackson.map.JsonSerializer;
8   import org.codehaus.jackson.map.Module;
9   import org.codehaus.jackson.map.SerializationConfig;
10  import org.codehaus.jackson.map.Serializers;
11  import org.codehaus.jackson.map.introspect.BasicBeanDescription;
12  import org.codehaus.jackson.map.ser.BeanSerializerFactory;
13  import org.codehaus.jackson.map.type.TypeBindings;
14  import org.codehaus.jackson.map.type.TypeFactory;
15  import org.codehaus.jackson.map.type.TypeModifier;
16  import org.codehaus.jackson.type.JavaType;
17  
18  import java.lang.reflect.Type;
19  
20  class GuavaIterableCapableModule extends Module {
21      // TODO: REST-337 remove this and just use FluentIterable when we past guava-11 compatibility problems
22      static private final Class fluentIterableClass;
23  
24      static {
25          Class tmp = null;
26          try {
27              tmp = Class.forName("com.google.common.collect.FluentIterable");
28          } catch (ClassNotFoundException e) {
29              // that's OK - we don't have FluentIterable
30          }
31          fluentIterableClass = tmp;
32      }
33  
34      static private final TypeModifier guavaIterableTypeModifier = new TypeModifier() {
35          @Override
36          public JavaType modifyType(final JavaType type, final Type jdkType, final TypeBindings context, final TypeFactory typeFactory) {
37              final Class<?> raw = type.getRawClass();
38              if (fluentIterableClass.isAssignableFrom(raw)) {
39                  return typeFactory.constructParametricType(Iterable.class, typeFactory.unknownType());
40              }
41              return type;
42          }
43      };
44  
45      static private final Serializers.Base guavaSerializers = new Serializers.Base() {
46          @Override
47          public JsonSerializer<?> findSerializer(final SerializationConfig config, final JavaType type, final BeanDescription beanDesc, final BeanProperty property) {
48              final Class<?> raw = type.getRawClass();
49              if (fluentIterableClass.isAssignableFrom(raw)) {
50                  BasicBeanDescription basicBeanDescription = config.introspect(type);
51                  try {
52                      return BeanSerializerFactory.instance.findSerializerByAddonType(config, type, basicBeanDescription, property, false);
53                  } catch (JsonMappingException e) {
54                      // Had no luck - continue with super method
55                  }
56              }
57              return super.findSerializer(config, type, beanDesc, property);
58          }
59      };
60  
61      private final static Version version = new Version(0, 1, 0, null);
62  
63      @Override
64      public String getModuleName() {
65          return GuavaIterableCapableModule.class.getSimpleName();
66      }
67  
68      @Override
69      public Version version() {
70          return version;
71      }
72  
73      @Override
74      public void setupModule(final SetupContext context) {
75          if (fluentIterableClass != null) {
76              context.addTypeModifier(guavaIterableTypeModifier);
77              context.addSerializers(guavaSerializers);
78          }
79      }
80  }