001
014
015 package com.liferay.portlet.social.service.impl;
016
017 import com.liferay.portal.kernel.dao.orm.QueryUtil;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.util.StringBundler;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.kernel.util.Tuple;
026 import com.liferay.portal.model.Group;
027 import com.liferay.portal.model.Lock;
028 import com.liferay.portal.model.User;
029 import com.liferay.portal.util.PortalUtil;
030 import com.liferay.portlet.asset.model.AssetEntry;
031 import com.liferay.portlet.social.NoSuchActivityCounterException;
032 import com.liferay.portlet.social.model.SocialAchievement;
033 import com.liferay.portlet.social.model.SocialActivity;
034 import com.liferay.portlet.social.model.SocialActivityCounter;
035 import com.liferay.portlet.social.model.SocialActivityCounterConstants;
036 import com.liferay.portlet.social.model.SocialActivityCounterDefinition;
037 import com.liferay.portlet.social.model.SocialActivityDefinition;
038 import com.liferay.portlet.social.model.SocialActivityLimit;
039 import com.liferay.portlet.social.model.SocialActivityProcessor;
040 import com.liferay.portlet.social.service.SocialActivityCounterLocalService;
041 import com.liferay.portlet.social.service.base.SocialActivityCounterLocalServiceBaseImpl;
042 import com.liferay.portlet.social.service.persistence.SocialActivityCounterFinderUtil;
043 import com.liferay.portlet.social.util.SocialCounterPeriodUtil;
044
045 import java.util.Arrays;
046 import java.util.Collections;
047 import java.util.HashMap;
048 import java.util.List;
049 import java.util.Map;
050
051
054 public class SocialActivityCounterLocalServiceImpl
055 extends SocialActivityCounterLocalServiceBaseImpl {
056
057 public SocialActivityCounter addActivityCounter(
058 long groupId, long classNameId, long classPK, String name,
059 int ownerType, int currentValue, int totalValue)
060 throws PortalException, SystemException {
061
062 SocialActivityCounter activityCounter = null;
063
064 String lockKey = getLockKey(
065 groupId, classNameId, classPK, name, ownerType);
066
067 Lock lock = null;
068
069 while (true) {
070 try {
071 lock = lockLocalService.lock(
072 SocialActivityCounter.class.getName(), lockKey,
073 lockKey, false);
074 }
075 catch (Exception e) {
076 if (_log.isWarnEnabled()) {
077 _log.warn(
078 "Unable to acquire activity counter lock. Retrying.");
079 }
080
081 continue;
082 }
083
084 activityCounter = fetchLatestActivityCounter(
085 groupId, classNameId, classPK, name, ownerType, false);
086
087 if (activityCounter == null) {
088 if (!lock.isNew()) {
089 continue;
090 }
091
092 Group group = groupPersistence.findByPrimaryKey(groupId);
093
094 long activityCounterId = counterLocalService.increment();
095
096 activityCounter = socialActivityCounterPersistence.create(
097 activityCounterId);
098
099 activityCounter.setGroupId(groupId);
100 activityCounter.setCompanyId(group.getCompanyId());
101 activityCounter.setClassNameId(classNameId);
102 activityCounter.setClassPK(classPK);
103 activityCounter.setName(name);
104 activityCounter.setOwnerType(ownerType);
105 activityCounter.setCurrentValue(currentValue);
106 activityCounter.setTotalValue(totalValue);
107 activityCounter.setStartPeriod(
108 SocialCounterPeriodUtil.getStartPeriod());
109 activityCounter.setEndPeriod(
110 SocialActivityCounterConstants.END_PERIOD_UNDEFINED);
111
112 socialActivityCounterPersistence.update(activityCounter, false);
113 }
114
115 if (lock.isNew()) {
116 lockLocalService.unlock(
117 SocialActivityCounter.class.getName(), lockKey);
118 }
119
120 break;
121 }
122
123 return activityCounter;
124 }
125
126 public void addActivityCounters(SocialActivity activity)
127 throws PortalException, SystemException {
128
129 if (!socialActivitySettingLocalService.isEnabled(
130 activity.getGroupId(), activity.getClassNameId())) {
131
132 return;
133 }
134
135 User user = userPersistence.findByPrimaryKey(activity.getUserId());
136
137 SocialActivityDefinition activityDefinition =
138 socialActivitySettingLocalService.getActivityDefinition(
139 activity.getGroupId(), activity.getClassName(),
140 activity.getType());
141
142 if ((activityDefinition == null) || !activityDefinition.isEnabled()) {
143 return;
144 }
145
146 SocialActivityProcessor activityProcessor =
147 activityDefinition.getActivityProcessor();
148
149 if (activityProcessor != null) {
150 activityProcessor.processActivity(activity);
151 }
152
153 AssetEntry assetEntry = activity.getAssetEntry();
154
155 User assetEntryUser = userPersistence.findByPrimaryKey(
156 assetEntry.getUserId());
157
158 for (SocialActivityCounterDefinition activityCounterDefinition :
159 activityDefinition.getActivityCounterDefinitions()) {
160
161 if (addActivityCounter(
162 user, assetEntryUser, activityCounterDefinition) &&
163 checkActivityLimit(user, activity, activityCounterDefinition)) {
164
165 incrementActivityCounter(
166 activity.getGroupId(), user, activity.getAssetEntry(),
167 activityCounterDefinition);
168 }
169 }
170
171 for (SocialAchievement achievement :
172 activityDefinition.getAchievements()) {
173
174 achievement.processActivity(activity);
175 }
176
177 if (!user.isDefaultUser() && user.isActive()) {
178 incrementActivityCounter(
179 activity.getGroupId(),
180 PortalUtil.getClassNameId(User.class.getName()),
181 activity.getUserId(),
182 SocialActivityCounterConstants.NAME_USER_ACTIVITIES,
183 SocialActivityCounterConstants.TYPE_ACTOR, 1,
184 SocialActivityCounterConstants.PERIOD_LENGTH_SYSTEM);
185 }
186
187 if (!assetEntryUser.isDefaultUser() && assetEntryUser.isActive()) {
188 incrementActivityCounter(
189 activity.getGroupId(), activity.getClassNameId(),
190 activity.getClassPK(),
191 SocialActivityCounterConstants.NAME_ASSET_ACTIVITIES,
192 SocialActivityCounterConstants.TYPE_ASSET, 1,
193 SocialActivityCounterConstants.PERIOD_LENGTH_SYSTEM);
194 }
195 }
196
197 public void deleteActivityCounters(AssetEntry assetEntry)
198 throws PortalException, SystemException {
199
200 if (assetEntry == null) {
201 return;
202 }
203
204 SocialActivityCounter latestContributionActivityCounter =
205 fetchLatestActivityCounter(
206 assetEntry.getGroupId(),
207 PortalUtil.getClassNameId(User.class.getName()),
208 assetEntry.getUserId(),
209 SocialActivityCounterConstants.NAME_CONTRIBUTION,
210 SocialActivityCounterConstants.TYPE_CREATOR);
211
212 SocialActivityCounter latestPopularityActivityCounter =
213 fetchLatestActivityCounter(
214 assetEntry.getGroupId(), assetEntry.getClassNameId(),
215 assetEntry.getClassPK(),
216 SocialActivityCounterConstants.NAME_POPULARITY,
217 SocialActivityCounterConstants.TYPE_ASSET);
218
219 if ((latestContributionActivityCounter != null) &&
220 (latestPopularityActivityCounter != null)) {
221
222 int startPeriod = SocialCounterPeriodUtil.getStartPeriod();
223
224 if (latestContributionActivityCounter.getStartPeriod() !=
225 startPeriod) {
226
227 latestContributionActivityCounter = addNewPeriod(
228 latestContributionActivityCounter,
229 SocialActivityCounterConstants.PERIOD_LENGTH_SYSTEM);
230 }
231
232 if (latestPopularityActivityCounter.getStartPeriod() ==
233 startPeriod) {
234
235 latestContributionActivityCounter.setCurrentValue(
236 latestContributionActivityCounter.getCurrentValue() -
237 latestPopularityActivityCounter.getCurrentValue());
238 }
239
240 latestContributionActivityCounter.setTotalValue(
241 latestContributionActivityCounter.getTotalValue() -
242 latestPopularityActivityCounter.getTotalValue());
243
244 socialActivityCounterPersistence.update(
245 latestContributionActivityCounter, false);
246 }
247
248 deleteActivityCounters(
249 assetEntry.getClassNameId(), assetEntry.getClassPK());
250
251 socialActivityLimitPersistence.removeByC_C(
252 assetEntry.getClassNameId(), assetEntry.getClassPK());
253 }
254
255 public void deleteActivityCounters(long classNameId, long classPK)
256 throws SystemException {
257
258 socialActivityCounterPersistence.removeByC_C(classNameId, classPK);
259 }
260
261 public SocialActivityCounter fetchLatestActivityCounter(
262 long groupId, long classNameId, long classPK, String name,
263 int ownerType)
264 throws SystemException {
265
266 return fetchLatestActivityCounter(
267 groupId, classNameId, classPK, name, ownerType, true);
268 }
269
270 public SocialActivityCounter fetchLatestActivityCounter(
271 long groupId, long classNameId, long classPK, String name,
272 int ownerType, boolean retrieveFromCache)
273 throws SystemException {
274
275 return socialActivityCounterPersistence.fetchByG_C_C_N_O_E(
276 groupId, classNameId, classPK, name, ownerType,
277 SocialActivityCounterConstants.END_PERIOD_UNDEFINED,
278 retrieveFromCache);
279 }
280
281 public SocialActivityCounter getLatestActivityCounter(
282 long groupId, long classNameId, long classPK, String name,
283 int ownerType)
284 throws NoSuchActivityCounterException, SystemException {
285
286 return socialActivityCounterPersistence.findByG_C_C_N_O_E(
287 groupId, classNameId, classPK, name, ownerType,
288 SocialActivityCounterConstants.END_PERIOD_UNDEFINED);
289 }
290
291 public List<SocialActivityCounter> getOffsetActivityCounterDistribution(
292 long groupId, String name, int startOffset, int endOffset)
293 throws SystemException {
294
295 int startPeriod = SocialCounterPeriodUtil.getStartPeriod(startOffset);
296 int endPeriod = SocialCounterPeriodUtil.getEndPeriod(endOffset);
297
298 return getPeriodActivityCounterDistribution(
299 groupId, name, startPeriod, endPeriod);
300 }
301
302 public List<SocialActivityCounter> getOffsetActivityCounters(
303 long groupId, String name, int startOffset, int endOffset)
304 throws SystemException {
305
306 int startPeriod = SocialCounterPeriodUtil.getStartPeriod(startOffset);
307 int endPeriod = SocialCounterPeriodUtil.getEndPeriod(endOffset);
308
309 return getPeriodActivityCounters(groupId, name, startPeriod, endPeriod);
310 }
311
312 public List<SocialActivityCounter> getPeriodActivityCounterDistribution(
313 long groupId, String name, int startPeriod, int endPeriod)
314 throws SystemException {
315
316 int offset = SocialCounterPeriodUtil.getOffset(endPeriod);
317
318 int periodLength = SocialCounterPeriodUtil.getPeriodLength(offset);
319
320 return socialActivityCounterFinder.findAC_ByG_N_S_E_2(
321 groupId, name, startPeriod, endPeriod, periodLength);
322 }
323
324 public List<SocialActivityCounter> getPeriodActivityCounters(
325 long groupId, String name, int startPeriod, int endPeriod)
326 throws SystemException {
327
328 int offset = SocialCounterPeriodUtil.getOffset(endPeriod);
329
330 int periodLength = SocialCounterPeriodUtil.getPeriodLength(offset);
331
332 return socialActivityCounterFinder.findAC_ByG_N_S_E_1(
333 groupId, name, startPeriod, endPeriod, periodLength);
334 }
335
336 public int getUserActivityCounters(long groupId, String[] rankingNames)
337 throws SystemException {
338
339 return SocialActivityCounterFinderUtil.countU_ByG_N(
340 groupId, rankingNames);
341 }
342
343 public List<Tuple> getUserActivityCounters(
344 long groupId, String[] rankingNames, String[] selectedNames,
345 int start, int end)
346 throws SystemException {
347
348 List<Long> userIds = socialActivityCounterFinder.findU_ByG_N(
349 groupId, rankingNames, start, end);
350
351 if (userIds.isEmpty()) {
352 return Collections.emptyList();
353 }
354
355 Tuple[] userActivityCounters = new Tuple[userIds.size()];
356
357 List<SocialActivityCounter> activityCounters =
358 SocialActivityCounterFinderUtil.findAC_By_G_C_C_N_S_E(
359 groupId, userIds, selectedNames, QueryUtil.ALL_POS,
360 QueryUtil.ALL_POS);
361
362 long userId = 0;
363 Map<String, SocialActivityCounter> activityCountersMap = null;
364
365 for (SocialActivityCounter activityCounter : activityCounters) {
366 if (userId != activityCounter.getClassPK()) {
367 userId = activityCounter.getClassPK();
368 activityCountersMap =
369 new HashMap<String, SocialActivityCounter>();
370
371 Tuple userActivityCounter = new Tuple(
372 userId, activityCountersMap);
373
374 for (int i = 0; i < userIds.size(); i++) {
375 long curUserId = userIds.get(i);
376
377 if (userId == curUserId) {
378 userActivityCounters[i] = userActivityCounter;
379
380 break;
381 }
382 }
383 }
384
385 activityCountersMap.put(activityCounter.getName(), activityCounter);
386 }
387
388 return Arrays.asList(userActivityCounters);
389 }
390
391 public void incrementUserAchievementCounter(long userId, long groupId)
392 throws PortalException, SystemException {
393
394 incrementActivityCounter(
395 groupId, PortalUtil.getClassNameId(User.class.getName()), userId,
396 SocialActivityCounterConstants.NAME_USER_ACHIEVEMENTS,
397 SocialActivityCounterConstants.TYPE_ACTOR, 1,
398 SocialActivityCounterConstants.PERIOD_LENGTH_SYSTEM);
399 }
400
401 protected boolean addActivityCounter(
402 User user, User assetEntryUser,
403 SocialActivityCounterDefinition activityCounterDefinition) {
404
405 if ((user.isDefaultUser() || !user.isActive()) &&
406 (activityCounterDefinition.getOwnerType() !=
407 SocialActivityCounterConstants.TYPE_ASSET)) {
408
409 return false;
410 }
411
412 if ((assetEntryUser.isDefaultUser() || !assetEntryUser.isActive()) &&
413 (activityCounterDefinition.getOwnerType() !=
414 SocialActivityCounterConstants.TYPE_ACTOR)) {
415
416 return false;
417 }
418
419 if (!activityCounterDefinition.isEnabled() ||
420 (activityCounterDefinition.getIncrement() == 0)) {
421
422 return false;
423 }
424
425 String name = activityCounterDefinition.getName();
426
427 if ((user.getUserId() == assetEntryUser.getUserId()) &&
428 (name.equals(SocialActivityCounterConstants.NAME_CONTRIBUTION) ||
429 name.equals(SocialActivityCounterConstants.NAME_POPULARITY))) {
430
431 return false;
432 }
433
434 return true;
435 }
436
437 protected SocialActivityCounter addNewPeriod(
438 SocialActivityCounter activityCounter, int periodLength)
439 throws PortalException, SystemException {
440
441 if (activityCounter == null) {
442 return null;
443 }
444
445 if (periodLength ==
446 SocialActivityCounterConstants.PERIOD_LENGTH_SYSTEM) {
447
448 activityCounter.setEndPeriod(
449 SocialCounterPeriodUtil.getStartPeriod() - 1);
450 }
451 else {
452 activityCounter.setEndPeriod(
453 activityCounter.getStartPeriod() + periodLength - 1);
454 }
455
456 socialActivityCounterPersistence.update(activityCounter, false);
457
458 return addActivityCounter(
459 activityCounter.getGroupId(), activityCounter.getClassNameId(),
460 activityCounter.getClassPK(), activityCounter.getName(),
461 activityCounter.getOwnerType(), 0, activityCounter.getTotalValue());
462 }
463
464 protected boolean checkActivityLimit(
465 User user, SocialActivity activity,
466 SocialActivityCounterDefinition activityCounterDefinition)
467 throws PortalException, SystemException {
468
469 if (activityCounterDefinition.getLimitValue() == 0) {
470 return true;
471 }
472
473 long classPK = activity.getClassPK();
474
475 String name = activityCounterDefinition.getName();
476
477 if (name.equals(SocialActivityCounterConstants.NAME_PARTICIPATION)) {
478 classPK = 0;
479 }
480
481 SocialActivityLimit activityLimit =
482 socialActivityLimitPersistence.fetchByG_U_C_C_A_A(
483 activity.getGroupId(), user.getUserId(),
484 activity.getClassNameId(), classPK, activity.getType(),
485 activityCounterDefinition.getName());
486
487 if (activityLimit == null) {
488 try {
489 activityLimit =
490 socialActivityLimitLocalService.addActivityLimit(
491 user.getUserId(), activity.getGroupId(),
492 activity.getClassNameId(), classPK, activity.getType(),
493 activityCounterDefinition.getName(),
494 activityCounterDefinition.getLimitPeriod());
495 }
496 catch (SystemException se) {
497 activityLimit =
498 socialActivityLimitPersistence.fetchByG_U_C_C_A_A(
499 activity.getGroupId(), user.getUserId(),
500 activity.getClassNameId(), classPK, activity.getType(),
501 activityCounterDefinition.getName());
502
503 if (activityLimit == null) {
504 throw se;
505 }
506 }
507 }
508
509 int count = activityLimit.getCount(
510 activityCounterDefinition.getLimitPeriod());
511
512 if (count < activityCounterDefinition.getLimitValue()) {
513 activityLimit.setCount(
514 activityCounterDefinition.getLimitPeriod(), count + 1);
515
516 socialActivityLimitPersistence.update(activityLimit, false);
517
518 return true;
519 }
520
521 return false;
522 }
523
524 protected String getLockKey(
525 long groupId, long classNameId, long classPK, String name,
526 int ownerType) {
527
528 StringBundler sb = new StringBundler(7);
529
530 sb.append(StringUtil.toHexString(groupId));
531 sb.append(StringPool.POUND);
532 sb.append(StringUtil.toHexString(classNameId));
533 sb.append(StringPool.POUND);
534 sb.append(StringUtil.toHexString(classPK));
535 sb.append(StringPool.POUND);
536 sb.append(name);
537
538 return sb.toString();
539 }
540
541 protected void incrementActivityCounter(
542 long groupId, long classNameId, long classPK, String name,
543 int ownerType, int increment, int periodLength)
544 throws PortalException, SystemException {
545
546 SocialActivityCounter activityCounter = fetchLatestActivityCounter(
547 groupId, classNameId, classPK, name, ownerType);
548
549 if (activityCounter == null) {
550 activityCounter = addActivityCounter(
551 groupId, classNameId, classPK, name, ownerType, 0, 0);
552
553 if (periodLength > 0) {
554 activityCounter.setStartPeriod(
555 SocialCounterPeriodUtil.getActivityDay());
556 }
557 }
558
559 if (!activityCounter.isActivePeriod(periodLength)) {
560 activityCounter = addNewPeriod(activityCounter, periodLength);
561 }
562
563 activityCounter.setCurrentValue(
564 activityCounter.getCurrentValue() + increment);
565 activityCounter.setTotalValue(
566 activityCounter.getTotalValue() + increment);
567
568 socialActivityCounterPersistence.update(activityCounter, false);
569 }
570
571 protected void incrementActivityCounter(
572 long groupId, User user, AssetEntry assetEntry,
573 SocialActivityCounterDefinition activityCounterDefinition)
574 throws PortalException, SystemException {
575
576 int ownerType = activityCounterDefinition.getOwnerType();
577 long userClassNameId = PortalUtil.getClassNameId(User.class.getName());
578
579 if (ownerType == SocialActivityCounterConstants.TYPE_ACTOR) {
580 incrementActivityCounter(
581 groupId, userClassNameId, user.getUserId(),
582 activityCounterDefinition.getName(), ownerType,
583 activityCounterDefinition.getIncrement(),
584 activityCounterDefinition.getPeriodLength());
585 }
586 else if (ownerType == SocialActivityCounterConstants.TYPE_ASSET) {
587 incrementActivityCounter(
588 groupId, assetEntry.getClassNameId(), assetEntry.getClassPK(),
589 activityCounterDefinition.getName(), ownerType,
590 activityCounterDefinition.getIncrement(),
591 activityCounterDefinition.getPeriodLength());
592 }
593 else {
594 incrementActivityCounter(
595 groupId, userClassNameId, assetEntry.getUserId(),
596 activityCounterDefinition.getName(), ownerType,
597 activityCounterDefinition.getIncrement(),
598 activityCounterDefinition.getPeriodLength());
599 }
600 }
601
602 private static Log _log = LogFactoryUtil.getLog(
603 SocialActivityCounterLocalService.class);
604
605 }