001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.social.service.impl;
016    
017    import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
018    import com.liferay.portal.kernel.cache.PortalCache;
019    import com.liferay.portal.kernel.dao.orm.QueryUtil;
020    import com.liferay.portal.kernel.exception.PortalException;
021    import com.liferay.portal.kernel.exception.SystemException;
022    import com.liferay.portal.kernel.lock.LockProtectedAction;
023    import com.liferay.portal.kernel.transaction.Propagation;
024    import com.liferay.portal.kernel.transaction.Transactional;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.kernel.util.Tuple;
028    import com.liferay.portal.model.Group;
029    import com.liferay.portal.model.User;
030    import com.liferay.portal.util.PortalUtil;
031    import com.liferay.portal.util.PropsValues;
032    import com.liferay.portlet.asset.model.AssetEntry;
033    import com.liferay.portlet.social.model.SocialAchievement;
034    import com.liferay.portlet.social.model.SocialActivity;
035    import com.liferay.portlet.social.model.SocialActivityConstants;
036    import com.liferay.portlet.social.model.SocialActivityCounter;
037    import com.liferay.portlet.social.model.SocialActivityCounterConstants;
038    import com.liferay.portlet.social.model.SocialActivityCounterDefinition;
039    import com.liferay.portlet.social.model.SocialActivityDefinition;
040    import com.liferay.portlet.social.model.SocialActivityLimit;
041    import com.liferay.portlet.social.model.SocialActivityProcessor;
042    import com.liferay.portlet.social.model.impl.SocialActivityImpl;
043    import com.liferay.portlet.social.service.base.SocialActivityCounterLocalServiceBaseImpl;
044    import com.liferay.portlet.social.service.persistence.SocialActivityCounterFinder;
045    import com.liferay.portlet.social.util.SocialCounterPeriodUtil;
046    
047    import java.util.ArrayList;
048    import java.util.Arrays;
049    import java.util.Collections;
050    import java.util.HashMap;
051    import java.util.List;
052    import java.util.Map;
053    
054    /**
055     * The social activity counter local service. This service is responsible for
056     * creating and/or incrementing counters in response to an activity. It also
057     * provides methods for querying activity counters within a time period.
058     *
059     * <p>
060     * Under normal circumstances only the {@link
061     * #addActivityCounters(SocialActivity)} should be called directly and even that
062     * is usually not necessary as it is automatically called by the social activity
063     * service.
064     * </p>
065     *
066     * @author Zsolt Berentey
067     * @author Shuyang Zhou
068     */
069    public class SocialActivityCounterLocalServiceImpl
070            extends SocialActivityCounterLocalServiceBaseImpl {
071    
072            /**
073             * Adds an activity counter with a default period length.
074             *
075             * <p>
076             * This method uses the lock service to guard against multiple threads
077             * trying to insert the same counter because this service is called
078             * asynchronously from the social activity service.
079             * </p>
080             *
081             * @param      groupId the primary key of the group
082             * @param      classNameId the primary key of the entity's class this
083             *             counter belongs to
084             * @param      classPK the primary key of the entity this counter belongs to
085             * @param      name the counter's name
086             * @param      ownerType the counter's owner type. Acceptable values are
087             *             <code>TYPE_ACTOR</code>, <code>TYPE_ASSET</code> and
088             *             <code>TYPE_CREATOR</code> defined in {@link
089             *             com.liferay.portlet.social.model.SocialActivityCounterConstants}.
090             * @param      currentValue the counter's current value (optionally
091             *             <code>0</code>)
092             * @param      totalValue the counter's total value (optionally
093             *             <code>0</code>)
094             * @param      startPeriod the counter's start period
095             * @param      endPeriod the counter's end period
096             * @return     the added activity counter
097             * @throws     PortalException if the group or the previous activity counter
098             *             could not be found
099             * @throws     SystemException if a system exception occurred
100             * @deprecated As of 6.2.0, replaced by {@link #addActivityCounter(long,
101             *             long, long, String, int, int, long, int)}
102             */
103            @Override
104            public SocialActivityCounter addActivityCounter(
105                            long groupId, long classNameId, long classPK, String name,
106                            int ownerType, int currentValue, int totalValue, int startPeriod,
107                            int endPeriod)
108                    throws PortalException, SystemException {
109    
110                    return addActivityCounter(
111                            groupId, classNameId, classPK, name, ownerType, totalValue, 0, 0);
112            }
113    
114            /**
115             * Adds an activity counter specifying a previous activity and period
116             * length.
117             *
118             * <p>
119             * This method uses the lock service to guard against multiple threads
120             * trying to insert the same counter because this service is called
121             * asynchronously from the social activity service.
122             * </p>
123             *
124             * @param      groupId the primary key of the group
125             * @param      classNameId the primary key of the entity's class this
126             *             counter belongs to
127             * @param      classPK the primary key of the entity this counter belongs to
128             * @param      name the counter name
129             * @param      ownerType the counter's owner type. Acceptable values are
130             *             <code>TYPE_ACTOR</code>, <code>TYPE_ASSET</code> and
131             *             <code>TYPE_CREATOR</code> defined in {@link
132             *             com.liferay.portlet.social.model.SocialActivityCounterConstants}.
133             * @param      currentValue the current value of the counter (optionally
134             *             <code>0</code>)
135             * @param      totalValue the counter's total value (optionally
136             *             <code>0</code>)
137             * @param      startPeriod the counter's start period
138             * @param      endPeriod the counter's end period
139             * @param      previousActivityCounterId the primary key of the activity
140             *             counter for the previous time period (optionally
141             *             <code>0</code>, if this is the first)
142             * @param      periodLength the period length in days,
143             *             <code>PERIOD_LENGTH_INFINITE</code> for never ending counters
144             *             or <code>PERIOD_LENGTH_SYSTEM</code> for the period length
145             *             defined in <code>portal-ext.properties</code>. For more
146             *             information see {@link
147             *             com.liferay.portlet.social.model.SocialActivityCounterConstants}.
148             * @return     the added activity counter
149             * @throws     PortalException if the group or the previous activity counter
150             *             could not be found
151             * @throws     SystemException if a system exception occurred
152             * @deprecated As of 6.2.0, replaced by {@link #addActivityCounter(long,
153             *             long, long, String, int, int, long, int)}
154             */
155            @Override
156            public SocialActivityCounter addActivityCounter(
157                            long groupId, long classNameId, long classPK, String name,
158                            int ownerType, int currentValue, int totalValue, int startPeriod,
159                            int endPeriod, long previousActivityCounterId, int periodLength)
160                    throws PortalException, SystemException {
161    
162                    return addActivityCounter(
163                            groupId, classNameId, classPK, name, ownerType, totalValue,
164                            previousActivityCounterId, periodLength);
165            }
166    
167            /**
168             * Adds an activity counter specifying a previous activity and period
169             * length.
170             *
171             * <p>
172             * This method uses the lock service to guard against multiple threads
173             * trying to insert the same counter because this service is called
174             * asynchronously from the social activity service.
175             * </p>
176             *
177             * @param  groupId the primary key of the group
178             * @param  classNameId the primary key of the entity's class this counter
179             *         belongs to
180             * @param  classPK the primary key of the entity this counter belongs to
181             * @param  name the counter name
182             * @param  ownerType the counter's owner type. Acceptable values are
183             *         <code>TYPE_ACTOR</code>, <code>TYPE_ASSET</code> and
184             *         <code>TYPE_CREATOR</code> defined in {@link
185             *         com.liferay.portlet.social.model.SocialActivityCounterConstants}.
186             * @param  totalValue the counter's total value (optionally <code>0</code>)
187             * @param  previousActivityCounterId the primary key of the activity counter
188             *         for the previous time period (optionally <code>0</code>, if this
189             *         is the first)
190             * @param  periodLength the period length in days,
191             *         <code>PERIOD_LENGTH_INFINITE</code> for never ending counters or
192             *         <code>PERIOD_LENGTH_SYSTEM</code> for the period length defined
193             *         in <code>portal-ext.properties</code>. For more information see
194             *         {@link
195             *         com.liferay.portlet.social.model.SocialActivityCounterConstants}.
196             * @return the added activity counter
197             * @throws PortalException if the group or the previous activity counter
198             *         could not be found
199             * @throws SystemException if a system exception occurred
200             */
201            @Override
202            @Transactional(propagation = Propagation.REQUIRES_NEW)
203            public SocialActivityCounter addActivityCounter(
204                            long groupId, long classNameId, long classPK, String name,
205                            int ownerType, int totalValue, long previousActivityCounterId,
206                            int periodLength)
207                    throws PortalException, SystemException {
208    
209                    SocialActivityCounter activityCounter = null;
210    
211                    if (previousActivityCounterId != 0) {
212                            activityCounter = socialActivityCounterPersistence.findByPrimaryKey(
213                                    previousActivityCounterId);
214    
215                            if (periodLength ==
216                                            SocialActivityCounterConstants.PERIOD_LENGTH_SYSTEM) {
217    
218                                    activityCounter.setEndPeriod(
219                                            SocialCounterPeriodUtil.getStartPeriod() - 1);
220                            }
221                            else {
222                                    activityCounter.setEndPeriod(
223                                            activityCounter.getStartPeriod() + periodLength - 1);
224                            }
225    
226                            socialActivityCounterPersistence.update(activityCounter);
227                    }
228    
229                    activityCounter = socialActivityCounterPersistence.fetchByG_C_C_N_O_E(
230                            groupId, classNameId, classPK, name, ownerType,
231                            SocialActivityCounterConstants.END_PERIOD_UNDEFINED, false);
232    
233                    if (activityCounter != null) {
234                            return activityCounter;
235                    }
236    
237                    Group group = groupPersistence.findByPrimaryKey(groupId);
238    
239                    long activityCounterId = counterLocalService.increment();
240    
241                    activityCounter = socialActivityCounterPersistence.create(
242                            activityCounterId);
243    
244                    activityCounter.setGroupId(groupId);
245                    activityCounter.setCompanyId(group.getCompanyId());
246                    activityCounter.setClassNameId(classNameId);
247                    activityCounter.setClassPK(classPK);
248                    activityCounter.setName(name);
249                    activityCounter.setOwnerType(ownerType);
250                    activityCounter.setTotalValue(totalValue);
251    
252                    if (periodLength ==
253                                    SocialActivityCounterConstants.PERIOD_LENGTH_SYSTEM) {
254    
255                            activityCounter.setStartPeriod(
256                                    SocialCounterPeriodUtil.getStartPeriod());
257                    }
258                    else {
259                            activityCounter.setStartPeriod(
260                                    SocialCounterPeriodUtil.getActivityDay());
261                    }
262    
263                    activityCounter.setEndPeriod(
264                            SocialActivityCounterConstants.END_PERIOD_UNDEFINED);
265                    activityCounter.setActive(true);
266    
267                    socialActivityCounterPersistence.update(activityCounter);
268    
269                    return activityCounter;
270            }
271    
272            /**
273             * Adds or increments activity counters related to an activity.
274             *
275             * </p>
276             * This method is called asynchronously from the social activity service
277             * when the user performs an activity defined in
278             * </code>liferay-social.xml</code>.
279             * </p>
280             *
281             * <p>
282             * This method first calls the activity processor class, if there is one
283             * defined for the activity, checks for limits and increments all the
284             * counters that belong to the activity. Afterwards, it processes the
285             * activity with respect to achievement classes, if any. Lastly it
286             * increments the built-in <code>user.activities</code> and
287             * <code>asset.activities</code> counters.
288             * </p>
289             *
290             * @param  activity the social activity
291             * @throws PortalException if an expected group or expected previous
292             *         activity counters could not be found
293             * @throws SystemException if a system exception occurred
294             */
295            @Override
296            public void addActivityCounters(SocialActivity activity)
297                    throws PortalException, SystemException {
298    
299                    if (!socialActivitySettingLocalService.isEnabled(
300                                    activity.getGroupId(), activity.getClassNameId())) {
301    
302                            return;
303                    }
304    
305                    if (!socialActivitySettingLocalService.isEnabled(
306                                    activity.getGroupId(), activity.getClassNameId(),
307                                    activity.getClassPK())) {
308    
309                            return;
310                    }
311    
312                    if ((activity.getType() ==
313                                    SocialActivityConstants.TYPE_MOVE_ATTACHMENT_TO_TRASH) ||
314                            (activity.getType() ==
315                                    SocialActivityConstants.TYPE_MOVE_TO_TRASH)) {
316    
317                            disableActivityCounters(
318                                    activity.getClassNameId(), activity.getClassPK());
319    
320                            return;
321                    }
322    
323                    if ((activity.getType() ==
324                                    SocialActivityConstants.TYPE_RESTORE_ATTACHMENT_FROM_TRASH) ||
325                            (activity.getType() ==
326                                    SocialActivityConstants.TYPE_RESTORE_FROM_TRASH)) {
327    
328                            enableActivityCounters(
329                                    activity.getClassNameId(), activity.getClassPK());
330    
331                            return;
332                    }
333    
334                    User user = userPersistence.findByPrimaryKey(activity.getUserId());
335    
336                    SocialActivityDefinition activityDefinition =
337                            socialActivitySettingLocalService.getActivityDefinition(
338                                    activity.getGroupId(), activity.getClassName(),
339                                    activity.getType());
340    
341                    if ((activityDefinition == null) ||
342                            !activityDefinition.isCountersEnabled()) {
343    
344                            return;
345                    }
346    
347                    SocialActivityProcessor activityProcessor =
348                            activityDefinition.getActivityProcessor();
349    
350                    if (activityProcessor != null) {
351                            activityProcessor.processActivity(activity);
352                    }
353    
354                    AssetEntry assetEntry = activity.getAssetEntry();
355    
356                    User assetEntryUser = userPersistence.findByPrimaryKey(
357                            assetEntry.getUserId());
358    
359                    List<SocialActivityCounter> activityCounters =
360                            new ArrayList<SocialActivityCounter>();
361    
362                    for (SocialActivityCounterDefinition activityCounterDefinition :
363                                    activityDefinition.getActivityCounterDefinitions()) {
364    
365                            if (isAddActivityCounter(
366                                            user, assetEntryUser, assetEntry,
367                                            activityCounterDefinition)) {
368    
369                                    SocialActivityCounter activityCounter = addActivityCounter(
370                                            activity.getGroupId(), user, activity,
371                                            activityCounterDefinition);
372    
373                                    activityCounters.add(activityCounter);
374                            }
375                    }
376    
377                    SocialActivityCounter assetActivitiesCounter = null;
378    
379                    if (!assetEntryUser.isDefaultUser() && assetEntryUser.isActive() &&
380                            assetEntry.isVisible()) {
381    
382                            assetActivitiesCounter = addAssetActivitiesCounter(activity);
383                    }
384    
385                    SocialActivityCounter userActivitiesCounter = null;
386    
387                    if (!user.isDefaultUser() && user.isActive()) {
388                            userActivitiesCounter = addUserActivitiesCounter(activity);
389                    }
390    
391                    for (SocialActivityCounter activityCounter : activityCounters) {
392                            SocialActivityCounterDefinition activityCounterDefinition =
393                                    activityDefinition.getActivityCounterDefinition(
394                                            activityCounter.getName());
395    
396                            if (checkActivityLimit(user, activity, activityCounterDefinition)) {
397                                    incrementActivityCounter(
398                                            activityCounter, activityCounterDefinition);
399                            }
400                    }
401    
402                    if (assetActivitiesCounter != null) {
403                            incrementActivityCounter(
404                                    assetActivitiesCounter,
405                                    _assetActivitiesActivityCounterDefinition);
406                    }
407    
408                    if (userActivitiesCounter != null) {
409                            incrementActivityCounter(
410                                    userActivitiesCounter,
411                                    _userActivitiesActivityCounterDefinition);
412                    }
413    
414                    for (SocialAchievement achievement :
415                                    activityDefinition.getAchievements()) {
416    
417                            achievement.processActivity(activity);
418                    }
419            }
420    
421            /**
422             * Creates an activity counter with a default period length, adding it into
423             * the database.
424             *
425             * @param      groupId the primary key of the group
426             * @param      classNameId the primary key of the entity's class this
427             *             counter belongs to
428             * @param      classPK the primary key of the entity this counter belongs to
429             * @param      name the counter's name
430             * @param      ownerType the counter's owner type. Acceptable values are
431             *             <code>TYPE_ACTOR</code>, <code>TYPE_ASSET</code> and
432             *             <code>TYPE_CREATOR</code> defined in {@link
433             *             com.liferay.portlet.social.model.SocialActivityCounterConstants}.
434             * @param      currentValue the counter's current value (optionally
435             *             <code>0</code>)
436             * @param      totalValue the counter's total value (optionally
437             *             <code>0</code>)
438             * @param      startPeriod the counter's start period
439             * @param      endPeriod the counter's end period
440             * @return     the created activity counter
441             * @throws     PortalException if the group or a previous activity counter
442             *             could not be found
443             * @throws     SystemException if a system exception occurred
444             * @deprecated As of 6.2.0, replaced by {@link #addActivityCounter(long,
445             *             long, long, String, int, int, long, int)}
446             */
447            @Override
448            @Transactional(propagation = Propagation.REQUIRES_NEW)
449            public SocialActivityCounter createActivityCounter(
450                            long groupId, long classNameId, long classPK, String name,
451                            int ownerType, int currentValue, int totalValue, int startPeriod,
452                            int endPeriod)
453                    throws PortalException, SystemException {
454    
455                    return addActivityCounter(
456                            groupId, classNameId, classPK, name, ownerType, totalValue, 0, 0);
457            }
458    
459            /**
460             * Creates an activity counter, adding it into the database.
461             *
462             * <p>
463             * This method actually creates the counter in the database. It requires a
464             * new transaction so that other threads can find the new counter when the
465             * lock in the calling method is released.
466             * </p>
467             *
468             * @param      groupId the primary key of the group
469             * @param      classNameId the primary key of the entity's class this
470             *             counter belongs to
471             * @param      classPK the primary key of the entity this counter belongs to
472             * @param      name the counter's name
473             * @param      ownerType the counter's owner type. Acceptable values are
474             *             <code>TYPE_ACTOR</code>, <code>TYPE_ASSET</code> and
475             *             <code>TYPE_CREATOR</code> defined in {@link
476             *             com.liferay.portlet.social.model.SocialActivityCounterConstants}.
477             * @param      currentValue the counter's current value (optionally
478             *             <code>0</code>)
479             * @param      totalValue the counter's total value of the counter
480             *             (optionally <code>0</code>)
481             * @param      startPeriod the counter's start period
482             * @param      endPeriod the counter's end period
483             * @param      previousActivityCounterId the primary key of the activity
484             *             counter for the previous time period (optionally
485             *             <code>0</code>, if this is the first)
486             * @param      periodLength the period length in days,
487             *             <code>PERIOD_LENGTH_INFINITE</code> for never ending counters
488             *             or <code>PERIOD_LENGTH_SYSTEM</code> for the period length
489             *             defined in <code>portal-ext.properties</code>. For more
490             *             information see {@link
491             *             com.liferay.portlet.social.model.SocialActivityConstants}.
492             * @return     the created activity counter
493             * @throws     PortalException if the group or the previous activity counter
494             *             could not be found
495             * @throws     SystemException if a system exception occurred
496             * @deprecated As of 6.2.0, replaced by {@link #addActivityCounter(long,
497             *             long, long, String, int, int, long, int)}
498             */
499            @Override
500            @Transactional(propagation = Propagation.REQUIRES_NEW)
501            public SocialActivityCounter createActivityCounter(
502                            long groupId, long classNameId, long classPK, String name,
503                            int ownerType, int currentValue, int totalValue, int startPeriod,
504                            int endPeriod, long previousActivityCounterId, int periodLength)
505                    throws PortalException, SystemException {
506    
507                    return addActivityCounter(
508                            groupId, classNameId, classPK, name, ownerType, totalValue,
509                            previousActivityCounterId, periodLength);
510            }
511    
512            /**
513             * Deletes all activity counters, limits, and settings related to the asset.
514             *
515             * <p>
516             * This method subtracts the asset's popularity from the owner's
517             * contribution points. It also creates a new contribution period if the
518             * latest one does not belong to the current period.
519             * </p>
520             *
521             * @param  assetEntry the asset entry
522             * @throws PortalException if the new contribution counter could not be
523             *         created
524             * @throws SystemException if a system exception occurred
525             */
526            @Override
527            public void deleteActivityCounters(AssetEntry assetEntry)
528                    throws PortalException, SystemException {
529    
530                    if (assetEntry == null) {
531                            return;
532                    }
533    
534                    adjustUserContribution(assetEntry, false);
535    
536                    socialActivityCounterPersistence.removeByC_C(
537                            assetEntry.getClassNameId(), assetEntry.getClassPK());
538    
539                    socialActivityLimitPersistence.removeByC_C(
540                            assetEntry.getClassNameId(), assetEntry.getClassPK());
541    
542                    socialActivitySettingLocalService.deleteActivitySetting(
543                            assetEntry.getGroupId(), assetEntry.getClassName(),
544                            assetEntry.getClassPK());
545    
546                    clearFinderCache();
547            }
548    
549            /**
550             * Deletes all activity counters, limits, and settings related to the entity
551             * identified by the class name ID and class primary key.
552             *
553             * @param  classNameId the primary key of the entity's class
554             * @param  classPK the primary key of the entity
555             * @throws PortalException if the entity is an asset and its owner's
556             *         contribution counter could not be updated
557             * @throws SystemException if a system exception occurred
558             */
559            @Override
560            public void deleteActivityCounters(long classNameId, long classPK)
561                    throws PortalException, SystemException {
562    
563                    String className = PortalUtil.getClassName(classNameId);
564    
565                    if (!className.equals(User.class.getName())) {
566                            AssetEntry assetEntry = assetEntryLocalService.fetchEntry(
567                                    className, classPK);
568    
569                            deleteActivityCounters(assetEntry);
570                    }
571                    else {
572                            socialActivityCounterPersistence.removeByC_C(classNameId, classPK);
573    
574                            socialActivityLimitPersistence.removeByUserId(classPK);
575                    }
576    
577                    clearFinderCache();
578            }
579    
580            /**
581             * Deletes all activity counters for the entity identified by the class name
582             * and class primary key.
583             *
584             * @param  className the entity's class name
585             * @param  classPK the primary key of the entity
586             * @throws PortalException if the entity is an asset and its owner's
587             *         contribution counter could not be updated
588             * @throws SystemException if a system exception occurred
589             */
590            @Override
591            public void deleteActivityCounters(String className, long classPK)
592                    throws PortalException, SystemException {
593    
594                    if (!className.equals(User.class.getName())) {
595                            AssetEntry assetEntry = assetEntryLocalService.fetchEntry(
596                                    className, classPK);
597    
598                            deleteActivityCounters(assetEntry);
599                    }
600                    else {
601                            long classNameId = PortalUtil.getClassNameId(className);
602    
603                            socialActivityCounterPersistence.removeByC_C(classNameId, classPK);
604    
605                            socialActivityLimitPersistence.removeByUserId(classPK);
606                    }
607    
608                    clearFinderCache();
609            }
610    
611            /**
612             * Disables all the counters of an asset identified by the class name ID and
613             * class primary key.
614             *
615             * <p>
616             * This method is used by the recycle bin to disable all counters of assets
617             * put into the recycle bin. It adjusts the owner's contribution score.
618             * </p>
619             *
620             * @param  classNameId the primary key of the asset's class
621             * @param  classPK the primary key of the asset
622             * @throws PortalException if the asset owner's contribution counter could
623             *         not be updated
624             * @throws SystemException if a system exception occurred
625             */
626            @Override
627            public void disableActivityCounters(long classNameId, long classPK)
628                    throws PortalException, SystemException {
629    
630                    String className = PortalUtil.getClassName(classNameId);
631    
632                    disableActivityCounters(className, classPK);
633            }
634    
635            /**
636             * Disables all the counters of an asset identified by the class name and
637             * class primary key.
638             *
639             * <p>
640             * This method is used by the recycle bin to disable all counters of assets
641             * put into the recycle bin. It adjusts the owner's contribution score.
642             * </p>
643             *
644             * @param  className the asset's class name
645             * @param  classPK the primary key of the asset
646             * @throws PortalException if the asset owner's contribution counter could
647             *         not be updated
648             * @throws SystemException if a system exception occurred
649             */
650            @Override
651            public void disableActivityCounters(String className, long classPK)
652                    throws PortalException, SystemException {
653    
654                    AssetEntry assetEntry = assetEntryLocalService.fetchEntry(
655                            className, classPK);
656    
657                    if (assetEntry == null) {
658                            return;
659                    }
660    
661                    List<SocialActivityCounter> activityCounters =
662                            socialActivityCounterPersistence.findByC_C(
663                                    assetEntry.getClassNameId(), classPK);
664    
665                    adjustUserContribution(assetEntry, false);
666    
667                    for (SocialActivityCounter activityCounter : activityCounters) {
668                            if (activityCounter.isActive()) {
669                                    activityCounter.setActive(false);
670    
671                                    socialActivityCounterPersistence.update(activityCounter);
672                            }
673                    }
674    
675                    clearFinderCache();
676            }
677    
678            /**
679             * Enables all activity counters of an asset identified by the class name ID
680             * and class primary key.
681             *
682             * <p>
683             * This method is used by the recycle bin to enable all counters of assets
684             * restored from the recycle bin. It adjusts the owner's contribution score.
685             * </p>
686             *
687             * @param  classNameId the primary key of the asset's class
688             * @param  classPK the primary key of the asset
689             * @throws PortalException if the asset owner's contribution counter could
690             *         not be updated
691             * @throws SystemException if a system exception occurred
692             */
693            @Override
694            public void enableActivityCounters(long classNameId, long classPK)
695                    throws PortalException, SystemException {
696    
697                    String className = PortalUtil.getClassName(classNameId);
698    
699                    enableActivityCounters(className, classPK);
700            }
701    
702            /**
703             * Enables all the counters of an asset identified by the class name and
704             * class primary key.
705             *
706             * <p>
707             * This method is used by the recycle bin to enable all counters of assets
708             * restored from the recycle bin. It adjusts the owner's contribution score.
709             * </p>
710             *
711             * @param  className the asset's class name
712             * @param  classPK the primary key of the asset
713             * @throws PortalException if the asset owner's contribution counter could
714             *         not be updated
715             * @throws SystemException if a system exception occurred
716             */
717            @Override
718            public void enableActivityCounters(String className, long classPK)
719                    throws PortalException, SystemException {
720    
721                    AssetEntry assetEntry = assetEntryLocalService.fetchEntry(
722                            className, classPK);
723    
724                    if (assetEntry == null) {
725                            return;
726                    }
727    
728                    List<SocialActivityCounter> activityCounters =
729                            socialActivityCounterPersistence.findByC_C(
730                                    assetEntry.getClassNameId(), classPK);
731    
732                    adjustUserContribution(assetEntry, true);
733    
734                    for (SocialActivityCounter activityCounter : activityCounters) {
735                            if (!activityCounter.isActive()) {
736                                    activityCounter.setActive(true);
737    
738                                    socialActivityCounterPersistence.update(activityCounter);
739                            }
740                    }
741    
742                    clearFinderCache();
743            }
744    
745            /**
746             * Returns the activity counter with the given name, owner, and end period
747             * that belong to the given entity.
748             *
749             * @param  groupId the primary key of the group
750             * @param  classNameId the primary key of the entity's class
751             * @param  classPK the primary key of the entity
752             * @param  name the counter name
753             * @param  ownerType the owner type
754             * @param  endPeriod the end period, <code>-1</code> for the latest one
755             * @return the matching activity counter
756             * @throws SystemException if a system exception occurred
757             */
758            @Override
759            public SocialActivityCounter fetchActivityCounterByEndPeriod(
760                            long groupId, long classNameId, long classPK, String name,
761                            int ownerType, int endPeriod)
762                    throws SystemException {
763    
764                    return socialActivityCounterPersistence.fetchByG_C_C_N_O_E(
765                            groupId, classNameId, classPK, name, ownerType, endPeriod);
766            }
767    
768            /**
769             * Returns the activity counter with the given name, owner, and start period
770             * that belong to the given entity.
771             *
772             * @param  groupId the primary key of the group
773             * @param  classNameId the primary key of the entity's class
774             * @param  classPK the primary key of the entity
775             * @param  name the counter name
776             * @param  ownerType the owner type
777             * @param  startPeriod the start period
778             * @return the matching activity counter
779             * @throws SystemException if a system exception occurred
780             */
781            @Override
782            public SocialActivityCounter fetchActivityCounterByStartPeriod(
783                            long groupId, long classNameId, long classPK, String name,
784                            int ownerType, int startPeriod)
785                    throws SystemException {
786    
787                    return socialActivityCounterPersistence.fetchByG_C_C_N_O_S(
788                            groupId, classNameId, classPK, name, ownerType, startPeriod);
789            }
790    
791            /**
792             * Returns the latest activity counter with the given name and owner that
793             * belong to the given entity.
794             *
795             * @param  groupId the primary key of the group
796             * @param  classNameId the primary key of the entity's class
797             * @param  classPK the primary key of the entity
798             * @param  name the counter name
799             * @param  ownerType the owner type
800             * @return the matching activity counter
801             * @throws SystemException if a system exception occurred
802             */
803            @Override
804            public SocialActivityCounter fetchLatestActivityCounter(
805                            long groupId, long classNameId, long classPK, String name,
806                            int ownerType)
807                    throws SystemException {
808    
809                    return socialActivityCounterPersistence.fetchByG_C_C_N_O_E(
810                            groupId, classNameId, classPK, name, ownerType,
811                            SocialActivityCounterConstants.END_PERIOD_UNDEFINED);
812            }
813    
814            /**
815             * Returns all the activity counters with the given name and period offsets.
816             *
817             * <p>
818             * The start and end offsets can belong to different periods. This method
819             * groups the counters by name and returns the sum of their current values.
820             * </p>
821             *
822             * @param  groupId the primary key of the group
823             * @param  name the counter name
824             * @param  startOffset the offset for the start period
825             * @param  endOffset the offset for the end period
826             * @return the matching activity counters
827             * @throws SystemException if a system exception occurred
828             */
829            @Override
830            public List<SocialActivityCounter> getOffsetActivityCounters(
831                            long groupId, String name, int startOffset, int endOffset)
832                    throws SystemException {
833    
834                    int startPeriod = SocialCounterPeriodUtil.getStartPeriod(startOffset);
835                    int endPeriod = SocialCounterPeriodUtil.getEndPeriod(endOffset);
836    
837                    return getPeriodActivityCounters(groupId, name, startPeriod, endPeriod);
838            }
839    
840            /**
841             * Returns the distribution of the activity counters with the given name and
842             * period offsets.
843             *
844             * <p>
845             * The start and end offsets can belong to different periods. This method
846             * groups the counters by their owner entity (usually some asset) and
847             * returns a counter for each entity class with the sum of the counters'
848             * current values.
849             * </p>
850             *
851             * @param  groupId the primary key of the group
852             * @param  name the counter name
853             * @param  startOffset the offset for the start period
854             * @param  endOffset the offset for the end period
855             * @return the distribution of matching activity counters
856             * @throws SystemException if a system exception occurred
857             */
858            @Override
859            public List<SocialActivityCounter> getOffsetDistributionActivityCounters(
860                            long groupId, String name, int startOffset, int endOffset)
861                    throws SystemException {
862    
863                    int startPeriod = SocialCounterPeriodUtil.getStartPeriod(startOffset);
864                    int endPeriod = SocialCounterPeriodUtil.getEndPeriod(endOffset);
865    
866                    return getPeriodDistributionActivityCounters(
867                            groupId, name, startPeriod, endPeriod);
868            }
869    
870            /**
871             * Returns all the activity counters with the given name and time period.
872             *
873             * <p>
874             * The start and end period values can belong to different periods. This
875             * method groups the counters by name and returns the sum of their current
876             * values.
877             * </p>
878             *
879             * @param  groupId the primary key of the group
880             * @param  name the counter name
881             * @param  startPeriod the start period
882             * @param  endPeriod the end period
883             * @return the matching activity counters
884             * @throws SystemException if a system exception occurred
885             */
886            @Override
887            public List<SocialActivityCounter> getPeriodActivityCounters(
888                            long groupId, String name, int startPeriod, int endPeriod)
889                    throws SystemException {
890    
891                    if (endPeriod == SocialActivityCounterConstants.END_PERIOD_UNDEFINED) {
892                            endPeriod = SocialCounterPeriodUtil.getEndPeriod();
893                    }
894    
895                    int offset = SocialCounterPeriodUtil.getOffset(endPeriod);
896    
897                    int periodLength = SocialCounterPeriodUtil.getPeriodLength(offset);
898    
899                    return socialActivityCounterFinder.findAC_ByG_N_S_E_1(
900                            groupId, name, startPeriod, endPeriod, periodLength);
901            }
902    
903            /**
904             * Returns the distribution of activity counters with the given name and
905             * time period.
906             *
907             * <p>
908             * The start and end period values can belong to different periods. This
909             * method groups the counters by their owner entity (usually some asset) and
910             * returns a counter for each entity class with the sum of the counters'
911             * current values.
912             * </p>
913             *
914             * @param  groupId the primary key of the group
915             * @param  name the counter name
916             * @param  startPeriod the start period
917             * @param  endPeriod the end period
918             * @return the distribution of matching activity counters
919             * @throws SystemException if a system exception occurred
920             */
921            @Override
922            public List<SocialActivityCounter> getPeriodDistributionActivityCounters(
923                            long groupId, String name, int startPeriod, int endPeriod)
924                    throws SystemException {
925    
926                    int offset = SocialCounterPeriodUtil.getOffset(endPeriod);
927    
928                    int periodLength = SocialCounterPeriodUtil.getPeriodLength(offset);
929    
930                    return socialActivityCounterFinder.findAC_ByG_N_S_E_2(
931                            groupId, name, startPeriod, endPeriod, periodLength);
932            }
933    
934            /**
935             * Returns the range of tuples that contain users and a list of activity
936             * counters.
937             *
938             * <p>
939             * The counters returned for each user are passed to this method in the
940             * selectedNames array. The method also accepts an array of counter names
941             * that are used to rank the users.
942             * </p>
943             *
944             * <p>
945             * Useful when paginating results. Returns a maximum of <code>end -
946             * start</code> instances. <code>start</code> and <code>end</code> are not
947             * primary keys, they are indexes in the result set. Thus, <code>0</code>
948             * refers to the first result in the set. Setting both <code>start</code>
949             * and <code>end</code> to {@link
950             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
951             * result set.
952             * </p>
953             *
954             * @param  groupId the primary key of the group
955             * @param  rankingNames the ranking counter names
956             * @param  selectedNames the counter names that will be returned with each
957             *         user
958             * @param  start the lower bound of the range of results
959             * @param  end the upper bound of the range of results (not inclusive)
960             * @return the range of matching tuples
961             * @throws SystemException if a system exception occurred
962             */
963            @Override
964            public List<Tuple> getUserActivityCounters(
965                            long groupId, String[] rankingNames, String[] selectedNames,
966                            int start, int end)
967                    throws SystemException {
968    
969                    List<Long> userIds = socialActivityCounterFinder.findU_ByG_N(
970                            groupId, rankingNames, start, end);
971    
972                    if (userIds.isEmpty()) {
973                            return Collections.emptyList();
974                    }
975    
976                    Tuple[] userActivityCounters = new Tuple[userIds.size()];
977    
978                    List<SocialActivityCounter> activityCounters =
979                            socialActivityCounterFinder.findAC_By_G_C_C_N_S_E(
980                                    groupId, userIds, selectedNames, QueryUtil.ALL_POS,
981                                    QueryUtil.ALL_POS);
982    
983                    long userId = 0;
984                    Map<String, SocialActivityCounter> activityCountersMap = null;
985    
986                    for (SocialActivityCounter activityCounter : activityCounters) {
987                            if (userId != activityCounter.getClassPK()) {
988                                    userId = activityCounter.getClassPK();
989                                    activityCountersMap =
990                                            new HashMap<String, SocialActivityCounter>();
991    
992                                    Tuple userActivityCounter = new Tuple(
993                                            userId, activityCountersMap);
994    
995                                    for (int i = 0; i < userIds.size(); i++) {
996                                            long curUserId = userIds.get(i);
997    
998                                            if (userId == curUserId) {
999                                                    userActivityCounters[i] = userActivityCounter;
1000    
1001                                                    break;
1002                                            }
1003                                    }
1004                            }
1005    
1006                            activityCountersMap.put(activityCounter.getName(), activityCounter);
1007                    }
1008    
1009                    return Arrays.asList(userActivityCounters);
1010            }
1011    
1012            /**
1013             * Returns the number of users having a rank based on the given counters.
1014             *
1015             * @param  groupId the primary key of the group
1016             * @param  rankingNames the ranking counter names
1017             * @return the number of matching users
1018             * @throws SystemException if a system exception occurred
1019             */
1020            @Override
1021            public int getUserActivityCountersCount(long groupId, String[] rankingNames)
1022                    throws SystemException {
1023    
1024                    return socialActivityCounterFinder.countU_ByG_N(groupId, rankingNames);
1025            }
1026    
1027            /**
1028             * Increments the <code>user.achievements</code> counter for a user.
1029             *
1030             * <p>
1031             * This method should be used by an external achievement class when the
1032             * users unlocks an achievement.
1033             * </p>
1034             *
1035             * @param  userId the primary key of the user
1036             * @param  groupId the primary key of the group
1037             * @throws PortalException if the group or an expected previous activity
1038             *         counter could not be found
1039             * @throws SystemException if a system exception occurred
1040             */
1041            @Override
1042            public void incrementUserAchievementCounter(long userId, long groupId)
1043                    throws PortalException, SystemException {
1044    
1045                    User user = userPersistence.findByPrimaryKey(userId);
1046    
1047                    SocialActivityCounter activityCounter = addActivityCounter(
1048                            groupId, user, new SocialActivityImpl(),
1049                            _userAchievementsActivityCounterDefinition);
1050    
1051                    incrementActivityCounter(
1052                            activityCounter, _userAchievementsActivityCounterDefinition);
1053            }
1054    
1055            protected SocialActivityCounter addActivityCounter(
1056                            final long groupId, final User user, final SocialActivity activity,
1057                            final SocialActivityCounterDefinition activityCounterDefinition)
1058                    throws PortalException, SystemException {
1059    
1060                    int ownerType = activityCounterDefinition.getOwnerType();
1061    
1062                    long classNameId = getClassNameId(activity.getAssetEntry(), ownerType);
1063                    long classPK = getClassPK(user, activity.getAssetEntry(), ownerType);
1064    
1065                    SocialActivityCounter activityCounter = fetchLatestActivityCounter(
1066                            groupId, classNameId, classPK, activityCounterDefinition.getName(),
1067                            ownerType);
1068    
1069                    if (activityCounter == null) {
1070                            activityCounter = lockProtectedAddActivityCounter(
1071                                    groupId, classNameId, classPK,
1072                                    activityCounterDefinition.getName(), ownerType, 0, 0,
1073                                    activityCounterDefinition.getPeriodLength());
1074                    }
1075                    else if (!activityCounter.isActivePeriod(
1076                                            activityCounterDefinition.getPeriodLength())) {
1077    
1078                            activityCounter = lockProtectedAddActivityCounter(
1079                                    groupId, classNameId, classPK,
1080                                    activityCounterDefinition.getName(), ownerType,
1081                                    activityCounter.getTotalValue(),
1082                                    activityCounter.getActivityCounterId(),
1083                                    activityCounterDefinition.getPeriodLength());
1084                    }
1085    
1086                    if (activityCounterDefinition.getLimitValue() > 0) {
1087                            SocialActivityLimit activityLimit =
1088                                    socialActivityLimitPersistence.fetchByG_U_C_C_A_A(
1089                                            groupId, user.getUserId(), activity.getClassNameId(),
1090                                            getLimitClassPK(activity, activityCounterDefinition),
1091                                            activity.getType(), activityCounterDefinition.getName());
1092    
1093                            if (activityLimit == null) {
1094                                    lockProtectedGetActivityLimit(
1095                                            groupId, user, activity, activityCounterDefinition);
1096                            }
1097                    }
1098    
1099                    return activityCounter;
1100            }
1101    
1102            protected SocialActivityCounter addAssetActivitiesCounter(
1103                            SocialActivity activity)
1104                    throws PortalException, SystemException {
1105    
1106                    User user = userPersistence.findByPrimaryKey(activity.getUserId());
1107    
1108                    return addActivityCounter(
1109                            activity.getGroupId(), user, activity,
1110                            _assetActivitiesActivityCounterDefinition);
1111            }
1112    
1113            protected SocialActivityCounter addUserActivitiesCounter(
1114                            SocialActivity activity)
1115                    throws PortalException, SystemException {
1116    
1117                    User user = userPersistence.findByPrimaryKey(activity.getUserId());
1118    
1119                    return addActivityCounter(
1120                            activity.getGroupId(), user, activity,
1121                            _userActivitiesActivityCounterDefinition);
1122            }
1123    
1124            protected void adjustUserContribution(AssetEntry assetEntry, boolean enable)
1125                    throws PortalException, SystemException {
1126    
1127                    if (assetEntry == null) {
1128                            return;
1129                    }
1130    
1131                    SocialActivityCounter latestPopularityActivityCounter =
1132                            fetchLatestActivityCounter(
1133                                    assetEntry.getGroupId(), assetEntry.getClassNameId(),
1134                                    assetEntry.getClassPK(),
1135                                    SocialActivityCounterConstants.NAME_POPULARITY,
1136                                    SocialActivityCounterConstants.TYPE_ASSET);
1137    
1138                    if ((latestPopularityActivityCounter == null) ||
1139                            (enable && latestPopularityActivityCounter.isActive()) ||
1140                            (!enable && !latestPopularityActivityCounter.isActive())) {
1141    
1142                            return;
1143                    }
1144    
1145                    int factor = -1;
1146    
1147                    if (enable) {
1148                            factor = 1;
1149                    }
1150    
1151                    SocialActivityCounter latestContributionActivityCounter =
1152                            fetchLatestActivityCounter(
1153                                    assetEntry.getGroupId(),
1154                                    PortalUtil.getClassNameId(User.class.getName()),
1155                                    assetEntry.getUserId(),
1156                                    SocialActivityCounterConstants.NAME_CONTRIBUTION,
1157                                    SocialActivityCounterConstants.TYPE_CREATOR);
1158    
1159                    if (latestContributionActivityCounter == null) {
1160                            return;
1161                    }
1162    
1163                    int startPeriod = SocialCounterPeriodUtil.getStartPeriod();
1164    
1165                    if (latestContributionActivityCounter.getStartPeriod() != startPeriod) {
1166                            latestContributionActivityCounter = addActivityCounter(
1167                                    latestContributionActivityCounter.getGroupId(),
1168                                    latestContributionActivityCounter.getClassNameId(),
1169                                    latestContributionActivityCounter.getClassPK(),
1170                                    latestContributionActivityCounter.getName(),
1171                                    latestContributionActivityCounter.getOwnerType(), 0,
1172                                    latestContributionActivityCounter.getTotalValue(),
1173                                    SocialCounterPeriodUtil.getStartPeriod(),
1174                                    SocialActivityCounterConstants.END_PERIOD_UNDEFINED,
1175                                    latestContributionActivityCounter.getActivityCounterId(),
1176                                    SocialActivityCounterConstants.PERIOD_LENGTH_SYSTEM);
1177                    }
1178    
1179                    if (latestPopularityActivityCounter.getStartPeriod() == startPeriod) {
1180                            latestContributionActivityCounter.setCurrentValue(
1181                                    latestContributionActivityCounter.getCurrentValue() +
1182                                            (latestPopularityActivityCounter.getCurrentValue() *
1183                                                    factor));
1184                    }
1185    
1186                    latestContributionActivityCounter.setTotalValue(
1187                            latestContributionActivityCounter.getTotalValue() +
1188                                    (latestPopularityActivityCounter.getTotalValue() * factor));
1189    
1190                    socialActivityCounterPersistence.update(
1191                            latestContributionActivityCounter);
1192            }
1193    
1194            protected boolean checkActivityLimit(
1195                            User user, SocialActivity activity,
1196                            SocialActivityCounterDefinition activityCounterDefinition)
1197                    throws PortalException, SystemException {
1198    
1199                    if (activityCounterDefinition.getLimitValue() == 0) {
1200                            return true;
1201                    }
1202    
1203                    long classPK = activity.getClassPK();
1204    
1205                    String name = activityCounterDefinition.getName();
1206    
1207                    if (name.equals(SocialActivityCounterConstants.NAME_PARTICIPATION)) {
1208                            classPK = 0;
1209                    }
1210    
1211                    SocialActivityLimit activityLimit =
1212                            socialActivityLimitPersistence.findByG_U_C_C_A_A(
1213                                    activity.getGroupId(), user.getUserId(),
1214                                    activity.getClassNameId(), classPK, activity.getType(), name);
1215    
1216                    int count = activityLimit.getCount(
1217                            activityCounterDefinition.getLimitPeriod());
1218    
1219                    if (count < activityCounterDefinition.getLimitValue()) {
1220                            activityLimit.setCount(
1221                                    activityCounterDefinition.getLimitPeriod(), count + 1);
1222    
1223                            socialActivityLimitPersistence.update(activityLimit);
1224    
1225                            return true;
1226                    }
1227    
1228                    return false;
1229            }
1230    
1231            protected void clearFinderCache() {
1232                    PortalCache<String, SocialActivityCounter> portalCache =
1233                            MultiVMPoolUtil.getCache(
1234                                    SocialActivityCounterFinder.class.getName());
1235    
1236                    portalCache.removeAll();
1237            }
1238    
1239            protected long getClassNameId(AssetEntry assetEntry, int ownerType) {
1240                    if (ownerType == SocialActivityCounterConstants.TYPE_ASSET) {
1241                            return assetEntry.getClassNameId();
1242                    }
1243    
1244                    return PortalUtil.getClassNameId(User.class.getName());
1245            }
1246    
1247            protected long getClassPK(User user, AssetEntry assetEntry, int ownerType) {
1248                    if (ownerType == SocialActivityCounterConstants.TYPE_ACTOR) {
1249                            return user.getUserId();
1250                    }
1251    
1252                    if (ownerType == SocialActivityCounterConstants.TYPE_ASSET) {
1253                            return assetEntry.getClassPK();
1254                    }
1255    
1256                    return assetEntry.getUserId();
1257            }
1258    
1259            protected long getLimitClassPK(
1260                    SocialActivity activity,
1261                    SocialActivityCounterDefinition activityCounterDefinition) {
1262    
1263                    String name = activityCounterDefinition.getName();
1264    
1265                    if (name.equals(SocialActivityCounterConstants.NAME_PARTICIPATION)) {
1266                            return 0;
1267                    }
1268    
1269                    return activity.getClassPK();
1270            }
1271    
1272            protected void incrementActivityCounter(
1273                            SocialActivityCounter activityCounter,
1274                            SocialActivityCounterDefinition activityCounterDefinition)
1275                    throws SystemException {
1276    
1277                    activityCounter.setCurrentValue(
1278                            activityCounter.getCurrentValue() +
1279                                    activityCounterDefinition.getIncrement());
1280                    activityCounter.setTotalValue(
1281                            activityCounter.getTotalValue() +
1282                                    activityCounterDefinition.getIncrement());
1283    
1284                    socialActivityCounterPersistence.update(activityCounter);
1285    
1286                    socialActivityCounterPersistence.clearCache(activityCounter);
1287            }
1288    
1289            protected boolean isAddActivityCounter(
1290                    User user, User assetEntryUser, AssetEntry assetEntry,
1291                    SocialActivityCounterDefinition activityCounterDefinition) {
1292    
1293                    if ((user.isDefaultUser() || !user.isActive()) &&
1294                            (activityCounterDefinition.getOwnerType() !=
1295                                    SocialActivityCounterConstants.TYPE_ASSET)) {
1296    
1297                            return false;
1298                    }
1299    
1300                    if ((assetEntryUser.isDefaultUser() || !assetEntryUser.isActive()) &&
1301                            (activityCounterDefinition.getOwnerType() !=
1302                                    SocialActivityCounterConstants.TYPE_ACTOR)) {
1303    
1304                            return false;
1305                    }
1306    
1307                    if (!activityCounterDefinition.isEnabled() ||
1308                            (activityCounterDefinition.getIncrement() == 0)) {
1309    
1310                            return false;
1311                    }
1312    
1313                    String name = activityCounterDefinition.getName();
1314    
1315                    if ((user.getUserId() == assetEntryUser.getUserId()) &&
1316                            (name.equals(SocialActivityCounterConstants.NAME_CONTRIBUTION) ||
1317                             name.equals(SocialActivityCounterConstants.NAME_POPULARITY))) {
1318    
1319                            return false;
1320                    }
1321    
1322                    if ((activityCounterDefinition.getOwnerType() ==
1323                                    SocialActivityCounterConstants.TYPE_ASSET) &&
1324                            !assetEntry.isVisible()) {
1325    
1326                            return false;
1327                    }
1328    
1329                    return true;
1330            }
1331    
1332            protected SocialActivityCounter lockProtectedAddActivityCounter(
1333                            final long groupId, final long classNameId, final long classPK,
1334                            final String name, final int ownerType, final int totalValue,
1335                            final long previousActivityCounterId, final int periodLength)
1336                    throws PortalException, SystemException {
1337    
1338                    String lockKey = StringUtil.merge(
1339                            new Object[] {
1340                                    groupId, classNameId, classPK, name, ownerType
1341                            },
1342                            StringPool.POUND);
1343    
1344                    LockProtectedAction<SocialActivityCounter> lockProtectedAction =
1345                            new LockProtectedAction<SocialActivityCounter>(
1346                                    SocialActivityCounter.class, lockKey,
1347                                    PropsValues.SOCIAL_ACTIVITY_LOCK_TIMEOUT,
1348                                    PropsValues.SOCIAL_ACTIVITY_LOCK_RETRY_DELAY) {
1349    
1350                            @Override
1351                            protected SocialActivityCounter performProtectedAction()
1352                                    throws PortalException, SystemException {
1353    
1354                                    SocialActivityCounter activityCounter =
1355                                            socialActivityCounterLocalService.addActivityCounter(
1356                                                    groupId, classNameId, classPK, name, ownerType,
1357                                                    totalValue, previousActivityCounterId, periodLength);
1358    
1359                                    return activityCounter;
1360                            }
1361    
1362                    };
1363    
1364                    lockProtectedAction.performAction();
1365    
1366                    return lockProtectedAction.getReturnValue();
1367            }
1368    
1369            protected void lockProtectedGetActivityLimit(
1370                            final long groupId, final User user, final SocialActivity activity,
1371                            final SocialActivityCounterDefinition activityCounterDefinition)
1372                    throws PortalException, SystemException {
1373    
1374                    final long classPK = getLimitClassPK(
1375                            activity, activityCounterDefinition);
1376    
1377                    String lockKey = StringUtil.merge(
1378                            new Object[] {
1379                                    groupId, user.getUserId(), activity.getClassNameId(), classPK,
1380                                    activity.getType(), activityCounterDefinition.getName()
1381                            },
1382                            StringPool.POUND);
1383    
1384                    LockProtectedAction<SocialActivityLimit> lockProtectedAction =
1385                            new LockProtectedAction<SocialActivityLimit>(
1386                                    SocialActivityLimit.class, lockKey,
1387                                    PropsValues.SOCIAL_ACTIVITY_LOCK_TIMEOUT,
1388                                    PropsValues.SOCIAL_ACTIVITY_LOCK_RETRY_DELAY) {
1389    
1390                            @Override
1391                            protected SocialActivityLimit performProtectedAction()
1392                                    throws PortalException, SystemException {
1393    
1394                                    SocialActivityLimit activityLimit =
1395                                            socialActivityLimitPersistence.fetchByG_U_C_C_A_A(
1396                                                    groupId, user.getUserId(), activity.getClassNameId(),
1397                                                    classPK, activity.getType(),
1398                                                    activityCounterDefinition.getName());
1399    
1400                                    if (activityLimit == null) {
1401                                            activityLimit =
1402                                                    socialActivityLimitLocalService.addActivityLimit(
1403                                                            user.getUserId(), activity.getGroupId(),
1404                                                            activity.getClassNameId(), classPK,
1405                                                            activity.getType(),
1406                                                            activityCounterDefinition.getName(),
1407                                                            activityCounterDefinition.getLimitPeriod());
1408                                    }
1409    
1410                                    return activityLimit;
1411                            }
1412                    };
1413    
1414                    lockProtectedAction.performAction();
1415    
1416                    socialActivityLimitPersistence.cacheResult(
1417                            lockProtectedAction.getReturnValue());
1418            }
1419    
1420            private SocialActivityCounterDefinition
1421                    _assetActivitiesActivityCounterDefinition =
1422                            new SocialActivityCounterDefinition(
1423                                    SocialActivityCounterConstants.NAME_ASSET_ACTIVITIES,
1424                                    SocialActivityCounterConstants.TYPE_ASSET);
1425            private SocialActivityCounterDefinition
1426                    _userAchievementsActivityCounterDefinition =
1427                            new SocialActivityCounterDefinition(
1428                                    SocialActivityCounterConstants.NAME_USER_ACHIEVEMENTS,
1429                                    SocialActivityCounterConstants.TYPE_ACTOR);
1430            private SocialActivityCounterDefinition
1431                    _userActivitiesActivityCounterDefinition =
1432                            new SocialActivityCounterDefinition(
1433                                    SocialActivityCounterConstants.NAME_USER_ACTIVITIES,
1434                                    SocialActivityCounterConstants.TYPE_ACTOR);
1435    
1436    }