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.jsonwebservice;
016    
017    import com.liferay.portal.kernel.annotation.AnnotationLocator;
018    import com.liferay.portal.kernel.bean.BeanLocator;
019    import com.liferay.portal.kernel.bean.BeanLocatorException;
020    import com.liferay.portal.kernel.jsonwebservice.JSONWebService;
021    import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceActionsManagerUtil;
022    import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceMappingResolver;
023    import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceMode;
024    import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceNaming;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.util.ProxyUtil;
028    import com.liferay.portal.spring.aop.ServiceBeanAopProxy;
029    import com.liferay.portal.util.PropsValues;
030    
031    import java.lang.reflect.Method;
032    
033    import java.util.HashMap;
034    import java.util.Map;
035    
036    import org.springframework.aop.TargetSource;
037    import org.springframework.aop.framework.AdvisedSupport;
038    
039    /**
040     * @author Igor Spasic
041     */
042    public class JSONWebServiceRegistrator {
043    
044            public JSONWebServiceRegistrator() {
045                    _jsonWebServiceNaming = new JSONWebServiceNaming();
046    
047                    _jsonWebServiceMappingResolver = new JSONWebServiceMappingResolver(
048                            _jsonWebServiceNaming);
049            }
050    
051            public JSONWebServiceRegistrator(
052                    JSONWebServiceNaming jsonWebServiceNaming) {
053    
054                    _jsonWebServiceNaming = jsonWebServiceNaming;
055    
056                    _jsonWebServiceMappingResolver = new JSONWebServiceMappingResolver(
057                            _jsonWebServiceNaming);
058            }
059    
060            public void processAllBeans(String contextPath, BeanLocator beanLocator) {
061                    if (beanLocator == null) {
062                            return;
063                    }
064    
065                    String[] beanNames = beanLocator.getNames();
066    
067                    for (String beanName : beanNames) {
068                            processBean(contextPath, beanLocator, beanName);
069                    }
070            }
071    
072            public void processBean(
073                    String contextPath, BeanLocator beanLocator, String beanName) {
074    
075                    if (!PropsValues.JSON_WEB_SERVICE_ENABLED) {
076                            return;
077                    }
078    
079                    Object bean = null;
080    
081                    try {
082                            bean = beanLocator.locate(beanName);
083                    }
084                    catch (BeanLocatorException e) {
085                            return;
086                    }
087    
088                    JSONWebService jsonWebService = AnnotationLocator.locate(
089                            bean.getClass(), JSONWebService.class);
090    
091                    if (jsonWebService != null) {
092                            try {
093                                    onJSONWebServiceBean(contextPath, bean, jsonWebService);
094                            }
095                            catch (Exception e) {
096                                    _log.error(e, e);
097                            }
098                    }
099            }
100    
101            public void processBean(String contextPath, Object bean) {
102                    if (!PropsValues.JSON_WEB_SERVICE_ENABLED) {
103                            return;
104                    }
105    
106                    JSONWebService jsonWebService = AnnotationLocator.locate(
107                            bean.getClass(), JSONWebService.class);
108    
109                    if (jsonWebService == null) {
110                            return;
111                    }
112    
113                    try {
114                            onJSONWebServiceBean(contextPath, bean, jsonWebService);
115                    }
116                    catch (Exception e) {
117                            _log.error(e, e);
118                    }
119            }
120    
121            public void setWireViaUtil(boolean wireViaUtil) {
122                    this._wireViaUtil = wireViaUtil;
123            }
124    
125            protected Class<?> getTargetClass(Object service) throws Exception {
126                    if (ProxyUtil.isProxyClass(service.getClass())) {
127                            AdvisedSupport advisedSupport =
128                                    ServiceBeanAopProxy.getAdvisedSupport(service);
129    
130                            TargetSource targetSource = advisedSupport.getTargetSource();
131    
132                            service = targetSource.getTarget();
133                    }
134    
135                    return service.getClass();
136            }
137    
138            protected Class<?> loadUtilClass(Class<?> implementationClass)
139                    throws ClassNotFoundException {
140    
141                    if (_utilClasses == null) {
142                            _utilClasses = new HashMap<Class<?>, Class<?>>();
143                    }
144    
145                    Class<?> utilClass = _utilClasses.get(implementationClass);
146    
147                    if (utilClass != null) {
148                            return utilClass;
149                    }
150    
151                    String utilClassName =
152                            _jsonWebServiceNaming.convertImplClassNameToUtilClassName(
153                                    implementationClass);
154    
155                    ClassLoader classLoader = implementationClass.getClassLoader();
156    
157                    utilClass = classLoader.loadClass(utilClassName);
158    
159                    _utilClasses.put(implementationClass, utilClass);
160    
161                    return utilClass;
162            }
163    
164            protected void onJSONWebServiceBean(
165                            String contextPath, Object serviceBean,
166                            JSONWebService jsonWebService)
167                    throws Exception {
168    
169                    JSONWebServiceMode jsonWebServiceMode = JSONWebServiceMode.MANUAL;
170    
171                    if (jsonWebService != null) {
172                            jsonWebServiceMode = jsonWebService.mode();
173                    }
174    
175                    Class<?> serviceBeanClass = getTargetClass(serviceBean);
176    
177                    Method[] methods = serviceBeanClass.getMethods();
178    
179                    for (Method method : methods) {
180                            Class<?> declaringClass = method.getDeclaringClass();
181    
182                            if (declaringClass != serviceBeanClass) {
183                                    continue;
184                            }
185    
186                            if (!_jsonWebServiceNaming.isIncludedMethod(method)) {
187                                    continue;
188                            }
189    
190                            JSONWebService methodJSONWebService = method.getAnnotation(
191                                    JSONWebService.class);
192    
193                            if (jsonWebServiceMode.equals(JSONWebServiceMode.AUTO)) {
194                                    if (methodJSONWebService == null) {
195                                            registerJSONWebServiceAction(
196                                                    contextPath, serviceBean, serviceBeanClass, method);
197                                    }
198                                    else {
199                                            JSONWebServiceMode methodJSONWebServiceMode =
200                                                    methodJSONWebService.mode();
201    
202                                            if (!methodJSONWebServiceMode.equals(
203                                                            JSONWebServiceMode.IGNORE)) {
204    
205                                                    registerJSONWebServiceAction(
206                                                            contextPath, serviceBean, serviceBeanClass, method);
207                                            }
208                                    }
209                            }
210                            else if (methodJSONWebService != null) {
211                                    JSONWebServiceMode methodJSONWebServiceMode =
212                                            methodJSONWebService.mode();
213    
214                                    if (!methodJSONWebServiceMode.equals(
215                                                    JSONWebServiceMode.IGNORE)) {
216    
217                                            registerJSONWebServiceAction(
218                                                    contextPath, serviceBean, serviceBeanClass, method);
219                                    }
220                            }
221                    }
222            }
223    
224            protected void registerJSONWebServiceAction(
225                            String contextPath, Object serviceBean, Class<?> serviceBeanClass,
226                            Method method)
227                    throws Exception {
228    
229                    String httpMethod = _jsonWebServiceMappingResolver.resolveHttpMethod(
230                            method);
231    
232                    if (!_jsonWebServiceNaming.isValidHttpMethod(httpMethod)) {
233                            return;
234                    }
235    
236                    if (_wireViaUtil) {
237                            Class<?> utilClass = loadUtilClass(serviceBeanClass);
238    
239                            try {
240                                    method = utilClass.getMethod(
241                                            method.getName(), method.getParameterTypes());
242                            }
243                            catch (NoSuchMethodException nsme) {
244                                    return;
245                            }
246                    }
247    
248                    String path = _jsonWebServiceMappingResolver.resolvePath(
249                            serviceBeanClass, method);
250    
251                    if (!_jsonWebServiceNaming.isIncludedPath(contextPath, path)) {
252                            return;
253                    }
254    
255                    if (_wireViaUtil) {
256                            JSONWebServiceActionsManagerUtil.registerJSONWebServiceAction(
257                                    contextPath, method.getDeclaringClass(), method, path,
258                                    httpMethod);
259                    }
260                    else {
261                            JSONWebServiceActionsManagerUtil.registerJSONWebServiceAction(
262                                    contextPath, serviceBean, serviceBeanClass, method, path,
263                                    httpMethod);
264                    }
265            }
266    
267            private static Log _log = LogFactoryUtil.getLog(
268                    JSONWebServiceRegistrator.class);
269    
270            private final JSONWebServiceMappingResolver _jsonWebServiceMappingResolver;
271            private final JSONWebServiceNaming _jsonWebServiceNaming;
272            private Map<Class<?>, Class<?>> _utilClasses;
273            private boolean _wireViaUtil;
274    
275    }