SAIL-160: CMIS Policy no-op implementations

- SOAP and REST binding create/update methods throw exceptions allowed by spec and read method returns empty set
- Moved transaction interceptor into org.alfresco.repo.transaction package and removed redundant runAs call
- PropertyFilter parsing corrected and made a shared service
- Removed replicated code from webservice getTypeDefinition implementation
- Moved association property getting into CMISServices

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19239 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2010-03-11 22:41:13 +00:00
parent 546c0fb262
commit 22ec153ed9
6 changed files with 523 additions and 11 deletions

View File

@@ -188,8 +188,10 @@ public interface CMISServices
* @param propertyName
* the property name
* @return value
* @throws CMISInvalidArgumentException
* if an argument is invalid
*/
public Serializable getProperty(AssociationRef assocRef, String propertyName);
public Serializable getProperty(AssociationRef assocRef, String propertyName) throws CMISInvalidArgumentException;
/**
* Get all properties of a node's type.
@@ -202,6 +204,17 @@ public interface CMISServices
*/
public Map<String, Serializable> getProperties(NodeRef nodeRef) throws CMISInvalidArgumentException;
/**
* Get all properties of an association's type.
*
* @param assocRef
* the association
* @return the properties
* @throws CMISInvalidArgumentException
* if an argument is invalid
*/
public Map<String, Serializable> getProperties(AssociationRef assocRef) throws CMISInvalidArgumentException;
/**
* Get all of a node's values for the properties in the given type or aspect.
*
@@ -449,6 +462,17 @@ public interface CMISServices
*/
public CMISTypeDefinition getTypeDefinition(String typeId) throws CMISInvalidArgumentException;
/**
* Gets the type definition for a given object.
*
* @param object
* the object
* @return the type definition
* @throws CMISInvalidArgumentException
* if an argument is invalid
*/
public CMISTypeDefinition getTypeDefinition(Object object) throws CMISInvalidArgumentException;
/**
* Gets the CMIS base types.
*
@@ -754,4 +778,94 @@ public interface CMISServices
InputStream contentStream, String mimeType) throws CMISConstraintException, CMISVersioningException,
CMISObjectNotFoundException, CMISContentAlreadyExistsException, CMISStreamNotSupportedException,
CMISInvalidArgumentException, CMISPermissionDeniedException;
/**
* Creates a policy object of the specified type, and optionally adds the policy to a folder. Currently no policy
* types can be created in Alfresco.
*
* @param properties
* CMIS properties
* @param folderId
* parent folder for this new policy
* @param policies
* the policies
* @return Id of the created policy object
* @throws CMISConstraintException
* if there is a problem with the supplied properties
* @throws CMISInvalidArgumentException
* if an argument is invalid
* @throws CMISRuntimeException
* on other exceptions
*/
public String createPolicy(Map<String, Serializable> properties, String folderId, List<String> policies)
throws CMISConstraintException, CMISRuntimeException, CMISInvalidArgumentException;
/**
* Applies a policy object to a target object.
*
* @param policyId
* policy Id
* @param objectId
* target object Id
* @throws CMISConstraintException
* if an object isn't of the right type
* @throws CMISVersioningException
* if an object's versioning state isn't as expected
* @throws CMISObjectNotFoundException
* if an object does not exist
* @throws CMISInvalidArgumentException
* if an argument is invalid
* @throws CMISPermissionDeniedException
* if access to an object is denied
*/
public void applyPolicy(String policyId, String objectId) throws CMISConstraintException, CMISVersioningException,
CMISObjectNotFoundException, CMISInvalidArgumentException, CMISPermissionDeniedException;
/**
* Gets the list of policy objects currently applied to a target object.
*
* @param objectId
* the object id
* @param filter
* property filter
* @return the applied policies
* @throws CMISConstraintException
* if an object isn't of the right type
* @throws CMISVersioningException
* if an object's versioning state isn't as expected
* @throws CMISObjectNotFoundException
* if an object does not exist
* @throws CMISInvalidArgumentException
* if an argument is invalid
* @throws CMISPermissionDeniedException
* if access to an object is denied
* @throws CMISFilterNotValidException
* if the property filter is invalid
*/
public List<CMISTypeDefinition> getAppliedPolicies(String objectId, String filter) throws CMISConstraintException,
CMISVersioningException, CMISObjectNotFoundException, CMISInvalidArgumentException,
CMISPermissionDeniedException, CMISFilterNotValidException;
/**
* Removes a previously applied policy from a target object. The policy object is not deleted, and may still be
* applied to other objects.
*
* @param policyId
* policy Id
* @param objectId
* target object Id.
* @throws CMISConstraintException
* if an object isn't of the right type
* @throws CMISVersioningException
* if an object's versioning state isn't as expected
* @throws CMISObjectNotFoundException
* if an object does not exist
* @throws CMISInvalidArgumentException
* if an argument is invalid
* @throws CMISPermissionDeniedException
* if access to an object is denied
*/
public void removePolicy(String policyId, String objectId) throws CMISConstraintException, CMISVersioningException,
CMISObjectNotFoundException, CMISInvalidArgumentException, CMISPermissionDeniedException;
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.cmis;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Property filter supporting CMIS filter expression
*
* @author Dmitry Lazurkin
* @author Dmitry Velichkevich
*/
public class PropertyFilter
{
public static final String MATCH_ALL_FILTER = "*";
public static final String PROPERTY_NAME_TOKENS_DELIMITER = ",";
private static final Pattern PROPERTY_FILTER_REGEX = Pattern.compile("^([^\\s,\"'\\\\\\.\\(\\)]+)(,[^\\s,\"'\\\\\\.\\(\\)]+)*$");
private Set<String> properties;
/**
* @param filter filter value (case insensitive)
* @throws FilterNotValidException if filter string isn't valid
*/
public PropertyFilter(String filter) throws CMISFilterNotValidException
{
if (filter != null)
{
if (!PROPERTY_FILTER_REGEX.matcher(filter).matches())
{
throw new CMISFilterNotValidException("Property filter \"" + filter + "\" is invalid");
}
if (!filter.equals(MATCH_ALL_FILTER))
{
String[] tokens = filter.split(PROPERTY_NAME_TOKENS_DELIMITER);
properties = new HashSet<String>(tokens.length * 2);
for (String token : tokens)
{
properties.add(token);
}
}
}
}
/**
* @param property property token name
* @return <b>true</b> returns if property is allowed by filter. In other case returns <b>false</b>
*/
public boolean allow(String property)
{
return properties == null || properties.contains(property);
}
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.cmis;
import junit.framework.TestCase;
/**
* @author Dmitry Velichkevich
*/
public class PropertyFilterTest extends TestCase
{
private static final String NAME_TOKEN = "name";
private static final String[] FILTER_TOKENS = new String[] { NAME_TOKEN, "objectId" };
private static final String[] TOKENS_THAT_ARE_NOT_ALLOWED = new String[] { "ParentId", "parentId", "ParEnTiD", "IsMajorVersion", "iSmAJORvERSION" };
private static final String VALID_MATCHE_ALL_FILTER = "*";
private static final String VALID_FILTER_WITH_NAME = NAME_TOKEN;
private static final String VALID_FILTER_WITH_SEVERAL_TOKENS = "name,objectId";
private static final String LONG_VALID_FILTER_WITH_SEVERAL_TOKENS = "objectId,name,CreationDate*,Created;By";
private static final String INVALID_MATCHE_ALL_FILTER = "*,";
private static final String INVALID_FILTER_WITH_NAME = "*name,";
private static final String INVALID_FILTER_WITH_SEVERAL_TOKENS = "name,,objectId";
private static final String LONG_INVALID_FILTER_WITH_SEVERAL_TOKENS = "objectId, name CreationDate, CreatedBy*";
private static final String INVALID_FILTER_WITH_SEVERAL_TOKENS_WITHOUT_BREAKS = ",name,objectId,CreationDate";
private static final String INVALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_BREAKS_IN_SOME_PLACES = " name, objectId,CreationDate CreatedBy ModifiedBy, LastModifiedBy";
private static final String INVALID_FILTER_WITH_FIRST_BREAK_SYMBOL = " name, objectId,CreationDate, CreatedBy, ModifiedBy, LastModifiedBy";
private static final String INVALID_FILTER_WITH_DENIED_SYMBOL = "objectId\"name";
private static final String INVALID_FILTER_WITH_LAST_INVALID_SYMBOL = "objectId,name\\";
public void testValidFilters() throws Exception
{
allTokensValidAssertion(new PropertyFilter(null));
allTokensValidAssertion(new PropertyFilter(VALID_MATCHE_ALL_FILTER));
onlyNameTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_NAME));
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS));
nameAndObjectIdTokensAssertionValid(new PropertyFilter(LONG_VALID_FILTER_WITH_SEVERAL_TOKENS));
}
public void testInvalidFilters() throws Exception
{
invalidFilterAssertion(INVALID_MATCHE_ALL_FILTER);
invalidFilterAssertion(INVALID_FILTER_WITH_NAME);
invalidFilterAssertion(INVALID_FILTER_WITH_SEVERAL_TOKENS);
invalidFilterAssertion(LONG_INVALID_FILTER_WITH_SEVERAL_TOKENS);
invalidFilterAssertion(INVALID_FILTER_WITH_SEVERAL_TOKENS_WITHOUT_BREAKS);
invalidFilterAssertion(INVALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_BREAKS_IN_SOME_PLACES);
invalidFilterAssertion(INVALID_FILTER_WITH_FIRST_BREAK_SYMBOL);
invalidFilterAssertion(INVALID_FILTER_WITH_DENIED_SYMBOL);
invalidFilterAssertion(INVALID_FILTER_WITH_LAST_INVALID_SYMBOL);
}
private void nameAndObjectIdTokensAssertionValid(PropertyFilter propertyFilter)
{
for (String token : FILTER_TOKENS)
{
assertTrue(token + " should be allowed", propertyFilter.allow(token));
}
for (String token : TOKENS_THAT_ARE_NOT_ALLOWED)
{
assertFalse(token + " should not be allowed", propertyFilter.allow(token));
}
}
private void onlyNameTokensAssertionValid(PropertyFilter propertyFilter)
{
for (String token : FILTER_TOKENS)
{
if (!token.equals(NAME_TOKEN))
{
break;
}
assertTrue(propertyFilter.allow(token));
}
for (String token : TOKENS_THAT_ARE_NOT_ALLOWED)
{
assertFalse(propertyFilter.allow(token));
}
}
private void allTokensValidAssertion(PropertyFilter propertyFilter)
{
for (String token : FILTER_TOKENS)
{
assertTrue(propertyFilter.allow(token));
}
for (String token : TOKENS_THAT_ARE_NOT_ALLOWED)
{
assertTrue(propertyFilter.allow(token));
}
}
private void invalidFilterAssertion(String filterValue)
{
try
{
new PropertyFilter(filterValue);
fail("Invalid filter \"" + filterValue + "\" was interpreted as valid");
}
catch (CMISFilterNotValidException e)
{
// Success
}
}
}

