001/* 002 * (C) Copyright 2006-2016 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 */ 019package org.nuxeo.ecm.rating; 020 021import static org.nuxeo.ecm.rating.api.Constants.RATING_VERB_PREFIX; 022 023import java.io.Serializable; 024import java.util.ArrayList; 025import java.util.Collection; 026import java.util.Collections; 027import java.util.List; 028import java.util.Map; 029 030import javax.persistence.EntityManager; 031import javax.persistence.Query; 032 033import org.nuxeo.ecm.activity.ActivitiesList; 034import org.nuxeo.ecm.activity.ActivitiesListImpl; 035import org.nuxeo.ecm.activity.Activity; 036import org.nuxeo.ecm.activity.ActivityHelper; 037import org.nuxeo.ecm.activity.ActivityReply; 038import org.nuxeo.ecm.activity.ActivityStreamFilter; 039import org.nuxeo.ecm.activity.ActivityStreamService; 040import org.nuxeo.ecm.activity.ActivityStreamServiceImpl; 041import org.nuxeo.ecm.core.api.NuxeoException; 042 043/** 044 * Activity Stream filter handling rating activities. 045 * <p> 046 * The different queries this filter can handle are defined in the {@link QueryType} enum. 047 * 048 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a> 049 * @since 5.6 050 */ 051public class RatingActivityStreamFilter implements ActivityStreamFilter { 052 053 public static final String ID = "RatingActivityStreamFilter"; 054 055 public enum QueryType { 056 GET_ACTOR_RATINGS_FOR_OBJECT, GET_RATINGS_FOR_OBJECT, GET_RATED_CHILDREN_FOR_CONTEXT, GET_RATINGS_FOR_CANCEL, GET_LATEST_RATED_FOR_OBJECT 057 } 058 059 public static final String QUERY_TYPE_PARAMETER = "queryTypeParameter"; 060 061 public static final String TARGET_OBJECT_PARAMETER = "targetObject"; 062 063 public static final String ASPECT_PARAMETER = "aspect"; 064 065 public static final String ACTOR_PARAMETER = "actor"; 066 067 public static final String RATING_PARAMETER = "rating"; 068 069 public static final String CONTEXT_PARAMETER = "context"; 070 071 @Override 072 public String getId() { 073 return ID; 074 } 075 076 @Override 077 public boolean isInterestedIn(Activity activity) { 078 String verb = activity.getVerb(); 079 return verb != null && verb.startsWith(RATING_VERB_PREFIX); 080 } 081 082 @Override 083 public void handleNewActivity(ActivityStreamService activityStreamService, Activity activity) { 084 // nothing to do for now 085 } 086 087 @Override 088 public void handleRemovedActivities(ActivityStreamService activityStreamService, ActivitiesList activities) { 089 List<String> activityObjects = new ArrayList<>(); 090 for (Activity activity : activities) { 091 activityObjects.add(ActivityHelper.createActivityObject(activity)); 092 for (ActivityReply reply : activity.getActivityReplies()) { 093 activityObjects.add(ActivityHelper.createActivityObject(reply.getId())); 094 } 095 } 096 removeAllRatingActivitiesFor(activityStreamService, activityObjects); 097 } 098 099 @Override 100 public void handleRemovedActivityReply(ActivityStreamService activityStreamService, Activity activity, 101 ActivityReply activityReply) { 102 removeAllRatingActivitiesFor(activityStreamService, 103 Collections.singleton(ActivityHelper.createActivityObject(activityReply.getId()))); 104 } 105 106 protected void removeAllRatingActivitiesFor(ActivityStreamService activityStreamService, 107 Collection<String> activityObjects) { 108 EntityManager em = ((ActivityStreamServiceImpl) activityStreamService).getEntityManager(); 109 Query query = em.createQuery( 110 "delete from Activity activity where activity.verb LIKE :verb and activity.target in (:target)"); 111 query.setParameter("verb", RATING_VERB_PREFIX + "%"); 112 query.setParameter("target", activityObjects); 113 query.executeUpdate(); 114 } 115 116 @Override 117 @SuppressWarnings("unchecked") 118 public ActivitiesList query(ActivityStreamService activityStreamService, Map<String, Serializable> parameters, 119 long offset, long limit) { 120 EntityManager em = ((ActivityStreamServiceImpl) activityStreamService).getEntityManager(); 121 QueryType queryType = (QueryType) parameters.get(QUERY_TYPE_PARAMETER); 122 if (queryType == null) { 123 return new ActivitiesListImpl(); 124 } 125 126 Query query = null; 127 StringBuilder sb; 128 String targetObject = (String) parameters.get(TARGET_OBJECT_PARAMETER); 129 String aspect = (String) parameters.get(ASPECT_PARAMETER); 130 String actor = (String) parameters.get(ACTOR_PARAMETER); 131 Integer rating = (Integer) parameters.get(RATING_PARAMETER); 132 String context = (String) parameters.get(CONTEXT_PARAMETER); 133 switch (queryType) { 134 case GET_ACTOR_RATINGS_FOR_OBJECT: 135 sb = new StringBuilder( 136 "select activity from Activity activity where activity.verb = :verb and activity.actor = :actor and activity.target = :targetObject and activity.context is null"); 137 if (rating != null) { 138 sb.append(" and activity.object = :rating"); 139 } 140 query = em.createQuery(sb.toString()); 141 query.setParameter("verb", RATING_VERB_PREFIX + aspect); 142 query.setParameter(TARGET_OBJECT_PARAMETER, targetObject); 143 query.setParameter(ACTOR_PARAMETER, actor); 144 if (rating != null) { 145 query.setParameter(RATING_PARAMETER, String.valueOf(rating)); 146 } 147 break; 148 case GET_RATINGS_FOR_OBJECT: 149 sb = new StringBuilder( 150 "select activity from Activity activity where activity.verb = :verb and activity.target = :targetObject and activity.context is null"); 151 if (rating != null) { 152 sb.append(" and activity.object = :rating"); 153 } 154 query = em.createQuery(sb.toString()); 155 query.setParameter("verb", RATING_VERB_PREFIX + aspect); 156 query.setParameter(TARGET_OBJECT_PARAMETER, targetObject); 157 if (rating != null) { 158 query.setParameter(RATING_PARAMETER, String.valueOf(rating)); 159 } 160 break; 161 case GET_RATED_CHILDREN_FOR_CONTEXT: 162 sb = new StringBuilder( 163 "select activity from Activity activity where activity.verb = :verb and activity.context = :context"); 164 if (rating != null) { 165 sb.append(" and activity.object = :rating"); 166 } 167 query = em.createQuery(sb.toString()); 168 query.setParameter("verb", RATING_VERB_PREFIX + aspect); 169 query.setParameter(CONTEXT_PARAMETER, context); 170 if (rating != null) { 171 query.setParameter(RATING_PARAMETER, String.valueOf(rating)); 172 } 173 break; 174 case GET_RATINGS_FOR_CANCEL: 175 sb = new StringBuilder("select activity from Activity activity where activity.target = :targetObject"); 176 if (rating != null) { 177 sb.append(" and activity.object = :rating"); 178 } 179 if (actor != null) { 180 sb.append(" and activity.actor = :actor"); 181 } 182 if (aspect != null) { 183 sb.append(" and activity.verb = :verb"); 184 } else { 185 sb.append(" and activity.verb LIKE :verb"); 186 aspect = "%"; 187 } 188 query = em.createQuery(sb.toString()); 189 query.setParameter("verb", RATING_VERB_PREFIX + aspect); 190 query.setParameter(TARGET_OBJECT_PARAMETER, targetObject); 191 if (rating != null) { 192 query.setParameter(RATING_PARAMETER, String.valueOf(rating)); 193 } 194 if (actor != null) { 195 query.setParameter(ACTOR_PARAMETER, actor); 196 } 197 break; 198 case GET_LATEST_RATED_FOR_OBJECT: 199 query = em.createQuery( 200 "select activity from Activity activity where activity.target LIKE :targetObject and activity.context is null and activity.actor = :actor and activity.verb = :verb order by activity.publishedDate DESC, activity.id DESC"); 201 query.setParameter("verb", RATING_VERB_PREFIX + aspect); 202 query.setParameter(ACTOR_PARAMETER, actor); 203 query.setParameter(TARGET_OBJECT_PARAMETER, ActivityHelper.DOC_PREFIX + "%"); 204 break; 205 default: 206 throw new NuxeoException("Unknown query type: " + queryType); 207 } 208 209 if (limit > 0) { 210 query.setMaxResults((int) limit); 211 } 212 if (offset > 0) { 213 query.setFirstResult((int) offset); 214 } 215 return new ActivitiesListImpl(query.getResultList()); 216 } 217}