You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by ja...@apache.org on 2011/10/27 11:15:53 UTC

svn commit: r1189687 - in /incubator/rave/trunk: rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/ rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/ rave-components/rave-core/src/main/java/org/apac...

Author: jasha
Date: Thu Oct 27 09:15:52 2011
New Revision: 1189687

URL: http://svn.apache.org/viewvc?rev=1189687&view=rev
Log:
RAVE-71 apply 2nd patch by Sean Cooper (accidentally applied the wrong patch version in revision 1188100). 
Moved most WidgetRating related actions to WidgetRatingService/Repository.

Modified:
    incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRepository.java
    incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRepository.java
    incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetRatingService.java
    incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetService.java
    incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingService.java
    incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetService.java
    incubator/rave/trunk/rave-components/rave-core/src/main/resources/META-INF/persistence.xml
    incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/JpaWidgetRepositoryTest.java
    incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingServiceTest.java
    incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetServiceTest.java
    incubator/rave/trunk/rave-components/rave-core/src/test/resources/test_data.sql
    incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rest/WidgetApi.java
    incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java
    incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ModelKeys.java
    incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/WidgetApiTest.java
    incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java
    incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/store.jsp
    incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/widget.jsp
    incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave_store.js

Modified: incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRepository.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRepository.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRepository.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRepository.java Thu Oct 27 09:15:52 2011
@@ -20,9 +20,13 @@ package org.apache.rave.portal.repositor
 
 import org.apache.rave.persistence.Repository;
 import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.WidgetRating;
 import org.apache.rave.portal.model.WidgetStatus;
+import org.apache.rave.portal.model.util.WidgetStatistics;
 
 import java.util.List;
+import java.util.Map;
+
 
 public interface WidgetRepository extends Repository<Widget> {
     /**
@@ -115,4 +119,29 @@ public interface WidgetRepository extend
      * @return {@link Widget} if it can be found, otherwise {@literal null}
      */
     Widget getByUrl(String widgetUrl);
+    
+    /**
+     * Generates the widget statistics for a gadget including the user's specific information.
+     * 
+     * @param widget_id id of the widget
+     * @param user_id id of the user
+     * @return {@link WidgetStatistics} with the rating information
+     */
+    WidgetStatistics getWidgetStatistics(long widget_id, long user_id);
+
+    /**
+     * Generates the mapping of widget statistics for the user.
+     *
+     * @param userId id of the user
+     * @return Mapping of {@link WidgetStatistics} objects keyed off of the widget's entityId
+     */
+    Map<Long, WidgetStatistics> getAllWidgetStatistics(long userId);
+
+    /**
+     * Generates the mapping of widget ratings for the user.
+     *
+     * @param userId id of the user
+     * @return Mapping of {@link WidgetRating} objects keyed off of the widget's entityId
+     */
+    Map<Long, WidgetRating> getUsersWidgetRatings(long userId);
 }
\ No newline at end of file

Modified: incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRepository.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRepository.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRepository.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRepository.java Thu Oct 27 09:15:52 2011
@@ -23,12 +23,15 @@ package org.apache.rave.portal.repositor
 import org.apache.commons.lang.StringUtils;
 import org.apache.rave.persistence.jpa.AbstractJpaRepository;
 import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.WidgetRating;
 import org.apache.rave.portal.model.WidgetStatus;
+import org.apache.rave.portal.model.util.WidgetStatistics;
 import org.apache.rave.portal.repository.WidgetRepository;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Repository;
 
+import javax.persistence.NoResultException;
 import javax.persistence.Query;
 import javax.persistence.TypedQuery;
 import javax.persistence.criteria.CriteriaBuilder;
@@ -38,7 +41,9 @@ import javax.persistence.criteria.Path;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import static org.apache.rave.persistence.jpa.util.JpaUtil.getPagedResultList;
 import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
@@ -170,13 +175,29 @@ public class JpaWidgetRepository extends
         return widgetType.get("widgetStatus");
     }
 
+    /**
+     * Sets input as free text search term to a query
+     *
+     * @param query      {@link javax.persistence.Query}
+     * @param searchTerm free text
+     */
+    protected void setFreeTextSearchTerm(Query query, final String searchTerm) {
+        query.setParameter(Widget.PARAM_SEARCH_TERM, getLowercaseWildcardSearchTerm(searchTerm));
+    }
+
+    private String getLowercaseWildcardSearchTerm(String searchTerm) {
+        if (StringUtils.isBlank(searchTerm)) {
+            return searchTerm;
+        }
+        return "%" + searchTerm.toLowerCase() + "%";
+    }
 
     @Override
     public Widget getByUrl(String widgetUrl) {
         if (StringUtils.isBlank(widgetUrl)) {
             throw new IllegalArgumentException("Widget URL must not be empty");
         }
-        
+
         TypedQuery<Widget> query = manager.createNamedQuery(Widget.WIDGET_GET_BY_URL, Widget.class);
         // url is a unique field, so no paging needed
         query.setParameter(Widget.PARAM_URL, widgetUrl);
@@ -184,20 +205,86 @@ public class JpaWidgetRepository extends
         return getSingleResult(resultList);
     }
 
