Package org.impalaframework.spring.service.proxy

Source Code of org.impalaframework.spring.service.proxy.ServiceEndpointInterceptor

/*
* Copyright 2007-2008 the original author or authors.
*
* 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 org.impalaframework.spring.service.proxy;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.impalaframework.exception.NoServiceException;
import org.impalaframework.service.ServiceRegistryEntry;
import org.impalaframework.spring.service.ServiceEndpointTargetSource;

/**
* Interceptor which uses a {@link ServiceEndpointTargetSource} to retrieve a {@link ServiceRegistryEntry}, from which it
* obtains a service object to which to pass to the standard Spring AOP {@link MethodInvocation#proceed()} call.
*
* It also performs a number of other responsibilities, such as:
* <ul>
* <li>retrying for certain number of times using a certain interval if no reference could be obtained
* <li>setting the thread context class loader to that of the class loader responsible for loading the invocation target
* <li>logging if no service can be found
* <li>throwing a {@link NoServiceException} if no service can be found
* <li>or proceeding with a no-op proxy implementation of the service if no service can be found
* </ul>
* All of these behaviours can be enabled, disabled or controlled via configuration, as described in {@link DefaultProxyFactoryCreator}.
*
* @see DefaultProxyFactoryCreator
*
* @author Phil Zoio
*/
public class ServiceEndpointInterceptor implements MethodInterceptor {

    final Log log = LogFactory.getLog(ServiceEndpointInterceptor.class);

    private ServiceEndpointTargetSource targetSource;

    private String beanName;

    private boolean proceedWithNoService;

    private boolean logWarningNoService;
   
    private boolean setContextClassLoader;
   
    private int retryCount;
   
    private int retryInterval;

    public ServiceEndpointInterceptor(ServiceEndpointTargetSource targetSource, String beanName) {
        this.targetSource = targetSource;
        this.beanName = beanName;
    }

    public Object invoke(MethodInvocation invocation) throws Throwable {
       
        final boolean setCCCL = setContextClassLoader;
       
        ServiceRegistryEntry serviceReference = targetSource.getServiceRegistryReference();
       
        int retriesUsed = 0;
        while (serviceReference == null && retriesUsed < retryCount) {
            try {
                Thread.sleep(retryInterval);
            }
            catch (InterruptedException e) {
            }
            serviceReference = targetSource.getServiceRegistryReference();
            retriesUsed++;
        }

        if (serviceReference != null) {
           
            final Thread currentThread;
            final ClassLoader existingClassLoader;
            if (setCCCL) {
                currentThread = Thread.currentThread()
                existingClassLoader= currentThread.getContextClassLoader();
            } else {
                currentThread = null;
                existingClassLoader = null;
            }
           
            try {
                if (setCCCL) {
                    currentThread.setContextClassLoader(serviceReference.getBeanClassLoader());
                }
                return invocation.proceed();
               
            } finally {
                //reset the previous class loader
                if (setCCCL) {
                    Thread.currentThread().setContextClassLoader(existingClassLoader);
                }
            }
        }
        else {
           
            if (logWarningNoService) {
                log.warn("************************************************************************* ");
                log.warn("No service available for bean " + beanName + ". Proceeding with stub implementation");
                log.warn("************************************************************************* ");
            }
           
            if (proceedWithNoService) {
                return invokeDummy(invocation);
            }
            else {
                throw new NoServiceException("No service available for bean " + beanName);
            }
        }
    }

    public Object invokeDummy(MethodInvocation invocation) throws Throwable {

        log.debug("Calling method " +  invocation);
        Class<?> returnType = invocation.getMethod().getReturnType();

        if (Void.TYPE.equals(returnType))
            return null;
        if (Byte.TYPE.equals(returnType))
            return (byte) 0;
        if (Short.TYPE.equals(returnType))
            return (short) 0;
        if (Integer.TYPE.equals(returnType))
            return (int) 0;
        if (Long.TYPE.equals(returnType))
            return 0L;
        if (Float.TYPE.equals(returnType))
            return 0f;
        if (Double.TYPE.equals(returnType))
            return 0d;
        if (Boolean.TYPE.equals(returnType))
            return false;

        return null;
    }

    public void setProceedWithNoService(boolean proceedWithNoService) {
        this.proceedWithNoService = proceedWithNoService;
    }

    public void setLogWarningNoService(boolean logWarningNoService) {
        this.logWarningNoService = logWarningNoService;
    }

    public void setSetContextClassLoader(boolean setContextClassLoader) {
        this.setContextClassLoader = setContextClassLoader;
    }

    public void setRetryCount(int retryCount) {
        this.retryCount = retryCount;
    }

    public void setRetryInterval(int retryInterval) {
        this.retryInterval = retryInterval;
    }

}
TOP

Related Classes of org.impalaframework.spring.service.proxy.ServiceEndpointInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.