/* * Copyright (c) 2009 Lockheed Martin Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.eurekastreams.server.persistence.mappers.stream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Map; import org.eurekastreams.commons.hibernate.ModelViewResultTransformer; import org.eurekastreams.server.domain.stream.Comment; import org.eurekastreams.server.persistence.mappers.DomainMapper; import org.eurekastreams.server.persistence.mappers.cache.CacheKeys; import org.eurekastreams.server.persistence.mappers.cache.cachedfieldpopulators.CommentDTOPopulator; import org.eurekastreams.server.search.factories.CommentDTOFactory; import org.eurekastreams.server.search.modelview.CommentDTO; import org.hibernate.Criteria; import org.hibernate.criterion.ProjectionList; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; /** * DAO object that returns sorted list of fully populated CommentDTO objects associated with the id list passed in. * Returned list is sorted by Comment id. * * @deprecated GetCommentsByIdsDbMapper should be used. That is the db portion of the new decorated mapper design (this * mapper didn't get completed). Note new version doesn't order results based on id, but respects the order * of the requested ids. If you want them sorted, pass sorted ids. * */ @Deprecated public class GetCommentsById extends CachedDomainMapper implements DomainMapper<List<Long>, List<CommentDTO>> { /** * ModelViewResultsTransformer for CommentDTOs. */ private ModelViewResultTransformer<CommentDTO> resultTransformer = new ModelViewResultTransformer<CommentDTO>( new CommentDTOFactory()); /** * Comparator for sorting Comments. */ private CommentDTOComparator comparator = new CommentDTOComparator(); /** * The CommentDTOPopulator instance. */ private CommentDTOPopulator commentDTOPopulator; /** * Constructor. * * @param inCommentDTOPopulator * The CommentDTOPopulator instance. */ public GetCommentsById(final CommentDTOPopulator inCommentDTOPopulator) { commentDTOPopulator = inCommentDTOPopulator; } /** * Returns sorted list of fully populated CommentDTO objects associated with the id list passed in. Returned list is * sorted DESC. by Comment id. * * @param inCommentIds * the list of comment ids. * @return Sorted list of fully populated CommentDTO objects associated with the id list passed in. Returned list is * sorted ascending by Comment id. */ @Override public List<CommentDTO> execute(final List<Long> inCommentIds) { // short-circuit if null or empty list of ids. if (inCommentIds == null || inCommentIds.size() == 0) { return new ArrayList<CommentDTO>(0); } // Finds comments in the cache. Map<String, CommentDTO> cachedComments = getCachedComments(inCommentIds); // Get list of commentDTOs from DB. List<CommentDTO> commentDTOs = getCommentDTOsFromDataSource(getUncachedIds(inCommentIds, cachedComments)); // Fully populate and cache the new DTOs commentDTOPopulator.execute(commentDTOs, getCache()); // Add previously cached DTOs to list for full set commentDTOs.addAll(cachedComments.values()); // Sort based on comment id (DESC). Collections.sort(commentDTOs, comparator); Date currentDate = new Date(); for (CommentDTO currentComment : commentDTOs) { currentComment.setServerDateTime(currentDate); } return commentDTOs; } /** * Queries DB to get CommentDTOs associated with ids passed in. * * @param unCachedIds * Ids for DTOs to be returned. * @return List of CommentDTOs associated with ids passed in. */ @SuppressWarnings("unchecked") private List<CommentDTO> getCommentDTOsFromDataSource(final List<Long> unCachedIds) { List<CommentDTO> results = null; // One or more of the activities were missing in the cache so go to the database if (unCachedIds.size() != 0) { Criteria criteria = getHibernateSession().createCriteria(Comment.class); ProjectionList fields = Projections.projectionList(); fields.add(getColumn("id")); fields.add(getColumn("body")); fields.add(getColumn("timeSent")); fields.add(Projections.property("author.id").as("authorId")); fields.add(Projections.property("target.id").as("activityId")); criteria.setProjection(fields); criteria.setResultTransformer(resultTransformer); criteria.add(Restrictions.in("this.id", unCachedIds)); results = criteria.list(); } return (results == null) ? new ArrayList<CommentDTO>(0) : results; } /** * Given the full list of CommentIds requested, and a map of CommentDTOs that were present in cache, returns the * list of Comment ids that need to be loaded from DB. * * @param inCommentIds * Complete list of Comment ids requested. * @param cachedComments * Map of CommentDTOs from complete list that were present in cache. * @return List of Comment ids that need ot be loaded from DB. */ private List<Long> getUncachedIds(final List<Long> inCommentIds, final Map<String, CommentDTO> cachedComments) { List<Long> results = new ArrayList<Long>(); // if not all are found, determine which ones where not and if (cachedComments.size() != inCommentIds.size()) { // Determines if any of the activities were missing from the cache for (long commentId : inCommentIds) { if (!cachedComments.containsKey(CacheKeys.COMMENT_BY_ID + commentId)) { results.add(commentId); } } } return results; } /** * Returns map of CommentDTOs, keyed by cacheKey, from list of Comment ids that were present in the cache. * * @param inCommentIds * Full list of Comment ids requested. * @return Map of CommentDTOs, keyed by cacheKey, from list of Comment ids that were present in the cache. */ @SuppressWarnings("unchecked") private Map<String, CommentDTO> getCachedComments(final List<Long> inCommentIds) { List<String> keys = new ArrayList<String>(inCommentIds.size()); for (long key : inCommentIds) { keys.add(CacheKeys.COMMENT_BY_ID + key); } return (Map<String, CommentDTO>) (Map<String, ? >) getCache().multiGet(keys); } /** * CommentDTO comaparator for sorting the list. NOTE: This comparator is used to sort the comment list by comment id * in ascending manner (most recent first). * */ public class CommentDTOComparator implements Comparator<CommentDTO> { /** * Compares two CommentDTO objects based on id value. This is set up to create a ascending list of commmentDTOs * based on id. * * @param inComment1 * first commentDTO. * @param inComment2 * second commentDTO. * @return 1/-1/0 based on if comment1 id is >/</== comment2 id. */ @Override public int compare(final CommentDTO inComment1, final CommentDTO inComment2) { long id1 = inComment1.getId(); long id2 = inComment2.getId(); if (id1 > id2) { return 1; } else if (id1 < id2) { return -1; } else { return 0; } } } }