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

com.owlike.genson.convert.BasicConvertersFactory Maven / Gradle / Ivy

package com.owlike.genson.convert;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.owlike.genson.Context;
import com.owlike.genson.Converter;
import com.owlike.genson.Deserializer;
import com.owlike.genson.Factory;
import com.owlike.genson.Genson;
import com.owlike.genson.Operations;
import com.owlike.genson.Serializer;
import com.owlike.genson.Wrapper;
import com.owlike.genson.reflect.BeanDescriptorProvider;
import com.owlike.genson.reflect.TypeUtil;
import com.owlike.genson.stream.ObjectReader;
import com.owlike.genson.stream.ObjectWriter;

/**
 * This is the base factory that will create converters based on the default ones and on custom
 * Serializer, Deserializer and Converter. But it also uses factories (default and custom) and
 * {@link com.owlike.genson.reflect.BeanDescriptorProvider BeanDescriptorProvider} that is
 * responsible of creating bean converters.
 * 

* When you ask for a Converter it will *

    *
      *
    1. Lookup in the registered Serializers for one that is parameterized with the current type, if * found we finished (it takes the first one, so the order matters).
    2. *
    3. Else we will try the factories by searching the ones that can create and instance of * Serializer<CurrentType> (again the order is very important). We continue while they return * null.
    4. *
    5. If no factory could create an instance we will use BeanDescriptorProvider.
    6. *
    * *
  • We apply all the same logic a second time for Deserializer.
  • *
  • If they are both an instance of Converter then we return one of them
  • *
  • Otherwise we will wrap both into a Converter.
  • *
*

* Note that the create method from the registered factories will only be called if the type with * which they are parameterized is assignable from the current type. For example, if we look for a * serializer of Integer then Factory<Converter<Integer>> and Factory<Serializer<Object>> match * both, the first registered will be used. * * @author eugen */ public class BasicConvertersFactory implements Factory> { private final Map> serializersMap; private final Map> deserializersMap; private final List> factories; private final BeanDescriptorProvider beanDescriptorProvider; public BasicConvertersFactory(Map> serializersMap, Map> deserializersMap, List> factories, BeanDescriptorProvider beanDescriptorProvider) { this.serializersMap = serializersMap; this.deserializersMap = deserializersMap; this.factories = factories; this.beanDescriptorProvider = beanDescriptorProvider; } @SuppressWarnings({"unchecked", "rawtypes"}) public Converter create(Type type, Genson genson) { Converter converter = null; Serializer serializer = provide(Serializer.class, type, serializersMap, genson); Deserializer deserializer = provide(Deserializer.class, type, deserializersMap, genson); if (serializer instanceof Converter && deserializer instanceof Converter) { converter = (Converter) deserializer; } else { converter = new DelegatedConverter(serializer, deserializer); } return converter; } @SuppressWarnings("unchecked") protected T provide(Class forClass, Type withParameterType, Map fromTypeMap, Genson genson) { if (fromTypeMap.containsKey(withParameterType)) return fromTypeMap.get(withParameterType); Type wrappedParameterType = withParameterType; if (withParameterType instanceof Class && ((Class) withParameterType).isPrimitive()) wrappedParameterType = TypeUtil.wrap((Class) withParameterType); for (Iterator> it = factories.iterator(); it.hasNext(); ) { Factory factory = it.next(); Object object; Type factoryType = TypeUtil.lookupGenericType(Factory.class, factory.getClass()); factoryType = TypeUtil.expandType(factoryType, factory.getClass()); // it is a parameterized type and we want the parameter corresponding to Serializer from // Factory> factoryType = TypeUtil.typeOf(0, factoryType); Type factoryParameter = TypeUtil.typeOf(0, factoryType); if (forClass.isAssignableFrom(TypeUtil.getRawClass(factoryType)) && TypeUtil.match(wrappedParameterType, factoryParameter, false) && (object = factory.create(withParameterType, genson)) != null) { return forClass.cast(object); } } return (T) beanDescriptorProvider.provide(TypeUtil.getRawClass(withParameterType), withParameterType, genson); } private class DelegatedConverter extends Wrapper> implements Converter { private final Serializer serializer; private final Deserializer deserializer; public DelegatedConverter(Serializer serializer, Deserializer deserializer) { this.serializer = serializer; this.deserializer = deserializer; } public void serialize(T obj, ObjectWriter writer, Context ctx) throws Exception { serializer.serialize(obj, writer, ctx); } public T deserialize(ObjectReader reader, Context ctx) throws Exception { return deserializer.deserialize(reader, ctx); } @Override public A getAnnotation(Class aClass) { A a = null; if (serializer != null) a = toAnnotatedElement(serializer).getAnnotation(aClass); if (deserializer != null && a == null) a = toAnnotatedElement(deserializer).getAnnotation(aClass); return a; } @Override public Annotation[] getAnnotations() { if (serializer != null && deserializer != null) return Operations.union(Annotation[].class, toAnnotatedElement(serializer) .getAnnotations(), toAnnotatedElement(deserializer).getAnnotations()); if (serializer != null) return toAnnotatedElement(serializer).getAnnotations(); if (deserializer != null) return toAnnotatedElement(deserializer).getAnnotations(); return new Annotation[0]; } @Override public Annotation[] getDeclaredAnnotations() { if (serializer != null && deserializer != null) return Operations.union(Annotation[].class, toAnnotatedElement(serializer) .getDeclaredAnnotations(), toAnnotatedElement(deserializer) .getDeclaredAnnotations()); if (serializer != null) return toAnnotatedElement(serializer).getDeclaredAnnotations(); if (deserializer != null) return toAnnotatedElement(deserializer).getDeclaredAnnotations(); return new Annotation[0]; } @Override public boolean isAnnotationPresent(Class annotationClass) { if (serializer != null) return toAnnotatedElement(serializer).isAnnotationPresent(annotationClass); if (deserializer != null) return toAnnotatedElement(deserializer).isAnnotationPresent(annotationClass); return false; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy