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