001
014
015 package com.liferay.portal.spring.aop;
016
017 import com.liferay.portal.kernel.util.ProxyUtil;
018 import com.liferay.portal.kernel.util.ReflectionUtil;
019
020 import java.io.Closeable;
021 import java.io.IOException;
022
023 import java.lang.reflect.Constructor;
024 import java.lang.reflect.Field;
025
026 import org.springframework.aop.TargetSource;
027 import org.springframework.aop.framework.AdvisedSupport;
028 import org.springframework.aop.target.SingletonTargetSource;
029
030
033 public class ServiceWrapperProxyUtil {
034
035 public static Closeable createProxy(
036 Object springServiceProxy, Class<?> serviceWrapperClass)
037 throws Exception {
038
039 if (!ProxyUtil.isProxyClass(springServiceProxy.getClass())) {
040 throw new IllegalArgumentException(
041 springServiceProxy + " is not a Spring service proxy");
042 }
043
044 final AdvisedSupport advisedSupport =
045 ServiceBeanAopProxy.getAdvisedSupport(springServiceProxy);
046
047 final TargetSource targetSource = advisedSupport.getTargetSource();
048
049 final Object previousService = targetSource.getTarget();
050
051 Constructor<?>[] constructors =
052 serviceWrapperClass.getDeclaredConstructors();
053
054 Constructor<?> constructor = constructors[0];
055
056 constructor.setAccessible(true);
057
058 advisedSupport.setTargetSource(
059 new SingletonTargetSource(
060 constructor.newInstance(previousService)));
061
062 return new Closeable() {
063
064 @Override
065 public void close() throws IOException {
066 advisedSupport.setTargetSource(targetSource);
067
068 try {
069 targetSource.releaseTarget(previousService);
070 }
071 catch (Exception e) {
072 throw new IOException(e);
073 }
074 }
075
076 };
077 }
078
079 public static Closeable injectFieldProxy(
080 Object springServiceProxy, String fieldName, Class<?> wrapperClass)
081 throws Exception {
082
083 if (!ProxyUtil.isProxyClass(springServiceProxy.getClass())) {
084 throw new IllegalArgumentException(
085 springServiceProxy + " is not a Spring service proxy");
086 }
087
088 AdvisedSupport advisedSupport = ServiceBeanAopProxy.getAdvisedSupport(
089 springServiceProxy);
090
091 TargetSource targetSource = advisedSupport.getTargetSource();
092
093 final Object targetService = targetSource.getTarget();
094
095 Class<?> clazz = targetService.getClass();
096
097 Field field = null;
098
099 while (clazz != null) {
100 try {
101 field = ReflectionUtil.getDeclaredField(clazz, fieldName);
102
103 break;
104 }
105 catch (NoSuchFieldException nsfe) {
106 clazz = clazz.getSuperclass();
107 }
108 }
109
110 if (field == null) {
111 throw new IllegalArgumentException(
112 "Unable to locate field " + fieldName + " in " + targetService);
113 }
114
115 final Field finalField = field;
116
117 final Object previousValue = finalField.get(targetService);
118
119 Constructor<?>[] constructors = wrapperClass.getDeclaredConstructors();
120
121 Constructor<?> constructor = constructors[0];
122
123 constructor.setAccessible(true);
124
125 finalField.set(targetService, constructor.newInstance(previousValue));
126
127 return new Closeable() {
128
129 @Override
130 public void close() throws IOException {
131 try {
132 finalField.set(targetService, previousValue);
133 }
134 catch (ReflectiveOperationException roe) {
135 throw new IOException(roe);
136 }
137 }
138
139 };
140 }
141
142 }