org.eurekastreams.server.action.execution.GetStreamDiscoverListsDTOExecution.java Source code

Java tutorial

Introduction

Here is the source code for org.eurekastreams.server.action.execution.GetStreamDiscoverListsDTOExecution.java

Source

/*
 * Copyright (c) 2011-2012 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;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

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.commons.util.CollectionListAdapter;
import org.eurekastreams.server.domain.EntityType;
import org.eurekastreams.server.domain.Follower.FollowerStatus;
import org.eurekastreams.server.domain.dto.DisplayInfoSettable;
import org.eurekastreams.server.domain.dto.StreamDTO;
import org.eurekastreams.server.domain.dto.StreamDiscoverListsDTO;
import org.eurekastreams.server.domain.strategies.DisplayInfoSettableDataPopulator;
import org.eurekastreams.server.domain.strategies.FollowerStatusPopulator;
import org.eurekastreams.server.persistence.comparators.StreamDTOFollowerCountDescendingComparator;
import org.eurekastreams.server.persistence.mappers.DomainMapper;
import org.eurekastreams.server.persistence.mappers.requests.SuggestedStreamsRequest;
import org.eurekastreams.server.search.modelview.DomainGroupModelView;
import org.eurekastreams.server.search.modelview.PersonModelView;

import edu.emory.mathcs.backport.java.util.Collections;

/**
 * Execution strategy to get suggested group and people streams for a user.
 */
public class GetStreamDiscoverListsDTOExecution implements ExecutionStrategy<PrincipalActionContext> {
    /**
     * Logger.
     */
    private final Log log = LogFactory.make();

    /**
     * Mapper to get suggested people streams.
     */
    private final DomainMapper<SuggestedStreamsRequest, List<PersonModelView>> suggestedPersonMapper;

    /**
     * Mapper to get suggested group streams.
     */
    private final DomainMapper<SuggestedStreamsRequest, List<DomainGroupModelView>> suggestedGroupMapper;

    /**
     * Mapper to get the stream discovery lists that are the same for everyone.
     */
    private final DomainMapper<Serializable, StreamDiscoverListsDTO> streamDiscoveryListsMapper;

    /**
     * Data populator for setting the DisplayName and avatar id on DisplayInfoSettables.
     */
    private final DisplayInfoSettableDataPopulator displayInfoSettableDataPopulator;

    /**
     * {@link FollowerStatusPopulator}.
     */
    private final FollowerStatusPopulator<DisplayInfoSettable> followerStatusPopulator;

    /**
     * Mapper to get a list of PersonModelViews from a list of AccountIds.
     */
    private final DomainMapper<List<Long>, List<PersonModelView>> getPersonModelViewsByIdsDAO;

    /**
     * The number of stream suggestions to get.
     */
    final int suggestionCount;

    /**
     * Constructor.
     *
     * @param inSuggestedPersonMapper
     *            mapper to get suggested people streams
     * @param inSuggestedGroupMapper
     *            mapper to get suggested group streams
     * @param inSuggestionCount
     *            the number of suggested streams to get
     * @param inStreamDiscoveryListsMapper
     *            mapper to get the stream discovery lists that are the same for everyone
     * @param inDisplayInfoSettableDataPopulator
     *            data populator for setting the DisplayName and avatar id on DisplayInfoSettables
     * @param inFollowerStatusPopulator
     *            list of DisplayInfoSettable.
     * @param inGetPersonModelViewsByIdsDAO
     *            Mapper to get a list of PersonModelViews from a list of AccountIds.
     */
    public GetStreamDiscoverListsDTOExecution(
            final DomainMapper<SuggestedStreamsRequest, List<PersonModelView>> inSuggestedPersonMapper,
            final DomainMapper<SuggestedStreamsRequest, List<DomainGroupModelView>> inSuggestedGroupMapper,
            final int inSuggestionCount,
            final DomainMapper<Serializable, StreamDiscoverListsDTO> inStreamDiscoveryListsMapper,
            final DisplayInfoSettableDataPopulator inDisplayInfoSettableDataPopulator,
            final FollowerStatusPopulator<DisplayInfoSettable> inFollowerStatusPopulator,
            final DomainMapper<List<Long>, List<PersonModelView>> inGetPersonModelViewsByIdsDAO) {
        suggestedPersonMapper = inSuggestedPersonMapper;
        suggestedGroupMapper = inSuggestedGroupMapper;
        suggestionCount = inSuggestionCount;
        streamDiscoveryListsMapper = inStreamDiscoveryListsMapper;
        displayInfoSettableDataPopulator = inDisplayInfoSettableDataPopulator;
        followerStatusPopulator = inFollowerStatusPopulator;
        getPersonModelViewsByIdsDAO = inGetPersonModelViewsByIdsDAO;
    }

