Subversion Repositories bacoAlunos

Rev

Rev 1969 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.owlike.genson.reflect;

import static com.owlike.genson.reflect.TypeUtil.getRawClass;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.owlike.genson.Genson;

public interface BeanPropertyFactory {
  PropertyAccessor createAccessor(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Field.html">Field field, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Genson genson);

  PropertyAccessor createAccessor(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Method.html">Method method, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Genson genson);

  BeanCreator createCreator(1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Constructor<?> ctr, 1.5.0/docs/api/java/lang/String.html">String[] resolvedNames,
                                   Genson genson);

  BeanCreator createCreator(1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, 1.5.0/docs/api/java/lang/reflect/Method.html">Method method, 1.5.0/docs/api/java/lang/String.html">String[] resolvedNames,
                                   Genson genson);

  PropertyMutator createMutator(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Field.html">Field field, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Genson genson);

  PropertyMutator createMutator(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Method.html">Method method, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Genson genson);

  class CompositeFactory implements BeanPropertyFactory {
    private final List<BeanPropertyFactory> factories;

    public CompositeFactory(List<? extends BeanPropertyFactory> factories) {
      this.factories = new ArrayList<BeanPropertyFactory>(factories);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public PropertyAccessor createAccessor(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Field.html">Field field, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Genson genson) {
      for (BeanPropertyFactory factory : factories) {
        PropertyAccessor accessor = factory.createAccessor(name, field, ofType, genson);
        if (accessor != null) return accessor;
      }
      throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException("Failed to create a accessor for field " + field);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public PropertyAccessor createAccessor(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Method.html">Method method, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType,
                                           Genson genson) {
      for (BeanPropertyFactory factory : factories) {
        PropertyAccessor accessor = factory.createAccessor(name, method, ofType, genson);
        if (accessor != null) return accessor;
      }
      throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException("Failed to create a accessor for method " + method);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public BeanCreator createCreator(1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Constructor<?> ctr, 1.5.0/docs/api/java/lang/String.html">String[] resolvedNames,
                                     Genson genson) {
      for (BeanPropertyFactory factory : factories) {
        BeanCreator creator = factory.createCreator(ofType, ctr, resolvedNames, genson);
        if (creator != null) return creator;
      }
      throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException("Failed to create a BeanCreator for constructor " + ctr);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public BeanCreator createCreator(1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, 1.5.0/docs/api/java/lang/reflect/Method.html">Method method, 1.5.0/docs/api/java/lang/String.html">String[] resolvedNames,
                                     Genson genson) {
      for (BeanPropertyFactory factory : factories) {
        BeanCreator creator = factory.createCreator(ofType, method, resolvedNames, genson);
        if (creator != null) return creator;
      }
      throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException("Failed to create a BeanCreator for method " + method);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public PropertyMutator createMutator(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Field.html">Field field, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Genson genson) {
      for (BeanPropertyFactory factory : factories) {
        PropertyMutator mutator = factory.createMutator(name, field, ofType, genson);
        if (mutator != null) return mutator;
      }
      throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException("Failed to create a mutator for field " + field);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public PropertyMutator createMutator(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Method.html">Method method, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Genson genson) {
      for (BeanPropertyFactory factory : factories) {
        PropertyMutator mutator = factory.createMutator(name, method, ofType, genson);
        if (mutator != null) return mutator;
      }
      throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException("Failed to create a mutator for method " + method);
    }
  }

  class StandardFactory implements BeanPropertyFactory {
    public PropertyAccessor createAccessor(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Field.html">Field field, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Genson genson) {
      Class<?> ofClass = getRawClass(ofType);
      1.5.0/docs/api/java/lang/reflect/Type.html">Type expandedType = TypeUtil.expandType(field.getGenericType(), ofType);
      return new PropertyAccessor.FieldAccessor(name, field, expandedType, ofClass);
    }

    public PropertyAccessor createAccessor(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Method.html">Method method, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType,
                                           Genson genson) {
      1.5.0/docs/api/java/lang/reflect/Type.html">Type expandedType = TypeUtil.expandType(method.getGenericReturnType(), ofType);
      return new PropertyAccessor.MethodAccessor(name, method, expandedType,
        getRawClass(ofType));
    }

    public PropertyMutator createMutator(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Field.html">Field field, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Genson genson) {
      Class<?> ofClass = getRawClass(ofType);
      1.5.0/docs/api/java/lang/reflect/Type.html">Type expandedType = TypeUtil.expandType(field.getGenericType(), ofType);
      return new PropertyMutator.FieldMutator(name, field, expandedType, ofClass);
    }

    public PropertyMutator createMutator(1.5.0/docs/api/java/lang/String.html">String name, 1.5.0/docs/api/java/lang/reflect/Method.html">Method method, 1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Genson genson) {
      1.5.0/docs/api/java/lang/reflect/Type.html">Type expandedType = TypeUtil.expandType(method.getGenericParameterTypes()[0], ofType);
      return new PropertyMutator.MethodMutator(name, method, expandedType,
        getRawClass(ofType));
    }

    // ofClass is not necessarily of same type as method return type, as ofClass corresponds to
    // the declaring class!
    public BeanCreator createCreator(1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, 1.5.0/docs/api/java/lang/reflect/Method.html">Method method, 1.5.0/docs/api/java/lang/String.html">String[] resolvedNames,
                                     Genson genson) {
      return new BeanCreator.MethodBeanCreator(method, resolvedNames, expandTypes(
        method.getGenericParameterTypes(), ofType), getRawClass(ofType));
    }

    public BeanCreator createCreator(1.5.0/docs/api/java/lang/reflect/Type.html">Type ofType, Constructor<?> ctr, 1.5.0/docs/api/java/lang/String.html">String[] resolvedNames,
                                     Genson genson) {
      return new BeanCreator.ConstructorBeanCreator(getRawClass(ofType), ctr, resolvedNames,
        expandTypes(ctr.getGenericParameterTypes(), ofType));
    }

    public 1.5.0/docs/api/java/lang/reflect/Type.html">Type[] expandTypes(1.5.0/docs/api/java/lang/reflect/Type.html">Type[] typesToExpand, 1.5.0/docs/api/java/lang/reflect/Type.html">Type inContext) {
      1.5.0/docs/api/java/lang/reflect/Type.html">Type[] expandedTypes = new 1.5.0/docs/api/java/lang/reflect/Type.html">Type[typesToExpand.length];
      for (int i = 0; i < typesToExpand.length; i++) {
        expandedTypes[i] = TypeUtil.expandType(typesToExpand[i], inContext);
      }
      return expandedTypes;
    }
  }
}