View File

@@ -232,7 +232,7 @@ public class CMISMapping implements InitializingBean
registerEvaluator(CMISScope.DOCUMENT, new ParentActionEvaluator(new FixedValueActionEvaluator<NodeRef>(serviceRegistry, CMISAllowedActionEnum.CAN_REMOVE_OBJECT_FROM_FOLDER, true)));
registerEvaluator(CMISScope.DOCUMENT, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_CONTENT_STREAM, PermissionService.READ_CONTENT));
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator<NodeRef>(serviceRegistry, CMISAllowedActionEnum.CAN_APPLY_POLICY, false));
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator<NodeRef>(serviceRegistry, CMISAllowedActionEnum.CAN_GET_APPLIED_POLICIES, false));
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator<NodeRef>(serviceRegistry, CMISAllowedActionEnum.CAN_GET_APPLIED_POLICIES, true));
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator<NodeRef>(serviceRegistry, CMISAllowedActionEnum.CAN_REMOVE_POLICY, false));
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator<NodeRef>(serviceRegistry, CMISAllowedActionEnum.CAN_CREATE_RELATIONSHIP, true));
registerEvaluator(CMISScope.DOCUMENT, new FixedValueActionEvaluator<NodeRef>(serviceRegistry, CMISAllowedActionEnum.CAN_GET_RENDITIONS, true));
@@ -250,7 +250,7 @@ public class CMISMapping implements InitializingBean
// Is CAN_MOVE_OBJECT correct mapping?
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_MOVE_OBJECT, PermissionService.DELETE_NODE));
registerEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator<NodeRef>(serviceRegistry, CMISAllowedActionEnum.CAN_APPLY_POLICY, false));
registerEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator<NodeRef>(serviceRegistry, CMISAllowedActionEnum.CAN_GET_APPLIED_POLICIES, false));
registerEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator<NodeRef>(serviceRegistry, CMISAllowedActionEnum.CAN_GET_APPLIED_POLICIES, true));
registerEvaluator(CMISScope.FOLDER, new FixedValueActionEvaluator<NodeRef>(serviceRegistry, CMISAllowedActionEnum.CAN_REMOVE_POLICY, false));
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_GET_CHILDREN, PermissionService.READ_CHILDREN));
registerEvaluator(CMISScope.FOLDER, new PermissionActionEvaluator(serviceRegistry, CMISAllowedActionEnum.CAN_CREATE_DOCUMENT, PermissionService.CREATE_CHILDREN));

