001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.messaging.proxy;
016    
017    import com.liferay.portal.kernel.util.AggregateClassLoader;
018    
019    import java.lang.annotation.Annotation;
020    import java.lang.reflect.InvocationTargetException;
021    import java.lang.reflect.Method;
022    
023    /**
024     * @author Michael C. Han
025     */
026    public class MultiClassLoaderProxyRequest extends ProxyRequest {
027    
028            public MultiClassLoaderProxyRequest(Method method, Object[] arguments)
029                    throws Exception {
030    
031                    super(method, arguments);
032    
033                    ClassLoader[] classLoaders = inspectForClassLoaders(method);
034    
035                    _clientClassLoaders = AggregateClassLoader.getAggregateClassLoader(
036                            classLoaders);
037            }
038    
039            @Override
040            public Object execute(Object object) throws Exception {
041                    ClassLoader contextClassLoader = null;
042    
043                    if (_clientClassLoaders != null) {
044                            Thread currentThread = Thread.currentThread();
045    
046                            contextClassLoader = currentThread.getContextClassLoader();
047    
048                            ClassLoader invocationClassLoader =
049                                    AggregateClassLoader.getAggregateClassLoader(
050                                            new ClassLoader[] {
051                                                    contextClassLoader, _clientClassLoaders
052                                            });
053    
054                            currentThread.setContextClassLoader(invocationClassLoader);
055                    }
056    
057                    try {
058                            return super.execute(object);
059                    }
060                    catch (InvocationTargetException ite) {
061                            throw new Exception(ite.getTargetException());
062                    }
063                    finally {
064                            if (contextClassLoader != null) {
065                                    Thread currentThread = Thread.currentThread();
066    
067                                    currentThread.setContextClassLoader(contextClassLoader);
068                            }
069                    }
070            }
071    
072            protected ClassLoader[] inspectForClassLoaders(Method method)
073                    throws Exception {
074    
075                    Annotation[][] annotationsArray = method.getParameterAnnotations();
076    
077                    if ((annotationsArray == null) || (annotationsArray.length == 0)) {
078                            return null;
079                    }
080    
081                    for (int i = 0; i < annotationsArray.length; i++) {
082                            Annotation[] annotations = annotationsArray[i];
083    
084                            if ((annotations == null) || (annotations.length == 0)) {
085                                    continue;
086                            }
087    
088                            for (Annotation annotation : annotations) {
089                                    if (ExecutingClassLoaders.class.isAssignableFrom(
090                                                    annotation.annotationType())) {
091    
092                                            return (ClassLoader[])getArguments()[i];
093                                    }
094                            }
095                    }
096    
097                    return null;
098            }
099    
100            private ClassLoader _clientClassLoaders;
101    
102    }