/* * Copyright (c) 2011 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.action.execution.stream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.apache.commons.logging.Log; import org.eurekastreams.commons.actions.ExecutionStrategy; import org.eurekastreams.commons.actions.context.PrincipalActionContext; import org.eurekastreams.commons.exceptions.ExecutionException; import org.eurekastreams.commons.logging.LogFactory; import org.eurekastreams.server.action.request.stream.GetStreamsUserIsFollowingRequest; import org.eurekastreams.server.domain.Follower.FollowerStatus; import org.eurekastreams.server.domain.PagedSet; import org.eurekastreams.server.domain.dto.StreamDTO; import org.eurekastreams.server.domain.strategies.FollowerStatusPopulator; import org.eurekastreams.server.persistence.mappers.DomainMapper; import org.eurekastreams.server.search.modelview.DomainGroupModelView; import org.eurekastreams.server.search.modelview.PersonModelView; /** * Return list of StreamsDTOs representing streams a user is following. * */ public class GetStreamsUserIsFollowingExecution implements ExecutionStrategy<PrincipalActionContext> { /** * Logger. */ private final Log log = LogFactory.make(); /** * Mapper to get user id by accountid. */ private final DomainMapper<String, Long> getPersonIdByAccountIdMapper; /** * Mapper to get person ids for all persons current user is following. */ private final DomainMapper<Long, List<Long>> personIdsUserIsFollowingMapper; /** * Mapper to get group ids for all persons current user is following. */ private final DomainMapper<Long, List<Long>> groupIdsUserIsFollowingMapper; /** * Mapper to get Person model views. */ private final DomainMapper<List<Long>, List<PersonModelView>> personModelViewsMapper; /** * Mapper to get group model views. */ private final DomainMapper<List<Long>, List<DomainGroupModelView>> groupModelViewsMapper; /** * Populator for follower status of results. */ private final FollowerStatusPopulator<StreamDTO> followerStatusPopulator; /** * Comparator for StreamDTOs by display name. */ public static final Comparator<StreamDTO> STREAMDTO_DISPLAYNAME_COMPARATOR = new Comparator<StreamDTO>() { @Override public int compare(final StreamDTO a, final StreamDTO b) { return a.getDisplayName().compareToIgnoreCase(b.getDisplayName()); } }; /** * Constructor. * * @param inGetPersonIdByAccountIdMapper * Mapper to get user id by accountid. * @param inPersonIdsUserIsFollowingMapper * Mapper to get person ids for all persons current user is following. * @param inGroupIdsUserIsFollowingMapper * Mapper to get group ids for all persons current user is following. * @param inPersonModelViewsMapper * Mapper to get Person model views. * @param inGroupModelViewsMapper * Mapper to get group model views. * @param inFollowerStatusPopulator * Populator for follower status of results. */ public GetStreamsUserIsFollowingExecution(final DomainMapper<String, Long> inGetPersonIdByAccountIdMapper, final DomainMapper<Long, List<Long>> inPersonIdsUserIsFollowingMapper, final DomainMapper<Long, List<Long>> inGroupIdsUserIsFollowingMapper, final DomainMapper<List<Long>, List<PersonModelView>> inPersonModelViewsMapper, final DomainMapper<List<Long>, List<DomainGroupModelView>> inGroupModelViewsMapper, final FollowerStatusPopulator<StreamDTO> inFollowerStatusPopulator) { getPersonIdByAccountIdMapper = inGetPersonIdByAccountIdMapper; personIdsUserIsFollowingMapper = inPersonIdsUserIsFollowingMapper; groupIdsUserIsFollowingMapper = inGroupIdsUserIsFollowingMapper; personModelViewsMapper = inPersonModelViewsMapper; groupModelViewsMapper = inGroupModelViewsMapper; followerStatusPopulator = inFollowerStatusPopulator; } @Override public PagedSet<StreamDTO> execute(final PrincipalActionContext inActionContext) throws ExecutionException { GetStreamsUserIsFollowingRequest request = (GetStreamsUserIsFollowingRequest) inActionContext.getParams(); Long start = System.currentTimeMillis(); Long userId = getPersonIdByAccountIdMapper.execute(request.getAccountId()); log.debug("Lookup requested user id time: " + (System.currentTimeMillis() - start) + "(ms)."); Long currentUserId = inActionContext.getPrincipal().getId(); ArrayList<StreamDTO> results = new ArrayList<StreamDTO>(); PagedSet<StreamDTO> pagedResults = new PagedSet<StreamDTO>(); // get person/group ModelViews, which implement StreamDTO, and add to results; start = System.currentTimeMillis(); results.addAll(personModelViewsMapper.execute(personIdsUserIsFollowingMapper.execute(userId))); results.addAll(groupModelViewsMapper.execute(groupIdsUserIsFollowingMapper.execute(userId))); log.debug("Data retrieval time: " + (System.currentTimeMillis() - start) + "(ms)."); // if no results, short-circuit here. if (results.isEmpty()) { return pagedResults; } // sort results; start = System.currentTimeMillis(); Collections.sort(results, STREAMDTO_DISPLAYNAME_COMPARATOR); log.debug("Data sort time:" + (System.currentTimeMillis() - start) + "(ms)."); // set up PagedSet result and return. int total = results.size(); int startIndex = request.getStartIndex(); int endIndex = request.getEndIndex() >= total ? total - 1 : request.getEndIndex(); // Note that the end index in the request is INCLUSIVE but the end index for subList() is EXCLUSIVE, so account // for the difference. ArrayList<StreamDTO> trimmedResults = new ArrayList<StreamDTO>(results.subList(startIndex, endIndex + 1)); start = System.currentTimeMillis(); followerStatusPopulator.execute(currentUserId, trimmedResults, FollowerStatus.NOTFOLLOWING); log.debug("Populate follower status time: " + (System.currentTimeMillis() - start) + "(ms)."); pagedResults.setFromIndex(startIndex); pagedResults.setToIndex(endIndex); pagedResults.setTotal(total); pagedResults.setPagedSet(trimmedResults); return pagedResults; } }