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