/******************************************************************************* * Copyright (c) 2012-2016 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.everrest.core.impl.method; import org.everrest.core.method.TypeProducer; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Set; import java.util.SortedSet; import static org.everrest.core.util.ReflectionUtils.getStringConstructor; import static org.everrest.core.util.ReflectionUtils.getStringValueOfMethod; public class TypeProducerFactory { /** * @param aClass * method parameter class * @param genericType * method parameter type * @return TypeProducer * @see TypeProducer * @see Method#getParameterTypes() * @see Method#getGenericParameterTypes() */ public TypeProducer createTypeProducer(Class<?> aClass, Type genericType) { if (aClass == List.class || aClass == Set.class || aClass == SortedSet.class) { Class<?> actualTypeArgument = null; if (genericType != null) { actualTypeArgument = getActualTypeArgument(genericType); } Method methodValueOf; Constructor<?> constructor; if (actualTypeArgument == String.class || actualTypeArgument == null) { return new CollectionStringProducer(aClass); } else if ((methodValueOf = getStringValueOfMethod(actualTypeArgument)) != null) { return new CollectionStringValueOfProducer(aClass, methodValueOf); } else if ((constructor = getStringConstructor(actualTypeArgument)) != null) { return new CollectionStringConstructorProducer(aClass, constructor); } } else { Method methodValueOf; Constructor<?> constructor; if (aClass.isPrimitive()) { return new PrimitiveTypeProducer(aClass); } else if (aClass == String.class) { return new StringProducer(); } else if ((methodValueOf = getStringValueOfMethod(aClass)) != null) { return new StringValueOfProducer(methodValueOf); } else if ((constructor = getStringConstructor(aClass)) != null) { return new StringConstructorProducer(constructor); } } throw new IllegalArgumentException(String.format("Unsupported type %s", aClass)); } /** * Get actual type argument for supplied type. * * @param type * See {@link Type} * @return first actual type argument if type is {@link ParameterizedType}, {@code null} otherwise */ private Class<?> getActualTypeArgument(Type type) { if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)type; Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); if (actualTypeArguments.length == 1) { try { return (Class<?>)actualTypeArguments[0]; } catch (ClassCastException e) { throw new RuntimeException(String.format("Unsupported type %s", actualTypeArguments[0])); } } } return null; } }