001
014
015 package com.liferay.portal.deploy.hot;
016
017 import com.liferay.portal.kernel.bean.BeanLocatorException;
018 import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.ProxyUtil;
022 import com.liferay.portal.service.ServiceWrapper;
023 import com.liferay.portal.spring.aop.ServiceBeanAopCacheManagerUtil;
024 import com.liferay.portal.spring.aop.ServiceBeanAopProxy;
025 import com.liferay.registry.Registry;
026 import com.liferay.registry.RegistryUtil;
027 import com.liferay.registry.ServiceReference;
028 import com.liferay.registry.ServiceTracker;
029 import com.liferay.registry.ServiceTrackerCustomizer;
030
031 import java.lang.reflect.Method;
032
033 import org.springframework.aop.TargetSource;
034 import org.springframework.aop.framework.AdvisedSupport;
035
036
039 public class ServiceWrapperRegistry {
040
041 public ServiceWrapperRegistry() {
042 Registry registry = RegistryUtil.getRegistry();
043
044 _serviceTracker = registry.trackServices(
045 ServiceWrapper.class.getName(),
046 new ServiceWrapperServiceTrackerCustomizer());
047
048 _serviceTracker.open();
049 }
050
051 public void close() {
052 _serviceTracker.close();
053 }
054
055 private static final Log _log = LogFactoryUtil.getLog(
056 ServiceWrapperRegistry.class);
057
058 private final ServiceTracker<ServiceWrapper<?>, ServiceBag<?>>
059 _serviceTracker;
060
061 private class ServiceWrapperServiceTrackerCustomizer
062 implements ServiceTrackerCustomizer<ServiceWrapper<?>, ServiceBag<?>> {
063
064 @Override
065 public ServiceBag<?> addingService(
066 ServiceReference<ServiceWrapper<?>> serviceReference) {
067
068 Registry registry = RegistryUtil.getRegistry();
069
070 ServiceWrapper<?> serviceWrapper = registry.getService(
071 serviceReference);
072
073 try {
074 return _getServiceBag(serviceWrapper);
075 }
076 catch (Throwable t) {
077 _log.error(t, t);
078 }
079 finally {
080 ServiceBeanAopCacheManagerUtil.reset();
081 }
082
083 return null;
084 }
085
086 @Override
087 public void modifiedService(
088 ServiceReference<ServiceWrapper<?>> serviceReference,
089 ServiceBag<?> serviceHolder) {
090 }
091
092 @Override
093 public void removedService(
094 ServiceReference<ServiceWrapper<?>> serviceReference,
095 ServiceBag<?> serviceBag) {
096
097 Registry registry = RegistryUtil.getRegistry();
098
099 registry.ungetService(serviceReference);
100
101 try {
102 serviceBag.replace();
103
104 ServiceBeanAopCacheManagerUtil.reset();
105 }
106 catch (Exception e) {
107 _log.error(e, e);
108 }
109 }
110
111 protected Object getServiceProxy(Class<?> serviceTypeClass) {
112 Object service = null;
113
114 try {
115 service = PortalBeanLocatorUtil.locate(
116 serviceTypeClass.getName());
117 }
118 catch (BeanLocatorException ble) {
119 Registry registry = RegistryUtil.getRegistry();
120
121 service = registry.getService(serviceTypeClass);
122 }
123
124 return service;
125 }
126
127 private <T> ServiceBag<?> _getServiceBag(
128 ServiceWrapper<T> serviceWrapper)
129 throws Throwable {
130
131 Class<?> clazz = serviceWrapper.getClass();
132
133 ClassLoader classLoader = clazz.getClassLoader();
134
135 Method method = clazz.getMethod(
136 "getWrappedService", new Class<?>[0]);
137
138 Class<?> serviceTypeClass = method.getReturnType();
139
140 Object serviceProxy = getServiceProxy(serviceTypeClass);
141
142 if (!ProxyUtil.isProxyClass(serviceProxy.getClass())) {
143 _log.error(
144 "Service hooks require Spring to be configured to use " +
145 "JdkDynamicProxy and will not work with CGLIB");
146
147 return null;
148 }
149
150 AdvisedSupport advisedSupport =
151 ServiceBeanAopProxy.getAdvisedSupport(serviceProxy);
152
153 TargetSource targetSource = advisedSupport.getTargetSource();
154
155 serviceWrapper.setWrappedService((T)targetSource.getTarget());
156
157 return new ServiceBag<>(
158 classLoader, advisedSupport, serviceTypeClass, serviceWrapper);
159 }
160
161 }
162
163 }