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
076 protected Class<?> getTargetClass(Object service) throws Exception {
077 while (ProxyUtil.isProxyClass(service.getClass())) {
078 InvocationHandler invocationHandler =
079 ProxyUtil.getInvocationHandler(service);
080
081 if (invocationHandler instanceof AdvisedSupportProxy) {
082 AdvisedSupport advisedSupport =
083 ServiceBeanAopProxy.getAdvisedSupport(service);
084
085 TargetSource targetSource = advisedSupport.getTargetSource();
086
087 service = targetSource.getTarget();
088 }
089 else if (invocationHandler instanceof ClassLoaderBeanHandler) {
090 ClassLoaderBeanHandler classLoaderBeanHandler =
091 (ClassLoaderBeanHandler)invocationHandler;
092
093 Object bean = classLoaderBeanHandler.getBean();
094
095 if (bean instanceof ServiceWrapper) {
096 ServiceWrapper<?> serviceWrapper = (ServiceWrapper<?>)bean;
097
098 service = serviceWrapper.getWrappedService();
099 }
100 else {
101 service = bean;
102 }
103 }
104 }
105
106 return service.getClass();
107 }
108
109 protected boolean isInterfaceMethod(Method method) {
110 Class<?> declaringClass = method.getDeclaringClass();
111
112 if (declaringClass.isInterface()) {
113 return true;
114 }
115
116 Queue<Class<?>> queue = new LinkedList<>(
117 Arrays.asList(declaringClass.getInterfaces()));
118
119 Class<?> superClass = declaringClass.getSuperclass();
120
121 if (superClass != null) {
122 queue.add(superClass);
123 }
124
125 Class<?> clazz = null;
126
127 while ((clazz = queue.poll()) != null) {
128 if (clazz.isInterface()) {
129 try {
130 clazz.getMethod(
131 method.getName(), method.getParameterTypes());
132
133 return true;
134 }
135 catch (ReflectiveOperationException roe) {
136 }
137 }
138 else {
139 queue.addAll(Arrays.asList(clazz.getInterfaces()));
140
141 superClass = clazz.getSuperclass();
142
143 if (superClass != null) {
144 queue.add(superClass);
145 }
146 }
147 }
148
149 return false;
150 }
151
152 }