    /**
     * Get the StreamDiscoverListsDTO for the current user, which includes data for all users along with suggestions for
     * the current user. Integer representing how many suggestions to get
     *
     * @param inActionContext
     *            the action context
     * @return StreamDiscoverListsDTO representing all of the discover page lists and the featured streams.
     * @throws ExecutionException
     *             (never)
     */
    @Override
    public Serializable execute(final PrincipalActionContext inActionContext) throws ExecutionException {
        Long personId = inActionContext.getPrincipal().getId();

        log.info("BEGIN getting the lists of streams that apply to all users.");
        StreamDiscoverListsDTO result = streamDiscoveryListsMapper.execute(null);
        log.info("END getting the lists of streams that apply to all users.");

        log.info("BEGIN getting the list of suggested streams for user " + personId);
        getSuggestionsForPerson(personId, result);
        log.info("END getting the list of suggested streams for user " + personId);

        // put all of the streams in a single list for transient data population
        List<DisplayInfoSettable> displayInfoSettables = new ArrayList<DisplayInfoSettable>();
        displayInfoSettables.addAll(result.getFeaturedStreams());
        displayInfoSettables.addAll(result.getMostFollowedStreams());
        displayInfoSettables.addAll(result.getMostRecentStreams());
        displayInfoSettables.addAll(result.getMostViewedStreams());
        displayInfoSettables.addAll(result.getSuggestedStreams());
        displayInfoSettables.addAll(result.getMostActiveStreams().getResultsSublist());

        // determine list of allowed people (not locked/deactivated)
        Set<Long> allowedPeople = getAllowedPeopleList(displayInfoSettables);
        // remove all unallowed people from lists
        filterList(result.getFeaturedStreams(), allowedPeople);
        filterList(result.getMostFollowedStreams(), allowedPeople);
        filterList(result.getMostRecentStreams(), allowedPeople);
        filterList(result.getMostViewedStreams(), allowedPeople);
        filterList(result.getSuggestedStreams(), allowedPeople);
        int oldCount = result.getMostActiveStreams().getResultsSublist().size();
        filterList(result.getMostActiveStreams().getResultsSublist(), allowedPeople);
        result.getMostActiveStreams().setTotalResultsCount(result.getMostActiveStreams().getTotalResultsCount()
                - (oldCount - result.getMostActiveStreams().getResultsSublist().size()));

        // fill in the avatars and display names of all of the StreamDTOs
        log.info("BEGIN setting the display info on " + displayInfoSettables.size()
                + " GroupModelViews and PersonModelViews");
        displayInfoSettableDataPopulator.execute(displayInfoSettables);
        log.info("END setting the display info on " + displayInfoSettables.size()
                + " GroupModelViews and PersonModelViews");

        // Set follower status on all dtos.
        log.info("BEGIN setting the follower statuses on " + displayInfoSettables.size()
                + " GroupModelViews and PersonModelViews");
        followerStatusPopulator.execute(personId, displayInfoSettables, FollowerStatus.NOTFOLLOWING);
        log.info("END setting the follower statuses on " + displayInfoSettables.size()
                + " GroupModelViews and PersonModelViews");
        return result;
    }

    /**
     * Get the suggested streams for the current user, and populate them in the input StreamDiscoverListsDTO.
     *
     * @param inPersonId
     *            the person id to fetch suggested streams for
     * @param inStreamDiscoverLists
     *            the StreamDiscoverListsDTO to add the results to
     */
    private void getSuggestionsForPerson(final Long inPersonId,
            final StreamDiscoverListsDTO inStreamDiscoverLists) {
        SuggestedStreamsRequest mapperRequest = new SuggestedStreamsRequest(inPersonId, suggestionCount);
        ArrayList<StreamDTO> suggestions = new ArrayList<StreamDTO>();

        suggestions.addAll(suggestedPersonMapper.execute(mapperRequest));
        suggestions.addAll(suggestedGroupMapper.execute(mapperRequest));

        // sort the list
        Collections.sort(suggestions, new StreamDTOFollowerCountDescendingComparator());

        // return those requested
        if (suggestions.size() > suggestionCount) {
            suggestions = new ArrayList<StreamDTO>(suggestions.subList(0, suggestionCount));
        }
        inStreamDiscoverLists.setSuggestedStreams(suggestions);
    }

    /**
     * Given the list of streams, determines which person streams are allowed to be shown.
     *
     * @param displayInfoSettables
     *            List of streams.
     * @return Which person streams are allowed to be shown.
     */
    private Set<Long> getAllowedPeopleList(final List<DisplayInfoSettable> displayInfoSettables) {
        Set<Long> ids = new HashSet<Long>();
        for (DisplayInfoSettable ds : displayInfoSettables) {
            if (EntityType.PERSON.equals(ds.getEntityType())) {
                ids.add(ds.getEntityId());
            }
        }
        List<PersonModelView> people = getPersonModelViewsByIdsDAO.execute(new CollectionListAdapter<Long>(ids));
        Set<Long> allowedIds = new HashSet<Long>();
        for (PersonModelView person : people) {
            if (!person.isAccountLocked()) {
                allowedIds.add(person.getId());
            }
        }
        return allowedIds;
    }

    /**
     * Removes any non-allowed people (locked, deactivated) from the list.
     *
     * @param list
     *            List to update.
     * @param allowedPeople
     *            IDs of people to allow.
     */
    private void filterList(final List<? extends DisplayInfoSettable> list, final Set<Long> allowedPeople) {
        for (int i = 0; i < list.size(); i++) {
            DisplayInfoSettable item = list.get(i);
            if (EntityType.PERSON.equals(item.getEntityType()) && !allowedPeople.contains(item.getEntityId())) {
                list.remove(i);
                i--;
            }
        }
    }
}