001/* 002 * (C) Copyright 2006-2018 Nuxeo (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 <[email protected]> 018 */ 019 020package org.nuxeo.ecm.rating; 021 022import static org.nuxeo.ecm.core.schema.FacetNames.SUPER_SPACE; 023import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.ACTOR_PARAMETER; 024import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.ASPECT_PARAMETER; 025import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.CONTEXT_PARAMETER; 026import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.QUERY_TYPE_PARAMETER; 027import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.QueryType.GET_ACTOR_RATINGS_FOR_OBJECT; 028import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.QueryType.GET_LATEST_RATED_FOR_OBJECT; 029import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.QueryType.GET_RATED_CHILDREN_FOR_CONTEXT; 030import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.QueryType.GET_RATINGS_FOR_CANCEL; 031import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.QueryType.GET_RATINGS_FOR_OBJECT; 032import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.RATING_PARAMETER; 033import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.TARGET_OBJECT_PARAMETER; 034import static org.nuxeo.ecm.rating.api.Constants.RATING_VERB_PREFIX; 035 036import java.io.Serializable; 037import java.util.HashMap; 038import java.util.Map; 039 040import org.apache.commons.logging.Log; 041import org.apache.commons.logging.LogFactory; 042import org.nuxeo.ecm.activity.ActivitiesList; 043import org.nuxeo.ecm.activity.Activity; 044import org.nuxeo.ecm.activity.ActivityBuilder; 045import org.nuxeo.ecm.activity.ActivityHelper; 046import org.nuxeo.ecm.activity.ActivityStreamService; 047import org.nuxeo.ecm.core.api.DocumentModel; 048import org.nuxeo.ecm.core.api.IdRef; 049import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner; 050import org.nuxeo.ecm.rating.api.RatingService; 051import org.nuxeo.runtime.api.Framework; 052import org.nuxeo.runtime.model.DefaultComponent; 053 054/** 055 * Default implementation of {@see RatingService}. 056 * 057 * @author <a href="mailto:[email protected]">Thomas Roger</a> 058 * @since 5.6 059 */ 060public class RatingServiceImpl extends DefaultComponent implements RatingService { 061 062 private static final Log log = LogFactory.getLog(RatingServiceImpl.class); 063 064 @Override 065 public void rate(String username, int rating, String activityObject, String aspect) { 066 Activity activity = new ActivityBuilder().verb(RATING_VERB_PREFIX + aspect) 067 .actor(ActivityHelper.createUserActivityObject(username)) 068 .target(activityObject) 069 .object(String.valueOf(rating)) 070 .build(); 071 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 072 activityStreamService.addActivity(activity); 073 074 addSuperSpaceRate(activity); 075 } 076 077 @Override 078 public void cancelRate(String username, String activityObject, String aspect) { 079 Map<String, Serializable> parameters = new HashMap<>(); 080 parameters.put(QUERY_TYPE_PARAMETER, GET_RATINGS_FOR_CANCEL); 081 parameters.put(ACTOR_PARAMETER, ActivityHelper.createUserActivityObject(username)); 082 parameters.put(TARGET_OBJECT_PARAMETER, activityObject); 083 parameters.put(ASPECT_PARAMETER, aspect); 084 085 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 086 ActivitiesList activities = activityStreamService.query(RatingActivityStreamFilter.ID, parameters); 087 activityStreamService.removeActivities(activities); 088 } 089 090 @Override 091 public void cancelRates(String activityObject, String aspect) { 092 Map<String, Serializable> parameters = new HashMap<>(); 093 parameters.put(QUERY_TYPE_PARAMETER, GET_RATINGS_FOR_CANCEL); 094 parameters.put(TARGET_OBJECT_PARAMETER, activityObject); 095 parameters.put(ASPECT_PARAMETER, aspect); 096 097 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 098 ActivitiesList activities = activityStreamService.query(RatingActivityStreamFilter.ID, parameters); 099 activityStreamService.removeActivities(activities); 100 } 101 102 @Override 103 public boolean hasUserRated(String username, String activityObject, String aspect) { 104 Map<String, Serializable> parameters = new HashMap<>(); 105 parameters.put(QUERY_TYPE_PARAMETER, GET_ACTOR_RATINGS_FOR_OBJECT); 106 parameters.put(ACTOR_PARAMETER, ActivityHelper.createUserActivityObject(username)); 107 parameters.put(TARGET_OBJECT_PARAMETER, activityObject); 108 parameters.put(ASPECT_PARAMETER, aspect); 109 110 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 111 ActivitiesList activities = activityStreamService.query(RatingActivityStreamFilter.ID, parameters); 112 return !activities.isEmpty(); 113 } 114 115 @Override 116 public long getRatesCount(String activityObject, String aspect) { 117 Map<String, Serializable> parameters = new HashMap<>(); 118 parameters.put(QUERY_TYPE_PARAMETER, GET_RATINGS_FOR_OBJECT); 119 parameters.put(TARGET_OBJECT_PARAMETER, activityObject); 120 parameters.put(ASPECT_PARAMETER, aspect); 121 122 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 123 ActivitiesList activities = activityStreamService.query(RatingActivityStreamFilter.ID, parameters); 124 return activities.size(); 125 } 126 127 @Override 128 public long getRatesCount(String activityObject, int rating, String aspect) { 129 Map<String, Serializable> parameters = new HashMap<>(); 130 parameters.put(QUERY_TYPE_PARAMETER, GET_RATINGS_FOR_OBJECT); 131 parameters.put(TARGET_OBJECT_PARAMETER, activityObject); 132 parameters.put(ASPECT_PARAMETER, aspect); 133 parameters.put(RATING_PARAMETER, Integer.valueOf(rating)); 134 135 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 136 ActivitiesList activities = activityStreamService.query(RatingActivityStreamFilter.ID, parameters); 137 return activities.size(); 138 } 139 140 @Override 141 public long getRatesCountForUser(String username, String activityObject, String aspect) { 142 Map<String, Serializable> parameters = new HashMap<>(); 143 parameters.put(QUERY_TYPE_PARAMETER, GET_ACTOR_RATINGS_FOR_OBJECT); 144 parameters.put(ACTOR_PARAMETER, ActivityHelper.createUserActivityObject(username)); 145 parameters.put(TARGET_OBJECT_PARAMETER, activityObject); 146 parameters.put(ASPECT_PARAMETER, aspect); 147 148 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 149 ActivitiesList activities = activityStreamService.query(RatingActivityStreamFilter.ID, parameters); 150 return activities.size(); 151 } 152 153 @Override 154 public long getRatesCountForUser(String username, String activityObject, int rating, String aspect) { 155 Map<String, Serializable> parameters = new HashMap<>(); 156 parameters.put(QUERY_TYPE_PARAMETER, GET_ACTOR_RATINGS_FOR_OBJECT); 157 parameters.put(ACTOR_PARAMETER, ActivityHelper.createUserActivityObject(username)); 158 parameters.put(TARGET_OBJECT_PARAMETER, activityObject); 159 parameters.put(ASPECT_PARAMETER, aspect); 160 parameters.put(RATING_PARAMETER, Integer.valueOf(rating)); 161 162 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 163 ActivitiesList activities = activityStreamService.query(RatingActivityStreamFilter.ID, parameters); 164 return activities.size(); 165 } 166 167 @Override 168 public double getAverageRating(String activityObject, String aspect) { 169 Map<String, Serializable> parameters = new HashMap<>(); 170 parameters.put(QUERY_TYPE_PARAMETER, GET_RATINGS_FOR_OBJECT); 171 parameters.put(TARGET_OBJECT_PARAMETER, activityObject); 172 parameters.put(ASPECT_PARAMETER, aspect); 173 174 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 175 ActivitiesList activities = activityStreamService.query(RatingActivityStreamFilter.ID, parameters); 176 return computeAverage(activities); 177 } 178 179 @Override 180 public double getAverageRatingForUser(String username, String activityObject, String aspect) { 181 Map<String, Serializable> parameters = new HashMap<>(); 182 parameters.put(QUERY_TYPE_PARAMETER, GET_ACTOR_RATINGS_FOR_OBJECT); 183 parameters.put(ACTOR_PARAMETER, ActivityHelper.createUserActivityObject(username)); 184 parameters.put(TARGET_OBJECT_PARAMETER, activityObject); 185 parameters.put(ASPECT_PARAMETER, aspect); 186 187 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 188 ActivitiesList activities = activityStreamService.query(RatingActivityStreamFilter.ID, parameters); 189 return computeAverage(activities); 190 } 191 192 @Override 193 public ActivitiesList getRatedChildren(String activityObject, int rating, String aspect) { 194 Map<String, Serializable> parameters = new HashMap<>(); 195 parameters.put(QUERY_TYPE_PARAMETER, GET_RATED_CHILDREN_FOR_CONTEXT); 196 parameters.put(CONTEXT_PARAMETER, activityObject); 197 parameters.put(ASPECT_PARAMETER, aspect); 198 parameters.put(RATING_PARAMETER, Integer.valueOf(rating)); 199 200 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 201 return activityStreamService.query(RatingActivityStreamFilter.ID, parameters); 202 } 203 204 @Override 205 public ActivitiesList getLastestRatedDocByUser(String username, String aspect, int limit) { 206 Map<String, Serializable> parameters = new HashMap<>(); 207 parameters.put(QUERY_TYPE_PARAMETER, GET_LATEST_RATED_FOR_OBJECT); 208 parameters.put(ACTOR_PARAMETER, ActivityHelper.createUserActivityObject(username)); 209 parameters.put(ASPECT_PARAMETER, aspect); 210 211 ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 212 return activityStreamService.query(RatingActivityStreamFilter.ID, parameters, 0, limit); 213 } 214 215 private double computeAverage(ActivitiesList activities) { 216 double average = 0; 217 for (Activity activity : activities) { 218 try { 219 average += Integer.valueOf(activity.getObject()).intValue(); 220 } catch (NumberFormatException e) { 221 log.warn(activity.getObject() + " is not a valid rating"); 222 } 223 } 224 return average / activities.size(); 225 } 226 227 protected void addSuperSpaceRate(final Activity fromActivity) { 228 final String activityObject = fromActivity.getTarget(); 229 if (!ActivityHelper.isDocument(activityObject)) { 230 return; 231 } 232 233 final ActivityStreamService activityStreamService = Framework.getService(ActivityStreamService.class); 234 new UnrestrictedSessionRunner(ActivityHelper.getRepositoryName(activityObject)) { 235 @Override 236 public void run() { 237 IdRef docId = new IdRef(ActivityHelper.getDocumentId(activityObject)); 238 for (DocumentModel parent : session.getParentDocuments(docId)) { 239 if (!parent.hasFacet(SUPER_SPACE)) { 240 continue; 241 } 242 Activity activity = new ActivityBuilder(fromActivity).context( 243 ActivityHelper.createDocumentActivityObject(parent)).build(); 244 activityStreamService.addActivity(activity); 245 } 246 } 247 }.runUnrestricted(); 248 } 249}