001    /**
002     * Copyright (c) 2000-present 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.util;
016    
017    import com.liferay.portal.kernel.bean.ClassLoaderBeanHandler;
018    import com.liferay.registry.Registry;
019    import com.liferay.registry.RegistryUtil;
020    import com.liferay.registry.ServiceTracker;
021    
022    import java.lang.reflect.InvocationHandler;
023    import java.lang.reflect.InvocationTargetException;
024    import java.lang.reflect.Method;
025    
026    /**
027     * @author Brian Wing Shun Chan
028     */
029    public class ProxyFactory {
030    
031            public static <T> T newDummyInstance(Class<T> interfaceClass) {
032                    return (T)ProxyUtil.newProxyInstance(
033                            interfaceClass.getClassLoader(), new Class[] {interfaceClass},
034                            new DummyInvocationHandler<T>());
035            }
036    
037            public static Object newInstance(
038                            ClassLoader classLoader, Class<?> interfaceClass,
039                            String implClassName)
040                    throws Exception {
041    
042                    return newInstance(
043                            classLoader, new Class[] {interfaceClass}, implClassName);
044            }
045    
046            public static Object newInstance(
047                            ClassLoader classLoader, Class<?>[] interfaceClasses,
048                            String implClassName)
049                    throws Exception {
050    
051                    Object instance = InstanceFactory.newInstance(
052                            classLoader, implClassName);
053    
054                    return ProxyUtil.newProxyInstance(
055                            classLoader, interfaceClasses,
056                            new ClassLoaderBeanHandler(instance, classLoader));
057            }
058    
059            public static <T> T newServiceTrackedInstance(Class<T> interfaceClass) {
060                    return (T)ProxyUtil.newProxyInstance(
061                            interfaceClass.getClassLoader(), new Class[] {interfaceClass},
062                            new ServiceTrackedInvocationHandler<T>(interfaceClass));
063            }
064    
065            private static class DummyInvocationHandler<T>
066                    implements InvocationHandler {
067    
068                    @Override
069                    public Object invoke(Object proxy, Method method, Object[] arguments)
070                            throws Throwable {
071    
072                            Class<?> returnType = method.getReturnType();
073    
074                            if (returnType.equals(boolean.class)) {
075                                    return GetterUtil.DEFAULT_BOOLEAN;
076                            }
077                            else if (returnType.equals(byte.class)) {
078                                    return GetterUtil.DEFAULT_BYTE;
079                            }
080                            else if (returnType.equals(double.class)) {
081                                    return GetterUtil.DEFAULT_DOUBLE;
082                            }
083                            else if (returnType.equals(float.class)) {
084                                    return GetterUtil.DEFAULT_FLOAT;
085                            }
086                            else if (returnType.equals(int.class)) {
087                                    return GetterUtil.DEFAULT_INTEGER;
088                            }
089                            else if (returnType.equals(long.class)) {
090                                    return GetterUtil.DEFAULT_LONG;
091                            }
092                            else if (returnType.equals(short.class)) {
093                                    return GetterUtil.DEFAULT_SHORT;
094                            }
095    
096                            return method.getDefaultValue();
097                    }
098    
099            }
100    
101            private static class ServiceTrackedInvocationHandler<T>
102                    implements InvocationHandler {
103    
104                    @Override
105                    public Object invoke(Object proxy, Method method, Object[] arguments)
106                            throws Throwable {
107    
108                            T service = _serviceTracker.getService();
109    
110                            if (service != null) {
111                                    try {
112                                            return method.invoke(service, arguments);
113                                    }
114                                    catch (InvocationTargetException ite) {
115                                            throw ite.getTargetException();
116                                    }
117                            }
118    
119                            Class<?> returnType = method.getReturnType();
120    
121                            if (returnType.equals(boolean.class)) {
122                                    return GetterUtil.DEFAULT_BOOLEAN;
123                            }
124                            else if (returnType.equals(byte.class)) {
125                                    return GetterUtil.DEFAULT_BYTE;
126                            }
127                            else if (returnType.equals(double.class)) {
128                                    return GetterUtil.DEFAULT_DOUBLE;
129                            }
130                            else if (returnType.equals(float.class)) {
131                                    return GetterUtil.DEFAULT_FLOAT;
132                            }
133                            else if (returnType.equals(int.class)) {
134                                    return GetterUtil.DEFAULT_INTEGER;
135                            }
136                            else if (returnType.equals(long.class)) {
137                                    return GetterUtil.DEFAULT_LONG;
138                            }
139                            else if (returnType.equals(short.class)) {
140                                    return GetterUtil.DEFAULT_SHORT;
141                            }
142    
143                            return method.getDefaultValue();
144                    }
145    
146                    private ServiceTrackedInvocationHandler(Class<T> interfaceClass) {
147                            Registry registry = RegistryUtil.getRegistry();
148    
149                            _serviceTracker = registry.trackServices(interfaceClass);
150    
151                            _serviceTracker.open();
152                    }
153    
154                    private final ServiceTracker<T, T> _serviceTracker;
155    
156            }
157    
158    }