001
014
015 package com.liferay.portal.systemevent;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.systemevent.SystemEvent;
020 import com.liferay.portal.kernel.systemevent.SystemEventHierarchyEntry;
021 import com.liferay.portal.kernel.systemevent.SystemEventHierarchyEntryThreadLocal;
022 import com.liferay.portal.kernel.util.StringBundler;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.model.AuditedModel;
025 import com.liferay.portal.model.ClassedModel;
026 import com.liferay.portal.model.GroupedModel;
027 import com.liferay.portal.model.StagedModel;
028 import com.liferay.portal.model.SystemEventConstants;
029 import com.liferay.portal.model.TypedModel;
030 import com.liferay.portal.service.SystemEventLocalServiceUtil;
031 import com.liferay.portal.spring.aop.AnnotationChainableMethodAdvice;
032 import com.liferay.portlet.exportimport.lar.StagedModelType;
033
034 import java.io.Serializable;
035
036 import java.lang.annotation.Annotation;
037 import java.lang.reflect.Method;
038
039 import org.aopalliance.intercept.MethodInvocation;
040
041
044 public class SystemEventAdvice
045 extends AnnotationChainableMethodAdvice<SystemEvent> {
046
047 @Override
048 public void afterReturning(MethodInvocation methodInvocation, Object result)
049 throws Throwable {
050
051 SystemEvent systemEvent = findAnnotation(methodInvocation);
052
053 if ((systemEvent == _nullSystemEvent) || !systemEvent.send()) {
054 return;
055 }
056
057 if (!isValid(methodInvocation, _PHASE_AFTER_RETURNING)) {
058 return;
059 }
060
061 Object[] arguments = methodInvocation.getArguments();
062
063 ClassedModel classedModel = (ClassedModel)arguments[0];
064
065 long groupId = getGroupId(classedModel);
066
067 String className = getClassName(classedModel);
068
069 String referrerClassName = null;
070
071 if (classedModel instanceof TypedModel) {
072 TypedModel typedModel = (TypedModel)classedModel;
073
074 referrerClassName = typedModel.getClassName();
075 }
076
077 long classPK = getClassPK(classedModel);
078
079 SystemEventHierarchyEntry systemEventHierarchyEntry =
080 SystemEventHierarchyEntryThreadLocal.peek();
081
082 if ((systemEventHierarchyEntry != null) &&
083 systemEventHierarchyEntry.hasTypedModel(className, classPK)) {
084
085 if (groupId > 0) {
086 SystemEventLocalServiceUtil.addSystemEvent(
087 0, groupId, systemEventHierarchyEntry.getClassName(),
088 classPK, systemEventHierarchyEntry.getUuid(),
089 referrerClassName, systemEvent.type(),
090 systemEventHierarchyEntry.getExtraData());
091 }
092 else {
093 SystemEventLocalServiceUtil.addSystemEvent(
094 getCompanyId(classedModel),
095 systemEventHierarchyEntry.getClassName(), classPK,
096 systemEventHierarchyEntry.getUuid(), referrerClassName,
097 systemEvent.type(),
098 systemEventHierarchyEntry.getExtraData());
099 }
100 }
101 else if (groupId > 0) {
102 SystemEventLocalServiceUtil.addSystemEvent(
103 0, groupId, className, classPK, getUuid(classedModel),
104 referrerClassName, systemEvent.type(), StringPool.BLANK);
105 }
106 else {
107 SystemEventLocalServiceUtil.addSystemEvent(
108 getCompanyId(classedModel), className, classPK,
109 getUuid(classedModel), referrerClassName, systemEvent.type(),
110 StringPool.BLANK);
111 }
112 }
113
114 @Override
115 public Object before(MethodInvocation methodInvocation) throws Throwable {
116 SystemEvent systemEvent = findAnnotation(methodInvocation);
117
118 if (systemEvent == _nullSystemEvent) {
119 return null;
120 }
121
122 if (systemEvent.action() != SystemEventConstants.ACTION_NONE) {
123 if (!isValid(methodInvocation, _PHASE_BEFORE)) {
124 return null;
125 }
126
127 Object[] arguments = methodInvocation.getArguments();
128
129 ClassedModel classedModel = (ClassedModel)arguments[0];
130
131 SystemEventHierarchyEntry systemEventHierarchyEntry =
132 SystemEventHierarchyEntryThreadLocal.push(
133 getClassName(classedModel), getClassPK(classedModel),
134 systemEvent.action());
135
136 if (systemEventHierarchyEntry != null) {
137 systemEventHierarchyEntry.setUuid(getUuid(classedModel));
138 }
139 }
140
141 return null;
142 }
143
144 @Override
145 public void duringFinally(MethodInvocation methodInvocation) {
146 SystemEvent systemEvent = findAnnotation(methodInvocation);
147
148 if (systemEvent == _nullSystemEvent) {
149 return;
150 }
151
152 if (!isValid(methodInvocation, _PHASE_DURING_FINALLY)) {
153 return;
154 }
155
156 if (systemEvent.action() == SystemEventConstants.ACTION_NONE) {
157 return;
158 }
159
160 Object[] arguments = methodInvocation.getArguments();
161
162 ClassedModel classedModel = (ClassedModel)arguments[0];
163
164 long classPK = getClassPK(classedModel);
165
166 if (classPK == 0) {
167 return;
168 }
169
170 SystemEventHierarchyEntryThreadLocal.pop(
171 getClassName(classedModel), classPK);
172 }
173
174 @Override
175 public SystemEvent getNullAnnotation() {
176 return _nullSystemEvent;
177 }
178
179 protected String getClassName(ClassedModel classedModel) {
180 String className = classedModel.getModelClassName();
181
182 if (classedModel instanceof StagedModel) {
183 StagedModel stagedModel = (StagedModel)classedModel;
184
185 StagedModelType stagedModelType = stagedModel.getStagedModelType();
186
187 className = stagedModelType.getClassName();
188 }
189
190 return className;
191 }
192
193 protected long getClassPK(ClassedModel classedModel) {
194 Serializable primaryKeyObj = classedModel.getPrimaryKeyObj();
195
196 if (!(primaryKeyObj instanceof Long)) {
197 return 0;
198 }
199
200 return (Long)primaryKeyObj;
201 }
202
203 protected long getCompanyId(ClassedModel classedModel) {
204 if (classedModel instanceof AuditedModel) {
205 AuditedModel auditedModel = (AuditedModel)classedModel;
206
207 return auditedModel.getCompanyId();
208 }
209
210 if (classedModel instanceof GroupedModel) {
211 GroupedModel groupedModel = (GroupedModel)classedModel;
212
213 return groupedModel.getCompanyId();
214 }
215
216 if (classedModel instanceof StagedModel) {
217 StagedModel stagedModel = (StagedModel)classedModel;
218
219 return stagedModel.getCompanyId();
220 }
221
222 return 0;
223 }
224
225 protected long getGroupId(ClassedModel classedModel) {
226 if (!(classedModel instanceof GroupedModel)) {
227 return 0;
228 }
229
230 GroupedModel groupedModel = (GroupedModel)classedModel;
231
232 return groupedModel.getGroupId();
233 }
234
235 protected String getUuid(ClassedModel classedModel) throws Exception {
236 if (classedModel instanceof StagedModel) {
237 StagedModel stagedModel = (StagedModel)classedModel;
238
239 return stagedModel.getUuid();
240 }
241
242 Method getUuidMethod = null;
243
244 try {
245 Class<?> modelClass = classedModel.getClass();
246
247 getUuidMethod = modelClass.getMethod("getUuid", new Class[0]);
248 }
249 catch (Exception e) {
250 return StringPool.BLANK;
251 }
252
253 return (String)getUuidMethod.invoke(classedModel, new Object[0]);
254 }
255
256 protected boolean isValid(MethodInvocation methodInvocation, int phase) {
257 Method method = methodInvocation.getMethod();
258
259 Class<?>[] parameterTypes = method.getParameterTypes();
260
261 if (parameterTypes.length == 0) {
262 if (_log.isDebugEnabled() && (phase == _PHASE_BEFORE)) {
263 _log.debug(
264 "The method " + methodInvocation +
265 " must have at least one parameter");
266 }
267
268 return false;
269 }
270
271 Class<?> parameterType = parameterTypes[0];
272
273 if (!ClassedModel.class.isAssignableFrom(parameterType)) {
274 if (_log.isDebugEnabled() && (phase == _PHASE_BEFORE)) {
275 _log.debug(
276 "The first parameter of " + methodInvocation +
277 " must implement ClassedModel");
278 }
279
280 return false;
281 }
282
283 Object[] arguments = methodInvocation.getArguments();
284
285 ClassedModel classedModel = (ClassedModel)arguments[0];
286
287 if ((classedModel == null) ||
288 !(classedModel.getPrimaryKeyObj() instanceof Long)) {
289
290 if (_log.isDebugEnabled() && (phase == _PHASE_BEFORE)) {
291 _log.debug(
292 "The first parameter of " + methodInvocation +
293 " must be a long");
294 }
295
296 return false;
297 }
298
299 if (phase != _PHASE_AFTER_RETURNING) {
300 return true;
301 }
302
303 if (!AuditedModel.class.isAssignableFrom(parameterType) &&
304 !GroupedModel.class.isAssignableFrom(parameterType) &&
305 !StagedModel.class.isAssignableFrom(parameterType)) {
306
307 if (_log.isDebugEnabled()) {
308 StringBundler sb = new StringBundler(4);
309
310 sb.append("If send is true, the first parameter of ");
311 sb.append(methodInvocation);
312 sb.append(" must implement AuditedModel, GroupedModel, or ");
313 sb.append("StagedModel");
314
315 _log.debug(sb.toString());
316 }
317
318 return false;
319 }
320
321 return true;
322 }
323
324 private static final int _PHASE_AFTER_RETURNING = 1;
325
326 private static final int _PHASE_BEFORE = 0;
327
328 private static final int _PHASE_DURING_FINALLY = 2;
329
330 private static final Log _log = LogFactoryUtil.getLog(
331 SystemEventAdvice.class);
332
333 private static final SystemEvent _nullSystemEvent = new SystemEvent() {
334
335 @Override
336 public Class<? extends Annotation> annotationType() {
337 return SystemEvent.class;
338 }
339
340 @Override
341 public int action() {
342 return SystemEventConstants.ACTION_NONE;
343 }
344
345 @Override
346 public boolean send() {
347 return false;
348 }
349
350 @Override
351 public int type() {
352 return 0;
353 }
354
355 };
356
357 }