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