/*
* Copyright (c) 2009-2010 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.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.PersistenceException;
import org.apache.commons.logging.Log;
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.UpdateOrganizationNameRequest;
import org.eurekastreams.server.domain.DomainFormatUtility;
import org.eurekastreams.server.domain.Organization;
import org.eurekastreams.server.domain.Person;
import org.eurekastreams.server.persistence.OrganizationMapper;
import org.eurekastreams.server.persistence.PersonMapper;
import org.eurekastreams.server.persistence.mappers.DomainMapper;
import org.eurekastreams.server.persistence.mappers.cache.ClearPrivateGroupIdsViewableByCoordinatorCacheOnOrgUpdate;
import org.eurekastreams.server.search.modelview.OrganizationModelView;
import org.hibernate.validator.InvalidStateException;
import org.hibernate.validator.InvalidValue;
/**
* Class to update an Organization.
*
*/
public class OrganizationUpdater extends OrganizationPersister
{
/**
* Logger.
*/
private Log log = LogFactory.make();
/**
* Mapper to get org model view from cache (or database if not in cache).
*/
private DomainMapper<List<Long>, List<OrganizationModelView>> cachedOrganizationMapper;
/**
* key for passing original coordinators in map.
*/
private static final String ORIG_CORD_IDS_KEY = "__origCoordIds";
/**
* Cache mapper to delete activity search strings for people that are coordinators of the organization being
* updated.
*/
private ClearPrivateGroupIdsViewableByCoordinatorCacheOnOrgUpdate
// line break
clearActivityStreamSearchStringsForOrgCoordinatorMapper;
/**
* Constructor.
*
* @param inOrganizationMapper
* The org mapper.
* @param inPersonMapper
* The person mapper.
* @param inCachedOrganizationMapper
* The organization mapper.
* @param inClearActivityStreamSearchStringsForOrgCoordinatorMapper
* the cache mapper to use to clear out the activity search strings for the coordinators of the org being
* updated
*/
public OrganizationUpdater(final OrganizationMapper inOrganizationMapper, final PersonMapper inPersonMapper,
final DomainMapper<List<Long>, List<OrganizationModelView>> inCachedOrganizationMapper,
final ClearPrivateGroupIdsViewableByCoordinatorCacheOnOrgUpdate
// line break
inClearActivityStreamSearchStringsForOrgCoordinatorMapper)
{
super(inOrganizationMapper);
cachedOrganizationMapper = inCachedOrganizationMapper;
clearActivityStreamSearchStringsForOrgCoordinatorMapper =
// line break
inClearActivityStreamSearchStringsForOrgCoordinatorMapper;
}
/**
* Returns Organization base on id passed in inFields.
*
* @param inActionContext
* Action context
* @param inFields
* the property map.
* @return Organization base on id passed in inFields.
*/
@Override
public Organization get(final TaskHandlerActionContext<PrincipalActionContext> inActionContext,
final Map<String, Serializable> inFields)
{
long id = Long.parseLong(inFields.get(OrganizationModelView.ID_KEY).toString());
Organization entity = getOrgMapper().findById(id);
Set<Person> originalCoordinators = entity.getCoordinators();
Set<Long> originalCoordinatorIds = new HashSet<Long>(originalCoordinators.size());
for (Person p : originalCoordinators)
{
originalCoordinatorIds.add(p.getId());
}
inFields.put(ORIG_CORD_IDS_KEY, (Serializable) originalCoordinatorIds);
// clear the activity search strings for all coordinators, in case we're
// updating the coordinator list
clearActivityStreamSearchStringsForOrgCoordinatorMapper.execute(id);
return entity;
}
/**
* This method is different from its parent in that it does not attempt to bootstrap people into the organization.
* We're just updating, not LDAP work gets done here.
*
* @param inActionContext
* The action context
* @param inFields
* The property map.
* @param inOrganization
* The organization.
* @throws Exception
* If error occurs.
*/
@Override
public void persist(final TaskHandlerActionContext<PrincipalActionContext> inActionContext,
final Map<String, Serializable> inFields, final Organization inOrganization) throws Exception
{
// Checks to see if the name has changed, and queue up action to update
// cache if so
List<Long> ids = new ArrayList<Long>();
ids.add(inOrganization.getId());
List<OrganizationModelView> orgs = cachedOrganizationMapper.execute(ids);
if (orgs.size() > 0 && inFields.containsKey(OrganizationModelView.NAME_KEY)
&& orgs.get(0).getName() != (String) inFields.get(OrganizationModelView.NAME_KEY))
{
// puts async action on queue
inActionContext.getUserActionRequests().add(
new UserActionRequest("updateCachedOrganizationNameAction", null,
new UpdateOrganizationNameRequest(inOrganization.getId(), inOrganization.getName())));
}
// TODO there are no keywords from what i can tell in an organization.
inOrganization.setCapabilities(DomainFormatUtility.splitCapabilitiesString((String) inFields.get("keywords")));
// call concrete class to persist the org
persistOrg(inActionContext, inOrganization);
// kick off an async action to update the coordinators' activity search strings
queueAsyncAction(inActionContext, inOrganization, (Set<Long>) inFields.get(ORIG_CORD_IDS_KEY));
}
/**
* Persists modified object.
*
* @param inActionContext
* the action context
* @param inOrganization
* The organization.
*/
@Override
protected void persistOrg(final TaskHandlerActionContext<PrincipalActionContext> inActionContext,
final Organization inOrganization)
{
try
{
getOrgMapper().flush();
}
catch (InvalidStateException e)
{
log.error("Failed to persist Organization", 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 Organization", e);
}
}
}