001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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 ble) {
085                            return;
086                    }
087    
088                    if (bean == null) {
089                            return;
090                    }
091    
092                    JSONWebService jsonWebService = AnnotationLocator.locate(
093                            bean.getClass(), JSONWebService.class);
094    
095                    if (jsonWebService != null) {
096                            try {
097                                    onJSONWebServiceBean(contextPath, bean, jsonWebService);
098                            }
099                            catch (Exception e) {
100                                    _log.error(e, e);
101                            }
102                    }
103            }
104    
105            public void processBean(String contextPath, Object bean) {
106                    if (!PropsValues.JSON_WEB_SERVICE_ENABLED) {
107                            return;
108                    }
109    
110                    JSONWebService jsonWebService = AnnotationLocator.locate(
111                            bean.getClass(), JSONWebService.class);
112    
113                    if (jsonWebService == null) {
114                            return;
115                    }
116    
117                    try {
118                            onJSONWebServiceBean(contextPath, bean, jsonWebService);
119                    }
120                    catch (Exception e) {
121                            _log.error(e, e);
122                    }
123            }
124    
125            public void setWireViaUtil(boolean wireViaUtil) {
126                    this._wireViaUtil = wireViaUtil;
127            }
128    
129            protected Class<?> getTargetClass(Object service) throws Exception {
130                    if (ProxyUtil.isProxyClass(service.getClass())) {
131                            AdvisedSupport advisedSupport =
132                                    ServiceBeanAopProxy.getAdvisedSupport(service);
133    
134                            TargetSource targetSource = advisedSupport.getTargetSource();
135    
136                            service = targetSource.getTarget();
137                    }
138    
139                    return service.getClass();
140            }
141    
142            protected Class<?> loadUtilClass(Class<?> implementationClass)
143                    throws ClassNotFoundException {
144    
145                    if (_utilClasses == null) {
146                            _utilClasses = new HashMap<Class<?>, Class<?>>();
147                    }
148    
149                    Class<?> utilClass = _utilClasses.get(implementationClass);
150    
151                    if (utilClass != null) {
152                            return utilClass;
153                    }
154    
155                    String utilClassName =
156                            _jsonWebServiceNaming.convertImplClassNameToUtilClassName(
157                                    implementationClass);
158    
159                    ClassLoader classLoader = implementationClass.getClassLoader();
160    
161                    utilClass = classLoader.loadClass(utilClassName);
162    
163                    _utilClasses.put(implementationClass, utilClass);
164    
165                    return utilClass;
166            }
167    
168            protected void onJSONWebServiceBean(
169                            String contextPath, Object serviceBean,
170                            JSONWebService jsonWebService)
171                    throws Exception {
172    
173                    JSONWebServiceMode jsonWebServiceMode = JSONWebServiceMode.MANUAL;
174    
175                    if (jsonWebService != null) {
176                            jsonWebServiceMode = jsonWebService.mode();
177                    }
178    
179                    Class<?> serviceBeanClass = getTargetClass(serviceBean);
180    
181                    Method[] methods = serviceBeanClass.getMethods();
182    
183                    for (Method method : methods) {
184                            Class<?> declaringClass = method.getDeclaringClass();
185    
186                            if (declaringClass != serviceBeanClass) {
187                                    continue;
188                            }
189    
190                            if (!_jsonWebServiceNaming.isIncludedMethod(method)) {
191                                    continue;
192                            }
193    
194                            JSONWebService methodJSONWebService = method.getAnnotation(
195                                    JSONWebService.class);
196    
197                            if (jsonWebServiceMode.equals(JSONWebServiceMode.AUTO)) {
198                                    if (methodJSONWebService == null) {
199                                            registerJSONWebServiceAction(
200                                                    contextPath, serviceBean, serviceBeanClass, method);
201                                    }
202                                    else {
203                                            JSONWebServiceMode methodJSONWebServiceMode =
204                                                    methodJSONWebService.mode();
205    
206                                            if (!methodJSONWebServiceMode.equals(
207                                                            JSONWebServiceMode.IGNORE)) {
208    
209                                                    registerJSONWebServiceAction(
210                                                            contextPath, serviceBean, serviceBeanClass, method);
211                                            }
212                                    }
213                            }
214                            else if (methodJSONWebService != null) {
215                                    JSONWebServiceMode methodJSONWebServiceMode =
216                                            methodJSONWebService.mode();
217    
218                                    if (!methodJSONWebServiceMode.equals(
219                                                    JSONWebServiceMode.IGNORE)) {
220    
221                                            registerJSONWebServiceAction(
222                                                    contextPath, serviceBean, serviceBeanClass, method);
223                                    }
224                            }
225                    }
226            }
227    
228            protected void registerJSONWebServiceAction(
229                            String contextPath, Object serviceBean, Class<?> serviceBeanClass,
230                            Method method)
231                    throws Exception {
232    
233                    String httpMethod = _jsonWebServiceMappingResolver.resolveHttpMethod(
234                            method);
235    
236                    if (!_jsonWebServiceNaming.isValidHttpMethod(httpMethod)) {
237                            return;
238                    }
239    
240                    if (_wireViaUtil) {
241                            Class<?> utilClass = loadUtilClass(serviceBeanClass);
242    
243                            try {
244                                    method = utilClass.getMethod(
245                                            method.getName(), method.getParameterTypes());
246                            }
247                            catch (NoSuchMethodException nsme) {
248                                    return;
249                            }
250                    }
251    
252                    String path = _jsonWebServiceMappingResolver.resolvePath(
253                            serviceBeanClass, method);
254    
255                    if (!_jsonWebServiceNaming.isIncludedPath(contextPath, path)) {
256                            return;
257                    }
258    
259                    if (_wireViaUtil) {
260                            JSONWebServiceActionsManagerUtil.registerJSONWebServiceAction(
261                                    contextPath, method.getDeclaringClass(), method, path,
262                                    httpMethod);
263                    }
264                    else {
265                            JSONWebServiceActionsManagerUtil.registerJSONWebServiceAction(
266                                    contextPath, serviceBean, serviceBeanClass, method, path,
267                                    httpMethod);
268                    }
269            }
270    
271            private static Log _log = LogFactoryUtil.getLog(
272                    JSONWebServiceRegistrator.class);
273    
274            private final JSONWebServiceMappingResolver _jsonWebServiceMappingResolver;
275            private final JSONWebServiceNaming _jsonWebServiceNaming;
276            private Map<Class<?>, Class<?>> _utilClasses;
277            private boolean _wireViaUtil;
278    
279    }