View File

@@ -60,6 +60,7 @@ import org.alfresco.cmis.CMISTypesFilterEnum;
import org.alfresco.cmis.CMISUpdatabilityEnum;
import org.alfresco.cmis.CMISVersioningException;
import org.alfresco.cmis.CMISVersioningStateEnum;
import org.alfresco.cmis.PropertyFilter;
import org.alfresco.cmis.dictionary.CMISFolderTypeDefinition;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
@@ -778,6 +779,27 @@ public class CMISServicesImpl implements CMISServices, ApplicationContextAware,
return typeDef;
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.CMISServices#getTypeDefinition(java.lang.Object)
*/
public CMISTypeDefinition getTypeDefinition(Object object) throws CMISInvalidArgumentException
{
if (object instanceof Version)
{
return getTypeDefinition(((Version) object).getFrozenStateNodeRef());
}
else if (object instanceof NodeRef)
{
return getTypeDefinition((NodeRef) object);
}
else if (object instanceof AssociationRef)
{
return getTypeDefinition((AssociationRef) object);
}
throw new CMISInvalidArgumentException("Invalid type " + object.getClass());
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.CMISServices#getBaseTypes()
@@ -789,16 +811,12 @@ public class CMISServicesImpl implements CMISServices, ApplicationContextAware,
/*
* (non-Javadoc)
* @see org.alfresco.cmis.CMISServices#getProperty(org.alfresco.service.cmr.repository.AssociationRef, java.lang.String)
* @see org.alfresco.cmis.CMISServices#getProperty(org.alfresco.service.cmr.repository.AssociationRef,
* java.lang.String)
*/
public Serializable getProperty(AssociationRef assocRef, String propertyName)
public Serializable getProperty(AssociationRef assocRef, String propertyName) throws CMISInvalidArgumentException
{
QName typeQName = assocRef.getTypeQName();
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForClass(typeQName);
if (typeDef == null)
{
throw new AlfrescoRuntimeException("Relationship Type " + typeQName + " not found in CMIS Dictionary");
}
CMISTypeDefinition typeDef = getTypeDefinition(assocRef);
CMISPropertyDefinition propDef = cmisDictionaryService.findProperty(propertyName, typeDef);
if (propDef == null)
{
@@ -817,6 +835,22 @@ public class CMISServicesImpl implements CMISServices, ApplicationContextAware,
return getProperties(nodeRef, getTypeDefinition(nodeRef));
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.CMISServices#getProperties(org.alfresco.service.cmr.repository.AssociationRef)
*/
public Map<String, Serializable> getProperties(AssociationRef assocRef) throws CMISInvalidArgumentException
{
CMISTypeDefinition typeDef = getTypeDefinition(assocRef);
Map<String, CMISPropertyDefinition> propDefs = typeDef.getPropertyDefinitions();
Map<String, Serializable> values = new HashMap<String, Serializable>(propDefs.size() * 2);
for (CMISPropertyDefinition propDef : propDefs.values())
{
values.put(propDef.getPropertyId().getId(), propDef.getPropertyAccessor().getValue(assocRef));
}
return values;
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.CMISServices#getProperties(org.alfresco.service.cmr.repository.NodeRef,
@@ -1193,6 +1227,10 @@ public class CMISServicesImpl implements CMISServices, ApplicationContextAware,
return (T) associationRef;
}
}
else
{
throw new CMISInvalidArgumentException(objectId + " is not an object ID");
}
}
catch (AccessDeniedException e)
{
@@ -1728,6 +1766,81 @@ public class CMISServicesImpl implements CMISServices, ApplicationContextAware,
}
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.CMISServices#createPolicy(java.util.Map, java.lang.String, java.util.List)
*/
public String createPolicy(Map<String, Serializable> properties, String folderId, List<String> policies)
throws CMISConstraintException, CMISRuntimeException, CMISInvalidArgumentException
{
String typeId = (String) properties.get(CMISDictionaryModel.PROP_OBJECT_TYPE_ID);
if (typeId == null)
{
throw new CMISConstraintException("Policy type ID not specified");
}
CMISTypeDefinition typeDefinition = getTypeDefinition(typeId);
if (typeDefinition.getBaseType().getTypeId() != CMISDictionaryModel.POLICY_TYPE_ID)
{
throw new CMISConstraintException(typeId + " is not a policy type");
}
if (!typeDefinition.isCreatable())
{
throw new CMISConstraintException(typeId + " is not a creatable type");
}
// Should never get here, as currently no policy types are creatable
throw new CMISRuntimeException("Internal error");
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.CMISServices#applyPolicy(java.lang.String, java.lang.String)
*/
public void applyPolicy(String policyId, String objectId) throws CMISConstraintException, CMISVersioningException,
CMISObjectNotFoundException, CMISInvalidArgumentException, CMISPermissionDeniedException
{
CMISTypeDefinition typeDef = getTypeDefinition(getReadableObject(objectId, Object.class));
if (!typeDef.isControllablePolicy())
{
throw new CMISConstraintException("Type " + typeDef.getTypeId().getId() + " does not allow policies to be applied");
}
getReadableObject(policyId, CMISTypeDefinition.class);
// Expect exception to be throw by now
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.CMISServices#getAppliedPolicies(java.lang.String, java.lang.String)
*/
public List<CMISTypeDefinition> getAppliedPolicies(String objectId, String filter) throws CMISConstraintException,
CMISVersioningException, CMISObjectNotFoundException, CMISInvalidArgumentException,
CMISPermissionDeniedException, CMISFilterNotValidException
{
// Get the object
getReadableObject(objectId, Object.class);
// Parse the filter
new PropertyFilter(filter);
// Nothing else to do
return Collections.emptyList();
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.CMISServices#removePolicy(java.lang.String, java.lang.String)
*/
public void removePolicy(String policyId, String objectId) throws CMISConstraintException, CMISVersioningException,
CMISObjectNotFoundException, CMISInvalidArgumentException, CMISPermissionDeniedException
{
CMISTypeDefinition typeDef = getTypeDefinition(getReadableObject(objectId, Object.class));
if (!typeDef.isControllablePolicy())
{
throw new CMISConstraintException("Type " + typeDef.getTypeId().getId() + " does not allow policies to be applied");
}
getReadableObject(policyId, CMISTypeDefinition.class);
// Expect exception to be throw by now
}
/**
* Validates that a node is versionable.
*

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.transaction;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.transaction.TransactionService;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.interceptor.TransactionAttribute;
/**
* @author Dmitry Velichkevich
*/
public class RetryingTransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor
{
private TransactionService transactionService;
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
public Object invoke(final MethodInvocation target) throws Throwable
{
if ((null != target) && (null != target.getThis()) && (null != target.getMethod()))
{
final Method method = target.getMethod();
final TransactionAttribute transactionAttribute = getTransactionAttributeSource().getTransactionAttribute(method, target.getThis().getClass());
if (null != transactionAttribute)
{
return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Object>()
{
public Object execute() throws Throwable
{
try
{
return method.invoke(target.getThis(), target.getArguments());
}
catch (InvocationTargetException e)
{
if (null != e.getTargetException())
{
throw e.getTargetException();
}
else
{
throw new AlfrescoRuntimeException(e.getMessage(), e);
}
}
}
}, transactionAttribute.isReadOnly(), (TransactionAttribute.PROPAGATION_REQUIRES_NEW == transactionAttribute.getPropagationBehavior()));
}
else
{
return method.invoke(target.getThis(), target.getArguments());
}
}
throw new AlfrescoRuntimeException("Invalid undefined MethodInvocation instance");
}
}