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.jsonwebservice.JSONWebServiceRegistrator;
026    import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceScannerStrategy;
027    import com.liferay.portal.kernel.log.Log;
028    import com.liferay.portal.kernel.log.LogFactoryUtil;
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    /**
037     * @author Igor Spasic
038     */
039    public class DefaultJSONWebServiceRegistrator
040            implements JSONWebServiceRegistrator {
041    
042            public DefaultJSONWebServiceRegistrator() {
043                    _jsonWebServiceNaming =
044                            JSONWebServiceActionsManagerUtil.getJSONWebServiceNaming();
045    
046                    _jsonWebServiceMappingResolver = new JSONWebServiceMappingResolver(
047                            _jsonWebServiceNaming);
048    
049                    _jsonWebServiceScannerStrategy =
050                            new SpringJSONWebServiceScannerStrategy();
051            }
052    
053            public DefaultJSONWebServiceRegistrator(
054                    JSONWebServiceNaming jsonWebServiceNaming,
055                    JSONWebServiceScannerStrategy jsonWebServiceScannerStrategy) {
056    
057                    _jsonWebServiceNaming = jsonWebServiceNaming;
058                    _jsonWebServiceScannerStrategy = jsonWebServiceScannerStrategy;
059    
060                    _jsonWebServiceMappingResolver = new JSONWebServiceMappingResolver(
061                            _jsonWebServiceNaming);
062            }
063    
064            public DefaultJSONWebServiceRegistrator(
065                    JSONWebServiceScannerStrategy jsonWebServiceScannerStrategy) {
066    
067                    this(
068                            JSONWebServiceActionsManagerUtil.getJSONWebServiceNaming(),
069                            jsonWebServiceScannerStrategy);
070            }
071    
072            public void processAllBeans(
073                    String contextName, String contextPath, BeanLocator beanLocator) {
074    
075                    if (beanLocator == null) {
076                            return;
077                    }
078    
079                    String[] beanNames = beanLocator.getNames();
080    
081                    for (String beanName : beanNames) {
082                            processBean(contextName, contextPath, beanLocator, beanName);
083                    }
084            }
085    
086            public void processBean(
087                    String contextName, String contextPath, BeanLocator beanLocator,
088                    String beanName) {
089    
090                    if (!PropsValues.JSON_WEB_SERVICE_ENABLED) {
091                            return;
092                    }
093    
094                    Object bean = null;
095    
096                    try {
097                            bean = beanLocator.locate(beanName);
098                    }
099                    catch (BeanLocatorException ble) {
100                            return;
101                    }
102    
103                    if (bean == null) {
104                            return;
105                    }
106    
107                    JSONWebService jsonWebService = AnnotationLocator.locate(
108                            bean.getClass(), JSONWebService.class);
109    
110                    if (jsonWebService != null) {
111                            try {
112                                    onJSONWebServiceBean(
113                                            contextName, contextPath, bean, jsonWebService);
114                            }
115                            catch (Exception e) {
116                                    _log.error(e, e);
117                            }
118                    }
119            }
120    
121            @Override
122            public void processBean(
123                    String contextName, String contextPath, Object bean) {
124    
125                    if (!PropsValues.JSON_WEB_SERVICE_ENABLED) {
126                            return;
127                    }
128    
129                    JSONWebService jsonWebService = AnnotationLocator.locate(
130                            bean.getClass(), JSONWebService.class);
131    
132                    if (jsonWebService == null) {
133                            return;
134                    }
135    
136                    try {
137                            onJSONWebServiceBean(
138                                    contextName, contextPath, bean, jsonWebService);
139                    }
140                    catch (Exception e) {
141                            _log.error(e, e);
142                    }
143            }
144    
145            public void setWireViaUtil(boolean wireViaUtil) {
146                    this._wireViaUtil = wireViaUtil;
147            }
148    
149            protected Class<?> loadUtilClass(Class<?> implementationClass)
150                    throws ClassNotFoundException {
151    
152                    if (_utilClasses == null) {
153                            _utilClasses = new HashMap<>();
154                    }
155    
156                    Class<?> utilClass = _utilClasses.get(implementationClass);
157    
158                    if (utilClass != null) {
159                            return utilClass;
160                    }
161    
162                    String utilClassName =
163                            _jsonWebServiceNaming.convertServiceImplClassToUtilClassName(
164                                    implementationClass);
165    
166                    ClassLoader classLoader = implementationClass.getClassLoader();
167    
168                    utilClass = classLoader.loadClass(utilClassName);
169    
170                    _utilClasses.put(implementationClass, utilClass);
171    
172                    return utilClass;
173            }
174    
175            protected void onJSONWebServiceBean(
176                            String contextName, String contextPath, Object serviceBean,
177                            JSONWebService jsonWebService)
178                    throws Exception {
179    
180                    JSONWebServiceMode jsonWebServiceMode = JSONWebServiceMode.MANUAL;
181    
182                    if (jsonWebService != null) {
183                            jsonWebServiceMode = jsonWebService.mode();
184                    }
185    
186                    JSONWebServiceScannerStrategy.MethodDescriptor[] methodDescriptors =
187                            _jsonWebServiceScannerStrategy.scan(serviceBean);
188    
189                    for (JSONWebServiceScannerStrategy.MethodDescriptor methodDescriptor :
190                                    methodDescriptors) {
191    
192                            Method method = methodDescriptor.getMethod();
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,
205                                                    methodDescriptor.getDeclaringClass(), 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                                                            methodDescriptor.getDeclaringClass(), 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,
229                                                    methodDescriptor.getDeclaringClass(), 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                    DefaultJSONWebServiceRegistrator.class);
280    
281            private final JSONWebServiceMappingResolver _jsonWebServiceMappingResolver;
282            private final JSONWebServiceNaming _jsonWebServiceNaming;
283            private final JSONWebServiceScannerStrategy _jsonWebServiceScannerStrategy;
284            private Map<Class<?>, Class<?>> _utilClasses;
285            private boolean _wireViaUtil;
286    
287    }