001/* 002 * (C) Copyright 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 * Arnaud Kervern 018 */ 019package org.nuxeo.ecm.rating; 020 021import static org.nuxeo.ecm.rating.RatingActivityStreamFilter.QUERY_TYPE_PARAMETER; 022import static org.nuxeo.ecm.rating.api.Constants.LIKE_ASPECT; 023import static org.nuxeo.ecm.rating.api.Constants.RATING_VERB_PREFIX; 024 025import java.io.Serializable; 026import java.util.Collection; 027import java.util.Map; 028 029import javax.persistence.EntityManager; 030import javax.persistence.Query; 031 032import org.apache.commons.logging.Log; 033import org.apache.commons.logging.LogFactory; 034import org.nuxeo.ecm.activity.ActivitiesList; 035import org.nuxeo.ecm.activity.ActivitiesListImpl; 036import org.nuxeo.ecm.activity.Activity; 037import org.nuxeo.ecm.activity.ActivityBuilder; 038import org.nuxeo.ecm.activity.ActivityReply; 039import org.nuxeo.ecm.activity.ActivityStreamFilter; 040import org.nuxeo.ecm.activity.ActivityStreamService; 041import org.nuxeo.ecm.activity.ActivityStreamServiceImpl; 042 043/** 044 * An activity stream filter to handle likes count 045 * 046 * @author <a href="mailto:akervern@nuxeo.com">Arnaud Kervern</a> 047 * @since 5.6 048 */ 049public class LikesCountActivityStreamFilter implements ActivityStreamFilter { 050 051 public enum QueryType { 052 GET_DOCUMENTS_COUNT, GET_MINI_MESSAGE_COUNT 053 } 054 055 public static final String ID = "LikesCountActivityStreamFilter"; 056 057 public static final String CONTEXT_PARAMETER = "context"; 058 059 public static final String ASPECT_PARAMETER = "aspect"; 060 061 public static final String OBJECT_PARAMETER = "object"; 062 063 public static final String ACTOR_PARAMETER = "actor"; 064 065 public static final String FROMDT_PARAMETER = "fromDt"; 066 067 public static final String TODT_PARAMETER = "toDt"; 068 069 protected static final String VERB_PARAMETER = "verb"; 070 071 protected static final String VERB_MINIMESSAGE_PARAMETER = "verbMiniMessage"; 072 073 private static final Log log = LogFactory.getLog(LikesCountActivityStreamFilter.class); 074 075 @Override 076 public String getId() { 077 return ID; 078 } 079 080 @Override 081 public boolean isInterestedIn(Activity activity) { 082 return false; 083 } 084 085 @Override 086 public void handleNewActivity(ActivityStreamService activityStreamService, Activity activity) { 087 // Nothing to do for now 088 } 089 090 @Override 091 @Deprecated 092 public void handleRemovedActivities(ActivityStreamService activityStreamService, 093 Collection<Serializable> activityIds) { 094 // Nothing to do for now 095 } 096 097 @Override 098 public void handleRemovedActivities(ActivityStreamService activityStreamService, ActivitiesList activities) { 099 } 100 101 @Override 102 public void handleRemovedActivityReply(ActivityStreamService activityStreamService, Activity activity, 103 ActivityReply activityReply) { 104 } 105 106 @Override 107 public ActivitiesList query(ActivityStreamService activityStreamService, Map<String, Serializable> parameters, 108 long offset, long limit) { 109 QueryType queryType = (QueryType) parameters.get(QUERY_TYPE_PARAMETER); 110 if (queryType == null) { 111 return new ActivitiesListImpl(); 112 } 113 114 Query query = null; 115 String queryStr = ""; 116 String innerStr = ""; 117 EntityManager em = ((ActivityStreamServiceImpl) activityStreamService).getEntityManager(); 118 Serializable actor = parameters.get(ACTOR_PARAMETER); 119 120 switch (queryType) { 121 case GET_DOCUMENTS_COUNT: 122 // InnerQuery indicates if the actor has alredy liked or not 123 innerStr = "SELECT COUNT(activity2) FROM Activity activity2 WHERE activity2.verb = :verb"; 124 innerStr += " AND activity2.context = :context AND activity2.object = :object"; 125 innerStr += " AND activity2.actor = :actor AND activity2.target = activity.target"; 126 if (parameters.containsKey(FROMDT_PARAMETER)) { 127 innerStr += " AND activity2.publishedDate BETWEEN :fromDt AND :toDt"; 128 } 129 queryStr = "SELECT activity.target, count(activity), (" + innerStr + ") FROM Activity activity"; 130 queryStr += " WHERE activity.verb = :verb and activity.context = :context"; 131 queryStr += " AND activity.object = :object"; 132 if (parameters.containsKey(FROMDT_PARAMETER)) { 133 queryStr += " AND activity.publishedDate BETWEEN :fromDt AND :toDt"; 134 } 135 queryStr += " GROUP BY activity.target ORDER BY COUNT(activity) DESC"; 136 137 Serializable object = String.valueOf(parameters.get(OBJECT_PARAMETER)); 138 query = em.createQuery(queryStr); 139 query.setParameter(OBJECT_PARAMETER, object); 140 141 break; 142 case GET_MINI_MESSAGE_COUNT: 143 // InnerQuery indicates if the actor has alredy liked or not 144 innerStr = "Select count(likes2) from Activity as likes2 "; 145 innerStr += " where likes.target = likes2.target and likes2.actor = :actor"; 146 if (parameters.containsKey(FROMDT_PARAMETER)) { 147 innerStr += " AND likes2.publishedDate BETWEEN :fromDt AND :toDt"; 148 } 149 queryStr = "Select likes.target, count(likes), (" + innerStr 150 + ") from Activity as likes, Activity as minimessage"; 151 queryStr += " where concat('activity:', cast(minimessage.id as string)) = likes.target"; 152 queryStr += " and minimessage.verb = :verbMiniMessage and minimessage.context = :context"; 153 queryStr += " and likes.verb = :verb"; 154 if (parameters.containsKey(FROMDT_PARAMETER)) { 155 queryStr += " AND likes.publishedDate BETWEEN :fromDt AND :toDt"; 156 } 157 queryStr += " group by likes.target order by count(likes) desc"; 158 159 query = em.createQuery(queryStr); 160 query.setParameter(VERB_MINIMESSAGE_PARAMETER, "minimessage"); 161 162 break; 163 default: 164 log.info("Unknown query type: " + queryType); 165 return new ActivitiesListImpl(); 166 } 167 168 // Default parameters 169 query.setParameter(CONTEXT_PARAMETER, parameters.get(CONTEXT_PARAMETER)); 170 query.setParameter(VERB_PARAMETER, RATING_VERB_PREFIX + LIKE_ASPECT); 171 query.setParameter(ACTOR_PARAMETER, actor); 172 if (parameters.containsKey(FROMDT_PARAMETER)) { 173 query.setParameter(FROMDT_PARAMETER, parameters.get(FROMDT_PARAMETER)); 174 query.setParameter(TODT_PARAMETER, parameters.get(TODT_PARAMETER)); 175 } 176 177 if (limit > 0) { 178 query.setMaxResults((int) limit); 179 } 180 if (offset > 0) { 181 query.setFirstResult((int) offset); 182 } 183 184 ActivitiesList likesCount = new ActivitiesListImpl(); 185 for (Object result : query.getResultList()) { 186 Object[] objects = (Object[]) result; 187 ActivityBuilder ab = new ActivityBuilder().verb(RATING_VERB_PREFIX + LIKE_ASPECT).actor((String) actor).object( 188 String.valueOf(objects[1])).target((String) objects[0]).context(String.valueOf(objects[2])); 189 likesCount.add(ab.build()); 190 } 191 192 return likesCount; 193 } 194}