/*
* 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.activity;
import java.util.ArrayList;
import java.util.List;
import org.eurekastreams.commons.exceptions.ValidationException;
import org.eurekastreams.server.domain.EntityType;
import org.eurekastreams.server.domain.stream.ActivityDTO;
import org.eurekastreams.server.persistence.mappers.DomainMapper;
import org.eurekastreams.server.persistence.mappers.stream.GetDomainGroupsByShortNames;
import org.eurekastreams.server.search.modelview.DomainGroupModelView;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/**
* Class that performs the validation for Share activities.
*
*/
public class ShareVerbValidator implements ActivityValidator
{
/**
* Local instance of the activity mapper.
*/
private DomainMapper<List<Long>, List<ActivityDTO>> activityMapper;
/**
* Local instance of the TransactionManager to be injected.
*/
private PlatformTransactionManager transMgr;
/**
* Used to lookup groups too see if sharing is allowed (private groups).
*/
private GetDomainGroupsByShortNames groupShortNameCacheMapper;
/**
* Base constructor.
*
* @param inActivityMapper
* - mapper for retrieving Activities by id from storage.
* @param inTransManager
* - transaction manager for shared verb validation. This is needed because this validator uses the
* BulkActivities Mapper to retrieve the original Activity to be sure that the properties are the same as
* the shared Activity.
* @param inGroupShortNameCacheMapper
* The mapper to get a group by short name. needed because private group activities can not be shared.
*/
public ShareVerbValidator(final DomainMapper<List<Long>, List<ActivityDTO>> inActivityMapper,
final PlatformTransactionManager inTransManager,
final GetDomainGroupsByShortNames inGroupShortNameCacheMapper)
{
activityMapper = inActivityMapper;
transMgr = inTransManager;
groupShortNameCacheMapper = inGroupShortNameCacheMapper;
}
/**
* Perform the validation to ensure a correctly formed Share Activity. The following criteria are enforced:
*
* - Original Actor must be supplied
*
* - Original Activity must be found in the db and only one occurrence of Activity Id.
*
* - Original Activity BaseObjectProperties must match the new Activity's BaseObjectProperties.
*
* - Original Actor of the Shared Activity must match the Actor of the Original Activity.
*
* - BaseObjectType of the shared activity must match the BaseObjectType of the original activity.
*
* - Original Activity must not be from a Private Group.
*
* @param inActivity
* - activityDTO instance to validate.
*/
public void validate(final ActivityDTO inActivity)
{
DefaultTransactionDefinition transDef = new DefaultTransactionDefinition();
transDef.setName("LookupActivityTransaction");
transDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus transStatus = transMgr.getTransaction(transDef);
ValidationException ve = new ValidationException();
// Actor is not validated because it is supplied by the action.
if (inActivity.getOriginalActor() == null || inActivity.getOriginalActor().getUniqueIdentifier() == null
|| inActivity.getOriginalActor().getUniqueIdentifier().length() <= 0)
{
ve.addError("OriginalActor", "Must be included for Share verbs.");
throw ve;
}
List<Long> activityIds = new ArrayList<Long>(1);
activityIds.add(new Long(inActivity.getBaseObjectProperties().get("originalActivityId")));
inActivity.getBaseObjectProperties().remove("originalActivityId");
List<ActivityDTO> originalActivityResults;
try
{
originalActivityResults = activityMapper.execute(activityIds);
// If the original activity cannot be found throw an error right away.
if (originalActivityResults.size() == 0)
{
ve.addError("OriginalActivity", "activity being shared could not be found in the db.");
throw ve;
}
// if a unuqie activity is not found throw an error.
if (originalActivityResults.size() > 1)
{
ve.addError("OriginalActivity", "more than one result was found for the original activity id.");
}
ActivityDTO origActivity = originalActivityResults.get(0);
if (origActivity.getDestinationStream().getType() == EntityType.GROUP)
{
DomainGroupModelView group = groupShortNameCacheMapper.fetchUniqueResult(origActivity
.getDestinationStream().getUniqueIdentifier());
if (group != null && !group.isPublic())
{
ve.addError("OriginalActivity", "OriginalActivity from a private group and can not be shared.");
throw ve;
}
else if (group == null)
{
ve.addError("OriginalActivity", "OriginalActivity Group Entity not found.");
}
}
if (!inActivity.getBaseObjectProperties().equals(origActivity.getBaseObjectProperties()))
{
ve.addError("BaseObjectProperties",
"Oringal Activity BaseObjectProperties must equal the properties of the Shared Activity.");
}
else
{
// Push the property back onto the object properties for use
// in storing the original id.
inActivity.getBaseObjectProperties().put("originalActivityId", activityIds.get(0).toString());
}
if (!inActivity.getOriginalActor().getUniqueIdentifier().equals(
origActivity.getActor().getUniqueIdentifier()))
{
ve.addError("OriginalActor",
"Original actor of the shared activity does not match the actor of the original activity.");
}
if (!inActivity.getBaseObjectType().equals(origActivity.getBaseObjectType()))
{
ve.addError("BaseObjectType", "activity must be of the same type as the original activity.");
}
transMgr.commit(transStatus);
}
catch (Exception ex)
{
transMgr.rollback(transStatus);
ve.addError("OriginalActivity", "Error occurred accessing the original activity.");
}
if (!ve.getErrors().isEmpty())
{
throw ve;
}
}
}