001/* 002 * (C) Copyright 2012-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 * 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 public void handleRemovedActivities(ActivityStreamService activityStreamService, ActivitiesList activities) { 092 } 093 094 @Override 095 public void handleRemovedActivityReply(ActivityStreamService activityStreamService, Activity activity, 096 ActivityReply activityReply) { 097 } 098 099 @Override 100 public ActivitiesList query(ActivityStreamService activityStreamService, Map<String, Serializable> parameters, 101 long offset, long limit) { 102 QueryType queryType = (QueryType) parameters.get(QUERY_TYPE_PARAMETER); 103 if (queryType == null) { 104 return new ActivitiesListImpl(); 105 } 106 107 Query query; 108 String queryStr; 109 String innerStr; 110 EntityManager em = ((ActivityStreamServiceImpl) activityStreamService).getEntityManager(); 111 Serializable actor = parameters.get(ACTOR_PARAMETER); 112 113 switch (queryType) { 114 case GET_DOCUMENTS_COUNT: 115 // InnerQuery indicates if the actor has alredy liked or not 116 innerStr = "SELECT COUNT(activity2) FROM Activity activity2 WHERE activity2.verb = :verb"; 117 innerStr += " AND activity2.context = :context AND activity2.object = :object"; 118 innerStr += " AND activity2.actor = :actor AND activity2.target = activity.target"; 119 if (parameters.containsKey(FROMDT_PARAMETER)) { 120 innerStr += " AND activity2.publishedDate BETWEEN :fromDt AND :toDt"; 121 } 122 queryStr = "SELECT activity.target, count(activity), (" + innerStr + ") FROM Activity activity"; 123 queryStr += " WHERE activity.verb = :verb and activity.context = :context"; 124 queryStr += " AND activity.object = :object"; 125 if (parameters.containsKey(FROMDT_PARAMETER)) { 126 queryStr += " AND activity.publishedDate BETWEEN :fromDt AND :toDt"; 127 } 128 queryStr += " GROUP BY activity.target ORDER BY COUNT(activity) DESC"; 129 130 Serializable object = String.valueOf(parameters.get(OBJECT_PARAMETER)); 131 query = em.createQuery(queryStr); 132 query.setParameter(OBJECT_PARAMETER, object); 133 134 break; 135 case GET_MINI_MESSAGE_COUNT: 136 // InnerQuery indicates if the actor has alredy liked or not 137 innerStr = "Select count(likes2) from Activity as likes2 "; 138 innerStr += " where likes.target = likes2.target and likes2.actor = :actor"; 139 if (parameters.containsKey(FROMDT_PARAMETER)) { 140 innerStr += " AND likes2.publishedDate BETWEEN :fromDt AND :toDt"; 141 } 142 queryStr = "Select likes.target, count(likes), (" + innerStr 143 + ") from Activity as likes, Activity as minimessage"; 144 queryStr += " where concat('activity:', cast(minimessage.id as string)) = likes.target"; 145 queryStr += " and minimessage.verb = :verbMiniMessage and minimessage.context = :context"; 146 queryStr += " and likes.verb = :verb"; 147 if (parameters.containsKey(FROMDT_PARAMETER)) { 148 queryStr += " AND likes.publishedDate BETWEEN :fromDt AND :toDt"; 149 } 150 queryStr += " group by likes.target order by count(likes) desc"; 151 152 query = em.createQuery(queryStr); 153 query.setParameter(VERB_MINIMESSAGE_PARAMETER, "minimessage"); 154 155 break; 156 default: 157 log.info("Unknown query type: " + queryType); 158 return new ActivitiesListImpl(); 159 } 160 161 // Default parameters 162 query.setParameter(CONTEXT_PARAMETER, parameters.get(CONTEXT_PARAMETER)); 163 query.setParameter(VERB_PARAMETER, RATING_VERB_PREFIX + LIKE_ASPECT); 164 query.setParameter(ACTOR_PARAMETER, actor); 165 if (parameters.containsKey(FROMDT_PARAMETER)) { 166 query.setParameter(FROMDT_PARAMETER, parameters.get(FROMDT_PARAMETER)); 167 query.setParameter(TODT_PARAMETER, parameters.get(TODT_PARAMETER)); 168 } 169 170 if (limit > 0) { 171 query.setMaxResults((int) limit); 172 } 173 if (offset > 0) { 174 query.setFirstResult((int) offset); 175 } 176 177 ActivitiesList likesCount = new ActivitiesListImpl(); 178 for (Object result : query.getResultList()) { 179 Object[] objects = (Object[]) result; 180 ActivityBuilder ab = new ActivityBuilder().verb(RATING_VERB_PREFIX + LIKE_ASPECT) 181 .actor((String) actor) 182 .object(String.valueOf(objects[1])) 183 .target((String) objects[0]) 184 .context(String.valueOf(objects[2])); 185 likesCount.add(ab.build()); 186 } 187 188 return likesCount; 189 } 190}