package org.springframework.cloud.service; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; /** * Base class to simplify creation of {@link ServiceConnectorCreator}s. * <p> * The type parameter define the service connector and service info types. * * @param <SC> service connector type * @param <SI> service info type * * @author Ramnivas Laddad */ public abstract class AbstractServiceConnectorCreator<SC, SI extends ServiceInfo> implements ServiceConnectorCreator<SC, SI> { private Class<SC> connectorType; private Class<SI> serviceInfoType; @SuppressWarnings("unchecked") public AbstractServiceConnectorCreator() { // A simple scheme to determine type parameters. If a type parameter in the class hierarchy // is of ServiceInfo type, we set the serrviceInfoType with it; other type parameters // are assumed to be of connector type. We let the last parameters override anything set // earlier to let the type parameters for classes close to AbstractServiceConnectorCreator win. Class<?> clazz = getClass(); while(clazz != AbstractServiceConnectorCreator.class) { if (clazz.getGenericSuperclass() instanceof ParameterizedType) { ParameterizedType genericSuperClass = (ParameterizedType) clazz.getGenericSuperclass(); Type[] typeArgs = genericSuperClass.getActualTypeArguments(); for (Type typeArg : typeArgs) { if (typeArg instanceof Class) { Class<?> typeClass = (Class<?>) typeArg; if (ServiceInfo.class.isAssignableFrom(typeClass)) { this.serviceInfoType = (Class<SI>) typeClass; } else { this.connectorType = (Class<SC>) typeClass; } } } } clazz = clazz.getSuperclass(); } } public Class<SC> getServiceConnectorType() { return connectorType; } public Class<SI> getServiceInfoType() { return serviceInfoType; } }