001
014
015 package com.liferay.portal.model;
016
017 import com.liferay.portal.kernel.bean.ClassLoaderBeanHandler;
018 import com.liferay.portal.kernel.util.ProxyUtil;
019 import com.liferay.portal.kernel.util.ReflectionUtil;
020 import com.liferay.registry.Filter;
021 import com.liferay.registry.Registry;
022 import com.liferay.registry.RegistryUtil;
023 import com.liferay.registry.ServiceReference;
024 import com.liferay.registry.ServiceRegistration;
025 import com.liferay.registry.ServiceTracker;
026 import com.liferay.registry.ServiceTrackerCustomizer;
027
028 import java.lang.reflect.InvocationHandler;
029
030 import java.util.ArrayList;
031 import java.util.List;
032 import java.util.Map;
033 import java.util.concurrent.ConcurrentHashMap;
034 import java.util.concurrent.ConcurrentMap;
035
036
039 public class ModelListenerRegistrationUtil {
040
041 public static <T> ModelListener<T>[] getModelListeners(Class<T> clazz) {
042 return _instance._getModelListeners(clazz);
043 }
044
045 public static void register(ModelListener<?> modelListener) {
046 _instance._register(modelListener.getClass().getName(), modelListener);
047 }
048
049 public static void unregister(ModelListener<?> modelListener) {
050 _instance._unregister(modelListener.getClass().getName());
051 }
052
053 private ModelListenerRegistrationUtil() {
054 Registry registry = RegistryUtil.getRegistry();
055
056 Filter filter = registry.getFilter(
057 "(objectClass=" + ModelListener.class.getName() + ")");
058
059 _serviceTracker = registry.trackServices(
060 filter, new ModelListenerTrackerCustomizer());
061
062 _serviceTracker.open();
063 }
064
065 private <T> ModelListener<T>[] _getModelListeners(Class<T> clazz) {
066 List<ModelListener<?>> modelListeners = _modelListeners.get(clazz);
067
068 if (modelListeners == null) {
069 modelListeners = new ArrayList<ModelListener<?>>();
070
071 List<ModelListener<?>> previousList = _modelListeners.putIfAbsent(
072 clazz, modelListeners);
073
074 if (previousList != null) {
075 modelListeners = previousList;
076 }
077 }
078
079 return modelListeners.toArray(new ModelListener[modelListeners.size()]);
080 }
081
082 private <T> void _register(
083 String className, ModelListener<T> modelListener) {
084
085 Registry registry = RegistryUtil.getRegistry();
086
087 ServiceRegistration<?> serviceRegistration = registry.registerService(
088 ModelListener.class.getName(), modelListener);
089
090 _serviceRegistrations.put(className, serviceRegistration);
091 }
092
093 private void _unregister(String className) {
094 ServiceRegistration<?> serviceRegistration =
095 _serviceRegistrations.remove(className);
096
097 if (serviceRegistration != null) {
098 serviceRegistration.unregister();
099 }
100 }
101
102 private static final ModelListenerRegistrationUtil _instance =
103 new ModelListenerRegistrationUtil();
104
105 private final ConcurrentMap<Class<?>, List<ModelListener<?>>>
106 _modelListeners =
107 new ConcurrentHashMap<Class<?>, List<ModelListener<?>>>();
108 private final Map<String, ServiceRegistration<?>> _serviceRegistrations =
109 new ConcurrentHashMap<String, ServiceRegistration<?>>();
110 private final ServiceTracker<ModelListener<?>, ModelListener<?>>
111 _serviceTracker;
112
113 private class ModelListenerTrackerCustomizer
114 implements
115 ServiceTrackerCustomizer<ModelListener<?>, ModelListener<?>> {
116
117 @Override
118 public ModelListener<?> addingService(
119 ServiceReference<ModelListener<?>> serviceReference) {
120
121 Registry registry = RegistryUtil.getRegistry();
122
123 ModelListener<?> modelListener = registry.getService(
124 serviceReference);
125
126 Class<?> clazz = _getModelListeners(modelListener);
127
128 if (clazz == null) {
129 return null;
130 }
131
132 List<ModelListener<?>> modelListeners = _modelListeners.get(clazz);
133
134 if (modelListeners == null) {
135 modelListeners = new ArrayList<ModelListener<?>>();
136
137 List<ModelListener<?>> previousModelListeners =
138 _modelListeners.putIfAbsent(clazz, modelListeners);
139
140 if (previousModelListeners != null) {
141 modelListeners = previousModelListeners;
142 }
143 }
144
145 modelListeners.add(modelListener);
146
147 return modelListener;
148 }
149
150 @Override
151 public void modifiedService(
152 ServiceReference<ModelListener<?>> serviceReference,
153 ModelListener<?> modelListener) {
154 }
155
156 @Override
157 public void removedService(
158 ServiceReference<ModelListener<?>> serviceReference,
159 ModelListener<?> modelListener) {
160
161 Registry registry = RegistryUtil.getRegistry();
162
163 registry.ungetService(serviceReference);
164
165 Class<?> clazz = _getModelListeners(modelListener);
166
167 List<ModelListener<?>> modelListeners = _modelListeners.get(clazz);
168
169 if (modelListeners != null) {
170 modelListeners.remove(modelListener);
171 }
172 }
173
174 private Class<?> _getModelListeners(ModelListener<?> modelListener) {
175 Class<?> clazz = modelListener.getClass();
176
177 if (ProxyUtil.isProxyClass(clazz)) {
178 InvocationHandler invocationHandler =
179 ProxyUtil.getInvocationHandler(modelListener);
180
181 if (invocationHandler instanceof ClassLoaderBeanHandler) {
182 ClassLoaderBeanHandler classLoaderBeanHandler =
183 (ClassLoaderBeanHandler)invocationHandler;
184
185 Object bean = classLoaderBeanHandler.getBean();
186
187 clazz = bean.getClass();
188 }
189 }
190
191 return ReflectionUtil.getGenericSuperType(clazz);
192 }
193
194 }
195
196 }