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