net.paslavsky.springrest.SpringRestClientFactoryBean.java Source code

Java tutorial

Introduction

Here is the source code for net.paslavsky.springrest.SpringRestClientFactoryBean.java

Source

/*
 * Copyright (c) 2014 Andrey Paslavsky.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.paslavsky.springrest;

import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

import java.net.URI;

/**
 * TODO Class description
 *
 * @author Andrey Paslavsky
 * @version 1.0
 */
public class SpringRestClientFactoryBean<T> extends AbstractFactoryBean<T> {
    private final Class<? extends T> clientClass;
    private AnnotationPreprocessor annotationPreprocessor = null;
    private ConversionService conversionService = null;
    private AuthenticationManager authenticationManager;
    private URI baseUrl;

    @SuppressWarnings("unchecked")
    SpringRestClientFactoryBean(final String clientClassName) {
        this((Class<? extends T>) getClientClass(clientClassName));
    }

    private static Class<?> getClientClass(String clientClassName) {
        Assert.hasText(clientClassName,
                "Argument 'clientClassName' must be a name of the class from default classpath");
        try {
            return ClassUtils.forName(clientClassName, ClassUtils.getDefaultClassLoader());
        } catch (ClassNotFoundException e) {
            throw new SpringRestClientConfigurationException("Wrong class name of the REST client", e);
        }
    }

    public SpringRestClientFactoryBean(Class<? extends T> clientClass) {
        Assert.notNull(clientClass, "Argument 'clientClass' can not be null!");
        this.clientClass = clientClass;
    }

    @SuppressWarnings("unused")
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @SuppressWarnings("unused")
    public void setBaseUrl(String baseUrlString) {
        setBaseUrl(URI.create(baseUrlString));
    }

    public void setBaseUrl(URI baseUrl) {
        this.baseUrl = baseUrl;
    }

    @SuppressWarnings("unused")
    public void setAnnotationPreprocessor(AnnotationPreprocessor annotationPreprocessor) {
        this.annotationPreprocessor = annotationPreprocessor;
    }

    private AnnotationPreprocessor getAnnotationPreprocessor() {
        if (annotationPreprocessor == null) {
            annotationPreprocessor = new CacheableAnnotationPreprocessor(new SpringAnnotationPreprocessor());
        }
        return annotationPreprocessor;
    }

    private ConversionService getConversionService() {
        if (conversionService == null) {
            conversionService = new DefaultConversionService();
        }
        return conversionService;
    }

    @SuppressWarnings("unused")
    public void setConversionService(ConversionService conversionService) {
        this.conversionService = conversionService;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        super.afterPropertiesSet();
    }

    @Override
    public final Class<?> getObjectType() {
        return clientClass;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected T createInstance() throws Exception {
        ProxyFactory factory = new ProxyFactory();
        if (getObjectType().isInterface()) {
            factory.setInterfaces(getObjectType());
        } else {
            factory.setTargetClass(getObjectType());
        }
        factory.addAdvisor(createRestMethodAdvisor());
        factory.addAdvisor(createToStringPointcutAdvisor());
        return (T) factory.getProxy();
    }

    private Advisor createRestMethodAdvisor() {
        SpringRestClientMethodInterceptor methodInterceptor = new SpringRestClientMethodInterceptor();
        methodInterceptor.setAnnotationPreprocessor(getAnnotationPreprocessor());
        methodInterceptor.setConversionService(getConversionService());
        methodInterceptor.setBaseUrl(baseUrl);
        methodInterceptor.setAuthenticationManager(authenticationManager);
        methodInterceptor.afterPropertiesSet();
        return new SpringRestClientAOPAdvisor(methodInterceptor);
    }

    private Advisor createToStringPointcutAdvisor() {
        return new SpringRestClientToStringAdvisor(clientClass);
    }
}