/* * Copyright (c) 2009-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.service.actions.strategies; import java.io.Serializable; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.persistence.PersistenceException; import org.apache.commons.logging.Log; import org.eurekastreams.commons.actions.InlineExecutionStrategyExecutor; import org.eurekastreams.commons.actions.TaskHandlerExecutionStrategy; import org.eurekastreams.commons.actions.context.DefaultPrincipal; import org.eurekastreams.commons.actions.context.PrincipalActionContext; import org.eurekastreams.commons.actions.context.TaskHandlerActionContext; import org.eurekastreams.commons.exceptions.ValidationException; import org.eurekastreams.commons.logging.LogFactory; import org.eurekastreams.commons.server.UserActionRequest; import org.eurekastreams.server.action.request.profile.SetFollowingStatusByGroupCreatorRequest; import org.eurekastreams.server.domain.DomainFormatUtility; import org.eurekastreams.server.domain.DomainGroup; import org.eurekastreams.server.domain.Follower; import org.eurekastreams.server.domain.Person; import org.eurekastreams.server.persistence.DomainGroupMapper; import org.eurekastreams.server.persistence.mappers.DomainMapper; import org.eurekastreams.server.persistence.mappers.GetAllPersonIdsWhoHaveGroupCoordinatorAccess; import org.eurekastreams.server.search.modelview.DomainGroupModelView; import org.hibernate.validator.InvalidStateException; import org.hibernate.validator.InvalidValue; /** * Class to update a Group. * */ public class GroupUpdater extends GroupPersister { /** * Logger. */ private final Log log = LogFactory.make(); /** * The key to use to store the original domain group name into the fields map between Get and Persist. */ private static final String ORIGINAL_GROUP_NAME_KEY = "__KEY_ORIGINAL_GROUP_NAME_KEY"; /** * The key to use to store the original domain group coordinators into the fields map between Get and Persist. */ private static final String ORIGINAL_GROUP_COORDINATORS_KEY = "__KEY_ORIGINAL_GROUP_COORDINATORS_KEY"; /** * Strategy for adding group followers (coordinators are automatically added as followers/members). */ private final TaskHandlerExecutionStrategy followStrategy; /** * Mapper to clear the existing coordinators and followers search text. */ private final DomainMapper<Long, Void> clearActivityStreamSearchStringForUsersMapper; /** * Constructor. * * @param inGroupMapper * The group mapper. * @param inAccessCheckerMapper * mapper to determine permissions * @param inClearActivityStreamSearchStringForUsersMapper * the mapper to clear out activity search strings for users * @param inFollowStrategy * used to automatically add coordinators as group followers/members. */ public GroupUpdater(final DomainGroupMapper inGroupMapper, final GetAllPersonIdsWhoHaveGroupCoordinatorAccess inAccessCheckerMapper, final DomainMapper<Long, Void> inClearActivityStreamSearchStringForUsersMapper, final TaskHandlerExecutionStrategy inFollowStrategy) { super(inGroupMapper); clearActivityStreamSearchStringForUsersMapper = inClearActivityStreamSearchStringForUsersMapper; followStrategy = inFollowStrategy; } /** * Returns Group base on id passed in inFields. * * @param inActionContext * action context * @param inFields * the property map. * @return group base on id passed in inFields. */ @Override public DomainGroup get(final TaskHandlerActionContext<PrincipalActionContext> inActionContext, final Map<String, Serializable> inFields) { long id = Long.parseLong(inFields.get("id").toString()); DomainGroup entity = getGroupMapper().findById(id); // store the original domain group name between get and persist inFields.put(ORIGINAL_GROUP_NAME_KEY, entity.getName()); inFields.put(ORIGINAL_GROUP_COORDINATORS_KEY, (Serializable) entity.getCoordinators()); // clear out the search text for the group coordinators now, before we // commit to the db if (!entity.isPublicGroup()) { clearActivityStreamSearchStringForUsersMapper.execute(entity.getId()); } return entity; } /** * Updates the Group Data. * * @param inActionContext * The action context. * @param inFields * The property map. * @param inGroup * The group. * @throws Exception * If error occurs. */ @Override public void persist(final TaskHandlerActionContext<PrincipalActionContext> inActionContext, final Map<String, Serializable> inFields, final DomainGroup inGroup) throws Exception { try { inGroup.setCapabilities(DomainFormatUtility.splitCapabilitiesString((String) inFields .get(DomainGroupModelView.KEYWORDS_KEY))); String creatorUserName = inActionContext.getActionContext().getPrincipal().getAccountId(); Set<Person> oldCoordinators = (Set<Person>) inFields.get(ORIGINAL_GROUP_COORDINATORS_KEY); Set<Person> newCoordinators = new HashSet<Person>(); newCoordinators.addAll(inGroup.getCoordinators()); newCoordinators.removeAll(oldCoordinators); // Make all coordinators follow/join the new group for (Person coordinator : newCoordinators) { SetFollowingStatusByGroupCreatorRequest currentRequest = new SetFollowingStatusByGroupCreatorRequest( coordinator.getId(), inGroup.getId(), Follower.FollowerStatus.FOLLOWING, inGroup.getName(), inGroup.getShortName(), false); new InlineExecutionStrategyExecutor().execute(followStrategy, currentRequest, new DefaultPrincipal( creatorUserName, inActionContext.getActionContext().getPrincipal().getOpenSocialId(), inActionContext.getActionContext().getPrincipal().getId()), inActionContext .getUserActionRequests()); } getGroupMapper().flush(); queueAsyncAction(inActionContext, inGroup, true); // see if the group name changed - if so, kick off a task to update all activities that were posted to the // group String previousGroupName = (String) inFields.get(ORIGINAL_GROUP_NAME_KEY); String newGroupName = inGroup.getName(); if (previousGroupName == null || !previousGroupName.equals(newGroupName)) { log.info("The name for domain group with short name " + inGroup.getShortName() + " has been changed from '" + previousGroupName + "' to '" + newGroupName + "'. Queuing up activityRecipientDomainGroupNameUpdaterAsyncAction async task to update " + "all activities posted to this group."); // group name updated - kick off a task to update all activities posted to the group inActionContext.getUserActionRequests().add( new UserActionRequest("activityRecipientDomainGroupNameUpdaterAsyncAction", null, inGroup .getShortName())); } } catch (InvalidStateException e) { log.error("Failed to persist Group", e); InvalidValue[] invalidValues = e.getInvalidValues(); ValidationException validationException = new ValidationException(); for (InvalidValue invalidValue : invalidValues) { validationException.addError(invalidValue.getPropertyName(), invalidValue.getMessage()); } throw validationException; } catch (PersistenceException e) { log.error("Failed to persist Group", e); } } }