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.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.messaging.async.Async;
020    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackUtil;
021    import com.liferay.portal.model.Group;
022    import com.liferay.portal.model.Layout;
023    import com.liferay.portal.model.User;
024    import com.liferay.portal.util.PropsValues;
025    import com.liferay.portlet.asset.model.AssetEntry;
026    import com.liferay.portlet.exportimport.lar.ExportImportThreadLocal;
027    import com.liferay.portlet.social.model.SocialActivity;
028    import com.liferay.portlet.social.model.SocialActivityConstants;
029    import com.liferay.portlet.social.model.SocialActivityDefinition;
030    import com.liferay.portlet.social.service.base.SocialActivityLocalServiceBaseImpl;
031    import com.liferay.portlet.social.util.SocialActivityHierarchyEntry;
032    import com.liferay.portlet.social.util.SocialActivityHierarchyEntryThreadLocal;
033    
034    import java.util.Date;
035    import java.util.List;
036    import java.util.concurrent.Callable;
037    
038    /**
039     * The social activity local service. This service provides the means to record
040     * and list social activities in groups and organizations.
041     *
042     * <p>
043     * Social activities are identified by their type and the type of asset they are
044     * done on. Each activity records the exact time of the action as well as human
045     * readable information needed for activity feeds.
046     * </p>
047     *
048     * <p>
049     * Most of the <i>get-</i> methods in this service order activities in
050     * descending order by their execution times, so the most recent activities are
051     * listed first.
052     * </p>
053     *
054     * @author Brian Wing Shun Chan
055     */
056    public class SocialActivityLocalServiceImpl
057            extends SocialActivityLocalServiceBaseImpl {
058    
059            /**
060             * Records an activity with the given time in the database.
061             *
062             * <p>
063             * This method records a social activity done on an asset, identified by its
064             * class name and class primary key, in the database. Additional information
065             * (such as the original message ID for a reply to a forum post) is passed
066             * in via the <code>extraData</code> in JSON format. For activities
067             * affecting another user, a mirror activity is generated that describes the
068             * action from the user's point of view. The target user's ID is passed in
069             * via the <code>receiverUserId</code>.
070             * </p>
071             *
072             * <p>
073             * Example for a mirrored activity:<br> When a user replies to a message
074             * boards post, the reply action is stored in the database with the
075             * <code>receiverUserId</code> being the ID of the author of the original
076             * message. The <code>extraData</code> contains the ID of the original
077             * message in JSON format. A mirror activity is generated with the values of
078             * the <code>userId</code> and the <code>receiverUserId</code> swapped. This
079             * mirror activity basically describes a "replied to" event.
080             * </p>
081             *
082             * <p>
083             * Mirror activities are most often used in relation to friend requests and
084             * activities.
085             * </p>
086             *
087             * @param userId the primary key of the acting user
088             * @param groupId the primary key of the group
089             * @param createDate the activity's date
090             * @param className the target asset's class name
091             * @param classPK the primary key of the target asset
092             * @param type the activity's type
093             * @param extraData any extra data regarding the activity
094             * @param receiverUserId the primary key of the receiving user
095             */
096            @Override
097            public void addActivity(
098                            long userId, long groupId, Date createDate, String className,
099                            long classPK, int type, String extraData, long receiverUserId)
100                    throws PortalException {
101    
102                    if (ExportImportThreadLocal.isImportInProcess()) {
103                            return;
104                    }
105    
106                    User user = userPersistence.findByPrimaryKey(userId);
107                    long classNameId = classNameLocalService.getClassNameId(className);
108    
109                    if (groupId > 0) {
110                            Group group = groupLocalService.getGroup(groupId);
111    
112                            if (group.isLayout()) {
113                                    Layout layout = layoutLocalService.getLayout(
114                                            group.getClassPK());
115    
116                                    groupId = layout.getGroupId();
117                            }
118                    }
119    
120                    final SocialActivity activity = socialActivityPersistence.create(0);
121    
122                    activity.setGroupId(groupId);
123                    activity.setCompanyId(user.getCompanyId());
124                    activity.setUserId(user.getUserId());
125                    activity.setCreateDate(createDate.getTime());
126                    activity.setMirrorActivityId(0);
127                    activity.setClassNameId(classNameId);
128                    activity.setClassPK(classPK);
129    
130                    SocialActivityHierarchyEntry activityHierarchyEntry =
131                            SocialActivityHierarchyEntryThreadLocal.peek();
132    
133                    if (activityHierarchyEntry != null) {
134                            activity.setParentClassNameId(
135                                    activityHierarchyEntry.getClassNameId());
136                            activity.setParentClassPK(activityHierarchyEntry.getClassPK());
137                    }
138    
139                    activity.setType(type);
140                    activity.setExtraData(extraData);
141                    activity.setReceiverUserId(receiverUserId);
142    
143                    AssetEntry assetEntry = assetEntryPersistence.fetchByC_C(
144                            classNameId, classPK);
145    
146                    activity.setAssetEntry(assetEntry);
147    
148                    SocialActivity mirrorActivity = null;
149    
150                    if ((receiverUserId > 0) && (userId != receiverUserId)) {
151                            mirrorActivity = socialActivityPersistence.create(0);
152    
153                            mirrorActivity.setGroupId(groupId);
154                            mirrorActivity.setCompanyId(user.getCompanyId());
155                            mirrorActivity.setUserId(receiverUserId);
156                            mirrorActivity.setCreateDate(createDate.getTime());
157                            mirrorActivity.setClassNameId(classNameId);
158                            mirrorActivity.setClassPK(classPK);
159    
160                            if (activityHierarchyEntry != null) {
161                                    mirrorActivity.setParentClassNameId(
162                                            activityHierarchyEntry.getClassNameId());
163                                    mirrorActivity.setParentClassPK(
164                                            activityHierarchyEntry.getClassPK());
165                            }
166    
167                            mirrorActivity.setType(type);
168                            mirrorActivity.setExtraData(extraData);
169                            mirrorActivity.setReceiverUserId(user.getUserId());
170                            mirrorActivity.setAssetEntry(assetEntry);
171                    }
172    
173                    final SocialActivity finalMirrorActivity = mirrorActivity;
174    
175                    Callable<Void> callable = new Callable<Void>() {
176    
177                            @Override
178                            public Void call() throws Exception {
179                                    socialActivityLocalService.addActivity(
180                                            activity, finalMirrorActivity);
181    
182                                    return null;
183                            }
184    
185                    };
186    
187                    TransactionCommitCallbackUtil.registerCallback(callable);
188            }
189    
190            /**
191             * Records an activity in the database, using a time based on the current
192             * time in an attempt to make the activity's time unique.
193             *
194             * @param userId the primary key of the acting user
195             * @param groupId the primary key of the group
196             * @param className the target asset's class name
197             * @param classPK the primary key of the target asset
198             * @param type the activity's type
199             * @param extraData any extra data regarding the activity
200             * @param receiverUserId the primary key of the receiving user
201             */
202            @Override
203            public void addActivity(
204                            long userId, long groupId, String className, long classPK, int type,
205                            String extraData, long receiverUserId)
206                    throws PortalException {
207    
208                    if (ExportImportThreadLocal.isImportInProcess()) {
209                            return;
210                    }
211    
212                    Date createDate = new Date();
213    
214                    long classNameId = classNameLocalService.getClassNameId(className);
215    
216                    while (true) {
217                            SocialActivity socialActivity =
218                                    socialActivityPersistence.fetchByG_U_CD_C_C_T_R(
219                                            groupId, userId, createDate.getTime(), classNameId, classPK,
220                                            type, receiverUserId);
221    
222                            if (socialActivity != null) {
223                                    createDate = new Date(createDate.getTime() + 1);
224                            }
225                            else {
226                                    break;
227                            }
228                    }
229    
230                    addActivity(
231                            userId, groupId, createDate, className, classPK, type, extraData,
232                            receiverUserId);
233            }
234    
235            @Async
236            @Override
237            public void addActivity(
238                            SocialActivity activity, SocialActivity mirrorActivity)
239                    throws PortalException {
240    
241                    if (ExportImportThreadLocal.isImportInProcess()) {
242                            return;
243                    }
244    
245                    if ((activity.getActivityId() > 0) ||
246                            ((mirrorActivity != null) &&
247                             (mirrorActivity.getActivityId() > 0))) {
248    
249                            throw new PortalException(
250                                    "Activity and mirror activity must not have primary keys set");
251                    }
252    
253                    if (isLogActivity(activity)) {
254                            long activityId = counterLocalService.increment(
255                                    SocialActivity.class.getName());
256    
257                            activity.setActivityId(activityId);
258    
259                            socialActivityPersistence.update(activity);
260    
261                            if (mirrorActivity != null) {
262                                    long mirrorActivityId = counterLocalService.increment(
263                                            SocialActivity.class.getName());
264    
265                                    mirrorActivity.setActivityId(mirrorActivityId);
266                                    mirrorActivity.setMirrorActivityId(activity.getPrimaryKey());
267    
268                                    socialActivityPersistence.update(mirrorActivity);
269                            }
270    
271                            if (PropsValues.SOCIAL_ACTIVITY_SETS_ENABLED) {
272                                    socialActivityInterpreterLocalService.updateActivitySet(
273                                            activity.getActivityId());
274                            }
275                    }
276    
277                    socialActivityCounterLocalService.addActivityCounters(activity);
278            }
279    
280            /**
281             * Records an activity in the database, but only if there isn't already an
282             * activity with the same parameters.
283             *
284             * <p>
285             * For the main functionality see {@link #addActivity(long, long, Date,
286             * String, long, int, String, long)}
287             * </p>
288             *
289             * @param userId the primary key of the acting user
290             * @param groupId the primary key of the group
291             * @param createDate the activity's date
292             * @param className the target asset's class name
293             * @param classPK the primary key of the target asset
294             * @param type the activity's type
295             * @param extraData any extra data regarding the activity
296             * @param receiverUserId the primary key of the receiving user
297             */
298            @Override
299            public void addUniqueActivity(
300                            long userId, long groupId, Date createDate, String className,
301                            long classPK, int type, String extraData, long receiverUserId)
302                    throws PortalException {
303    
304                    long classNameId = classNameLocalService.getClassNameId(className);
305    
306                    SocialActivity socialActivity =
307                            socialActivityPersistence.fetchByG_U_CD_C_C_T_R(
308                                    groupId, userId, createDate.getTime(), classNameId, classPK,
309                                    type, receiverUserId);
310    
311                    if (socialActivity != null) {
312                            return;
313                    }
314    
315                    addActivity(
316                            userId, groupId, createDate, className, classPK, type, extraData,
317                            receiverUserId);
318            }
319    
320            /**
321             * Records an activity with the current time in the database, but only if
322             * there isn't one with the same parameters.
323             *
324             * <p>
325             * For the main functionality see {@link #addActivity(long, long, Date,
326             * String, long, int, String, long)}
327             * </p>
328             *
329             * @param userId the primary key of the acting user
330             * @param groupId the primary key of the group
331             * @param className the target asset's class name
332             * @param classPK the primary key of the target asset
333             * @param type the activity's type
334             * @param extraData any extra data regarding the activity
335             * @param receiverUserId the primary key of the receiving user
336             */
337            @Override
338            public void addUniqueActivity(
339                            long userId, long groupId, String className, long classPK, int type,
340                            String extraData, long receiverUserId)
341                    throws PortalException {
342    
343                    long classNameId = classNameLocalService.getClassNameId(className);
344    
345                    int count = socialActivityPersistence.countByG_U_C_C_T_R(
346                            groupId, userId, classNameId, classPK, type, receiverUserId);
347    
348                    if (count > 0) {
349                            return;
350                    }
351    
352                    addActivity(
353                            userId, groupId, new Date(), className, classPK, type, extraData,
354                            receiverUserId);
355            }
356    
357            /**
358             * Removes stored activities for the asset.
359             *
360             * @param assetEntry the asset from which to remove stored activities
361             */
362            @Override
363            public void deleteActivities(AssetEntry assetEntry) throws PortalException {
364                    deleteActivities(assetEntry.getClassName(), assetEntry.getClassPK());
365            }
366    
367            @Override
368            public void deleteActivities(long groupId) {
369                    if (PropsValues.SOCIAL_ACTIVITY_SETS_ENABLED) {
370                            socialActivitySetPersistence.removeByGroupId(groupId);
371                    }
372    
373                    socialActivityPersistence.removeByGroupId(groupId);
374    
375                    socialActivityCounterPersistence.removeByGroupId(groupId);
376    
377                    socialActivityLimitPersistence.removeByGroupId(groupId);
378    
379                    socialActivitySettingPersistence.removeByGroupId(groupId);
380            }
381    
382            /**
383             * Removes stored activities for the asset identified by the class name and
384             * class primary key.
385             *
386             * @param className the target asset's class name
387             * @param classPK the primary key of the target asset
388             */
389            @Override
390            public void deleteActivities(String className, long classPK)
391                    throws PortalException {
392    
393                    long classNameId = classNameLocalService.getClassNameId(className);
394    
395                    deleteActivities(classNameId, classPK);
396            }
397    
398            /**
399             * Removes the stored activity from the database.
400             *
401             * @param activityId the primary key of the stored activity
402             */
403            @Override
404            public void deleteActivity(long activityId) throws PortalException {
405                    SocialActivity activity = socialActivityPersistence.findByPrimaryKey(
406                            activityId);
407    
408                    deleteActivity(activity);
409            }
410    
411            /**
412             * Removes the stored activity and its mirror activity from the database.
413             *
414             * @param activity the activity to be removed
415             */
416            @Override
417            public void deleteActivity(SocialActivity activity) throws PortalException {
418                    if (PropsValues.SOCIAL_ACTIVITY_SETS_ENABLED) {
419                            socialActivitySetLocalService.decrementActivityCount(
420                                    activity.getActivitySetId());
421                    }
422    
423                    socialActivityPersistence.remove(activity);
424    
425                    SocialActivity mirrorActivity =
426                            socialActivityPersistence.fetchByMirrorActivityId(
427                                    activity.getActivityId());
428    
429                    if (mirrorActivity != null) {
430                            socialActivityPersistence.remove(mirrorActivity);
431                    }
432            }
433    
434            /**
435             * Removes the user's stored activities from the database.
436             *
437             * <p>
438             * This method removes all activities where the user is either the actor or
439             * the receiver.
440             * </p>
441             *
442             * @param userId the primary key of the user
443             */
444            @Override
445            public void deleteUserActivities(long userId) throws PortalException {
446                    List<SocialActivity> activities =
447                            socialActivityPersistence.findByUserId(
448                                    userId, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
449    
450                    for (SocialActivity activity : activities) {
451                            if (PropsValues.SOCIAL_ACTIVITY_SETS_ENABLED) {
452                                    socialActivitySetLocalService.decrementActivityCount(
453                                            activity.getActivitySetId());
454                            }
455    
456                            socialActivityPersistence.remove(activity);
457                    }
458    
459                    activities = socialActivityPersistence.findByReceiverUserId(
460                            userId, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
461    
462                    for (SocialActivity activity : activities) {
463                            if (PropsValues.SOCIAL_ACTIVITY_SETS_ENABLED) {
464                                    socialActivitySetLocalService.decrementActivityCount(
465                                            activity.getActivitySetId());
466                            }
467    
468                            socialActivityPersistence.remove(activity);
469                    }
470    
471                    socialActivityCounterLocalService.deleteActivityCounters(
472                            User.class.getName(), userId);
473            }
474    
475            @Override
476            public SocialActivity fetchFirstActivity(
477                    String className, long classPK, int type) {
478    
479                    long classNameId = classNameLocalService.getClassNameId(className);
480    
481                    return socialActivityPersistence.fetchByC_C_T_First(
482                            classNameId, classPK, type, null);
483            }
484    
485            /**
486             * Returns a range of all the activities done on assets identified by the
487             * class name ID.
488             *
489             * <p>
490             * Useful when paginating results. Returns a maximum of <code>end -
491             * start</code> instances. <code>start</code> and <code>end</code> are not
492             * primary keys, they are indexes in the result set. Thus, <code>0</code>
493             * refers to the first result in the set. Setting both <code>start</code>
494             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
495             * result set.
496             * </p>
497             *
498             * @param  classNameId the target asset's class name ID
499             * @param  start the lower bound of the range of results
500             * @param  end the upper bound of the range of results (not inclusive)
501             * @return the range of matching activities
502             */
503            @Override
504            public List<SocialActivity> getActivities(
505                    long classNameId, int start, int end) {
506    
507                    return socialActivityPersistence.findByClassNameId(
508                            classNameId, start, end);
509            }
510    
511            /**
512             * Returns a range of all the activities done on the asset identified by the
513             * class name ID and class primary key that are mirrors of the activity
514             * identified by the mirror activity ID.
515             *
516             * <p>
517             * Useful when paginating results. Returns a maximum of <code>end -
518             * start</code> instances. <code>start</code> and <code>end</code> are not
519             * primary keys, they are indexes in the result set. Thus, <code>0</code>
520             * refers to the first result in the set. Setting both <code>start</code>
521             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
522             * result set.
523             * </p>
524             *
525             * @param  mirrorActivityId the primary key of the mirror activity
526             * @param  classNameId the target asset's class name ID
527             * @param  classPK the primary key of the target asset
528             * @param  start the lower bound of the range of results
529             * @param  end the upper bound of the range of results (not inclusive)
530             * @return the range of matching activities
531             */
532            @Override
533            public List<SocialActivity> getActivities(
534                    long mirrorActivityId, long classNameId, long classPK, int start,
535                    int end) {
536    
537                    return socialActivityPersistence.findByM_C_C(
538                            mirrorActivityId, classNameId, classPK, start, end);
539            }
540    
541            /**
542             * Returns a range of all the activities done on the asset identified by the
543             * class name and the class primary key that are mirrors of the activity
544             * identified by the mirror activity ID.
545             *
546             * <p>
547             * Useful when paginating results. Returns a maximum of <code>end -
548             * start</code> instances. <code>start</code> and <code>end</code> are not
549             * primary keys, they are indexes in the result set. Thus, <code>0</code>
550             * refers to the first result in the set. Setting both <code>start</code>
551             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
552             * result set.
553             * </p>
554             *
555             * @param  mirrorActivityId the primary key of the mirror activity
556             * @param  className the target asset's class name
557             * @param  classPK the primary key of the target asset
558             * @param  start the lower bound of the range of results
559             * @param  end the upper bound of the range of results (not inclusive)
560             * @return the range of matching activities
561             */
562            @Override
563            public List<SocialActivity> getActivities(
564                    long mirrorActivityId, String className, long classPK, int start,
565                    int end) {
566    
567                    long classNameId = classNameLocalService.getClassNameId(className);
568    
569                    return getActivities(
570                            mirrorActivityId, classNameId, classPK, start, end);
571            }
572    
573            /**
574             * Returns a range of all the activities done on assets identified by the
575             * class name.
576             *
577             * <p>
578             * Useful when paginating results. Returns a maximum of <code>end -
579             * start</code> instances. <code>start</code> and <code>end</code> are not
580             * primary keys, they are indexes in the result set. Thus, <code>0</code>
581             * refers to the first result in the set. Setting both <code>start</code>
582             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
583             * result set.
584             * </p>
585             *
586             * @param  className the target asset's class name
587             * @param  start the lower bound of the range of results
588             * @param  end the upper bound of the range of results (not inclusive)
589             * @return the range of matching activities
590             */
591            @Override
592            public List<SocialActivity> getActivities(
593                    String className, int start, int end) {
594    
595                    long classNameId = classNameLocalService.getClassNameId(className);
596    
597                    return getActivities(classNameId, start, end);
598            }
599    
600            /**
601             * Returns the number of activities done on assets identified by the class
602             * name ID.
603             *
604             * @param  classNameId the target asset's class name ID
605             * @return the number of matching activities
606             */
607            @Override
608            public int getActivitiesCount(long classNameId) {
609                    return socialActivityPersistence.countByClassNameId(classNameId);
610            }
611    
612            /**
613             * Returns the number of activities done on the asset identified by the
614             * class name ID and class primary key that are mirrors of the activity
615             * identified by the mirror activity ID.
616             *
617             * @param  mirrorActivityId the primary key of the mirror activity
618             * @param  classNameId the target asset's class name ID
619             * @param  classPK the primary key of the target asset
620             * @return the number of matching activities
621             */
622            @Override
623            public int getActivitiesCount(
624                    long mirrorActivityId, long classNameId, long classPK) {
625    
626                    return socialActivityPersistence.countByM_C_C(
627                            mirrorActivityId, classNameId, classPK);
628            }
629    
630            /**
631             * Returns the number of activities done on the asset identified by the
632             * class name and class primary key that are mirrors of the activity
633             * identified by the mirror activity ID.
634             *
635             * @param  mirrorActivityId the primary key of the mirror activity
636             * @param  className the target asset's class name
637             * @param  classPK the primary key of the target asset
638             * @return the number of matching activities
639             */
640            @Override
641            public int getActivitiesCount(
642                    long mirrorActivityId, String className, long classPK) {
643    
644                    long classNameId = classNameLocalService.getClassNameId(className);
645    
646                    return getActivitiesCount(mirrorActivityId, classNameId, classPK);
647            }
648    
649            /**
650             * Returns the number of activities done on assets identified by class name.
651             *
652             * @param  className the target asset's class name
653             * @return the number of matching activities
654             */
655            @Override
656            public int getActivitiesCount(String className) {
657                    long classNameId = classNameLocalService.getClassNameId(className);
658    
659                    return getActivitiesCount(classNameId);
660            }
661    
662            /**
663             * Returns the activity identified by its primary key.
664             *
665             * @param  activityId the primary key of the activity
666             * @return Returns the activity
667             */
668            @Override
669            public SocialActivity getActivity(long activityId) throws PortalException {
670                    return socialActivityPersistence.findByPrimaryKey(activityId);
671            }
672    
673            @Override
674            public List<SocialActivity> getActivitySetActivities(
675                    long activitySetId, int start, int end) {
676    
677                    return socialActivityPersistence.findByActivitySetId(
678                            activitySetId, start, end);
679            }
680    
681            /**
682             * Returns a range of all the activities done in the group.
683             *
684             * <p>
685             * This method only finds activities without mirrors.
686             * </p>
687             *
688             * <p>
689             * Useful when paginating results. Returns a maximum of <code>end -
690             * start</code> instances. <code>start</code> and <code>end</code> are not
691             * primary keys, they are indexes in the result set. Thus, <code>0</code>
692             * refers to the first result in the set. Setting both <code>start</code>
693             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
694             * result set.
695             * </p>
696             *
697             * @param  groupId the primary key of the group
698             * @param  start the lower bound of the range of results
699             * @param  end the upper bound of the range of results (not inclusive)
700             * @return the range of matching activities
701             */
702            @Override
703            public List<SocialActivity> getGroupActivities(
704                    long groupId, int start, int end) {
705    
706                    return socialActivityFinder.findByGroupId(groupId, start, end);
707            }
708    
709            /**
710             * Returns the number of activities done in the group.
711             *
712             * <p>
713             * This method only counts activities without mirrors.
714             * </p>
715             *
716             * @param  groupId the primary key of the group
717             * @return the number of matching activities
718             */
719            @Override
720            public int getGroupActivitiesCount(long groupId) {
721                    return socialActivityFinder.countByGroupId(groupId);
722            }
723    
724            /**
725             * Returns a range of activities done by users that are members of the
726             * group.
727             *
728             * <p>
729             * This method only finds activities without mirrors.
730             * </p>
731             *
732             * <p>
733             * Useful when paginating results. Returns a maximum of <code>end -
734             * start</code> instances. <code>start</code> and <code>end</code> are not
735             * primary keys, they are indexes in the result set. Thus, <code>0</code>
736             * refers to the first result in the set. Setting both <code>start</code>
737             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
738             * result set.
739             * </p>
740             *
741             * @param  groupId the primary key of the group
742             * @param  start the lower bound of the range of results
743             * @param  end the upper bound of the range of results (not inclusive)
744             * @return the range of matching activities
745             */
746            @Override
747            public List<SocialActivity> getGroupUsersActivities(
748                    long groupId, int start, int end) {
749    
750                    return socialActivityFinder.findByGroupUsers(groupId, start, end);
751            }
752    
753            /**
754             * Returns the number of activities done by users that are members of the
755             * group.
756             *
757             * <p>
758             * This method only counts activities without mirrors.
759             * </p>
760             *
761             * @param  groupId the primary key of the group
762             * @return the number of matching activities
763             */
764            @Override
765            public int getGroupUsersActivitiesCount(long groupId) {
766                    return socialActivityFinder.countByGroupUsers(groupId);
767            }
768    
769            /**
770             * Returns the activity that has the mirror activity.
771             *
772             * @param  mirrorActivityId the primary key of the mirror activity
773             * @return Returns the mirror activity
774             */
775            @Override
776            public SocialActivity getMirrorActivity(long mirrorActivityId)
777                    throws PortalException {
778    
779                    return socialActivityPersistence.findByMirrorActivityId(
780                            mirrorActivityId);
781            }
782    
783            /**
784             * Returns a range of all the activities done in the organization. This
785             * method only finds activities without mirrors.
786             *
787             * <p>
788             * Useful when paginating results. Returns a maximum of <code>end -
789             * start</code> instances. <code>start</code> and <code>end</code> are not
790             * primary keys, they are indexes in the result set. Thus, <code>0</code>
791             * refers to the first result in the set. Setting both <code>start</code>
792             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
793             * result set.
794             * </p>
795             *
796             * @param  organizationId the primary key of the organization
797             * @param  start the lower bound of the range of results
798             * @param  end the upper bound of the range of results (not inclusive)
799             * @return the range of matching activities
800             */
801            @Override
802            public List<SocialActivity> getOrganizationActivities(
803                    long organizationId, int start, int end) {
804    
805                    return socialActivityFinder.findByOrganizationId(
806                            organizationId, start, end);
807            }
808    
809            /**
810             * Returns the number of activities done in the organization. This method
811             * only counts activities without mirrors.
812             *
813             * @param  organizationId the primary key of the organization
814             * @return the number of matching activities
815             */
816            @Override
817            public int getOrganizationActivitiesCount(long organizationId) {
818                    return socialActivityFinder.countByOrganizationId(organizationId);
819            }
820    
821            /**
822             * Returns a range of all the activities done by users of the organization.
823             * This method only finds activities without mirrors.
824             *
825             * <p>
826             * Useful when paginating results. Returns a maximum of <code>end -
827             * start</code> instances. <code>start</code> and <code>end</code> are not
828             * primary keys, they are indexes in the result set. Thus, <code>0</code>
829             * refers to the first result in the set. Setting both <code>start</code>
830             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
831             * result set.
832             * </p>
833             *
834             * @param  organizationId the primary key of the organization
835             * @param  start the lower bound of the range of results
836             * @param  end the upper bound of the range of results (not inclusive)
837             * @return the range of matching activities
838             */
839            @Override
840            public List<SocialActivity> getOrganizationUsersActivities(
841                    long organizationId, int start, int end) {
842    
843                    return socialActivityFinder.findByOrganizationUsers(
844                            organizationId, start, end);
845            }
846    
847            /**
848             * Returns the number of activities done by users of the organization. This
849             * method only counts activities without mirrors.
850             *
851             * @param  organizationId the primary key of the organization
852             * @return the number of matching activities
853             */
854            @Override
855            public int getOrganizationUsersActivitiesCount(long organizationId) {
856                    return socialActivityFinder.countByOrganizationUsers(organizationId);
857            }
858    
859            /**
860             * Returns a range of all the activities done by users in a relationship
861             * with the user identified by the user ID.
862             *
863             * <p>
864             * Useful when paginating results. Returns a maximum of <code>end -
865             * start</code> instances. <code>start</code> and <code>end</code> are not
866             * primary keys, they are indexes in the result set. Thus, <>0</code> refers
867             * to the first result in the set. Setting both <code>start</code> and
868             * <code>end</code> to {@link QueryUtil#ALL_POS} will return the full result
869             * set.
870             * </p>
871             *
872             * @param  userId the primary key of the user
873             * @param  start the lower bound of the range of results
874             * @param  end the upper bound of the range of results (not inclusive)
875             * @return the range of matching activities
876             */
877            @Override
878            public List<SocialActivity> getRelationActivities(
879                    long userId, int start, int end) {
880    
881                    return socialActivityFinder.findByRelation(userId, start, end);
882            }
883    
884            /**
885             * Returns a range of all the activities done by users in a relationship of
886             * type <code>type</code> with the user identified by <code>userId</code>.
887             * This method only finds activities without mirrors.
888             *
889             * <p>
890             * Useful when paginating results. Returns a maximum of <code>end -
891             * start</code> instances. <code>start</code> and <code>end</code> are not
892             * primary keys, they are indexes in the result set. Thus, <code>0</code>
893             * refers to the first result in the set. Setting both <code>start</code>
894             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
895             * result set.
896             * </p>
897             *
898             * @param  userId the primary key of the user
899             * @param  type the relationship type
900             * @param  start the lower bound of the range of results
901             * @param  end the upper bound of the range of results (not inclusive)
902             * @return the range of matching activities
903             */
904            @Override
905            public List<SocialActivity> getRelationActivities(
906                    long userId, int type, int start, int end) {
907    
908                    return socialActivityFinder.findByRelationType(
909                            userId, type, start, end);
910            }
911    
912            /**
913             * Returns the number of activities done by users in a relationship with the
914             * user identified by userId.
915             *
916             * @param  userId the primary key of the user
917             * @return the number of matching activities
918             */
919            @Override
920            public int getRelationActivitiesCount(long userId) {
921                    return socialActivityFinder.countByRelation(userId);
922            }
923    
924            /**
925             * Returns the number of activities done by users in a relationship of type
926             * <code>type</code> with the user identified by <code>userId</code>. This
927             * method only counts activities without mirrors.
928             *
929             * @param  userId the primary key of the user
930             * @param  type the relationship type
931             * @return the number of matching activities
932             */
933            @Override
934            public int getRelationActivitiesCount(long userId, int type) {
935                    return socialActivityFinder.countByRelationType(userId, type);
936            }
937    
938            /**
939             * Returns a range of all the activities done by the user.
940             *
941             * <p>
942             * Useful when paginating results. Returns a maximum of <code>end -
943             * start</code> instances. <code>start</code> and <code>end</code> are not
944             * primary keys, they are indexes in the result set. Thus, <code>0</code>
945             * refers to the first result in the set. Setting both <code>start</code>
946             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
947             * result set.
948             * </p>
949             *
950             * @param  userId the primary key of the user
951             * @param  start the lower bound of the range of results
952             * @param  end the upper bound of the range of results (not inclusive)
953             * @return the range of matching activities
954             */
955            @Override
956            public List<SocialActivity> getUserActivities(
957                    long userId, int start, int end) {
958    
959                    return socialActivityPersistence.findByUserId(userId, start, end);
960            }
961    
962            /**
963             * Returns the number of activities done by the user.
964             *
965             * @param  userId the primary key of the user
966             * @return the number of matching activities
967             */
968            @Override
969            public int getUserActivitiesCount(long userId) {
970                    return socialActivityPersistence.countByUserId(userId);
971            }
972    
973            /**
974             * Returns a range of all the activities done in the user's groups. This
975             * method only finds activities without mirrors.
976             *
977             * <p>
978             * Useful when paginating results. Returns a maximum of <code>end -
979             * start</code> instances. <code>start</code> and <code>end</code> are not
980             * primary keys, they are indexes in the result set. Thus, <code>0</code>
981             * refers to the first result in the set. Setting both <code>start</code>
982             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
983             * result set.
984             * </p>
985             *
986             * @param  userId the primary key of the user
987             * @param  start the lower bound of the range of results
988             * @param  end the upper bound of the range of results (not inclusive)
989             * @return the range of matching activities
990             */
991            @Override
992            public List<SocialActivity> getUserGroupsActivities(
993                    long userId, int start, int end) {
994    
995                    return socialActivityFinder.findByUserGroups(userId, start, end);
996            }
997    
998            /**
999             * Returns the number of activities done in user's groups. This method only
1000             * counts activities without mirrors.
1001             *
1002             * @param  userId the primary key of the user
1003             * @return the number of matching activities
1004             */
1005            @Override
1006            public int getUserGroupsActivitiesCount(long userId) {
1007                    return socialActivityFinder.countByUserGroups(userId);
1008            }
1009    
1010            /**
1011             * Returns a range of all the activities done in the user's groups and
1012             * organizations. This method only finds activities without mirrors.
1013             *
1014             * <p>
1015             * Useful when paginating results. Returns a maximum of <code>end -
1016             * start</code> instances. <code>start</code> and <code>end</code> are not
1017             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1018             * refers to the first result in the set. Setting both <code>start</code>
1019             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1020             * result set.
1021             * </p>
1022             *
1023             * @param  userId the primary key of the user
1024             * @param  start the lower bound of the range of results
1025             * @param  end the upper bound of the range of results (not inclusive)
1026             * @return the range of matching activities
1027             */
1028            @Override
1029            public List<SocialActivity> getUserGroupsAndOrganizationsActivities(
1030                    long userId, int start, int end) {
1031    
1032                    return socialActivityFinder.findByUserGroupsAndOrganizations(
1033                            userId, start, end);
1034            }
1035    
1036            /**
1037             * Returns the number of activities done in user's groups and organizations.
1038             * This method only counts activities without mirrors.
1039             *
1040             * @param  userId the primary key of the user
1041             * @return the number of matching activities
1042             */
1043            @Override
1044            public int getUserGroupsAndOrganizationsActivitiesCount(long userId) {
1045                    return socialActivityFinder.countByUserGroupsAndOrganizations(userId);
1046            }
1047    
1048            /**
1049             * Returns a range of all activities done in the user's organizations. This
1050             * method only finds activities without mirrors.
1051             *
1052             * <p>
1053             * Useful when paginating results. Returns a maximum of <code>end -
1054             * start</code> instances. <code>start</code> and <code>end</code> are not
1055             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1056             * refers to the first result in the set. Setting both <code>start</code>
1057             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1058             * result set.
1059             * </p>
1060             *
1061             * @param  userId the primary key of the user
1062             * @param  start the lower bound of the range of results
1063             * @param  end the upper bound of the range of results (not inclusive)
1064             * @return the range of matching activities
1065             */
1066            @Override
1067            public List<SocialActivity> getUserOrganizationsActivities(
1068                    long userId, int start, int end) {
1069    
1070                    return socialActivityFinder.findByUserOrganizations(userId, start, end);
1071            }
1072    
1073            /**
1074             * Returns the number of activities done in the user's organizations. This
1075             * method only counts activities without mirrors.
1076             *
1077             * @param  userId the primary key of the user
1078             * @return the number of matching activities
1079             */
1080            @Override
1081            public int getUserOrganizationsActivitiesCount(long userId) {
1082                    return socialActivityFinder.countByUserOrganizations(userId);
1083            }
1084    
1085            protected void deleteActivities(long classNameId, long classPK)
1086                    throws PortalException {
1087    
1088                    if (PropsValues.SOCIAL_ACTIVITY_SETS_ENABLED) {
1089                            socialActivitySetLocalService.decrementActivityCount(
1090                                    classNameId, classPK);
1091                    }
1092    
1093                    socialActivityPersistence.removeByC_C(classNameId, classPK);
1094    
1095                    socialActivityCounterLocalService.deleteActivityCounters(
1096                            classNameId, classPK);
1097            }
1098    
1099            protected boolean isLogActivity(SocialActivity activity) {
1100                    if (activity.getType() == SocialActivityConstants.TYPE_DELETE) {
1101                            if (activity.getParentClassPK() == 0) {
1102                                    return true;
1103                            }
1104    
1105                            return false;
1106                    }
1107    
1108                    SocialActivityDefinition activityDefinition =
1109                            socialActivitySettingLocalService.getActivityDefinition(
1110                                    activity.getGroupId(), activity.getClassName(),
1111                                    activity.getType());
1112    
1113                    if (activityDefinition != null) {
1114                            return activityDefinition.isLogActivity();
1115                    }
1116    
1117                    if (activity.getType() < SocialActivityConstants.TYPE_VIEW) {
1118                            return true;
1119                    }
1120    
1121                    return false;
1122            }
1123    
1124    }