001/*
002 * (C) Copyright 2006-2012 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Thomas Roger <troger@nuxeo.com>
018 */
019
020package org.nuxeo.ecm.rating;
021
022import static org.nuxeo.ecm.activity.ActivityHelper.createDocumentActivityObject;
023import static org.nuxeo.ecm.activity.ActivityHelper.createUserActivityObject;
024import static org.nuxeo.ecm.rating.LikesCountActivityStreamFilter.ACTOR_PARAMETER;
025import static org.nuxeo.ecm.rating.LikesCountActivityStreamFilter.CONTEXT_PARAMETER;
026import static org.nuxeo.ecm.rating.LikesCountActivityStreamFilter.FROMDT_PARAMETER;
027import static org.nuxeo.ecm.rating.LikesCountActivityStreamFilter.OBJECT_PARAMETER;
028import static org.nuxeo.ecm.rating.LikesCountActivityStreamFilter.TODT_PARAMETER;
029import static org.nuxeo.ecm.rating.LikesCountActivityStreamFilter.QueryType.GET_DOCUMENTS_COUNT;
030import static org.nuxeo.ecm.rating.LikesCountActivityStreamFilter.QueryType.GET_MINI_MESSAGE_COUNT;
031import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.QUERY_TYPE_PARAMETER;
032import static org.nuxeo.ecm.rating.api.Constants.LIKE_ASPECT;
033import static org.nuxeo.ecm.rating.api.LikeStatus.DISLIKED;
034import static org.nuxeo.ecm.rating.api.LikeStatus.LIKED;
035import static org.nuxeo.ecm.rating.api.LikeStatus.UNKNOWN;
036
037import java.io.Serializable;
038import java.util.Collections;
039import java.util.Comparator;
040import java.util.Date;
041import java.util.HashMap;
042import java.util.Map;
043
044import org.nuxeo.ecm.activity.ActivitiesList;
045import org.nuxeo.ecm.activity.ActivitiesListImpl;
046import org.nuxeo.ecm.activity.Activity;
047import org.nuxeo.ecm.activity.ActivityStreamService;
048import org.nuxeo.ecm.core.api.CoreSession;
049import org.nuxeo.ecm.core.api.DocumentModel;
050import org.nuxeo.ecm.rating.api.LikeService;
051import org.nuxeo.ecm.rating.api.LikeStatus;
052import org.nuxeo.ecm.rating.api.RatingService;
053import org.nuxeo.runtime.api.Framework;
054import org.nuxeo.runtime.model.DefaultComponent;
055
056/**
057 * Default implementation of {@see LikeService}.
058 *
059 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a>
060 * @since 5.6
061 */
062public class LikeServiceImpl extends DefaultComponent implements LikeService {
063
064    public static final int LIKE_RATING = 1;
065
066    public static final int DISLIKE_RATING = -1;
067
068    @Override
069    public void like(String username, String activityObject) {
070        RatingService ratingService = Framework.getLocalService(RatingService.class);
071        ratingService.cancelRate(username, activityObject, LIKE_ASPECT);
072        ratingService.rate(username, LIKE_RATING, activityObject, LIKE_ASPECT);
073    }
074
075    @Override
076    public void like(String username, DocumentModel doc) {
077        like(username, createDocumentActivityObject(doc));
078    }
079
080    @Override
081    public boolean hasUserLiked(String username, String activityObject) {
082        RatingService ratingService = Framework.getLocalService(RatingService.class);
083        double average = ratingService.getAverageRatingForUser(username, activityObject, LIKE_ASPECT);
084        return average > 0;
085    }
086
087    @Override
088    public boolean hasUserLiked(String username, DocumentModel doc) {
089        return hasUserLiked(username, createDocumentActivityObject(doc));
090    }
091
092    @Override
093    public long getLikesCount(String activityObject) {
094        RatingService ratingService = Framework.getLocalService(RatingService.class);
095        return ratingService.getRatesCount(activityObject, LIKE_RATING, LIKE_ASPECT);
096    }
097
098    @Override
099    public long getLikesCount(DocumentModel doc) {
100        return getLikesCount(createDocumentActivityObject(doc));
101    }
102
103    @Override
104    public void dislike(String username, String activityObject) {
105        RatingService ratingService = Framework.getLocalService(RatingService.class);
106        ratingService.cancelRate(username, activityObject, LIKE_ASPECT);
107        ratingService.rate(username, DISLIKE_RATING, activityObject, LIKE_ASPECT);
108    }
109
110    @Override
111    public void dislike(String username, DocumentModel doc) {
112        dislike(username, createDocumentActivityObject(doc));
113    }
114
115    @Override
116    public boolean hasUserDisliked(String username, String activityObject) {
117        RatingService ratingService = Framework.getLocalService(RatingService.class);
118        double average = ratingService.getAverageRatingForUser(username, activityObject, LIKE_ASPECT);
119        return average < 0;
120    }
121
122    @Override
123    public boolean hasUserDisliked(String username, DocumentModel doc) {
124        return hasUserDisliked(username, createDocumentActivityObject(doc));
125    }
126
127    @Override
128    public long getDislikesCount(String activityObject) {
129        RatingService ratingService = Framework.getLocalService(RatingService.class);
130        return ratingService.getRatesCount(activityObject, DISLIKE_RATING, LIKE_ASPECT);
131    }
132
133    @Override
134    public long getDislikesCount(DocumentModel doc) {
135        return getDislikesCount(createDocumentActivityObject(doc));
136    }
137
138    @Override
139    public void cancel(String username, String activityObject) {
140        RatingService ratingService = Framework.getLocalService(RatingService.class);
141        ratingService.cancelRate(username, activityObject, LIKE_ASPECT);
142    }
143
144    @Override
145    public void cancel(String username, DocumentModel doc) {
146        cancel(username, createDocumentActivityObject(doc));
147    }
148
149    @Override
150    public LikeStatus getLikeStatus(String activityObject) {
151        long likesCount = getLikesCount(activityObject);
152        long dislikesCount = getDislikesCount(activityObject);
153        return new LikeStatus(activityObject, likesCount, dislikesCount);
154    }
155
156    @Override
157    public LikeStatus getLikeStatus(DocumentModel doc) {
158        return getLikeStatus(createDocumentActivityObject(doc));
159    }
160
161    @Override
162    public LikeStatus getLikeStatus(String username, String activityObject) {
163        long likesCount = getLikesCount(activityObject);
164        long dislikesCount = getDislikesCount(activityObject);
165        int userLikeStatus = hasUserLiked(username, activityObject) ? LIKED
166                : hasUserDisliked(username, activityObject) ? DISLIKED : UNKNOWN;
167        return new LikeStatus(activityObject, likesCount, dislikesCount, username, userLikeStatus);
168    }
169
170    @Override
171    public LikeStatus getLikeStatus(String username, DocumentModel doc) {
172        return getLikeStatus(username, createDocumentActivityObject(doc));
173    }
174
175    @Override
176    public ActivitiesList getMostLikedActivities(CoreSession session, int limit, DocumentModel source, Date fromDt,
177            Date toDt) {
178        // Get most liked Documents
179        Map<String, Serializable> parameters = new HashMap<String, Serializable>();
180        if (fromDt != null && toDt != null) {
181            parameters.put(FROMDT_PARAMETER, fromDt);
182            parameters.put(TODT_PARAMETER, toDt);
183        }
184        parameters.put(CONTEXT_PARAMETER, createDocumentActivityObject(source));
185        parameters.put(OBJECT_PARAMETER, Integer.valueOf(LIKE_RATING));
186        parameters.put(ACTOR_PARAMETER, createUserActivityObject(session.getPrincipal().getName()));
187        parameters.put(QUERY_TYPE_PARAMETER, GET_DOCUMENTS_COUNT);
188
189        ActivityStreamService activityStreamService = Framework.getLocalService(ActivityStreamService.class);
190        ActivitiesList documentActivitiesList = activityStreamService.query(LikesCountActivityStreamFilter.ID,
191                parameters);
192        ActivitiesList mostLikedActivities = documentActivitiesList.filterActivities(session);
193
194        // Get most liked minimessages
195        parameters.put(QUERY_TYPE_PARAMETER, GET_MINI_MESSAGE_COUNT);
196        ActivitiesList miniMessageActivitiesList = activityStreamService.query(LikesCountActivityStreamFilter.ID,
197                parameters, 0, limit);
198        mostLikedActivities.addAll(miniMessageActivitiesList);
199
200        // Sort by Object
201        Collections.sort(mostLikedActivities, new Comparator<Activity>() {
202            @Override
203            public int compare(Activity o1, Activity o2) {
204                return o2.getObject().compareTo(o1.getObject());
205            }
206        });
207
208        if (mostLikedActivities.size() > limit) {
209            return new ActivitiesListImpl(mostLikedActivities.subList(0, limit));
210        }
211        return mostLikedActivities;
212    }
213
214    @Override
215    public ActivitiesList getMostLikedActivities(CoreSession session, int limit, DocumentModel source) {
216        return getMostLikedActivities(session, limit, source, null, null);
217    }
218}