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