/* * Copyright (c) 2010-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; import java.io.Serializable; import java.util.ArrayList; 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.SharedResourceRequest; import org.eurekastreams.server.persistence.mappers.DomainMapper; import org.eurekastreams.server.search.modelview.PersonModelView; import org.eurekastreams.server.search.modelview.SharedResourceDTO; /** * Execution strategy for getting shared resources by unique key. */ public class GetSharedResourcePropertiesExecution implements ExecutionStrategy<PrincipalActionContext> { /** * Logger. */ private Log log = LogFactory.make(); /** * The mapper to get the shared resource dto by unique key - includes everything except the sampling of people that * liked the shared resource - those need to be filled in at runtime to avoid the headaches of keeping display names * and avatars in cache in yet another place. */ private DomainMapper<SharedResourceRequest, SharedResourceDTO> mapper; /** * Mapper to get skeleton person model views by ids - only info needed for avatars. */ private DomainMapper<List<Long>, List<PersonModelView>> getPeopleModelViewsByIdsMapper; /** * Constructor. * * @param inMapper * the mapper to get the shared resource dto by unique key - includes everything except the sampling of * people that liked the shared resource - those need to be filled in at runtime to avoid the headaches * of keeping display names and avatars in cache in yet another place * @param inGetPeopleModelViewsByIdsMapper * Mapper to get skeleton person model views by ids - only info needed for avatars */ public GetSharedResourcePropertiesExecution(final DomainMapper<SharedResourceRequest, SharedResourceDTO> inMapper, final DomainMapper<List<Long>, List<PersonModelView>> inGetPeopleModelViewsByIdsMapper) { mapper = inMapper; getPeopleModelViewsByIdsMapper = inGetPeopleModelViewsByIdsMapper; } /** * Get the shared resource dto by unique key, then fill in a sample of the people. * * @param inActionContext * the action context * @return a SharedResourceDTO for the input unique key - will not return null, it'll make a skeleton version if the * actual shared resource doesn't exist in the system * @throws ExecutionException * Never, actually */ @Override public Serializable execute(final PrincipalActionContext inActionContext) throws ExecutionException { SharedResourceRequest request = (SharedResourceRequest) inActionContext.getParams(); Long currentUserPersonId = inActionContext.getPrincipal().getId(); log.info("Searching for the cacheable component of the SharedResourceDTO"); // get the dto in its cacheable state - everything else i do to it here isn't cacheable, including setting // whether the current person liked it, and setting some skeleton personmodelviews for avatar display SharedResourceDTO dto = mapper.execute(request); // --- BEGIN customizing the previously cacheable DTO // make sure the collections aren't null if (dto.getLikerPersonIds() == null) { dto.setLikerPersonIds(new ArrayList<Long>()); } if (dto.getSharerPersonIds() == null) { dto.setSharerPersonIds(new ArrayList<Long>()); } dto.setSharersSample(new ArrayList<PersonModelView>()); dto.setLikersSample(new ArrayList<PersonModelView>()); log.info("Now customizing the SharedResourceDTO with info about the current user, and include avatar info"); // set whether the current user likes the shared resource dto.setIsLiked(dto.getLikerPersonIds().contains(currentUserPersonId)); // -- // create a sampling of the people that liked and shared a resource - trim the two lists each to 4 people, // make a single request to get the person modelviews, then put the modelviews back in the sample lists // -- List<Long> sharedPersonIds = dto.getSharerPersonIds(); List<Long> likedPersonIds = dto.getLikerPersonIds(); // 1. trim the list of people in the sample collections if (sharedPersonIds.size() > 4) { sharedPersonIds = sharedPersonIds.subList(0, 4); } if (likedPersonIds.size() > 4) { likedPersonIds = likedPersonIds.subList(0, 4); } // 2. put all the people ids together for a single request to get the skeleton person modelviews List<Long> personIds = new ArrayList<Long>(); personIds.addAll(sharedPersonIds); for (long id : likedPersonIds) { if (!personIds.contains(id)) { personIds.add(id); } } // 3. Create the sample lists of people that shared and liked this resource if (personIds.size() > 0) { List<PersonModelView> people = getPeopleModelViewsByIdsMapper.execute(personIds); PersonModelView foundPerson; for (long personId : personIds) { foundPerson = findPersonInList(people, personId); if (foundPerson != null) { // add the DTO to the people collections if (likedPersonIds.contains(personId)) { dto.getLikersSample().add(foundPerson); } if (sharedPersonIds.contains(personId)) { dto.getSharersSample().add(foundPerson); } } } } return dto; } /** * Get a person by id from a list of PersonModelViews. * * @param inPeople * the people to look through * @param personId * the person id we're looking for * @return the person with the input id in the list of person model views */ private PersonModelView findPersonInList(final List<PersonModelView> inPeople, final Long personId) { for (PersonModelView p : inPeople) { if (p.getId() == personId) { return p; } } return null; } }