001
014
015 package com.liferay.portal.jsonwebservice;
016
017 import com.liferay.portal.kernel.bean.ClassLoaderBeanHandler;
018 import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceScannerStrategy;
019 import com.liferay.portal.kernel.service.ServiceWrapper;
020 import com.liferay.portal.kernel.util.ProxyUtil;
021 import com.liferay.portal.spring.aop.AdvisedSupportProxy;
022 import com.liferay.portal.spring.aop.ServiceBeanAopProxy;
023
024 import java.lang.reflect.InvocationHandler;
025 import java.lang.reflect.Method;
026
027 import java.util.ArrayList;
028 import java.util.Arrays;
029 import java.util.LinkedList;
030 import java.util.List;
031 import java.util.Queue;
032
033 import org.springframework.aop.TargetSource;
034 import org.springframework.aop.framework.AdvisedSupport;
035
036
039 public class SpringJSONWebServiceScannerStrategy
040 implements JSONWebServiceScannerStrategy {
041
042 @Override
043 public MethodDescriptor[] scan(Object service) {
044 Class<?> clazz = null;
045
046 try {
047 clazz = getTargetClass(service);
048 }
049 catch (Exception e) {
050 return new MethodDescriptor[0];
051 }
052
053 Method[] methods = clazz.getMethods();
054
055 List<MethodDescriptor> methodDescriptors = new ArrayList<>(
056 methods.length);
057
058 for (Method method : methods) {
059 Class<?> declaringClass = method.getDeclaringClass();
060
061 if ((declaringClass != clazz) || !isInterfaceMethod(method)) {
062 continue;
063 }
064
065 methodDescriptors.add(new MethodDescriptor(method));
066 }
067
068 return methodDescriptors.toArray(
069 new MethodDescriptor[methodDescriptors.size()]);
070 }
071
072
075 protected Class<?> getTargetClass(Object service) throws Exception {
076 while (ProxyUtil.isProxyClass(service.getClass())) {
077 InvocationHandler invocationHandler =
078 ProxyUtil.getInvocationHandler(service);
079
080 if (invocationHandler instanceof AdvisedSupportProxy) {
081 AdvisedSupport advisedSupport =
082 ServiceBeanAopProxy.getAdvisedSupport(service);
083
084 TargetSource targetSource = advisedSupport.getTargetSource();
085
086 service = targetSource.getTarget();
087 }
088 else if (invocationHandler instanceof ClassLoaderBeanHandler) {
089 ClassLoaderBeanHandler classLoaderBeanHandler =
090 (ClassLoaderBeanHandler)invocationHandler;
091
092 Object bean = classLoaderBeanHandler.getBean();
093
094 if (bean instanceof ServiceWrapper) {
095 ServiceWrapper<?> serviceWrapper = (ServiceWrapper<?>)bean;
096
097 service = serviceWrapper.getWrappedService();
098 }
099 else {
100 service = bean;
101 }
102 }
103 }
104
105 return service.getClass();
106 }
107
108 protected boolean isInterfaceMethod(Method method) {
109 Class<?> declaringClass = method.getDeclaringClass();
110
111 if (declaringClass.isInterface()) {
112 return true;
113 }
114
115 Queue<Class<?>> queue = new LinkedList<>(
116 Arrays.asList(declaringClass.getInterfaces()));
117
118 Class<?> superClass = declaringClass.getSuperclass();
119
120 if (superClass != null) {
121 queue.add(superClass);
122 }
123
124 Class<?> clazz = null;
125
126 while ((clazz = queue.poll()) != null) {
127 if (clazz.isInterface()) {
128 try {
129 clazz.getMethod(
130 method.getName(), method.getParameterTypes());
131
132 return true;
133 }
134 catch (ReflectiveOperationException roe) {
135 }
136 }
137 else {
138 queue.addAll(Arrays.asList(clazz.getInterfaces()));
139
140 superClass = clazz.getSuperclass();
141
142 if (superClass != null) {
143 queue.add(superClass);
144 }
145 }
146 }
147
148 return false;
149 }
150
151 }