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