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