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