-    /**
-     * Sets input as free text search term to a query
-     *
-     * @param query      {@link javax.persistence.Query}
-     * @param searchTerm free text
-     */
-    protected void setFreeTextSearchTerm(Query query, final String searchTerm) {
-        query.setParameter(Widget.PARAM_SEARCH_TERM, getLowercaseWildcardSearchTerm(searchTerm));
+    @Override
+    public WidgetStatistics getWidgetStatistics(long widget_id, long user_id) {
+        WidgetStatistics widgetStatistics = new WidgetStatistics();
+
+        Query query = manager.createNamedQuery(WidgetRating.WIDGET_TOTAL_LIKES);
+        query.setParameter(WidgetRating.PARAM_WIDGET_ID, widget_id);
+        widgetStatistics.setTotalLike(((Number) query.getSingleResult()).intValue());
+
+        query = manager.createNamedQuery(WidgetRating.WIDGET_TOTAL_DISLIKES);
+        query.setParameter(WidgetRating.PARAM_WIDGET_ID, widget_id);
+        widgetStatistics.setTotalDislike(((Number) query.getSingleResult()).intValue());
+
+        try {
+            query = manager.createNamedQuery(WidgetRating.WIDGET_USER_RATING);
+            query.setParameter(WidgetRating.PARAM_WIDGET_ID, widget_id);
+            query.setParameter(WidgetRating.PARAM_USER_ID, user_id);
+            widgetStatistics.setUserRating(((Number) query.getSingleResult()).intValue());
+        } catch (NoResultException e) {
+            widgetStatistics.setUserRating(WidgetRating.UNSET);
+        }
+
+        return widgetStatistics;
     }
-    
-    private String getLowercaseWildcardSearchTerm(String searchTerm) {
-        if (StringUtils.isBlank(searchTerm)) {
-            return searchTerm;
+
+    @Override
+    public Map<Long, WidgetRating> getUsersWidgetRatings(long user_id) {
+        TypedQuery<WidgetRating> query =
+                manager.createNamedQuery(WidgetRating.WIDGET_ALL_USER_RATINGS, WidgetRating.class);
+        query.setParameter(WidgetRating.PARAM_USER_ID, user_id);
+
+        Map<Long, WidgetRating> map = new HashMap<Long, WidgetRating>();
+        for (WidgetRating widgetRating : query.getResultList()) {
+            map.put(widgetRating.getWidgetId(), widgetRating);
         }
-        return "%" + searchTerm.toLowerCase() + "%";
+
+        return map;
     }
+
+    @Override
+    public Map<Long, WidgetStatistics> getAllWidgetStatistics(long userId) {
+        HashMap<Long, WidgetStatistics> map = new HashMap<Long, WidgetStatistics>();
+
+        //Generate the mapping of all likes done for the widgets
+        Query query = manager.createNamedQuery(WidgetRating.WIDGET_ALL_TOTAL_LIKES);
+        for (Object[] result : (List<Object[]>) query.getResultList()) {
+            Long totalLikes = (Long) result[0];
+            Long widgetId = (Long) result[1];
+            WidgetStatistics widgetStatistics = new WidgetStatistics();
+            widgetStatistics.setTotalLike(totalLikes.intValue());
+            map.put(widgetId, widgetStatistics);
+        }
+
+        //Add the mapping of all dislikes done for the widgets
+        query = manager.createNamedQuery(WidgetRating.WIDGET_ALL_TOTAL_DISLIKES);
+        for (Object[] result : (List<Object[]>) query.getResultList()) {
+            Long totalDislikes = (Long) result[0];
+            Long widgetId = (Long) result[1];
+            WidgetStatistics widgetStatistics = map.get(widgetId);
+            if (widgetStatistics == null) {
+                widgetStatistics = new WidgetStatistics();
+                map.put(widgetId, widgetStatistics);
+            }
+            widgetStatistics.setTotalDislike(totalDislikes.intValue());
+        }
+
+        //Add the current user's current rating of the widget
+        Map<Long, WidgetRating> userRatings = getUsersWidgetRatings(userId);
+        for (Map.Entry<Long, WidgetStatistics> entry : map.entrySet()) {
+            //If the user has a widget rating then record it
+            if (userRatings.containsKey(entry.getKey())) {
+                entry.getValue().setUserRating(userRatings.get(entry.getKey()).getScore());
+            }
+            //otherwise set the rating to UNSET
+            else {
+                entry.getValue().setUserRating(WidgetRating.UNSET);
+            }
+        }
+
+        return map;
+    }
+
+
 }

Modified: incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetRatingService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetRatingService.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetRatingService.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetRatingService.java Thu Oct 27 09:15:52 2011
@@ -43,4 +43,19 @@ public interface WidgetRatingService {
      */
     void updateScore(WidgetRating widgetRating, Integer score);
 
+    /**
+     * Saves a {@link WidgetRating} for a widget
+     *
+     * @param rating   WidgetRating
+     */
+    void saveWidgetRating(WidgetRating rating);
+
+    /**
+     * Removes the rating of a widget
+     *
+     * @param widgetId unique identifier of a {@link org.apache.rave.portal.model.Widget}
+     * @param userId   unique identifier of a {@link org.apache.rave.portal.model.User}
+     */
+    void removeWidgetRating(long widgetId, long userId);
+
 }

Modified: incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetService.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetService.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetService.java Thu Oct 27 09:15:52 2011
@@ -20,8 +20,10 @@
 package org.apache.rave.portal.service;
 
 import org.apache.rave.portal.model.Widget;
-import org.apache.rave.portal.model.WidgetRating;
 import org.apache.rave.portal.model.util.SearchResult;
+import org.apache.rave.portal.model.util.WidgetStatistics;
+
+import java.util.Map;
 
 /**
  * Provides widget operations
@@ -117,26 +119,27 @@ public interface WidgetService {
     Widget registerNewWidget(Widget widget);
     
     /**
-     * Updates {@link Widget}
-     *
-     * @param widget to save
+     * Generates the widget statistics for a gadget including the user's specific information.
+     * 
+     * @param widgetId id of the widget
+     * @param userId id of the user
+     * @return {@link WidgetStatistics} with the rating information
      */
-    void updateWidget(Widget widget);
+    WidgetStatistics getWidgetStatistics(long widgetId, long userId);
 
     /**
-     * Saves a {@link WidgetRating} for a widget
-     *
-     * @param widgetId unique identifier of a {@link Widget}
-     * @param rating   WidgetRating
+     * Generates the mapping of widget statistics for the user.
+     * 
+     * @param userId id of the user
+     * @return Mapping of {@link WidgetStatistics} objects keyed off of the widget's entityId
      */
-    void saveWidgetRating(long widgetId, WidgetRating rating);
-
+    Map<Long, WidgetStatistics> getAllWidgetStatistics(long userId);
+    
     /**
-     * Removes the rating of a widget
+     * Updates {@link Widget}
      *
-     * @param widgetId unique identifier of a {@link Widget}
-     * @param userId   unique identifier of a {@link org.apache.rave.portal.model.User}
+     * @param widget to save
      */
-    void removeWidgetRating(long widgetId, long userId);
+    void updateWidget(Widget widget);
 
 }

Modified: incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingService.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingService.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingService.java Thu Oct 27 09:15:52 2011
@@ -26,10 +26,10 @@ import org.springframework.beans.factory
 import org.springframework.stereotype.Service;
 
 /**
-Default implementation for {@link org.apache.rave.portal.service.WidgetRatingService}
+ * Default implementation for {@link org.apache.rave.portal.service.WidgetRatingService}
  */
 @Service
-public class DefaultWidgetRatingService implements WidgetRatingService{
+public class DefaultWidgetRatingService implements WidgetRatingService {
 
     private final WidgetRatingRepository repository;
 
@@ -48,4 +48,23 @@ public class DefaultWidgetRatingService 
         widgetRating.setScore(score);
         repository.save(widgetRating);
     }
+
+    @Override
+    public void saveWidgetRating(WidgetRating rating) {
+        WidgetRating existingRating = getByWidgetIdAndUserId(rating.getWidgetId(), rating.getUserId());
+        if (existingRating == null) {
+            repository.save(rating);
+        } else {
+            updateScore(existingRating, rating.getScore());
+        }
+    }
+
+    @Override
+    public void removeWidgetRating(long widgetId, long userId) {
+        WidgetRating widgetRating = repository.getByWidgetIdAndUserId(widgetId, userId);
+        if (widgetRating == null) {
+            return;
+        }
+        repository.delete(widgetRating);
+    }
 }

Modified: incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetService.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetService.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetService.java Thu Oct 27 09:15:52 2011
@@ -21,11 +21,10 @@ package org.apache.rave.portal.service.i
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.rave.portal.model.Widget;
-import org.apache.rave.portal.model.WidgetRating;
 import org.apache.rave.portal.model.WidgetStatus;
 import org.apache.rave.portal.model.util.SearchResult;
+import org.apache.rave.portal.model.util.WidgetStatistics;
 import org.apache.rave.portal.repository.WidgetRepository;
-import org.apache.rave.portal.service.WidgetRatingService;
 import org.apache.rave.portal.service.WidgetService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,6 +32,7 @@ import org.springframework.beans.factory
 import org.springframework.stereotype.Service;
 
 import java.util.List;
+import java.util.Map;
 
 @Service
 public class DefaultWidgetService implements WidgetService {
@@ -40,12 +40,10 @@ public class DefaultWidgetService implem
     private static Logger logger = LoggerFactory.getLogger(DefaultWidgetService.class);
 
     private final WidgetRepository widgetRepository;
-    private final WidgetRatingService widgetRatingService;
 
     @Autowired
-    public DefaultWidgetService(WidgetRepository widgetRepository, WidgetRatingService widgetRatingService) {
+    public DefaultWidgetService(WidgetRepository widgetRepository) {
         this.widgetRepository = widgetRepository;
-        this.widgetRatingService = widgetRatingService;
     }
 
     @Override
@@ -133,40 +131,18 @@ public class DefaultWidgetService implem
     }
 
     @Override
-    public void updateWidget(Widget widget) {
-        widgetRepository.save(widget);
+    public WidgetStatistics getWidgetStatistics(long widgetId, long userId) {
+        return widgetRepository.getWidgetStatistics(widgetId, userId);
     }
 
     @Override
-    public void saveWidgetRating(long widgetId, WidgetRating rating) {
-        Widget widget = getWidget(widgetId);
-        List<WidgetRating> widgetRatings = widget.getRatings();
-
-        WidgetRating userWidgetRating = getUserWidgetRating(widget.getEntityId(), rating.getUserId());
-        if (userWidgetRating == null) {
-            widgetRatings.add(rating);
-            updateWidget(widget);
-        }
-        else {
-            widgetRatingService.updateScore(userWidgetRating, rating.getScore());
-        }
+    public Map<Long, WidgetStatistics> getAllWidgetStatistics(long userId) {
+        return widgetRepository.getAllWidgetStatistics(userId);
     }
 
     @Override
-    public void removeWidgetRating(long widgetId, long userId) {
-        Widget widget = getWidget(widgetId);
-        List<WidgetRating> widgetRatings = widget.getRatings();
-
-        WidgetRating userWidgetRating = getUserWidgetRating(widget.getEntityId(), userId);
-        if (userWidgetRating == null) {
-            return;
-        }
-        widgetRatings.remove(userWidgetRating);
-        updateWidget(widget);
-
+    public void updateWidget(Widget widget) {
+        widgetRepository.save(widget);
     }
 
-    private WidgetRating getUserWidgetRating(Long widgetId, Long userId) {
-        return widgetRatingService.getByWidgetIdAndUserId(widgetId, userId);
-    }
 }

Modified: incubator/rave/trunk/rave-components/rave-core/src/main/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/resources/META-INF/persistence.xml?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/resources/META-INF/persistence.xml (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/resources/META-INF/persistence.xml Thu Oct 27 09:15:52 2011
@@ -29,6 +29,7 @@
             <class>org.apache.rave.portal.model.RegionWidget</class>
             <class>org.apache.rave.portal.model.RegionWidgetPreference</class>
             <class>org.apache.rave.portal.model.Widget</class>
+            <class>org.apache.rave.portal.model.WidgetRating</class>
             <class>org.apache.rave.portal.model.PageLayout</class>
             <class>org.apache.rave.portal.model.Authority</class>
         </persistence-unit>

Modified: incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/JpaWidgetRepositoryTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/JpaWidgetRepositoryTest.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/JpaWidgetRepositoryTest.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/JpaWidgetRepositoryTest.java Thu Oct 27 09:15:52 2011
@@ -20,7 +20,9 @@
 package org.apache.rave.portal.repository;
 
 import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.WidgetRating;
 import org.apache.rave.portal.model.WidgetStatus;
+import org.apache.rave.portal.model.util.WidgetStatistics;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
@@ -34,6 +36,7 @@ import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
@@ -192,4 +195,142 @@ public class JpaWidgetRepositoryTest {
         assertEquals(longDescription, widget.getDescription());
     }
 
+    @Test 
+    public void getAllWidgetStatistics() {
+        Map<Long, WidgetStatistics> widgetStatistics = repository.getAllWidgetStatistics(1L);
+        
+        WidgetStatistics gadgetOne = widgetStatistics.get(1L);
+        assertEquals(0, gadgetOne.getTotalLike());
+        assertEquals(1, gadgetOne.getTotalDislike());
+        assertEquals(0, gadgetOne.getUserRating());
+        
+        WidgetStatistics gadgetTwo = widgetStatistics.get(2L);
+        assertEquals(1, gadgetTwo.getTotalLike());
+        assertEquals(0, gadgetTwo.getTotalDislike());
+        assertEquals(10, gadgetTwo.getUserRating());
+    }
+    
+    @Test
+    public void getUserWidgetRatings() {
+        Map<Long, WidgetRating> widgetRatings = repository.getUsersWidgetRatings(1L);
+        
+        WidgetRating gadgetOne = widgetRatings.get(1L);
+        assertEquals(WidgetRating.DISLIKE, gadgetOne.getScore());
+        assertEquals(new Long(1), gadgetOne.getUserId());
+        assertEquals(new Long(1), gadgetOne.getEntityId());
+        
+        WidgetRating gadgetTwo = widgetRatings.get(2L);
+        assertEquals(WidgetRating.LIKE, gadgetTwo.getScore());
+        assertEquals(new Long(1), gadgetTwo.getUserId());
+        assertEquals(new Long(2), gadgetTwo.getEntityId());
+    }
+    
+    @Test
+    public void getEmptyUserWidgetStatistics() {
+        //ensure that a bogus user has only UNSET widget ratings
+        for ( Map.Entry<Long, WidgetStatistics> entry : repository.getAllWidgetStatistics(Long.MAX_VALUE).entrySet()) {
+            assertEquals(WidgetRating.UNSET.intValue(), entry.getValue().getUserRating());
+        }
+    }
+    
+    @Test
+    public void getWidgetStatistics() {
+        Widget widget = repository.get(1L);
+        List<WidgetRating> ratings = widget.getRatings();
+        assertNotNull(ratings);
+        assertEquals(1, ratings.size());
+        
+        WidgetStatistics widgetStatistics = repository.getWidgetStatistics(widget.getEntityId(), 1L);
+        widgetStatistics.toString();
+        assertNotNull(widgetStatistics);
+        assertEquals(0, widgetStatistics.getTotalLike());
+        assertEquals(1, widgetStatistics.getTotalDislike());
+        assertEquals(WidgetRating.DISLIKE.intValue(), widgetStatistics.getUserRating());
+    }
+    
+    @Test
+    public void getPositiveWidgetStatsitics() {
+        Widget widget = repository.get(2L);
+        List<WidgetRating> ratings = widget.getRatings();
+        assertNotNull(ratings);
+        assertEquals(1, ratings.size());
+        
+        WidgetStatistics widgetStatistics = repository.getWidgetStatistics(widget.getEntityId(), 1L);
+        assertNotNull(widgetStatistics);
+        assertEquals(1, widgetStatistics.getTotalLike());
+        assertEquals(0, widgetStatistics.getTotalDislike());
+        assertEquals(WidgetRating.LIKE.intValue(), widgetStatistics.getUserRating());
+    }
+    
+    @Test
+    public void getMissingWidgetStatistics() {
+        Widget widget = repository.get(3L);
+        List<WidgetRating> ratings = widget.getRatings();
+        assertNotNull(ratings);
+        assertEquals(0, ratings.size());
+        
+        WidgetStatistics widgetStatistics = repository.getWidgetStatistics(widget.getEntityId(), 1L);
+        assertNotNull(widgetStatistics);
+        assertEquals(0, widgetStatistics.getTotalDislike());
+        assertEquals(0, widgetStatistics.getTotalLike());
+        assertEquals(WidgetRating.UNSET.intValue(), widgetStatistics.getUserRating());
+    }
+    
+    @Test
+    public void addWidgetRating() {
+        Widget widget = repository.get(3L);
+        assertNotNull(widget.getRatings());
+        WidgetRating widgetRating = new WidgetRating();
+        widgetRating.setScore(10);
+        widgetRating.setUserId(1L);
+        widgetRating.setWidgetId(widget.getEntityId());
+        widget.getRatings().add(widgetRating);
+        
+        repository.save(widget);
+        
+        Widget reloadedWidget = repository.get(3L);
+        List<WidgetRating> widgetRatings = reloadedWidget.getRatings();
+        assertNotNull(widgetRatings);
+        assertEquals(1, widgetRatings.size());
+        WidgetRating reloadedWidgetRating = widgetRatings.get(0);
+        assertNotNull(reloadedWidgetRating);
+        assertEquals(widgetRating.getScore(), reloadedWidgetRating.getScore());
+        assertEquals(widgetRating.getUserId(), reloadedWidgetRating.getUserId());
+        assertEquals(widget.getEntityId(), reloadedWidgetRating.getWidgetId());
+    }
+    
+    @Test public void updateWidgetRating() {
+        Widget widget = repository.get(4L);
+        assertNotNull(widget.getRatings());
+        WidgetRating widgetRating = new WidgetRating();
+        widgetRating.setScore(10);
+        widgetRating.setUserId(1L);
+        widgetRating.setWidgetId(widget.getEntityId());
+        widget.getRatings().add(widgetRating);
+        
+        repository.save(widget);
+        
+        Widget reloadedWidget = repository.get(4L);
+        List<WidgetRating> widgetRatings = reloadedWidget.getRatings();
+        assertNotNull(widgetRatings);
+        assertEquals(1, widgetRatings.size());
+        WidgetRating reloadedWidgetRating = widgetRatings.get(0);
+        assertNotNull(reloadedWidgetRating);
+        assertEquals(widgetRating.getScore(), reloadedWidgetRating.getScore());
+        assertEquals(widgetRating.getUserId(), reloadedWidgetRating.getUserId());
+        assertEquals(widget.getEntityId(), reloadedWidgetRating.getWidgetId());
+        
+        reloadedWidgetRating.setScore(0);
+        
+        repository.save(reloadedWidget);
+        reloadedWidget = repository.get(4L);
+        widgetRatings = reloadedWidget.getRatings();
+        assertNotNull(widgetRatings);
+        assertEquals(1, widgetRatings.size());
+        reloadedWidgetRating = widgetRatings.get(0);
+        assertNotNull(reloadedWidgetRating);
+        assertEquals(widgetRating.getScore(), reloadedWidgetRating.getScore());
+        assertEquals(widgetRating.getUserId(), reloadedWidgetRating.getUserId());
+        assertEquals(widget.getEntityId(), reloadedWidgetRating.getWidgetId());
+    }
 }

Modified: incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingServiceTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingServiceTest.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingServiceTest.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingServiceTest.java Thu Oct 27 09:15:52 2011
@@ -22,7 +22,6 @@ package org.apache.rave.portal.service.i
 import org.apache.rave.portal.model.WidgetRating;
 import org.apache.rave.portal.repository.WidgetRatingRepository;
 import org.apache.rave.portal.service.WidgetRatingService;
-import org.apache.rave.portal.service.impl.DefaultWidgetRatingService;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -65,7 +64,62 @@ public class DefaultWidgetRatingServiceT
         expect(repository.save(widgetRating)).andReturn(widgetRating);
         replay(repository, widgetRating);
         service.updateScore(widgetRating, 10);
-        
+
         verify(repository, widgetRating);
     }
+
+    @Test
+    public void saveWidgetRating_new() {
+        WidgetRating newRating = new WidgetRating();
+        newRating.setWidgetId(2L);
+        newRating.setUserId(1L);
+        newRating.setScore(10);
+
+        expect(repository.getByWidgetIdAndUserId(2L, 1L)).andReturn(null);
+        expect(repository.save(newRating)).andReturn(newRating);
+        replay(repository);
+
+        service.saveWidgetRating(newRating);
+        verify(repository);
+    }
+
+    @Test
+    public void saveWidgetRating_existing() {
+        WidgetRating existingRating = new WidgetRating(1L, 1L, 1L, 5);
+        WidgetRating newRating = new WidgetRating();
+        newRating.setWidgetId(1L);
+        newRating.setUserId(1L);
+        newRating.setScore(10);
+
+        expect(repository.getByWidgetIdAndUserId(1L, 1L)).andReturn(existingRating);
+        expect(repository.save(existingRating)).andReturn(existingRating);
+        replay(repository);
+
+        service.saveWidgetRating(newRating);
+        verify(repository);
+
+        assertEquals("Updated score", Integer.valueOf(10), existingRating.getScore());
+    }
+
+    @Test
+    public void removeWidgetRating_existingRating() {
+        final WidgetRating widgetRating = new WidgetRating(1L, 1L, 1L, 5);
+
+        expect(repository.getByWidgetIdAndUserId(1L, 1L)).andReturn(widgetRating);
+        repository.delete(widgetRating);
+        expectLastCall();
+        replay(repository);
+
+        service.removeWidgetRating(1L, 1L);
+    }
+
+    @Test
+    public void removeWidgetRating_notExisting() {
+
+        expect(repository.getByWidgetIdAndUserId(1L, 2L)).andReturn(null);
+        expectLastCall();
+        replay(repository);
+
+        service.removeWidgetRating(1L, 2L);
+    }
 }

Modified: incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetServiceTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetServiceTest.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetServiceTest.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetServiceTest.java Thu Oct 27 09:15:52 2011
@@ -20,21 +20,19 @@
 package org.apache.rave.portal.service.impl;
 
 import org.apache.rave.portal.model.Widget;
-import org.apache.rave.portal.model.WidgetRating;
 import org.apache.rave.portal.model.WidgetStatus;
 import org.apache.rave.portal.model.util.SearchResult;
+import org.apache.rave.portal.model.util.WidgetStatistics;
 import org.apache.rave.portal.repository.WidgetRepository;
-import org.apache.rave.portal.service.impl.DefaultWidgetService;
+import org.apache.rave.portal.service.WidgetService;
 import org.junit.Before;
 import org.junit.Test;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
-import org.apache.rave.portal.service.WidgetRatingService;
-import org.apache.rave.portal.service.WidgetService;
 import static junit.framework.Assert.assertTrue;
-import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
@@ -59,13 +57,13 @@ public class DefaultWidgetServiceTest {
     @Before
     public void setup() {
         repository = createNiceMock(WidgetRepository.class);
-        WidgetRatingService widgetRatingService = createMock(WidgetRatingService.class);
-        service = new DefaultWidgetService(repository, widgetRatingService);
+        service = new DefaultWidgetService(repository);
     }
 
     @Test
     public void getAvailableWidgets() {
         List<Widget> widgets = new ArrayList<Widget>();
+        expect(repository.getCountAll()).andReturn(1);
         expect(repository.getAll()).andReturn(widgets);
         replay(repository);
 
@@ -75,12 +73,13 @@ public class DefaultWidgetServiceTest {
 
     @Test
     public void getLimitedListOfWidgets() {
-        Widget widget1 = new Widget(1L,"http://example.com/widget1.xml");
-        Widget widget2 = new Widget(2L,"http://example.com/widget2.xml");
+        Widget widget1 = new Widget(1L, "http://example.com/widget1.xml");
+        Widget widget2 = new Widget(2L, "http://example.com/widget2.xml");
         List<Widget> widgets = new ArrayList<Widget>();
         widgets.add(widget1);
         widgets.add(widget2);
         final int pageSize = 10;
+        expect(repository.getCountAll()).andReturn(1);
         expect(repository.getLimitedList(0, pageSize)).andReturn(widgets);
         replay(repository);
 
@@ -92,14 +91,15 @@ public class DefaultWidgetServiceTest {
 
     @Test
     public void getPublishedWidgets() {
-        Widget widget1 = new Widget(1L,"http://example.com/widget1.xml");
+        Widget widget1 = new Widget(1L, "http://example.com/widget1.xml");
         widget1.setWidgetStatus(WidgetStatus.PUBLISHED);
-        Widget widget2 = new Widget(2L,"http://example.com/widget2.xml");
+        Widget widget2 = new Widget(2L, "http://example.com/widget2.xml");
         widget2.setWidgetStatus(WidgetStatus.PUBLISHED);
         List<Widget> widgets = new ArrayList<Widget>();
         widgets.add(widget1);
         widgets.add(widget2);
         final int pageSize = 10;
+        expect(repository.getCountByStatus(WidgetStatus.PUBLISHED)).andReturn(1);
         expect(repository.getByStatus(WidgetStatus.PUBLISHED, 0, pageSize)).andReturn(widgets);
         replay(repository);
 
@@ -129,7 +129,7 @@ public class DefaultWidgetServiceTest {
         widget.setEntityId(1L);
         List<Widget> widgets = new ArrayList<Widget>();
         widgets.add(widget);
-        
+
         expect(repository.getCountFreeTextSearch(searchTerm)).andReturn(totalResults);
         expect(repository.getByFreeTextSearch(searchTerm, offset, pageSize)).andReturn(widgets);
         replay(repository);
@@ -249,7 +249,7 @@ public class DefaultWidgetServiceTest {
     @Test
     public void updateWidget() {
         final String widgetUrl =
-                        "http://hosting.gmodules.com/ig/gadgets/file/112581010116074801021/hamster.xml";
+                "http://hosting.gmodules.com/ig/gadgets/file/112581010116074801021/hamster.xml";
         Widget widget = new Widget();
         widget.setUrl(widgetUrl);
         expect(repository.save(widget)).andReturn(widget).once();
@@ -262,76 +262,21 @@ public class DefaultWidgetServiceTest {
     }
 
     @Test
-    public void createWidgetRating() {
-        Widget widget = new Widget(1L, "http://example.com/widget.xml");
-        widget.setRatings(new ArrayList<WidgetRating>());
-        expect(repository.get(1)).andReturn(widget);
-        expect(repository.save(widget)).andReturn(widget);
+    public void widgetStatistics() {
+        expect(repository.getWidgetStatistics(1L, 1L)).andReturn(new WidgetStatistics());
         replay(repository);
 
-        WidgetRating newWidgetRating = new WidgetRating(1L, 1L, 1L, 1);
-        service.saveWidgetRating(1L, newWidgetRating);
-
-        List<WidgetRating> ratings = widget.getRatings();
-        assertNotNull(ratings);
-        assertEquals(1, ratings.size());
-        assertEquals(ratings.get(0), newWidgetRating);
+        service.getWidgetStatistics(1L, 1L);
+        verify(repository);
     }
 
+
     @Test
-    public void updateWidgetRating() {
-        Widget widget = new Widget();
-        List<WidgetRating> ratings = new ArrayList<WidgetRating>();
-        ratings.add(new WidgetRating(1L, 1L, 1L, 5));
-        widget.setRatings(ratings);
-        expect(repository.get(1)).andReturn(widget);
-        expect(repository.save(widget)).andReturn(widget);
-        replay(repository);
-        
-        WidgetRating newWidgetRating = new WidgetRating();
-        newWidgetRating.setWidgetId(1L);
-        newWidgetRating.setUserId(1L);
-        newWidgetRating.setScore(0);
-        
-        service.saveWidgetRating(1L, newWidgetRating);
-        
-        assertNotNull(ratings);
-        assertEquals(2, ratings.size());
-        assertEquals(ratings.get(1).getScore(), new Integer(0));
-    }
-    
-    @Test
-    public void deleteWidgetRating() {
-        Widget widget = new Widget();
-        List<WidgetRating> ratings = new ArrayList<WidgetRating>();
-        ratings.add(new WidgetRating(123L, 1L, 1L, 5));
-        widget.setRatings(ratings);
-        expect(repository.get(1)).andReturn(widget);
-        expect(repository.save(widget)).andReturn(widget);
+    public void allWidgetStatistics() {
+        expect(repository.getAllWidgetStatistics(1L)).andReturn(new HashMap<Long, WidgetStatistics>());
         replay(repository);
-        
-        service.removeWidgetRating(1, 1L);
-        
-        assertNotNull(ratings);
-        assertEquals(1, ratings.size());
-    }
-    
-    @Test
-    public void deleteUnsavedWidgetRating() {
-        Widget widget = new Widget();
-        List<WidgetRating> ratings = new ArrayList<WidgetRating>();
-        ratings.add(new WidgetRating(123L, 1L, 1L, 5));
-        widget.setRatings(ratings);
-        expect(repository.get(1)).andReturn(widget);
-        expect(repository.save(widget)).andReturn(widget);
-        replay(repository);
-        
-        service.removeWidgetRating(1, 2L);
-        
-        assertNotNull(ratings);
-        assertEquals(1, ratings.size());
-        assertEquals(ratings.get(0).getScore(), new Integer(5));
-    }
 
-    
+        service.getAllWidgetStatistics(1L);
+        verify(repository);
+    }
 }

Modified: incubator/rave/trunk/rave-components/rave-core/src/test/resources/test_data.sql
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/test/resources/test_data.sql?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/test/resources/test_data.sql (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/test/resources/test_data.sql Thu Oct 27 09:15:52 2011
@@ -41,8 +41,8 @@ INSERT INTO RAVE_PORTAL_SEQUENCES(seq_na
 INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values ('region_widget_preference', 1);
 INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@user_seq, 1);
 INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@widget_seq, 1);
-INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@granted_authority_seq, 1);
 INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@widget_rating_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@granted_authority_seq, 1);
 
   -- ***********************************************************************************
   -- start page layout data, required to make the portal work ---
@@ -268,7 +268,15 @@ INSERT INTO region_widget(entity_id, wid
 values (@next_region_widget, @tabnews_widget_id, @page_1_region_2, 1, FALSE);
 UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
 
-
+set @next_widget_rating = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_rating_seq);
+INSERT INTO widget_rating(entity_id, widget_id, user_id, score)
+values (@next_widget_rating, 1, 1, 0);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_rating_seq;
+
+set @next_widget_rating = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_rating_seq);
+INSERT INTO widget_rating(entity_id, widget_id, user_id, score)
+values (@next_widget_rating, 2, 1, 10);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_rating_seq;
 
 set @page_2_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
 INSERT INTO page (entity_id, name, owner_id, render_sequence, page_layout_id)
@@ -745,10 +753,4 @@ insert into granted_authority (entity_id
 values (@next_authority_id, 'administrator');
 UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @granted_authority_seq;
 
--- end authorities
-
--- Widget rating
-set @next_widget_rating_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_rating_seq);
-insert into widget_rating(entity_id, widget_id, user_id, score)
-values (@next_widget_rating_id, 1, 1, 10);
-UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_rating_seq;
\ No newline at end of file
+-- end authorities
\ No newline at end of file

Modified: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rest/WidgetApi.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rest/WidgetApi.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rest/WidgetApi.java (original)
+++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rest/WidgetApi.java Thu Oct 27 09:15:52 2011
@@ -21,7 +21,7 @@ package org.apache.rave.portal.web.api.r
 
 import org.apache.rave.portal.model.WidgetRating;
 import org.apache.rave.portal.service.UserService;
-import org.apache.rave.portal.service.WidgetService;
+import org.apache.rave.portal.service.WidgetRatingService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -41,12 +41,12 @@ import javax.servlet.http.HttpServletRes
 @RequestMapping("/api/rest/widgets")
 public class WidgetApi extends AbstractRestApi {
     private static Logger logger = LoggerFactory.getLogger(WidgetApi.class);
-    private final WidgetService widgetService;
+    private final WidgetRatingService widgetRatingService;
     private final UserService userService;
     
     @Autowired
-    public WidgetApi(WidgetService widgetService, UserService userService) {
-        this.widgetService = widgetService;
+    public WidgetApi(WidgetRatingService widgetRatingService, UserService userService) {
+        this.widgetRatingService = widgetRatingService;
         this.userService = userService;
     }
 
@@ -62,7 +62,7 @@ public class WidgetApi extends AbstractR
                             HttpServletResponse response) {
         logger.debug("DELETE WidgetRating received for /api/rest/widgets/{}", widgetId);
 
-        widgetService.removeWidgetRating(widgetId, userService.getAuthenticatedUser().getEntityId());
+        widgetRatingService.removeWidgetRating(widgetId, userService.getAuthenticatedUser().getEntityId());
         
         // send a 204 back for success since there is no content being returned
         response.setStatus(HttpStatus.NO_CONTENT.value());
@@ -78,7 +78,7 @@ public class WidgetApi extends AbstractR
         widgetRating.setScore(score);
         widgetRating.setUserId(userService.getAuthenticatedUser().getEntityId());
         widgetRating.setWidgetId(widgetId);
-        widgetService.saveWidgetRating(widgetId, widgetRating);
+        widgetRatingService.saveWidgetRating(widgetRating);
         
         // send a 204 back for success since there is no content being returned
         response.setStatus(HttpStatus.NO_CONTENT.value());

Modified: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java (original)
+++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java Thu Oct 27 09:15:52 2011
@@ -21,10 +21,8 @@ package org.apache.rave.portal.web.contr
 
 import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.model.Widget;
-import org.apache.rave.portal.model.WidgetRating;
 import org.apache.rave.portal.model.WidgetStatus;
 import org.apache.rave.portal.service.UserService;
-import org.apache.rave.portal.service.WidgetRatingService;
 import org.apache.rave.portal.service.WidgetService;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
@@ -49,16 +47,13 @@ public class WidgetStoreController {
 
     private final NewWidgetValidator widgetValidator;
 
-    private final WidgetRatingService widgetRatingService;
-
     private final UserService userService;
 
     @Autowired
     public WidgetStoreController(WidgetService widgetService, NewWidgetValidator validator,
-                                 WidgetRatingService widgetRatingService, UserService userService) {
+                                 UserService userService) {
         this.widgetService = widgetService;
         this.widgetValidator = validator;
-        this.widgetRatingService = widgetRatingService;
         this.userService = userService;
     }
 
@@ -73,9 +68,11 @@ public class WidgetStoreController {
     @RequestMapping(method = RequestMethod.GET)
     public String view(Model model, @RequestParam long referringPageId,
                        @RequestParam(required = false, defaultValue = "0") int offset) {
+        User user = userService.getAuthenticatedUser();
         model.addAttribute(ModelKeys.WIDGETS,
                 widgetService.getPublishedWidgets(offset, MAXIMUM_WIDGETS_PER_PAGE));
         model.addAttribute(ModelKeys.REFERRING_PAGE_ID, referringPageId);
+        model.addAttribute(ModelKeys.WIDGETS_STATISTICS, widgetService.getAllWidgetStatistics(user.getEntityId()));        
         return ViewNames.STORE;
     }
 
@@ -92,11 +89,8 @@ public class WidgetStoreController {
         model.addAttribute(ModelKeys.WIDGET, widgetService.getWidget(widgetId));
         model.addAttribute(ModelKeys.REFERRING_PAGE_ID, referringPageId);
 
-        final User authenticatedUser = userService.getAuthenticatedUser();
-        final WidgetRating widgetRating =
-                widgetRatingService.getByWidgetIdAndUserId(widgetId, authenticatedUser.getEntityId());
-        model.addAttribute("widgetRating", widgetRating);
-
+        final User user = userService.getAuthenticatedUser();
+        model.addAttribute(ModelKeys.WIDGET_STATISTICS, widgetService.getWidgetStatistics(widgetId, user.getEntityId()));
         return ViewNames.WIDGET;
     }
 
@@ -113,12 +107,15 @@ public class WidgetStoreController {
     public String viewSearchResult(Model model, @RequestParam long referringPageId,
                                    @RequestParam String searchTerm,
                                    @RequestParam(required = false, defaultValue = "0") int offset) {
+        User user = userService.getAuthenticatedUser();
         model.addAttribute(ModelKeys.WIDGETS,
                 widgetService.getPublishedWidgetsByFreeTextSearch(searchTerm, offset,
                         MAXIMUM_WIDGETS_PER_PAGE));
         model.addAttribute(ModelKeys.REFERRING_PAGE_ID, referringPageId);
         model.addAttribute(ModelKeys.SEARCH_TERM, searchTerm);
         model.addAttribute(ModelKeys.OFFSET, offset);
+        model.addAttribute(ModelKeys.WIDGETS_STATISTICS, widgetService.getAllWidgetStatistics(user.getEntityId()));
+        
         return ViewNames.STORE;
     }
 
@@ -160,7 +157,9 @@ public class WidgetStoreController {
             return ViewNames.ADD_WIDGET_FORM;
         }
 
+        User user = userService.getAuthenticatedUser();
         model.addAttribute(ModelKeys.WIDGET, storedWidget);
+        model.addAttribute(ModelKeys.WIDGET_STATISTICS, widgetService.getWidgetStatistics(storedWidget.getEntityId(), user.getEntityId()));
         return ViewNames.WIDGET;
     }
 }

Modified: incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ModelKeys.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ModelKeys.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ModelKeys.java (original)
+++ incubator/rave/trunk/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/util/ModelKeys.java Thu Oct 27 09:15:52 2011
@@ -29,6 +29,8 @@ public class ModelKeys {
     public static final String ERROR_MESSAGE = "errorMessage"; // an error message to be reported to the user
     public static final String WIDGETS = "widgets"; // a list of widget objects
     public static final String WIDGET = "widget";
+    public static final String WIDGET_STATISTICS = "widgetStatistics"; //statistics for a single widget
+    public static final String WIDGETS_STATISTICS = "widgetsStatistics"; //list of statistics for a list of widgets
     public static final String REFERRING_PAGE_ID = "referringPageId";
     public static final String OPENSOCIAL_ENVIRONMENT = "openSocialEnv";
     public static final String NEW_USER = "newUser"; //a new user instance created

Modified: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/WidgetApiTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/WidgetApiTest.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/WidgetApiTest.java (original)
+++ incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/WidgetApiTest.java Thu Oct 27 09:15:52 2011
@@ -22,7 +22,7 @@ package org.apache.rave.portal.web.api.r
 import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.model.WidgetRating;
 import org.apache.rave.portal.service.UserService;
-import org.apache.rave.portal.service.WidgetService;
+import org.apache.rave.portal.service.WidgetRatingService;
 import org.junit.Before;
 import org.junit.Test;
 import org.springframework.http.HttpStatus;
@@ -36,16 +36,16 @@ import static org.easymock.EasyMock.veri
 
 public class WidgetApiTest {
     private WidgetApi widgetApi;
-    private WidgetService widgetService;
+    private WidgetRatingService widgetRatingService;
     private UserService userService;
     private MockHttpServletResponse response;
 
     @Before
     public void setup() {
-        widgetService = createMock(WidgetService.class);
+        widgetRatingService = createMock(WidgetRatingService.class);
         userService = createMock(UserService.class);
         response = createMock(MockHttpServletResponse.class);
-        widgetApi = new WidgetApi(widgetService, userService);
+        widgetApi = new WidgetApi(widgetRatingService, userService);
     }
 
     @Test(expected = UnsupportedOperationException.class)
@@ -55,9 +55,9 @@ public class WidgetApiTest {
     
     @Test
     public void deleteWidgetRating() {
-        widgetService.removeWidgetRating(1L, 2L);
+        widgetRatingService.removeWidgetRating(1L, 2L);
         expectLastCall();
-        replay(widgetService);
+        replay(widgetRatingService);
         
         response.setStatus(HttpStatus.NO_CONTENT.value());
         replay(response);
@@ -68,7 +68,7 @@ public class WidgetApiTest {
         replay(userService);
         widgetApi.deleteWidgetRating(1L, response);
 
-        verify(widgetService, userService);
+        verify(widgetRatingService, userService);
         verify(response);
     }
     
@@ -78,9 +78,9 @@ public class WidgetApiTest {
         widgetRating.setScore(5);
         widgetRating.setUserId(2L);
         widgetRating.setWidgetId(1L);
-        widgetService.saveWidgetRating(1L, widgetRating);
+        widgetRatingService.saveWidgetRating(widgetRating);
         expectLastCall();
-        replay(widgetService);
+        replay(widgetRatingService);
         
         response.setStatus(HttpStatus.NO_CONTENT.value());
         replay(response);
@@ -92,7 +92,7 @@ public class WidgetApiTest {
 
         widgetApi.setWidgetRating(1L, 5, response);
         
-        verify(widgetService, userService);
+        verify(widgetRatingService, userService);
         verify(response);
     }
 }
\ No newline at end of file

Modified: incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java (original)
+++ incubator/rave/trunk/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java Thu Oct 27 09:15:52 2011
@@ -25,7 +25,6 @@ import org.apache.rave.portal.model.Widg
 import org.apache.rave.portal.model.WidgetStatus;
 import org.apache.rave.portal.model.util.SearchResult;
 import org.apache.rave.portal.service.UserService;
-import org.apache.rave.portal.service.WidgetRatingService;
 import org.apache.rave.portal.service.WidgetService;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
@@ -46,7 +45,6 @@ import static junit.framework.Assert.ass
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
-import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
@@ -66,16 +64,17 @@ public class WidgetStoreControllerTest {
     private static final long REFERRER_ID = 35L;
     private WidgetStoreController controller;
     private WidgetService widgetService;
-    private WidgetRatingService widgetRatingService;
-    private UserService userService;
 
     @Before
     public void setup() {
         widgetService = createNiceMock(WidgetService.class);
-        userService = createNiceMock(UserService.class);
+        UserService userService = createNiceMock(UserService.class);
+        User user = new User();
+        user.setEntityId(1L);
+        expect(userService.getAuthenticatedUser()).andReturn(user);
+        replay(userService);
         NewWidgetValidator widgetValidator = new NewWidgetValidator();
-        widgetRatingService = createMock(WidgetRatingService.class);
-        controller = new WidgetStoreController(widgetService, widgetValidator, widgetRatingService, userService);
+        controller = new WidgetStoreController(widgetService, widgetValidator, userService);
     }
 
     @Test
@@ -101,16 +100,13 @@ public class WidgetStoreControllerTest {
     public void viewWidget() {
         Model model = new ExtendedModelMap();
         Widget w = new Widget(1L, "http://example.com/widget.xml");
-        User user = new User(1L, "john.doe");
 
         expect(widgetService.getWidget(WIDGET_ID)).andReturn(w);
-        expect(userService.getAuthenticatedUser()).andReturn(user);
-        expect(widgetRatingService.getByWidgetIdAndUserId(1L, 1L)).andReturn(null);
-        replay(widgetService, userService, widgetRatingService);
+        replay(widgetService);
 
         String view = controller.viewWidget(model, WIDGET_ID, REFERRER_ID);
 
-        verify(widgetService, userService, widgetRatingService);
+        verify(widgetService);
         assertThat(view, is(equalTo(ViewNames.WIDGET)));
         assertThat(model.containsAttribute(ModelKeys.WIDGET), is(true));
         assertThat(((Widget) model.asMap().get(ModelKeys.WIDGET)), is(sameInstance(w)));
@@ -162,6 +158,7 @@ public class WidgetStoreControllerTest {
         final String widgetUrl = "http://example.com/newwidget.xml";
         final Model model = new ExtendedModelMap();
         final Widget widget = new Widget();
+        widget.setEntityId(1L);
         widget.setTitle("Widget title");
         widget.setUrl(widgetUrl);
         widget.setType("OpenSocial");

Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/store.jsp
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/store.jsp?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/store.jsp (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/store.jsp Thu Oct 27 09:15:52 2011
@@ -109,6 +109,14 @@
                                  width="120" height="60"/>
                         </c:if>
                         <div class="widgetType"><c:out value="${widget.type}"/></div>
+                        
+                        <div class="widgetRating">
+                            <fmt:message key="page.widget.rate"/>
+                            <div id="rating-${widget.entityId}" class="ratingButtons">
+                                <input type="radio" id="like-${widget.entityId}" class="widgetLikeButton" name="rating-${widget.entityId}"${widgetsStatistics[widget.entityId].userRating==10?" checked='true'":""}> <label for="like-${widget.entityId}">${widgetsStatistics[widget.entityId]!=null?widgetsStatistics[widget.entityId].totalLike:"0"}</label>
+                                <input type="radio" id="dislike-${widget.entityId}" class="widgetDislikeButton" name="rating-${widget.entityId}"${widgetsStatistics[widget.entityId].userRating==0?" checked='true'":""}> <label for="dislike-${widget.entityId}">${widgetsStatistics[widget.entityId]!=null?widgetsStatistics[widget.entityId].totalDislike:"0"}</label>
+                            </div>
+                        </div>
                     </div>
                     <div class="storeItemCenter">
                         <div id="widgetAdded_${widget.entityId}" class="storeButton">
@@ -153,11 +161,13 @@
 </div>
 
 <script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js"></script>
+<script src="//ajax.aspnetcdn.com/ajax/jquery.ui/1.8.13/jquery-ui.min.js"></script>
 <script src="<spring:url value="/script/rave.js"/>"></script>
 <script src="<spring:url value="/script/rave_api.js"/>"></script>
+<script src="<spring:url value="/script/rave_store.js"/>"></script>
 <script>
-    $(function() {
-        rave.setContext("<spring:url value="/app/" />");
+    $(function () {
+        rave.store.init();
     });
 </script>
 </rave:rave_generic_page>

Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/widget.jsp
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/widget.jsp?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/widget.jsp (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/widget.jsp Thu Oct 27 09:15:52 2011
@@ -71,17 +71,10 @@
                     <p><fmt:message key="widget.type.${widget.type}" /></p>
                 </div>
                 <div class="widgetRating">
-                        <%--@elvariable id="widgetRating" type="org.apache.rave.portal.model.WidgetRating"--%>
-                        <fmt:message key="page.widget.rate"/>
-                        <div id="radio">
-                        <c:set var="likeSelected"><c:if test="${not empty widgetRating and widgetRating.score eq 10}"> checked="checked"</c:if></c:set>
-                        <c:set var="dislikeSelected"><c:if test="${not empty widgetRating and widgetRating.score eq 0}"> checked="checked"</c:if></c:set>
-                        <input type="radio" id="like" name="rating"
-                               data-widget="<c:out value="${widget.entityId}"/>" ${likeSelected}>
-                            <label for="like"><fmt:message key="page.widget.rate.like"/></label>
-                        <input type="radio" id="dislike" name="rating"
-                               data-widget="<c:out value="${widget.entityId}"/>" ${dislikeSelected}>
-                            <label for="dislike"><fmt:message key="page.widget.rate.dislike"/></label>
+                    <fmt:message key="page.widget.rate"/>
+                    <div id="radio" class="ratingButtons">
+                       <input type="radio" id="like-${widget.entityId}" class="widgetLikeButton widgetRatingButton" value="10" name="rating-${widget.entityId}"${widgetStatistics.userRating=='10'?" checked='true'":""}> <label for="like-${widget.entityId}">${widgetStatistics.totalLike}</label>
+                       <input type="radio" id="dislike-${widget.entityId}" class="widgetDislikeButton widgetRatingButton" value="0" name="rating-${widget.entityId}"${widgetStatistics.userRating=='0'?" checked='true'":""}> <label for="dislike-${widget.entityId}">${widgetStatistics.totalDislike}</label>
                     </div>
                 </div>
             </div>

Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave_store.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave_store.js?rev=1189687&r1=1189686&r2=1189687&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave_store.js (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave_store.js Thu Oct 27 09:15:52 2011
@@ -18,34 +18,60 @@
  */
 var rave = rave || {};
 rave.store = rave.store || (function() {
-    function init() {
-        $("#radio").buttonset();
+    
+    function initRatings() {
+        $(".ratingButtons").buttonset();
+
+        $(".widgetLikeButton").button( {
+            icons: {primary: "ui-icon-plus"}
+        }).change(function() {
+            var widgetId = this.id.substring("like-".length);
+            rave.api.rest.updateWidgetRating({widgetId: widgetId, score: 10});
+            $(this).button("option", "label", parseInt($(this).button("option", "label")) + 1);
+
+            //if the other button in this pair was checked then ajdust its total, except in IE where
+            //the button has already toggled BEFORE the 'change' event in which case we have to assume
+            //that the user had a contrary selection prior to the change event
+            var dislikeButton = $("#dislike-"+widgetId);
+            if (dislikeButton.get(0).getAttribute("checked") == "true" || this.checked == true) {
+                dislikeButton.get(0).setAttribute("checked", "false");
+                var dislikes = parseInt(dislikeButton.button("option", "label")) - 1;
+                if (dislikes > -1) {
+                    $(dislikeButton).button("option", "label", dislikes);
+                }
+            }
+            
+            //flag this element as the currently checked one
+            this.setAttribute("checked", "true");
 
-        $("#like").button( {
-            icons: {
-                primary: "ui-icon-plus"
-            },
-            text: false
         });
 
-        $("#like").click(function() {
-            rave.api.rest.updateWidgetRating({widgetId: $(this).attr("data-widget"), score: 10});
-        });
-
-        $("#dislike").button( {
-            icons: {
-                primary: "ui-icon-minus"
-            },
-            text: false
-        });
-
-        $("#dislike").click(function() {
-            rave.api.rest.updateWidgetRating({widgetId: $(this).attr("data-widget"), score: 0});
+        $(".widgetDislikeButton").button( {
+            icons: {primary: "ui-icon-minus"}
+        }).change(function() {
+            var widgetId = this.id.substring("dislike-".length);
+            rave.api.rest.updateWidgetRating({widgetId: widgetId, score: 0});
+            $(this).button("option", "label", parseInt($(this).button("option", "label")) + 1);
+
+            //if the other button in this pair was checked then ajdust its total, except in IE where
+            //the button has already toggled BEFORE the 'change' event in which case we have to assume
+            //that the user had a contrary selection prior to the change event
+            var likeButton = $("#like-"+widgetId);
+            if (likeButton.get(0).getAttribute("checked") == "true" || this.checked == true) {
+                likeButton.get(0).setAttribute("checked", "false");
+                var likes = parseInt(likeButton.button("option", "label")) - 1;
+                if (likes > -1) {
+                    $("#like-"+widgetId).button("option", "label", likes);
+                }
+            }
+            
+            //flag this element as the currently checked item
+            this.setAttribute("checked", "true");
         });
     }
-
+    
     return {
-        init:init
+        init: initRatings
     };
-
-})();
+    
+}());
\ No newline at end of file