mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
RM-1635: Recordable Version Store Service Prototype (WIP)
* extended version service implementation that can use the file plan as an alternative version store, thus recording versions * extended version node service implementation that can retrieve recorded version information from the file plan (rather than the version frozen state) (properties only atm) * recordable version model including recorded version information and versionable aspect extension with auto recordable version policy defined * Recordable version service unit tests * Simple AdHoc recorded version integration test (shows recorded created and frozen property state recovered via file plan record) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@80223 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,79 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!-- Recordable Version Model -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- @since 2.3 -->
|
||||||
|
<!-- @author Roy Wetherall -->
|
||||||
|
|
||||||
|
<!-- Note: the rma: namespace is defined further on in the document -->
|
||||||
|
<model name="rmv:recordableVersion" xmlns="http://www.alfresco.org/model/dictionary/1.0">
|
||||||
|
|
||||||
|
<description>Recordable Version Model</description>
|
||||||
|
<author>Roy Wetherall</author>
|
||||||
|
<version>1.0</version>
|
||||||
|
|
||||||
|
<imports>
|
||||||
|
<!-- Import Alfresco Dictionary Definitions -->
|
||||||
|
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
|
||||||
|
<!-- Import Alfresco Content Domain Model Definitions -->
|
||||||
|
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
|
||||||
|
<!-- Import Alfresco Content Domain Model Definitions -->
|
||||||
|
<import uri="http://www.alfresco.org/model/system/1.0" prefix="sys" />
|
||||||
|
<!-- Import Alfresco Site Model Definitions -->
|
||||||
|
<import uri="http://www.alfresco.org/model/site/1.0" prefix="st"/>
|
||||||
|
<!-- Import Alfresco RM Model Definitions -->
|
||||||
|
<import uri="http://www.alfresco.org/model/recordsmanagement/1.0" prefix="rma"/>
|
||||||
|
</imports>
|
||||||
|
|
||||||
|
<namespaces>
|
||||||
|
<namespace uri="http://www.alfresco.org/model/recordableversion/1.0" prefix="rmv"/>
|
||||||
|
</namespaces>
|
||||||
|
|
||||||
|
<constraints>
|
||||||
|
<constraint name="rmv:recordableVersionPolicyList" type="LIST">
|
||||||
|
<title>Recordable Version Policy List</title>
|
||||||
|
<parameter name="allowedValues">
|
||||||
|
<list>
|
||||||
|
<value>NONE</value>
|
||||||
|
<value>MAJOR_ONLY</value>
|
||||||
|
<value>ALL</value>
|
||||||
|
</list>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="caseSensitive"><value>false</value></parameter>
|
||||||
|
</constraint>
|
||||||
|
</constraints>
|
||||||
|
|
||||||
|
<aspects>
|
||||||
|
|
||||||
|
<aspect name="rmv:versionable">
|
||||||
|
<properties>
|
||||||
|
<property name="rmv:filePlan">
|
||||||
|
<title>File Plan</title>
|
||||||
|
<type>d:noderef</type>
|
||||||
|
<index enabled="false"/>
|
||||||
|
</property>
|
||||||
|
<property name="rmv:recordableVersionPolicy">
|
||||||
|
<title>Recordable Version Policy</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
<default>disabled</default>
|
||||||
|
<index enabled="false"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint ref="rmv:recordableVersionPolicyList" />
|
||||||
|
</constraints>
|
||||||
|
</property>
|
||||||
|
</properties>
|
||||||
|
</aspect>
|
||||||
|
|
||||||
|
<aspect name="rmv:recordedVersion">
|
||||||
|
<properties>
|
||||||
|
<property name="rmv:recordNodeRef">
|
||||||
|
<title>Record Node Reference</title>
|
||||||
|
<type>d:noderef</type>
|
||||||
|
<index enabled="false"/>
|
||||||
|
</property>
|
||||||
|
</properties>
|
||||||
|
</aspect>
|
||||||
|
|
||||||
|
</aspects>
|
||||||
|
|
||||||
|
</model>
|
@@ -115,8 +115,11 @@
|
|||||||
<!-- Import workflows -->
|
<!-- Import workflows -->
|
||||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-workflow-context.xml"/>
|
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-workflow-context.xml"/>
|
||||||
|
|
||||||
<!-- Import record service -->
|
<!-- Import report service -->
|
||||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-report-context.xml"/>
|
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-report-context.xml"/>
|
||||||
|
|
||||||
|
<!-- Import recordable version services -->
|
||||||
|
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-version-context.xml"/>
|
||||||
|
|
||||||
<!-- RM Script API -->
|
<!-- RM Script API -->
|
||||||
|
|
||||||
|
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||||
|
|
||||||
|
<beans>
|
||||||
|
|
||||||
|
<!-- Recordable Version Model -->
|
||||||
|
<bean id="org_alfresco_module_rm_version_dictionaryBootstrap" parent="dictionaryModelBootstrap">
|
||||||
|
<property name="models">
|
||||||
|
<list>
|
||||||
|
<value>alfresco/module/org_alfresco_module_rm/model/recordableVersionModel.xml</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- extended version service bean definition -->
|
||||||
|
<bean id="rm.versionService" abstract="true" class="org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImpl">
|
||||||
|
<property name="filePlanService" ref="FilePlanService" />
|
||||||
|
<property name="fileFolderService" ref="fileFolderService" />
|
||||||
|
</bean>
|
||||||
|
<bean class="org.alfresco.module.org_alfresco_module_rm.util.BeanExtender">
|
||||||
|
<property name="beanName" value="versionService" />
|
||||||
|
<property name="extendingBeanName" value="rm.versionService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- extended version node service bean definition -->
|
||||||
|
<bean id="rm.versionNodeService" abstract="true" class="org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionNodeServiceImpl">
|
||||||
|
</bean>
|
||||||
|
<bean class="org.alfresco.module.org_alfresco_module_rm.util.BeanExtender">
|
||||||
|
<property name="beanName" value="versionNodeService" />
|
||||||
|
<property name="extendingBeanName" value="rm.versionNodeService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
@@ -252,6 +252,12 @@
|
|||||||
<version>0.1-incubating-unreleased</version>
|
<version>0.1-incubating-unreleased</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.myfaces.core</groupId>
|
||||||
|
<artifactId>myfaces-api</artifactId>
|
||||||
|
<version>2.1.9</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<!-- Database drivers -->
|
<!-- Database drivers -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>postgresql</groupId>
|
<groupId>postgresql</groupId>
|
||||||
|
@@ -35,7 +35,6 @@ import net.sf.acegisecurity.ConfigAttributeDefinition;
|
|||||||
import net.sf.acegisecurity.afterinvocation.AfterInvocationProvider;
|
import net.sf.acegisecurity.afterinvocation.AfterInvocationProvider;
|
||||||
import net.sf.acegisecurity.vote.AccessDecisionVoter;
|
import net.sf.acegisecurity.vote.AccessDecisionVoter;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
import org.alfresco.repo.search.SimpleResultSetMetaData;
|
import org.alfresco.repo.search.SimpleResultSetMetaData;
|
||||||
import org.alfresco.repo.search.impl.lucene.PagingLuceneResultSet;
|
import org.alfresco.repo.search.impl.lucene.PagingLuceneResultSet;
|
||||||
@@ -43,19 +42,17 @@ import org.alfresco.repo.search.impl.querymodel.QueryEngineResults;
|
|||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.permissions.PermissionCheckCollection;
|
import org.alfresco.repo.security.permissions.PermissionCheckCollection;
|
||||||
import org.alfresco.repo.security.permissions.PermissionCheckValue;
|
import org.alfresco.repo.security.permissions.PermissionCheckValue;
|
||||||
import org.alfresco.repo.security.permissions.PermissionCheckedValue;
|
|
||||||
import org.alfresco.repo.security.permissions.PermissionCheckedCollection.PermissionCheckedCollectionMixin;
|
import org.alfresco.repo.security.permissions.PermissionCheckedCollection.PermissionCheckedCollectionMixin;
|
||||||
|
import org.alfresco.repo.security.permissions.PermissionCheckedValue;
|
||||||
import org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterException;
|
import org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterException;
|
||||||
import org.alfresco.repo.security.permissions.impl.acegi.FilteringResultSet;
|
import org.alfresco.repo.security.permissions.impl.acegi.FilteringResultSet;
|
||||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
|
||||||
import org.alfresco.service.cmr.search.LimitBy;
|
import org.alfresco.service.cmr.search.LimitBy;
|
||||||
import org.alfresco.service.cmr.search.PermissionEvaluationMode;
|
import org.alfresco.service.cmr.search.PermissionEvaluationMode;
|
||||||
import org.alfresco.service.cmr.search.ResultSet;
|
import org.alfresco.service.cmr.search.ResultSet;
|
||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
|
||||||
import org.aopalliance.intercept.MethodInvocation;
|
import org.aopalliance.intercept.MethodInvocation;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 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.module.org_alfresco_module_rm.version;
|
||||||
|
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class containing recordable version model qualified names
|
||||||
|
*
|
||||||
|
* @author Roy Wetherall
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public interface RecordableVersionModel
|
||||||
|
{
|
||||||
|
/** Namespace details */
|
||||||
|
String RMV_URI = "http://www.alfresco.org/model/recordableversion/1.0";
|
||||||
|
String RMV_PREFIX = "rmv";
|
||||||
|
|
||||||
|
/** versionable aspect */
|
||||||
|
public QName ASPECT_VERSIONABLE = QName.createQName(RMV_URI, "versionable");
|
||||||
|
public QName PROP_RECORDABLE_VERSION_POLICY = QName.createQName(RMV_URI, "recordableVersionPolicy");
|
||||||
|
public QName PROP_FILE_PLAN = QName.createQName(RMV_URI, "filePlan");
|
||||||
|
|
||||||
|
/** recorded version aspect */
|
||||||
|
public QName ASPECT_RECORDED_VERSION = QName.createQName(RMV_URI, "recordedVersion");
|
||||||
|
public QName PROP_RECORD_NODE_REF = QName.createQName(RMV_URI, "recordNodeRef");
|
||||||
|
}
|
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 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.module.org_alfresco_module_rm.version;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
|
import org.alfresco.repo.version.Node2ServiceImpl;
|
||||||
|
import org.alfresco.repo.version.common.VersionUtil;
|
||||||
|
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Roy Wetherall
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl
|
||||||
|
implements RecordableVersionModel
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<QName, Serializable> getProperties(NodeRef nodeRef) throws InvalidNodeRefException
|
||||||
|
{
|
||||||
|
NodeRef converted = VersionUtil.convertNodeRef(nodeRef);
|
||||||
|
if (dbNodeService.hasAspect(converted, ASPECT_RECORDED_VERSION))
|
||||||
|
{
|
||||||
|
NodeRef record = (NodeRef)dbNodeService.getProperty(converted, PROP_RECORD_NODE_REF);
|
||||||
|
Map<QName, Serializable> properties = dbNodeService.getProperties(record);
|
||||||
|
return processProperties(properties);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return super.getProperties(nodeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<QName, Serializable> processProperties(Map<QName, Serializable> properties)
|
||||||
|
{
|
||||||
|
// revert modified record name
|
||||||
|
properties.put(ContentModel.PROP_NAME, properties.get(RecordsManagementModel.PROP_ORIGIONAL_NAME));
|
||||||
|
|
||||||
|
// remove all rma, rmc, rmr and rmv properties
|
||||||
|
|
||||||
|
// remove any properties relating to custom record-meta data
|
||||||
|
|
||||||
|
// do standard property processing
|
||||||
|
VersionUtil.convertFrozenToOriginalProps(properties);
|
||||||
|
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 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.module.org_alfresco_module_rm.version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roy Wetherall
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public enum RecordableVersionPolicy
|
||||||
|
{
|
||||||
|
NONE,
|
||||||
|
MAJOR_ONLY,
|
||||||
|
ALL
|
||||||
|
}
|
@@ -0,0 +1,334 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 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.module.org_alfresco_module_rm.version;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
||||||
|
import org.alfresco.repo.policy.PolicyScope;
|
||||||
|
import org.alfresco.repo.version.Version2Model;
|
||||||
|
import org.alfresco.repo.version.Version2ServiceImpl;
|
||||||
|
import org.alfresco.repo.version.VersionModel;
|
||||||
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
|
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.version.ReservedVersionNameException;
|
||||||
|
import org.alfresco.service.cmr.version.Version;
|
||||||
|
import org.alfresco.service.cmr.version.VersionType;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recordable version service implementation
|
||||||
|
*
|
||||||
|
* @author Roy Wetherall
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public class RecordableVersionServiceImpl extends Version2ServiceImpl
|
||||||
|
implements RecordableVersionModel
|
||||||
|
{
|
||||||
|
/** share logger with version2ServiceImpl */
|
||||||
|
private static Log logger = LogFactory.getLog(Version2ServiceImpl.class);
|
||||||
|
|
||||||
|
/** key used to indicate a recordable version */
|
||||||
|
public static final String KEY_RECORDABLE_VERSION = "recordable-version";
|
||||||
|
public static final String KEY_FILE_PLAN = "file-plan";
|
||||||
|
|
||||||
|
/** file plan service */
|
||||||
|
protected FilePlanService filePlanService;
|
||||||
|
|
||||||
|
/** file folder service */
|
||||||
|
protected FileFolderService fileFolderService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param filePlanService file plan service
|
||||||
|
*/
|
||||||
|
public void setFilePlanService(FilePlanService filePlanService)
|
||||||
|
{
|
||||||
|
this.filePlanService = filePlanService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fileFolderService file folder service
|
||||||
|
*/
|
||||||
|
public void setFileFolderService(FileFolderService fileFolderService)
|
||||||
|
{
|
||||||
|
this.fileFolderService = fileFolderService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.repo.version.Version2ServiceImpl#createVersion(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Version createVersion(NodeRef nodeRef, Map<String, Serializable> origVersionProperties, int versionNumber) throws ReservedVersionNameException
|
||||||
|
{
|
||||||
|
// TODO we only support recorded versions for sub types of cm:content
|
||||||
|
|
||||||
|
// create version properties if null
|
||||||
|
if (origVersionProperties == null)
|
||||||
|
{
|
||||||
|
origVersionProperties = new HashMap<String, Serializable>(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// only need to check the recordable version policy when the recordable version indicator is missing from the version properties
|
||||||
|
if (!origVersionProperties.containsKey(KEY_RECORDABLE_VERSION))
|
||||||
|
{
|
||||||
|
// get the version type
|
||||||
|
VersionType versionType = null;
|
||||||
|
if (origVersionProperties != null)
|
||||||
|
{
|
||||||
|
versionType = (VersionType)origVersionProperties.get(VersionModel.PROP_VERSION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine whether this is a recorded version or not
|
||||||
|
if (isCreateRecordedVersion(nodeRef, versionType))
|
||||||
|
{
|
||||||
|
origVersionProperties.put(KEY_RECORDABLE_VERSION, true);
|
||||||
|
if (!origVersionProperties.containsKey(KEY_FILE_PLAN))
|
||||||
|
{
|
||||||
|
// make sure the file plan is set to the default if not specified
|
||||||
|
origVersionProperties.put(KEY_FILE_PLAN, getFilePlan(nodeRef));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!origVersionProperties.containsKey(KEY_FILE_PLAN))
|
||||||
|
{
|
||||||
|
// make sure the file plan is set to the default if not specified
|
||||||
|
origVersionProperties.put(KEY_FILE_PLAN, getFilePlan(nodeRef));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.createVersion(nodeRef, origVersionProperties, versionNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param nodeRef
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private NodeRef getFilePlan(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
NodeRef filePlan = (NodeRef)nodeService.getProperty(nodeRef, PROP_FILE_PLAN);
|
||||||
|
if (filePlan == null)
|
||||||
|
{
|
||||||
|
filePlan = getFilePlan();
|
||||||
|
}
|
||||||
|
return filePlan;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private NodeRef getFilePlan()
|
||||||
|
{
|
||||||
|
NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
|
||||||
|
if (filePlan == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Can't create a recorded version, because there is no file plan.");
|
||||||
|
}
|
||||||
|
return filePlan;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether this is a recorded version or not.
|
||||||
|
*
|
||||||
|
* @param nodeRef
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isCreateRecordedVersion(NodeRef nodeRef, VersionType versionType)
|
||||||
|
{
|
||||||
|
boolean result = false;
|
||||||
|
if (nodeService.hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE))
|
||||||
|
{
|
||||||
|
String policyString = (String)nodeService.getProperty(nodeRef, PROP_RECORDABLE_VERSION_POLICY);
|
||||||
|
if (policyString != null)
|
||||||
|
{
|
||||||
|
RecordableVersionPolicy policy = RecordableVersionPolicy.valueOf(policyString.toUpperCase());
|
||||||
|
if (RecordableVersionPolicy.ALL.equals(policy) ||
|
||||||
|
(RecordableVersionPolicy.MAJOR_ONLY.equals(policy) &&
|
||||||
|
VersionType.MAJOR.equals(versionType)))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.repo.version.Version2ServiceImpl#createNewVersion(org.alfresco.service.namespace.QName, org.alfresco.service.cmr.repository.NodeRef, java.util.Map, java.util.Map, int, org.alfresco.repo.policy.PolicyScope)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected NodeRef createNewVersion( QName sourceTypeRef,
|
||||||
|
NodeRef versionHistoryRef,
|
||||||
|
Map<QName, Serializable> standardVersionProperties,
|
||||||
|
Map<String, Serializable> versionProperties,
|
||||||
|
int versionNumber,
|
||||||
|
PolicyScope nodeDetails)
|
||||||
|
{
|
||||||
|
NodeRef version = null;
|
||||||
|
|
||||||
|
if (versionProperties.containsKey(KEY_RECORDABLE_VERSION) &&
|
||||||
|
((Boolean)versionProperties.get(KEY_RECORDABLE_VERSION)).booleanValue())
|
||||||
|
{
|
||||||
|
// create a recorded version
|
||||||
|
version = createNewRecordedVersion(sourceTypeRef, versionHistoryRef, standardVersionProperties, versionProperties, versionNumber, nodeDetails);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// create a normal version
|
||||||
|
version = super.createNewVersion(sourceTypeRef, versionHistoryRef, standardVersionProperties, versionProperties, versionNumber, nodeDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param sourceTypeRef
|
||||||
|
* @param versionHistoryRef
|
||||||
|
* @param standardVersionProperties
|
||||||
|
* @param versionProperties
|
||||||
|
* @param versionNumber
|
||||||
|
* @param nodeDetails
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected NodeRef createNewRecordedVersion(QName sourceTypeRef,
|
||||||
|
NodeRef versionHistoryRef,
|
||||||
|
Map<QName, Serializable> standardVersionProperties,
|
||||||
|
Map<String, Serializable> versionProperties,
|
||||||
|
int versionNumber,
|
||||||
|
PolicyScope nodeDetails)
|
||||||
|
{
|
||||||
|
NodeRef versionNodeRef = null;
|
||||||
|
|
||||||
|
// Disable auto-version behaviour
|
||||||
|
policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_VERSIONABLE);
|
||||||
|
|
||||||
|
// disable other behaviours that we don't want to trigger during this process
|
||||||
|
policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT);
|
||||||
|
policyBehaviourFilter.disableBehaviour(ContentModel.TYPE_MULTILINGUAL_CONTAINER);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// get the destination file plan
|
||||||
|
NodeRef filePlan = (NodeRef)versionProperties.get(KEY_FILE_PLAN);
|
||||||
|
if (filePlan == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Can't create a new recorded version, because no file plan has been specified in the version properties.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the unfiled record folder
|
||||||
|
final NodeRef unfiledRecordFolder = filePlanService.getUnfiledContainer(filePlan);
|
||||||
|
|
||||||
|
// create a copy of the source node and place in the file plan
|
||||||
|
final NodeRef nodeRef = (NodeRef)standardVersionProperties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF);
|
||||||
|
|
||||||
|
// copy version state and create record
|
||||||
|
NodeRef record = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileInfo recordInfo = fileFolderService.copy(nodeRef, unfiledRecordFolder, null);
|
||||||
|
record = recordInfo.getNodeRef();
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Can't create recorded version, because copy fails.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up extended permissions
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
// create version nodeRef
|
||||||
|
ChildAssociationRef childAssocRef = this.dbNodeService.createNode(
|
||||||
|
versionHistoryRef,
|
||||||
|
Version2Model.CHILD_QNAME_VERSIONS,
|
||||||
|
QName.createQName(Version2Model.NAMESPACE_URI, Version2Model.CHILD_VERSIONS + "-" + versionNumber), // TODO - testing - note: all children (of a versioned node) will have the same version number, maybe replace with a version sequence of some sort 001-...00n
|
||||||
|
sourceTypeRef,
|
||||||
|
null);
|
||||||
|
versionNodeRef = childAssocRef.getChildRef();
|
||||||
|
|
||||||
|
// NOTE: special ML case - see also MultilingualContentServiceImpl.makeMLContainer
|
||||||
|
// if (sourceTypeRef.equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER))
|
||||||
|
// {
|
||||||
|
// // Set the permissions to allow anything by anyone
|
||||||
|
// permissionService.setPermission(
|
||||||
|
// versionNodeRef,
|
||||||
|
// PermissionService.ALL_AUTHORITIES,
|
||||||
|
// PermissionService.ALL_PERMISSIONS, true);
|
||||||
|
// permissionService.setPermission(
|
||||||
|
// versionNodeRef,
|
||||||
|
// AuthenticationUtil.getGuestUserName(),
|
||||||
|
// PermissionService.ALL_PERMISSIONS, true);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// add aspect with the standard version properties to the 'version' node
|
||||||
|
nodeService.addAspect(versionNodeRef, Version2Model.ASPECT_VERSION, standardVersionProperties);
|
||||||
|
|
||||||
|
// add the recordedVersion aspect with link to record
|
||||||
|
nodeService.addAspect(versionNodeRef, ASPECT_RECORDED_VERSION, Collections.singletonMap(PROP_RECORD_NODE_REF, (Serializable)record));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Enable behaviours
|
||||||
|
this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_VERSIONABLE);
|
||||||
|
this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT);
|
||||||
|
this.policyBehaviourFilter.enableBehaviour(ContentModel.TYPE_MULTILINGUAL_CONTAINER);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the auditable aspect is not there then add it to the 'version' node (after original aspects have been frozen)
|
||||||
|
if (dbNodeService.hasAspect(versionNodeRef, ContentModel.ASPECT_AUDITABLE) == false)
|
||||||
|
{
|
||||||
|
dbNodeService.addAspect(versionNodeRef, ContentModel.ASPECT_AUDITABLE, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isTraceEnabled())
|
||||||
|
{
|
||||||
|
logger.trace("createNewRecordedVersion created (" + versionNumber + ") " + versionNodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
return versionNodeRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Version getVersion(NodeRef versionRef)
|
||||||
|
{
|
||||||
|
Version version = super.getVersion(versionRef);
|
||||||
|
|
||||||
|
NodeRef record = (NodeRef)dbNodeService.getProperty(versionRef, PROP_RECORD_NODE_REF);
|
||||||
|
if (record != null)
|
||||||
|
{
|
||||||
|
version.getVersionProperties().put("RecordVersion", record);
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
}
|
@@ -27,6 +27,7 @@ import org.alfresco.module.org_alfresco_module_rm.test.integration.job.JobTestSu
|
|||||||
import org.alfresco.module.org_alfresco_module_rm.test.integration.record.RecordTestSuite;
|
import org.alfresco.module.org_alfresco_module_rm.test.integration.record.RecordTestSuite;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.test.integration.recordfolder.RecordFolderTestSuite;
|
import org.alfresco.module.org_alfresco_module_rm.test.integration.recordfolder.RecordFolderTestSuite;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.test.integration.report.ReportTestSuite;
|
import org.alfresco.module.org_alfresco_module_rm.test.integration.report.ReportTestSuite;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.test.integration.version.VersionTestSuite;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Suite;
|
import org.junit.runners.Suite;
|
||||||
import org.junit.runners.Suite.SuiteClasses;
|
import org.junit.runners.Suite.SuiteClasses;
|
||||||
@@ -49,7 +50,8 @@ import org.junit.runners.Suite.SuiteClasses;
|
|||||||
RecordTestSuite.class,
|
RecordTestSuite.class,
|
||||||
RecordFolderTestSuite.class,
|
RecordFolderTestSuite.class,
|
||||||
JobTestSuite.class,
|
JobTestSuite.class,
|
||||||
HoldTestSuite.class
|
HoldTestSuite.class,
|
||||||
|
VersionTestSuite.class
|
||||||
})
|
})
|
||||||
public class IntegrationTestSuite
|
public class IntegrationTestSuite
|
||||||
{
|
{
|
||||||
|
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 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.module.org_alfresco_module_rm.test.integration.version;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImpl;
|
||||||
|
import org.alfresco.repo.version.VersionModel;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.version.Version;
|
||||||
|
import org.alfresco.service.cmr.version.VersionType;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.util.PropertyMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Roy Wetherall
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public class AdHocRecordableVersions extends BaseRMTestCase implements RecordableVersionModel
|
||||||
|
{
|
||||||
|
private static final QName QNAME_PUBLISHER = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "publisher");
|
||||||
|
private static final QName QNAME_SUBJECT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "subject");
|
||||||
|
|
||||||
|
private static final String DESCRIPTION = "description";
|
||||||
|
private static final String PUBLISHER = "publisher";
|
||||||
|
private static final String SUBJECT = "subject";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isCollaborationSiteTest()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRecordAdHocVersionNoPolicy()
|
||||||
|
{
|
||||||
|
doBehaviourDrivenTest(new BehaviourDrivenTest()
|
||||||
|
{
|
||||||
|
private Version version;
|
||||||
|
private Map<String, Serializable> versionProperties;
|
||||||
|
|
||||||
|
public void given() throws Exception
|
||||||
|
{
|
||||||
|
// add Dublin core aspect
|
||||||
|
PropertyMap dublinCoreProperties = new PropertyMap(2);
|
||||||
|
dublinCoreProperties.put(QNAME_PUBLISHER, PUBLISHER);
|
||||||
|
dublinCoreProperties.put(QNAME_SUBJECT, SUBJECT);
|
||||||
|
nodeService.addAspect(documentLibrary, ContentModel.ASPECT_DUBLINCORE, dublinCoreProperties);
|
||||||
|
|
||||||
|
// setup version properties
|
||||||
|
versionProperties = new HashMap<String, Serializable>(4);
|
||||||
|
versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||||
|
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
|
||||||
|
versionProperties.put(RecordableVersionServiceImpl.KEY_FILE_PLAN, filePlan);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void when()
|
||||||
|
{
|
||||||
|
// create version
|
||||||
|
version = versionService.createVersion(dmDocument, versionProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void then()
|
||||||
|
{
|
||||||
|
// version has been created
|
||||||
|
assertNotNull(version);
|
||||||
|
|
||||||
|
// check the version properties
|
||||||
|
assertEquals(DESCRIPTION, version.getDescription());
|
||||||
|
assertEquals("0.1", version.getVersionLabel());
|
||||||
|
|
||||||
|
assertEquals(NAME_DM_DOCUMENT, nodeService.getProperty(dmDocument, ContentModel.PROP_NAME));
|
||||||
|
|
||||||
|
NodeRef frozen = version.getFrozenStateNodeRef();
|
||||||
|
assertEquals(NAME_DM_DOCUMENT, nodeService.getProperty(frozen, ContentModel.PROP_NAME));
|
||||||
|
|
||||||
|
// record version node reference is available on version
|
||||||
|
NodeRef record = (NodeRef)version.getVersionProperties().get("RecordVersion");
|
||||||
|
assertNotNull(record);
|
||||||
|
|
||||||
|
// record version is an unfiled record
|
||||||
|
assertTrue(recordService.isRecord(record));
|
||||||
|
assertFalse(recordService.isFiled(record));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 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.module.org_alfresco_module_rm.test.integration.version;
|
||||||
|
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Suite;
|
||||||
|
import org.junit.runners.Suite.SuiteClasses;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recordable Version Test Suite
|
||||||
|
*
|
||||||
|
* @author Roy Wetherall
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
@RunWith(Suite.class)
|
||||||
|
@SuiteClasses(
|
||||||
|
{
|
||||||
|
AdHocRecordableVersions.class
|
||||||
|
})
|
||||||
|
public class VersionTestSuite
|
||||||
|
{
|
||||||
|
}
|
@@ -7,7 +7,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
|
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
|
||||||
|
@@ -72,6 +72,7 @@ import org.alfresco.service.cmr.site.SiteInfo;
|
|||||||
import org.alfresco.service.cmr.site.SiteService;
|
import org.alfresco.service.cmr.site.SiteService;
|
||||||
import org.alfresco.service.cmr.site.SiteVisibility;
|
import org.alfresco.service.cmr.site.SiteVisibility;
|
||||||
import org.alfresco.service.cmr.tagging.TaggingService;
|
import org.alfresco.service.cmr.tagging.TaggingService;
|
||||||
|
import org.alfresco.service.cmr.version.VersionService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
@@ -105,6 +106,9 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
|||||||
protected QName TYPE_CUSTOM_TYPE = QName.createQName(URI, "customType");
|
protected QName TYPE_CUSTOM_TYPE = QName.createQName(URI, "customType");
|
||||||
protected QName ASPECT_CUSTOM_ASPECT = QName.createQName(URI, "customAspect");
|
protected QName ASPECT_CUSTOM_ASPECT = QName.createQName(URI, "customAspect");
|
||||||
protected QName ASPECT_RECORD_META_DATA = QName.createQName(URI, "recordMetaData");
|
protected QName ASPECT_RECORD_META_DATA = QName.createQName(URI, "recordMetaData");
|
||||||
|
|
||||||
|
/** test data */
|
||||||
|
protected String NAME_DM_DOCUMENT = "collabDocument.txt";
|
||||||
|
|
||||||
/** admin user */
|
/** admin user */
|
||||||
protected static final String ADMIN_USER = "admin";
|
protected static final String ADMIN_USER = "admin";
|
||||||
@@ -130,6 +134,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
|||||||
protected TaggingService taggingService;
|
protected TaggingService taggingService;
|
||||||
protected ActionService actionService;
|
protected ActionService actionService;
|
||||||
protected OwnableService ownableService;
|
protected OwnableService ownableService;
|
||||||
|
protected VersionService versionService;
|
||||||
|
|
||||||
/** RM Services */
|
/** RM Services */
|
||||||
protected DispositionService dispositionService;
|
protected DispositionService dispositionService;
|
||||||
@@ -364,6 +369,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
|||||||
taggingService = (TaggingService)applicationContext.getBean("TaggingService");
|
taggingService = (TaggingService)applicationContext.getBean("TaggingService");
|
||||||
actionService = (ActionService)applicationContext.getBean("ActionService");
|
actionService = (ActionService)applicationContext.getBean("ActionService");
|
||||||
ownableService = (OwnableService)applicationContext.getBean("OwnableService");
|
ownableService = (OwnableService)applicationContext.getBean("OwnableService");
|
||||||
|
versionService = (VersionService)applicationContext.getBean("VersionService");
|
||||||
|
|
||||||
// Get RM services
|
// Get RM services
|
||||||
dispositionService = (DispositionService)applicationContext.getBean("DispositionService");
|
dispositionService = (DispositionService)applicationContext.getBean("DispositionService");
|
||||||
@@ -736,7 +742,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase
|
|||||||
|
|
||||||
// create a folder and documents
|
// create a folder and documents
|
||||||
dmFolder = fileFolderService.create(documentLibrary, "collabFolder", ContentModel.TYPE_FOLDER).getNodeRef();
|
dmFolder = fileFolderService.create(documentLibrary, "collabFolder", ContentModel.TYPE_FOLDER).getNodeRef();
|
||||||
dmDocument = fileFolderService.create(dmFolder, "collabDocument.txt", ContentModel.TYPE_CONTENT).getNodeRef();
|
dmDocument = fileFolderService.create(dmFolder, NAME_DM_DOCUMENT, ContentModel.TYPE_CONTENT).getNodeRef();
|
||||||
|
|
||||||
dmConsumer = GUID.generate();
|
dmConsumer = GUID.generate();
|
||||||
dmConsumerNodeRef = createPerson(dmConsumer);
|
dmConsumerNodeRef = createPerson(dmConsumer);
|
||||||
|
@@ -51,7 +51,7 @@ public class FileReportActionUnitTest extends BaseUnitTest
|
|||||||
* @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before()
|
* @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void before()
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
super.before();
|
super.before();
|
||||||
|
|
||||||
|
@@ -67,7 +67,7 @@ public class HoldCapabilityConditionUnitTest extends BaseUnitTest
|
|||||||
*/
|
*/
|
||||||
@Before
|
@Before
|
||||||
@Override
|
@Override
|
||||||
public void before()
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
super.before();
|
super.before();
|
||||||
|
|
||||||
|
@@ -77,7 +77,7 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
@Override
|
@Override
|
||||||
public void before()
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
super.before();
|
super.before();
|
||||||
|
|
||||||
|
@@ -72,7 +72,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Before
|
@Before
|
||||||
public void before()
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
super.before();
|
super.before();
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@ public class FrozenEvaluatorUnitTest extends BaseUnitTest
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
@Override
|
@Override
|
||||||
public void before()
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
super.before();
|
super.before();
|
||||||
|
|
||||||
|
@@ -51,7 +51,7 @@ public class TransferEvaluatorUnitTest extends BaseUnitTest
|
|||||||
@Spy @InjectMocks TransferEvaluator transferEvaluator;
|
@Spy @InjectMocks TransferEvaluator transferEvaluator;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void before()
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
super.before();
|
super.before();
|
||||||
|
|
||||||
|
@@ -55,7 +55,7 @@ public class RecordServiceImplUnitTest extends BaseUnitTest
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Before
|
@Before
|
||||||
@Override
|
@Override
|
||||||
public void before()
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
super.before();
|
super.before();
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ public abstract class BaseHoldWebScriptUnitTest extends BaseWebScriptUnitTest
|
|||||||
* @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before()
|
* @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void before()
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
super.before();
|
super.before();
|
||||||
|
|
||||||
|
@@ -83,7 +83,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
|||||||
* @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before()
|
* @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void before()
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
super.before();
|
super.before();
|
||||||
|
|
||||||
|
@@ -32,7 +32,9 @@ import org.alfresco.module.org_alfresco_module_rm.record.RecordServiceImplUnitTe
|
|||||||
import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldPostUnitTest;
|
import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldPostUnitTest;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldPutUnitTest;
|
import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldPutUnitTest;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldsGetUnitTest;
|
import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldsGetUnitTest;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionServiceImplUnitTest;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.util.BeanExtenderUnitTest;
|
import org.alfresco.module.org_alfresco_module_rm.util.BeanExtenderUnitTest;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImplUnitTest;
|
||||||
import org.alfresco.repo.action.parameter.DateParameterProcessorUnitTest;
|
import org.alfresco.repo.action.parameter.DateParameterProcessorUnitTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Suite;
|
import org.junit.runners.Suite;
|
||||||
@@ -57,7 +59,8 @@ import org.junit.runners.Suite.SuiteClasses;
|
|||||||
// services
|
// services
|
||||||
RecordServiceImplUnitTest.class,
|
RecordServiceImplUnitTest.class,
|
||||||
HoldServiceImplUnitTest.class,
|
HoldServiceImplUnitTest.class,
|
||||||
//FilePlanPermissionServiceImplUnitTest.class,
|
FilePlanPermissionServiceImplUnitTest.class,
|
||||||
|
RecordableVersionServiceImplUnitTest.class,
|
||||||
|
|
||||||
// evaluators
|
// evaluators
|
||||||
TransferEvaluatorUnitTest.class,
|
TransferEvaluatorUnitTest.class,
|
||||||
|
@@ -23,6 +23,7 @@ import static org.mockito.Matchers.anyString;
|
|||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -41,11 +42,15 @@ import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderServi
|
|||||||
import org.alfresco.module.org_alfresco_module_rm.report.ReportService;
|
import org.alfresco.module.org_alfresco_module_rm.report.ReportService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
|
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
|
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
|
||||||
|
import org.alfresco.repo.policy.BehaviourFilter;
|
||||||
|
import org.alfresco.repo.policy.PolicyComponent;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.CopyService;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
@@ -77,7 +82,7 @@ import org.springframework.context.ApplicationContext;
|
|||||||
* @author Roy Wetherall
|
* @author Roy Wetherall
|
||||||
* @since 2.2
|
* @since 2.2
|
||||||
*/
|
*/
|
||||||
public class BaseUnitTest implements RecordsManagementModel
|
public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||||
{
|
{
|
||||||
protected NodeRef filePlanComponent;
|
protected NodeRef filePlanComponent;
|
||||||
protected NodeRef filePlan;
|
protected NodeRef filePlan;
|
||||||
@@ -95,6 +100,9 @@ public class BaseUnitTest implements RecordsManagementModel
|
|||||||
@Mock(name="searchService") protected SearchService mockedSearchService;
|
@Mock(name="searchService") protected SearchService mockedSearchService;
|
||||||
@Mock(name="retryingTransactionHelper") protected RetryingTransactionHelper mockedRetryingTransactionHelper;
|
@Mock(name="retryingTransactionHelper") protected RetryingTransactionHelper mockedRetryingTransactionHelper;
|
||||||
@Mock(name="authorityService") protected AuthorityService mockedAuthorityService;
|
@Mock(name="authorityService") protected AuthorityService mockedAuthorityService;
|
||||||
|
@Mock(name="policyComponent") protected PolicyComponent mockedPolicyComponent;
|
||||||
|
@Mock(name="copyService") protected CopyService mockedCopyService;
|
||||||
|
@Mock(name="fileFolderService") protected FileFolderService mockedFileFolderService;
|
||||||
|
|
||||||
/** rm service mocks */
|
/** rm service mocks */
|
||||||
@Mock(name="filePlanService") protected FilePlanService mockedFilePlanService;
|
@Mock(name="filePlanService") protected FilePlanService mockedFilePlanService;
|
||||||
@@ -105,6 +113,7 @@ public class BaseUnitTest implements RecordsManagementModel
|
|||||||
@Mock(name="reportService") protected ReportService mockedReportService;
|
@Mock(name="reportService") protected ReportService mockedReportService;
|
||||||
@Mock(name="filePlanRoleService") protected FilePlanRoleService mockedFilePlanRoleService;
|
@Mock(name="filePlanRoleService") protected FilePlanRoleService mockedFilePlanRoleService;
|
||||||
@Mock(name="recordsManagementAuditService") protected RecordsManagementAuditService mockedRecordsManagementAuditService;
|
@Mock(name="recordsManagementAuditService") protected RecordsManagementAuditService mockedRecordsManagementAuditService;
|
||||||
|
@Mock(name="policyBehaviourFilter") protected BehaviourFilter mockedBehaviourFilter;
|
||||||
|
|
||||||
/** application context mock */
|
/** application context mock */
|
||||||
@Mock(name="applicationContext") protected ApplicationContext mockedApplicationContext;
|
@Mock(name="applicationContext") protected ApplicationContext mockedApplicationContext;
|
||||||
@@ -118,7 +127,7 @@ public class BaseUnitTest implements RecordsManagementModel
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Before
|
@Before
|
||||||
public void before()
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
@@ -161,7 +170,7 @@ public class BaseUnitTest implements RecordsManagementModel
|
|||||||
doReturn(result).when(mockedNodeService).getChildAssocs(eq(recordFolder), eq(ContentModel.ASSOC_CONTAINS), any(QNamePattern.class));
|
doReturn(result).when(mockedNodeService).getChildAssocs(eq(recordFolder), eq(ContentModel.ASSOC_CONTAINS), any(QNamePattern.class));
|
||||||
doReturn(result).when(mockedNodeService).getParentAssocs(record);
|
doReturn(result).when(mockedNodeService).getParentAssocs(record);
|
||||||
doReturn(Collections.singletonList(recordFolder)).when(mockedRecordFolderService).getRecordFolders(record);
|
doReturn(Collections.singletonList(recordFolder)).when(mockedRecordFolderService).getRecordFolders(record);
|
||||||
doReturn(Collections.singletonList(record)).when(mockedRecordService).getRecords(recordFolder);
|
doReturn(Collections.singletonList(record)).when(mockedRecordService).getRecords(recordFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -250,6 +259,19 @@ public class BaseUnitTest implements RecordsManagementModel
|
|||||||
return generateNodeRef(type, true);
|
return generateNodeRef(type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to generate a cm:content node reference with a given name.
|
||||||
|
*
|
||||||
|
* @param name content name
|
||||||
|
* @return NodeRef node reference
|
||||||
|
*/
|
||||||
|
protected NodeRef generateCmContent(String name)
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = generateNodeRef(ContentModel.TYPE_CONTENT, true);
|
||||||
|
doReturn(name).when(mockedNodeService).getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||||
|
return nodeRef;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to generate a node reference of a particular type with a given existence characteristic.
|
* Helper method to generate a node reference of a particular type with a given existence characteristic.
|
||||||
*
|
*
|
||||||
@@ -268,6 +290,30 @@ public class BaseUnitTest implements RecordsManagementModel
|
|||||||
}
|
}
|
||||||
return nodeRef;
|
return nodeRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to generate a mocked child association reference.
|
||||||
|
*
|
||||||
|
* @param parent parent node (optional)
|
||||||
|
* @param child child node (optional)
|
||||||
|
* @return {@link ChildAssociationRef} mocked to return the parent and child nodes
|
||||||
|
*/
|
||||||
|
protected ChildAssociationRef generateChildAssociationRef(NodeRef parent, NodeRef child)
|
||||||
|
{
|
||||||
|
ChildAssociationRef mockedChildAssociationRef = mock(ChildAssociationRef.class);
|
||||||
|
|
||||||
|
if (parent != null)
|
||||||
|
{
|
||||||
|
doReturn(parent).when(mockedChildAssociationRef).getParentRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child != null)
|
||||||
|
{
|
||||||
|
doReturn(child).when(mockedChildAssociationRef).getChildRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
return mockedChildAssociationRef;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to make one node the primary parent of the other.
|
* Helper method to make one node the primary parent of the other.
|
||||||
|
@@ -61,7 +61,7 @@ public class BeanExtenderUnitTest extends BaseUnitTest
|
|||||||
@InjectMocks private BeanExtender beanExtender;
|
@InjectMocks private BeanExtender beanExtender;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void before()
|
public void before() throws Exception
|
||||||
{
|
{
|
||||||
super.before();
|
super.before();
|
||||||
|
|
||||||
|
@@ -0,0 +1,416 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 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.module.org_alfresco_module_rm.version;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.anyMap;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.anyString;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
||||||
|
import org.alfresco.repo.version.Version2Model;
|
||||||
|
import org.alfresco.repo.version.VersionMigrator;
|
||||||
|
import org.alfresco.repo.version.VersionModel;
|
||||||
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.version.VersionType;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recordable version service implementation unit test.
|
||||||
|
*
|
||||||
|
* @author Roy Wetherall
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
|
||||||
|
{
|
||||||
|
/** versioned content name */
|
||||||
|
private static final String CONTENT_NAME = "test.txt";
|
||||||
|
|
||||||
|
/** versioned node reference */
|
||||||
|
private NodeRef nodeRef;
|
||||||
|
private NodeRef record;
|
||||||
|
private NodeRef unfiledRecordContainer;
|
||||||
|
private NodeRef version;
|
||||||
|
|
||||||
|
/** mocked version properties */
|
||||||
|
private Map<String, Serializable> versionProperties;
|
||||||
|
|
||||||
|
/** mocked services */
|
||||||
|
private @Mock(name="versionMigrator") VersionMigrator mockedVersionMigrator;
|
||||||
|
private @Mock(name="dbNodeService") NodeService mockedDbNodeService;
|
||||||
|
|
||||||
|
/** recordable version service */
|
||||||
|
private @InjectMocks TestRecordableVersionServiceImpl recordableVersionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before()
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void before() throws Exception
|
||||||
|
{
|
||||||
|
super.before();
|
||||||
|
|
||||||
|
nodeRef = generateCmContent(CONTENT_NAME);
|
||||||
|
doReturn(123l).when(mockedNodeService).getProperty(nodeRef, ContentModel.PROP_NODE_DBID);
|
||||||
|
|
||||||
|
versionProperties = new HashMap<String, Serializable>(5);
|
||||||
|
|
||||||
|
recordableVersionService.initialise();
|
||||||
|
|
||||||
|
doReturn(generateChildAssociationRef(null, generateNodeRef(Version2Model.TYPE_QNAME_VERSION_HISTORY)))
|
||||||
|
.when(mockedDbNodeService).createNode(any(NodeRef.class),
|
||||||
|
any(QName.class),
|
||||||
|
any(QName.class),
|
||||||
|
eq(Version2Model.TYPE_QNAME_VERSION_HISTORY),
|
||||||
|
anyMap());
|
||||||
|
doReturn(generateChildAssociationRef(null, generateNodeRef(TYPE_CONTENT)))
|
||||||
|
.when(mockedDbNodeService).createNode(any(NodeRef.class),
|
||||||
|
any(QName.class),
|
||||||
|
any(QName.class),
|
||||||
|
eq(TYPE_CONTENT),
|
||||||
|
anyMap());
|
||||||
|
|
||||||
|
doReturn(filePlan).when(mockedFilePlanService).getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
|
||||||
|
doReturn(unfiledRecordContainer).when(mockedFilePlanService).getUnfiledContainer(any(NodeRef.class));
|
||||||
|
|
||||||
|
record = generateCmContent(CONTENT_NAME);
|
||||||
|
FileInfo mockedFileInfo = mock(FileInfo.class);
|
||||||
|
doReturn(record).when(mockedFileInfo).getNodeRef();
|
||||||
|
doReturn(mockedFileInfo).when(mockedFileFolderService).copy(any(NodeRef.class),
|
||||||
|
any(NodeRef.class),
|
||||||
|
any(String.class));
|
||||||
|
version = generateNodeRef(TYPE_CONTENT);
|
||||||
|
doReturn(generateChildAssociationRef(null, version)).when(mockedDbNodeService).createNode(
|
||||||
|
any(NodeRef.class),
|
||||||
|
eq(Version2Model.CHILD_QNAME_VERSIONS),
|
||||||
|
any(QName.class),
|
||||||
|
eq(TYPE_CONTENT),
|
||||||
|
anyMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given that the node has no recordable version aspect
|
||||||
|
* When I create a version
|
||||||
|
* Then version service creates a normal version.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void noAspect() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(false).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
// then a normal version is created
|
||||||
|
verifyNormalVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given that the node has a recordable version policy of null
|
||||||
|
* When I create a version
|
||||||
|
* Then the version service creates a normal version.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void policyNull() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(false).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
doReturn(null).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
// then a normal version is created
|
||||||
|
verifyNormalVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given that the node has a recordable version policy of NONE
|
||||||
|
* When I create a version
|
||||||
|
* Then the version service creates a normal version.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void policyNone() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
doReturn(RecordableVersionPolicy.NONE.toString()).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
// then a normal version is created
|
||||||
|
verifyNormalVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given that the node has a recordable version policy of ALL
|
||||||
|
* When I create a MINOR version then
|
||||||
|
* the version service creates a recorded version
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void policyAllVersionMinor() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
doReturn(RecordableVersionPolicy.ALL.toString()).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
// then the recorded version is created
|
||||||
|
verifyRecordedVersion(filePlan);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method that verifies that a recorded version was created.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void verifyRecordedVersion(NodeRef filePlan) throws Exception
|
||||||
|
{
|
||||||
|
// then unfiled container is retrieved for file plan
|
||||||
|
verify(mockedFilePlanService, times(1)).getUnfiledContainer(filePlan);
|
||||||
|
|
||||||
|
// then the node is copied into the file plan
|
||||||
|
verify(mockedFileFolderService, times(1)).copy(eq(nodeRef),
|
||||||
|
eq(unfiledRecordContainer),
|
||||||
|
anyString());
|
||||||
|
|
||||||
|
// then the version is created
|
||||||
|
verify(mockedDbNodeService, times(1)).createNode(any(NodeRef.class),
|
||||||
|
eq(Version2Model.CHILD_QNAME_VERSIONS),
|
||||||
|
any(QName.class),
|
||||||
|
eq(TYPE_CONTENT),
|
||||||
|
anyMap());
|
||||||
|
verify(mockedNodeService, times(1)).addAspect(eq(version), eq(Version2Model.ASPECT_VERSION), anyMap());
|
||||||
|
verify(mockedNodeService, times(1)).addAspect(eq(version), eq(RecordableVersionModel.ASPECT_RECORDED_VERSION),
|
||||||
|
eq(Collections.singletonMap(RecordableVersionModel.PROP_RECORD_NODE_REF, (Serializable)record)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method that verified that a recorded version was not created.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void verifyNormalVersion() throws Exception
|
||||||
|
{
|
||||||
|
// verify no interactions
|
||||||
|
verify(mockedFilePlanService, never()).getUnfiledContainer(any(NodeRef.class));
|
||||||
|
verify(mockedFileFolderService, never()).copy(eq(nodeRef),
|
||||||
|
eq(unfiledRecordContainer),
|
||||||
|
anyString());
|
||||||
|
|
||||||
|
// then the version is created
|
||||||
|
verify(mockedDbNodeService, times(1)).createNode(any(NodeRef.class),
|
||||||
|
eq(Version2Model.CHILD_QNAME_VERSIONS),
|
||||||
|
any(QName.class),
|
||||||
|
eq(TYPE_CONTENT),
|
||||||
|
anyMap());
|
||||||
|
verify(mockedNodeService, times(1)).addAspect(eq(version), eq(Version2Model.ASPECT_VERSION), anyMap());
|
||||||
|
verify(mockedNodeService, never()).addAspect(eq(version), eq(RecordableVersionModel.PROP_RECORD_NODE_REF), anyMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given that the node has a recordable version policy of ALL
|
||||||
|
* When I create a MAJOR version then
|
||||||
|
* the version service creates a recorded version
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void policyAllVersionMajor() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
doReturn(RecordableVersionPolicy.ALL.toString()).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
// then the recorded version is created
|
||||||
|
verifyRecordedVersion(filePlan);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given that the node has a recordable version policy of MAJOR_ONLY
|
||||||
|
* When I create a MINOR version then
|
||||||
|
* the version service creates a normal version
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void policyMajorOnlyVersionMinor() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
doReturn(RecordableVersionPolicy.MAJOR_ONLY.toString()).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
// then a normal version is created
|
||||||
|
verifyNormalVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given that the node has a recordable version policy of MAJOR_ONLY
|
||||||
|
* When I create a MAJOR version then
|
||||||
|
* the version service creates a recorded version
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void policyMajorOnlyVersionMajor() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
doReturn(RecordableVersionPolicy.MAJOR_ONLY.toString()).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
// then the recorded version is created
|
||||||
|
verifyRecordedVersion(filePlan);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given that the node has a valid recordable version policy
|
||||||
|
* And there is no file plan
|
||||||
|
* When I create a new version
|
||||||
|
* Then an exception should be thrown to indicate that there is no file plan
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void noFilePlan() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
doReturn(RecordableVersionPolicy.MAJOR_ONLY.toString()).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
|
||||||
|
doReturn(null).when(mockedFilePlanService).getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
|
||||||
|
|
||||||
|
// expected exception
|
||||||
|
exception.expect(AlfrescoRuntimeException.class);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given that the node has a valid recordable version policy
|
||||||
|
* And that I set a specific file plan in the version properties
|
||||||
|
* When I create a new version
|
||||||
|
* Then the recorded version should be directed to the specified file plan, not the default file plan
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void filePlanSpecifiedWithPolicy() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
doReturn(RecordableVersionPolicy.MAJOR_ONLY.toString()).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
|
||||||
|
|
||||||
|
// specify the file plan
|
||||||
|
NodeRef anotherFilePlan = generateNodeRef(TYPE_FILE_PLAN);
|
||||||
|
versionProperties.put(RecordableVersionServiceImpl.KEY_FILE_PLAN, anotherFilePlan);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
// then the recorded version is created
|
||||||
|
verifyRecordedVersion(anotherFilePlan);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given that the node has specifically indicated that a recorded version should be created
|
||||||
|
* And that I set a specific file plan in the version properties
|
||||||
|
* When I create a new version
|
||||||
|
* Then the recorded version should be directed to the specified file plan, not the default file plan
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void filePlanSpecifiedNoPolicy() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
|
||||||
|
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
|
||||||
|
|
||||||
|
// specify the file plan
|
||||||
|
NodeRef anotherFilePlan = generateNodeRef(TYPE_FILE_PLAN);
|
||||||
|
versionProperties.put(RecordableVersionServiceImpl.KEY_FILE_PLAN, anotherFilePlan);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
// then the recorded version is created
|
||||||
|
verifyRecordedVersion(anotherFilePlan);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void adHocRecordedVersionNoPolicy() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
|
||||||
|
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
// then the recorded version is created
|
||||||
|
verifyRecordedVersion(filePlan);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void adHocRecordedVersionOverridePolicy() throws Exception
|
||||||
|
{
|
||||||
|
// setup given conditions
|
||||||
|
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||||
|
doReturn(RecordableVersionPolicy.MAJOR_ONLY.toString()).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
|
||||||
|
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||||
|
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
|
||||||
|
|
||||||
|
// when version is created
|
||||||
|
recordableVersionService.createVersion(nodeRef, versionProperties);
|
||||||
|
|
||||||
|
// then the recorded version is created
|
||||||
|
verifyRecordedVersion(filePlan);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 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.module.org_alfresco_module_rm.version;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.repo.policy.PolicyScope;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.version.Version;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to help with the unit testing of RecordableVersionServiceImpl.
|
||||||
|
*
|
||||||
|
* @author Roy Wetherall
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public class TestRecordableVersionServiceImpl extends RecordableVersionServiceImpl
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void invokeBeforeCreateVersion(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void invokeAfterCreateVersion(NodeRef nodeRef, Version version)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void invokeAfterVersionRevert(NodeRef nodeRef, Version version)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void invokeOnCreateVersion(NodeRef nodeRef, Map<String, Serializable> versionProperties,PolicyScope nodeDetails)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String invokeCalculateVersionLabel(QName classRef, Version preceedingVersion, int versionNumber, Map<String, Serializable> versionProperties)
|
||||||
|
{
|
||||||
|
return "1.1";
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user