-
Notifications
You must be signed in to change notification settings - Fork 3.6k
/
ModelListenerRegistrationUtil.java
145 lines (107 loc) · 3.89 KB
/
ModelListenerRegistrationUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
* SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/
package com.liferay.portal.kernel.model;
import com.liferay.osgi.service.tracker.collections.map.ServiceTrackerMap;
import com.liferay.osgi.service.tracker.collections.map.ServiceTrackerMapFactory;
import com.liferay.portal.kernel.bean.ClassLoaderBeanHandler;
import com.liferay.portal.kernel.module.util.SystemBundleUtil;
import com.liferay.portal.kernel.util.ProxyUtil;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
/**
* @author Peter Fellwock
*/
public class ModelListenerRegistrationUtil {
public static <T> ModelListener<T>[] getModelListeners(Class<T> clazz) {
List<ModelListener<?>> modelListeners = _modelListeners.getService(
clazz.getName());
if (modelListeners == null) {
return new ModelListener[0];
}
return modelListeners.toArray(new ModelListener[0]);
}
public static void register(ModelListener<?> modelListener) {
Class<?> clazz = modelListener.getClass();
ServiceRegistration<?> serviceRegistration =
_bundleContext.registerService(
ModelListener.class, modelListener, null);
_serviceRegistrations.put(clazz.getName(), serviceRegistration);
}
public static void unregister(ModelListener<?> modelListener) {
Class<?> clazz = modelListener.getClass();
ServiceRegistration<?> serviceRegistration =
_serviceRegistrations.remove(clazz.getName());
if (serviceRegistration != null) {
serviceRegistration.unregister();
}
}
private static Class<?> _getGenericSuperType(Class<?> clazz) {
try {
ParameterizedType parameterizedType =
(ParameterizedType)clazz.getGenericSuperclass();
Type[] types = parameterizedType.getActualTypeArguments();
if (types.length > 0) {
return (Class<?>)types[0];
}
}
catch (Throwable throwable) {
}
return null;
}
private static Class<?> _getModelClass(ModelListener<?> modelListener) {
Class<?> clazz = modelListener.getModelClass();
if (clazz != null) {
return clazz;
}
clazz = modelListener.getClass();
if (ProxyUtil.isProxyClass(clazz)) {
InvocationHandler invocationHandler =
ProxyUtil.getInvocationHandler(modelListener);
if (invocationHandler instanceof ClassLoaderBeanHandler) {
ClassLoaderBeanHandler classLoaderBeanHandler =
(ClassLoaderBeanHandler)invocationHandler;
Object bean = classLoaderBeanHandler.getBean();
clazz = bean.getClass();
}
}
return _getGenericSuperType(clazz);
}
private static final BundleContext _bundleContext =
SystemBundleUtil.getBundleContext();
private static final ServiceTrackerMap<String, List<ModelListener<?>>>
_modelListeners;
private static final Map<String, ServiceRegistration<?>>
_serviceRegistrations = new ConcurrentHashMap<>();
static {
_modelListeners = ServiceTrackerMapFactory.openMultiValueMap(
_bundleContext,
(Class<ModelListener<?>>)(Class<?>)ModelListener.class, null,
(serviceReference, emitter) -> {
ModelListener<?> modelListener = _bundleContext.getService(
serviceReference);
Class<?> modelClass = _getModelClass(modelListener);
if (modelClass != null) {
emitter.emit(modelClass.getName());
}
},
(serviceReference1, serviceReference2) -> {
ModelListener<?> modelListener1 = _bundleContext.getService(
serviceReference1);
Class<?> clazz1 = modelListener1.getClass();
String name1 = clazz1.getName();
ModelListener<?> modelListener2 = _bundleContext.getService(
serviceReference2);
Class<?> clazz2 = modelListener2.getClass();
String name2 = clazz2.getName();
return name1.compareTo(name2);
});
}
}