RM-783: File destruction report action (part one)

* ReportService added ... will be used to consolidate the various reports withing RM (specifically those needed for DOD complicance)
  * Base and declarative implementations of report generators added
  * Destruction report configured with place holder implementation (still need to do name generation, meta-data and final template)
  * Report model added, with destructionReport type defined
  * FileDestructionReport capability added (and capability patch bean updated)
  * Repository action added to file destruction report
  * UI configured to show 'file destruction report' action .. (creates a report and files it as an unfiled record as the destruction report type)
  * fixed up destruction capabilities and actions (capability to destroy record regardless of its current dispostion state did not work)
  * added "AtLeastOne" composite capability condition
  * TODO destruction report template, name and meta-data generation
  * TODO patch to add report template structure to rm data dictionary area
  * TODO start refactor of existing reports including transfer, accession, userRights, filePlan and audit!!



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@52562 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2013-07-14 09:54:27 +00:00
parent 1e6d49dbab
commit b4d1194ae2
45 changed files with 1602 additions and 108 deletions

View File

@@ -185,7 +185,39 @@
</cm:contains>
</view:associations>
</cm:folder>
</cm:contains>
<cm:folder view:childName="cm:rm_report_templates">
<view:properties>
<sys:store-protocol>workspace</sys:store-protocol>
<sys:store-identifier>SpacesStore</sys:store-identifier>
<sys:node-uuid>rm_report_templates</sys:node-uuid>
<cm:name>Records Management Report Templates</cm:name>
<cm:title>Records Management Report Templates</cm:title>
<cm:description>Records management report templates.</cm:description>
</view:properties>
<view:associations>
<cm:contains>
<cm:content view:childName="cm:report_rmr_destructionReport.html.ftl">
<view:aspects>
<cm:titled></cm:titled>
<cm:author></cm:author>
<app:inlineeditable></app:inlineeditable>
<cm:versionable></cm:versionable>
</view:aspects>
<view:properties>
<sys:store-protocol>workspace</sys:store-protocol>
<sys:store-identifier>SpacesStore</sys:store-identifier>
<sys:node-uuid>rmr_destructionReport</sys:node-uuid>
<cm:description>Desruction report template.</cm:description>
<cm:content>contentUrl=classpath:alfresco/module/org_alfresco_module_rm/bootstrap/report/report_rmr_destructionReport.html.ftl|mimetype=text/plain|encoding=UTF-8</cm:content>
<cm:title>Destruction Report Template</cm:title>
<cm:name>report_rmr_destructionReport.html.ftl</cm:name>
</view:properties>
</cm:content>
</cm:contains>
</view:associations>
</cm:folder>
</cm:contains>
</view:associations>
</cm:folder>

View File

@@ -0,0 +1,10 @@
<html>
<head>
</head>
<body>
<h1>Destruction Report</h1>
</body>
</html>

View File

@@ -84,6 +84,17 @@
<property name="dispositionService" ref="DispositionService"/>
<property name="dispositionAction" value="destroy"/>
</bean>
<bean id="capabilityCondition.destroyIsScheduledOrComplete"
parent="capabilityCondition.base"
class="org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition.AtLeastOneCondition">
<property name="conditions">
<list>
<ref bean="capabilityCondition.destroyed" />
<ref bean="capabilityCondition.destroyIsScheduled" />
</list>
</property>
</bean>
<bean id="capabilityCondition.hasEvents"
parent="capabilityCondition.base"

View File

@@ -232,5 +232,23 @@
</map>
</property>
</bean>
<bean id="rmDestroyCapability"
parent="compositeCapability">
<property name="name" value="Destroy"/>
<property name="private" value="true"/>
<property name="kinds">
<list>
<value>RECORD_FOLDER</value>
<value>RECORD</value>
</list>
</property>
<property name="capabilities">
<list>
<ref bean="rmDestroyRecordsScheduledForDestructionCapability"/>
<ref bean="rmDestroyRecordsCapability"/>
</list>
</property>
</bean>
</beans>

View File

@@ -283,6 +283,7 @@
</bean>
<!-- Request record information capability -->
<!-- @since 2.1 -->
<bean id="rmRequestRecordInformationCapability"
parent="declarativeCapability">
<property name="name" value="RequestRecordInformation"/>
@@ -298,5 +299,27 @@
<property name="group"><ref bean="recordsGroup"/></property> <!-- Part of the records group of capabilities -->
<property name="index" value="100" />
</bean>
<!-- file destruction report capability -->
<bean id="rmFileDestructionReportCapability"
parent="declarativeCapability">
<property name="name" value="FileDestructionReport" />
<property name="permission" value="FileDestructionReport" /> <!-- Associated permission -->
<property name="kinds">
<list>
<value>RECORD</value> <!-- Only applies to records and record folders -->
<value>RECORD_FOLDER</value>
</list>
</property>
<property name="conditions">
<map>
<entry key="capabilityCondition.filling" value="true"/> <!-- Must have read and file permissions -->
<entry key="capabilityCondition.frozen" value="false"/> <!-- Not for frozen records -->
<entry key="capabilityCondition.destroyIsScheduledOrComplete" value="true"/> <!-- Only for records scheduled for destruction or destroyed -->
</map>
</property>
<property name="group"><ref bean="recordsGroup"/></property> <!-- Part of the records group of capabilities -->
<property name="index" value="110" />
</bean>
</beans>

View File

@@ -0,0 +1,7 @@
rmr_recordsmanagementreport.description=Records Management Report Content Model
rmr_recordsmanagementreport.type.rmr_report.title=Records Management Report
rmr_recordsmanagementreport.type.rmr_report.description=Records management report.
rmr_recordsmanagementreport.type.rmr_destructionReport.title=Records Management Report
rmr_recordsmanagementreport.type.rmr_destructionReport.description=Records management destruction report.

View File

@@ -83,6 +83,7 @@
<includePermissionGroup type="rma:filePlanComponent" permissionGroup="CreateRecords"/>
<includePermissionGroup type="rma:filePlanComponent" permissionGroup="ManageRules"/>
<includePermissionGroup type="rma:filePlanComponent" permissionGroup="RequestRecordInformation"/>
<includePermissionGroup type="rma:filePlanComponent" permissionGroup="FileDestructionReport"/>
</permissionGroup>
<permissionGroup name="Filing" allowFullControl="false" expose="true">
@@ -158,6 +159,7 @@
<permissionGroup name="CreateRecords" expose="false" allowFullControl="false"/>
<permissionGroup name="ManageRules" expose="false" allowFullControl="false"/>
<permissionGroup name="RequestRecordInformation" expose="false" allowFullControl="false"/>
<permissionGroup name="FileDestructionReport" expose="false" allowFullControl="false"/>
<!-- End -->
@@ -415,6 +417,10 @@
<grantedToGroup permissionGroup="RequestRecordInformation"/>
</permission>
<permission name="_FileDestructionReport" expose="false">
<grantedToGroup permissionGroup="FileDestructionReport"/>
</permission>
</permissionSet>
</permissions>

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Definition of Records Management Report Model -->
<!-- Note: the rma: namespace is defined further on in the document -->
<model name="rmr:recordsmanagementreport" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<!-- Meta-data about the model -->
<description>Records Management Report Model</description>
<author>Roy Wetherall</author>
<version>1.0</version>
<!-- Imports are required to allow references to definitions in other models -->
<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>
<!-- Report Namespace -->
<namespaces>
<namespace uri="http://www.alfresco.org/model/recordsmanagementreport/1.0" prefix="rmr"/>
</namespaces>
<types>
<type name="rmr:report">
<title>Report</title>
<parent>cm:content</parent>
</type>
<type name="rmr:destructionReport">
<title>Report</title>
<parent>rmr:report</parent>
</type>
</types>
</model>

View File

@@ -113,6 +113,9 @@
<!-- Import workflows -->
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-workflow-context.xml"/>
<!-- Import record service -->
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-report-context.xml"/>
<!-- RM Script API -->

View File

@@ -244,7 +244,7 @@
<bean id="destroy_security" class="org.alfresco.repo.security.permissions.impl.acegi.MethodSecurityInterceptor" parent="actionSecurity">
<property name="objectDefinitionSource">
<value>
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_CAP.0.rma:filePlanComponent.DestroyRecordsScheduledForDestruction
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_CAP.0.rma:filePlanComponent.Destroy
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW
org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW
</value>
@@ -253,9 +253,8 @@
<bean id="destroy" class="org.alfresco.module.org_alfresco_module_rm.action.impl.DestroyAction" parent="rmAction"
depends-on="rmDestroyRecordsScheduledForDestructionCapability">
<property name="policyComponent">
<ref bean="policyComponent"/>
</property>
<property name="policyComponent" ref="policyComponent"/>
<property name="capabilityService" ref="CapabilityService" />
<property name="eagerContentStoreCleaner" ref="eagerContentStoreCleaner"/>
<property name="ghostingEnabled">
<value>${rm.ghosting.enabled}</value>

View File

@@ -0,0 +1,106 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<!-- Report Content Model -->
<bean id="org_alfresco_module_rm_report_dictionaryBootstrap" parent="dictionaryModelBootstrap">
<property name="models">
<list>
<value>alfresco/module/org_alfresco_module_rm/model/reportModel.xml</value>
</list>
</property>
<property name="labels">
<list>
<value>alfresco/module/org_alfresco_module_rm/messages/report-model</value>
</list>
</property>
</bean>
<!-- Report Service -->
<bean id="reportService" parent="baseService" class="org.alfresco.module.org_alfresco_module_rm.report.ReportServiceImpl">
<property name="fileFolderService" ref="FileFolderService" />
<property name="filePlanService" ref="FilePlanService" />
<property name="contentService" ref="ContentService" />
<property name="recordService" ref="RecordService" />
</bean>
<bean id="ReportService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="org.alfresco.module.org_alfresco_module_rm.report.ReportService" />
<property name="target" ref="reportService"/>
<property name="interceptorNames">
<list>
<idref local="ReportService_transaction"/>
<idref bean="exceptionTranslator"/>
<idref local="ReportService_security"/>
</list>
</property>
</bean>
<bean id="ReportService_transaction" parent="baseTransaction"/>
<bean id="ReportService_security" parent="baseSecurity">
<property name="objectDefinitionSource">
<value>
<![CDATA[
org.alfresco.module.org_alfresco_module_rm.report.ReportService.getReportTypes=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.report.ReportService.registerReportGenerator=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.report.ReportService.generateReport=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.report.ReportService.fileReport=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.report.ReportService.*=RM_DENY
]]>
</value>
</property>
</bean>
<!-- Report Generators -->
<bean id="baseReportGenerator" abstract="true" init-method="init">
<property name="reportService" ref="reportService" />
<property name="namespaceService" ref="namespaceService"/>
</bean>
<bean id="declarativeReportGenerator" abstract="true" parent="baseReportGenerator" class="org.alfresco.module.org_alfresco_module_rm.report.generator.DeclarativeReportGenerator">
<property name="contentService" ref="ContentService"/>
<property name="mimetypeService" ref="MimetypeService"/>
<property name="fileFolderService" ref="FileFolderService"/>
<property name="templateService" ref="TemplateService"/>
</bean>
<bean id="destructionReportGenerator" parent="declarativeReportGenerator" >
<property name="reportTypeName" value="rmr:destructionReport" />
</bean>
<!-- Report Actions -->
<bean id="fileDestructionReport_proxy" parent="rmProxyAction" >
<property name="target">
<ref bean="fileDestructionReport"/>
</property>
<property name="interceptorNames">
<list>
<idref bean="fileDestructionReport_security"/>
</list>
</property>
</bean>
<bean id="fileDestructionReport_security" class="org.alfresco.repo.security.permissions.impl.acegi.MethodSecurityInterceptor" parent="actionSecurity">
<property name="objectDefinitionSource">
<value>
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_CAP.0.rma:filePlanComponent.FileDestructionReport
org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW
org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW
</value>
</property>
</bean>
<bean id="fileDestructionReport"
class="org.alfresco.module.org_alfresco_module_rm.report.action.FileDestructionReport"
parent="rmAction">
<property name="reportService" ref="ReportService" />
<property name="filePlanService" ref="FilePlanService" />
</bean>
</beans>

View File

@@ -1127,6 +1127,7 @@
<property name="notificationHelper" ref="recordsManagementNotificationHelper"/>
<property name="capabilityService" ref="CapabilityService" />
<property name="ruleService" ref="RuleService" />
<property name="fileFolderService" ref="FileFolderService" />
</bean>
<bean id="RecordService" class="org.springframework.aop.framework.ProxyFactoryBean">

View File

@@ -411,7 +411,19 @@
<value>RECORD</value>
</set>
</property>
<property name="capability" value ="DestroyRecordsScheduledForDestruction"/>
<property name="capability" value ="Destroy"/>
</bean>
<bean id="jsonConversionComponent.fileDestructionReportAction"
parent="jsonConversionComponent.baseAction">
<property name="name" value="fileDestructionReport"/>
<property name="kinds">
<set>
<value>RECORD_FOLDER</value>
<value>RECORD</value>
</set>
</property>
<property name="capability" value ="FileDestructionReport"/>
</bean>
<bean id="jsonConversionComponent.transferAction"

View File

@@ -128,7 +128,8 @@
"AccessAudit",
"ExportAudit",
"CreateModifyDestroyReferenceTypes",
"RequestRecordInformation"
"RequestRecordInformation",
"FileDestructionReport"
]
},
{
@@ -191,7 +192,8 @@
"CreateModifyDestroyReferenceTypes",
"ManageAccessControls",
"ManageRules",
"RequestRecordInformation"
"RequestRecordInformation",
"FileDestructionReport"
]
}
]

View File

@@ -46,10 +46,6 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx
private static final String MSG_NEXT_DISP_NOT_SET = "rm.action.next-disp-not-set";
private static final String MSG_NOT_NEXT_DISP = "rm.action.not-next-disp";
private static final String MSG_NOT_RECORD_FOLDER = "rm.action.not-record-folder";
/** Indicates whether the eligibility of the record should be checked or not */
// TODO add the capability to override this value using a property on the action
protected boolean checkEligibility = true;
/**
* All children of this implementation are disposition actions.
@@ -71,6 +67,28 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx
{
return true;
}
/**
* Indicates whether we should validate the next disposition action is the action we are
* trying to execute.
*
* @return
*/
protected boolean checkNextDispositionAction(NodeRef actionedUponNodeRef)
{
return true;
}
/**
* Indicated whether we should validate the disposition action is eligible or not.
*
* @param actionedUponNodeRef
* @return
*/
protected boolean checkEligibility(NodeRef actionedUponNodeRef)
{
return true;
}
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action,
@@ -87,7 +105,7 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx
DispositionSchedule di = checkDispositionActionExecutionValidity(actionedUponNodeRef, nextDispositionActionNodeRef, true);
// Check the eligibility of the action
if (checkEligibility == false ||
if (checkEligibility(actionedUponNodeRef) == false ||
dispositionService.isNextDispositionActionEligible(actionedUponNodeRef) == true)
{
if (di.isRecordLevelDisposition() == true)
@@ -187,7 +205,7 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx
* @param recordFolder
*/
protected abstract void executeRecordFolderLevelDisposition(Action action, NodeRef recordFolder);
/**
* @param nodeRef
* @return
@@ -221,30 +239,32 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx
}
}
// Check this the next disposition action
NodeRef nextDispositionAction = nextDispositionActionNodeRef;
if (nextDispositionAction == null)
if (checkNextDispositionAction(nodeRef) == true)
{
if (throwError)
// Check this the next disposition action
NodeRef nextDispositionAction = nextDispositionActionNodeRef;
if (nextDispositionAction == null)
{
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NEXT_DISP_NOT_SET, getName(), nodeRef.toString()));
if (throwError)
{
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NEXT_DISP_NOT_SET, getName(), nodeRef.toString()));
}
else
{
return null;
}
}
else
String actionName = (String) this.nodeService.getProperty(nextDispositionAction, PROP_DISPOSITION_ACTION);
if (actionName == null || actionName.equals(getName()) == false)
{
return null;
}
}
String actionName = (String) this.nodeService.getProperty(nextDispositionAction, PROP_DISPOSITION_ACTION);
if (actionName == null || actionName.equals(getName()) == false)
{
if (throwError)
{
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NOT_NEXT_DISP, getName(), nodeRef.toString()));
}
else
{
return null;
if (throwError)
{
throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NOT_NEXT_DISP, getName(), nodeRef.toString()));
}
else
{
return null;
}
}
}

View File

@@ -27,6 +27,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.model.RenditionModel;
import org.alfresco.module.org_alfresco_module_rm.action.RMDispositionActionExecuterAbstractBase;
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
import org.alfresco.repo.content.ContentServicePolicies;
import org.alfresco.repo.content.cleanup.EagerContentStoreCleaner;
import org.alfresco.repo.policy.JavaBehaviour;
@@ -36,6 +37,7 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.extensions.surf.util.I18NUtil;
@@ -49,6 +51,9 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
implements ContentServicePolicies.OnContentUpdatePolicy,
InitializingBean
{
/** Action name */
public static final String NAME = "destroy";
/** I18N */
private static final String MSG_GHOSTED_PROP_UPDATE = "rm.action.ghosted-prop-update";
@@ -57,6 +62,9 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
/** Eager content store cleaner */
private EagerContentStoreCleaner eagerContentStoreCleaner;
/** Capability service */
private CapabilityService capabilityService;
/** Indicates if ghosting is enabled or not */
private boolean ghostingEnabled = true;
@@ -77,6 +85,14 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
this.eagerContentStoreCleaner = eagerContentStoreCleaner;
}
/**
* @param capabilityService capability service
*/
public void setCapabilityService(CapabilityService capabilityService)
{
this.capabilityService = capabilityService;
}
/**
* @param ghostingEnabled true if ghosting is enabled, false otherwise
*/
@@ -84,6 +100,39 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
{
this.ghostingEnabled = ghostingEnabled;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.action.RMDispositionActionExecuterAbstractBase#checkNextDispositionAction()
*/
@Override
protected boolean checkNextDispositionAction(NodeRef actionedUponNodeRef)
{
return checkForDestroyRecordsCapability(actionedUponNodeRef);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.action.RMDispositionActionExecuterAbstractBase#checkEligibility(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
protected boolean checkEligibility(NodeRef actionedUponNodeRef)
{
return checkForDestroyRecordsCapability(actionedUponNodeRef);
}
/**
*
* @param actionedUponNodeRef
* @return
*/
private boolean checkForDestroyRecordsCapability(NodeRef actionedUponNodeRef)
{
boolean result = true;
if (AccessStatus.ALLOWED.equals(capabilityService.getCapability("DestroyRecords").hasPermission(actionedUponNodeRef)) == true)
{
result = false;
}
return result;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.action.RMDispositionActionExecuterAbstractBase#executeRecordFolderLevelDisposition(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)

View File

@@ -48,11 +48,18 @@ public class BootstrapImporterModuleComponent extends ImporterModuleComponent
@Override
protected void executeInternal() throws Throwable
{
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CONFIG_NODEID);
if (nodeService.exists(nodeRef) == false)
try
{
super.executeInternal();
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CONFIG_NODEID);
if (nodeService.exists(nodeRef) == false)
{
super.executeInternal();
}
}
}
catch (Throwable exception)
{
exception.printStackTrace();
throw exception;
}
}
}

View File

@@ -226,6 +226,12 @@ public class DeclarativeCapability extends AbstractCapability
if (expected != actual)
{
result = false;
if (logger.isDebugEnabled() == true)
{
logger.debug("Condition " + condition.getName() + " failed for capability " + getName() + " on nodeRef " + nodeRef.toString());
}
break;
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2005-2011 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.capability.declarative.condition;
import java.util.List;
import org.alfresco.module.org_alfresco_module_rm.capability.declarative.AbstractCapabilityCondition;
import org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Composite capability condition implementation that required at least one of the
* capability conditions to be true.
*
* @author Roy Wetherall
*/
public class AtLeastOneCondition extends AbstractCapabilityCondition
{
/** capability conditions */
private List<CapabilityCondition> conditions;
/**
* @param conditions capability conditions
*/
public void setConditions(List<CapabilityCondition> conditions)
{
this.conditions = conditions;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public boolean evaluate(NodeRef nodeRef)
{
boolean result = false;
if (conditions != null)
{
for (CapabilityCondition condition : conditions)
{
if (condition.evaluate(nodeRef) == true)
{
result = true;
break;
}
}
}
return result;
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2005-2013 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.patch;
import org.alfresco.repo.module.AbstractModuleComponent;
/**
* Module patch component base class.
*
* @author Roy Wetherall
* @since 2.1
*/
public abstract class ModulePatchComponent extends AbstractModuleComponent
{
@Override
protected void executeInternal() throws Throwable
{
try
{
executePatch();
}
catch (Throwable exception)
{
// record the exception otherwise it gets swallowed
exception.printStackTrace();
throw exception;
}
}
protected abstract void executePatch() throws Throwable;
}

View File

@@ -25,7 +25,6 @@ import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.notification.RecordsManagementNotificationHelper;
import org.alfresco.repo.module.AbstractModuleComponent;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.service.cmr.audit.AuditService;
import org.alfresco.service.cmr.repository.ContentService;
@@ -44,7 +43,7 @@ import org.springframework.beans.factory.BeanNameAware;
/**
* @author Roy Wetherall
*/
public class NotificationTemplatePatch extends AbstractModuleComponent
public class NotificationTemplatePatch extends ModulePatchComponent
implements BeanNameAware
{
/** Last patch update property */
@@ -127,7 +126,7 @@ public class NotificationTemplatePatch extends AbstractModuleComponent
* @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal()
*/
@Override
protected void executeInternal() throws Throwable
protected void executePatch() throws Throwable
{
if (logger.isDebugEnabled() == true)
{

View File

@@ -25,7 +25,6 @@ import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.notification.RecordsManagementNotificationHelper;
import org.alfresco.repo.module.AbstractModuleComponent;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
@@ -42,7 +41,7 @@ import org.springframework.beans.factory.BeanNameAware;
* @author Tuna Aksoy
* @since v2.1
*/
public class NotificationTemplatePatch_v21 extends AbstractModuleComponent
public class NotificationTemplatePatch_v21 extends ModulePatchComponent
implements BeanNameAware
{
/** Email template path */
@@ -85,7 +84,7 @@ public class NotificationTemplatePatch_v21 extends AbstractModuleComponent
}
@Override
protected void executeInternal() throws Throwable
protected void executePatch() throws Throwable
{
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CONFIG_NODEID);
if (nodeService.exists(nodeRef) == false)

View File

@@ -28,7 +28,6 @@ import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
import org.alfresco.module.org_alfresco_module_rm.role.Role;
import org.alfresco.repo.module.AbstractModuleComponent;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -40,7 +39,7 @@ import org.springframework.beans.factory.BeanNameAware;
* @author Roy Wetherall
* @since 2.1
*/
public class RMv21CapabilityPatch extends AbstractModuleComponent
public class RMv21CapabilityPatch extends ModulePatchComponent
implements BeanNameAware, RecordsManagementModel, DOD5015Model
{
/** Logger */
@@ -83,7 +82,7 @@ public class RMv21CapabilityPatch extends AbstractModuleComponent
* @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal()
*/
@Override
protected void executeInternal() throws Throwable
protected void executePatch() throws Throwable
{
if (logger.isDebugEnabled() == true)
{
@@ -119,8 +118,11 @@ public class RMv21CapabilityPatch extends AbstractModuleComponent
FilePlanRoleService.ROLE_ADMIN,
FilePlanRoleService.ROLE_POWER_USER,
FilePlanRoleService.ROLE_RECORDS_MANAGER,
FilePlanRoleService.ROLE_SECURITY_OFFICER);
FilePlanRoleService.ROLE_SECURITY_OFFICER);
addCapability(filePlan,
"FileDestructionReport",
FilePlanRoleService.ROLE_ADMIN,
FilePlanRoleService.ROLE_RECORDS_MANAGER);
}
if (logger.isDebugEnabled() == true)

View File

@@ -31,7 +31,6 @@ import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamicAuthority;
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority;
import org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService;
import org.alfresco.repo.module.AbstractModuleComponent;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -43,7 +42,7 @@ import org.springframework.beans.factory.BeanNameAware;
* @author Roy Wetherall
* @since 2.1
*/
public class RMv21InPlacePatch extends AbstractModuleComponent
public class RMv21InPlacePatch extends ModulePatchComponent
implements BeanNameAware, RecordsManagementModel, DOD5015Model
{
/** Extended reader and writer role details */
@@ -112,7 +111,7 @@ public class RMv21InPlacePatch extends AbstractModuleComponent
* @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal()
*/
@Override
protected void executeInternal() throws Throwable
protected void executePatch() throws Throwable
{
if (logger.isDebugEnabled() == true)
{

View File

@@ -26,7 +26,6 @@ import org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionSer
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.domain.patch.PatchDAO;
import org.alfresco.repo.domain.qname.QNameDAO;
import org.alfresco.repo.module.AbstractModuleComponent;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -42,7 +41,7 @@ import org.springframework.beans.factory.BeanNameAware;
* @author Roy Wetherall
* @since 2.1
*/
public class RMv21RecordInheritancePatch extends AbstractModuleComponent
public class RMv21RecordInheritancePatch extends ModulePatchComponent
implements BeanNameAware, RecordsManagementModel, DOD5015Model
{
@@ -108,7 +107,7 @@ public class RMv21RecordInheritancePatch extends AbstractModuleComponent
* @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal()
*/
@Override
protected void executeInternal() throws Throwable
protected void executePatch() throws Throwable
{
if (logger.isDebugEnabled() == true)
{

View File

@@ -25,10 +25,11 @@ import java.util.Set;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
import org.alfresco.module.org_alfresco_module_rm.role.Role;
import org.alfresco.repo.module.AbstractModuleComponent;
import org.alfresco.repo.security.authority.RMAuthority;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AuthorityService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanNameAware;
/**
@@ -37,8 +38,11 @@ import org.springframework.beans.factory.BeanNameAware;
* @author Tuna Aksoy
* @since 2.1
*/
public class RMv21RolesPatch extends AbstractModuleComponent implements BeanNameAware
public class RMv21RolesPatch extends ModulePatchComponent implements BeanNameAware
{
/** logger */
private static Log logger = LogFactory.getLog(RMv21RolesPatch.class);
private FilePlanService filePlanService;
private FilePlanRoleService filePlanRoleService;
private AuthorityService authorityService;
@@ -59,25 +63,49 @@ public class RMv21RolesPatch extends AbstractModuleComponent implements BeanName
}
@Override
protected void executeInternal() throws Throwable
protected void executePatch() throws Throwable
{
if (logger.isDebugEnabled() == true)
{
logger.debug("RM module: RMv21RolesPatch executing ...");
}
Set<NodeRef> filePlans = filePlanService.getFilePlans();
if (logger.isDebugEnabled() == true)
{
logger.debug(" ... updating " + filePlans.size() + " file plans");
}
for (NodeRef filePlan : filePlans)
{
boolean parentAddedToZone = false;
Set<Role> roles = filePlanRoleService.getRoles(filePlan);
for (Role role : roles)
{
String roleGroupName = role.getRoleGroupName();
addAuthorityToZone(roleGroupName);
if (parentAddedToZone == false)
String roleGroupName = role.getRoleGroupName();
if (authorityService.getAuthorityZones(roleGroupName).contains(RMAuthority.ZONE_APP_RM) == false)
{
String allRolesGroupName = filePlanRoleService.getAllRolesContainerGroup(filePlan);
addAuthorityToZone(allRolesGroupName);
parentAddedToZone = true;
if (logger.isDebugEnabled() == true)
{
logger.debug(" ... updating " + roleGroupName + " in file plan " + filePlan.toString());
}
addAuthorityToZone(roleGroupName);
if (parentAddedToZone == false)
{
String allRolesGroupName = filePlanRoleService.getAllRolesContainerGroup(filePlan);
addAuthorityToZone(allRolesGroupName);
parentAddedToZone = true;
}
}
}
}
if (logger.isDebugEnabled() == true)
{
logger.debug(" ... complete");
}
}
private void addAuthorityToZone(String roleGroupName)

View File

@@ -31,7 +31,6 @@ import org.alfresco.module.org_alfresco_module_rm.role.Role;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.domain.patch.PatchDAO;
import org.alfresco.repo.domain.qname.QNameDAO;
import org.alfresco.repo.module.AbstractModuleComponent;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -48,7 +47,7 @@ import org.springframework.beans.factory.BeanNameAware;
*
* @author Roy Wetherall
*/
public class RMv2FilePlanNodeRefPatch extends AbstractModuleComponent
public class RMv2FilePlanNodeRefPatch extends ModulePatchComponent
implements BeanNameAware, RecordsManagementModel, DOD5015Model
{
/** Logger */
@@ -116,7 +115,7 @@ public class RMv2FilePlanNodeRefPatch extends AbstractModuleComponent
* @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal()
*/
@Override
protected void executeInternal() throws Throwable
protected void executePatch() throws Throwable
{
if (logger.isDebugEnabled() == true)
{

View File

@@ -25,7 +25,6 @@ import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.domain.patch.PatchDAO;
import org.alfresco.repo.domain.qname.QNameDAO;
import org.alfresco.repo.module.AbstractModuleComponent;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
@@ -39,7 +38,7 @@ import org.springframework.beans.factory.BeanNameAware;
*
* @author Roy Wetherall
*/
public class RMv2ModelPatch extends AbstractModuleComponent
public class RMv2ModelPatch extends ModulePatchComponent
implements BeanNameAware, RecordsManagementModel, DOD5015Model
{
/** Logger */
@@ -76,7 +75,7 @@ public class RMv2ModelPatch extends AbstractModuleComponent
* @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal()
*/
@Override
protected void executeInternal() throws Throwable
protected void executePatch() throws Throwable
{
if (logger.isDebugEnabled() == true)
{

View File

@@ -28,7 +28,6 @@ import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
import org.alfresco.module.org_alfresco_module_rm.security.FilePlanAuthenticationService;
import org.alfresco.module.org_alfresco_module_rm.security.FilePlanAuthenticationServiceImpl;
import org.alfresco.repo.module.AbstractModuleComponent;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
@@ -42,7 +41,7 @@ import org.springframework.beans.factory.BeanNameAware;
*
* @author Roy Wetherall
*/
public class RMv2RMAdminUserPatch extends AbstractModuleComponent implements BeanNameAware
public class RMv2RMAdminUserPatch extends ModulePatchComponent implements BeanNameAware
{
/** Logger */
private static Log logger = LogFactory.getLog(RMv2RMAdminUserPatch.class);
@@ -117,7 +116,7 @@ public class RMv2RMAdminUserPatch extends AbstractModuleComponent implements Bea
* @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal()
*/
@Override
protected void executeInternal() throws Throwable
protected void executePatch() throws Throwable
{
if (logger.isDebugEnabled() == true)
{

View File

@@ -24,7 +24,6 @@ import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService;
import org.alfresco.module.org_alfresco_module_rm.search.SavedSearchDetails;
import org.alfresco.repo.module.AbstractModuleComponent;
import org.alfresco.service.cmr.site.SiteService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -36,7 +35,7 @@ import org.springframework.beans.factory.BeanNameAware;
*
* @author Roy Wetherall
*/
public class RMv2SavedSearchPatch extends AbstractModuleComponent
public class RMv2SavedSearchPatch extends ModulePatchComponent
implements BeanNameAware, RecordsManagementModel, DOD5015Model
{
/** Logger */
@@ -71,7 +70,7 @@ public class RMv2SavedSearchPatch extends AbstractModuleComponent
* @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal()
*/
@Override
protected void executeInternal() throws Throwable
protected void executePatch() throws Throwable
{
if (logger.isDebugEnabled() == true)
{

View File

@@ -19,8 +19,11 @@
package org.alfresco.module.org_alfresco_module_rm.record;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
@@ -73,6 +76,16 @@ public interface RecordService
* @see #createRecord(NodeRef, NodeRef, boolean)
*/
void createRecord(NodeRef filePlan, NodeRef nodeRef);
/**
* Creates a new document as a unfiled record.
*
* @param filePlan
* @param name
* @param type
* @param properties
*/
NodeRef createRecord(NodeRef filePlan, String name, QName type, Map<QName, Serializable> properties, ContentReader reader);
/**
* Indicates whether the record is filed or not

View File

@@ -59,7 +59,10 @@ import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.rule.RuleService;
@@ -173,6 +176,9 @@ public class RecordServiceImpl implements RecordService,
/** Rule service */
private RuleService ruleService;
/** File folder service */
private FileFolderService fileFolderService;
/** List of available record meta-data aspects */
private Set<QName> recordMetaDataAspects;
@@ -296,6 +302,14 @@ public class RecordServiceImpl implements RecordService,
{
this.ruleService = ruleService;
}
/**
* @param fileFolderService file folder service
*/
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
/**
* Init method
@@ -541,6 +555,53 @@ public class RecordServiceImpl implements RecordService,
});
}
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecord(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, org.alfresco.service.namespace.QName, java.util.Map, org.alfresco.service.cmr.repository.ContentReader)
*/
@Override
public NodeRef createRecord(NodeRef filePlan, String name, QName type, Map<QName, Serializable> properties, ContentReader reader)
{
ParameterCheck.mandatory("filePlan", filePlan);
ParameterCheck.mandatory("name", name);
// if none set the default record type is cm:content
if (type == null)
{
type = ContentModel.TYPE_CONTENT;
}
// TODO ensure that the type is a sub-type of cm:content
// get the unfiled record container for the file plan
NodeRef unfiledContainer = filePlanService.getUnfiledContainer(filePlan);
if (unfiledContainer == null)
{
throw new AlfrescoRuntimeException("Unable to create record, because unfiled container could not be found.");
}
// create the new record
NodeRef record = fileFolderService.create(unfiledContainer, name, type).getNodeRef();
// set the properties
if (properties != null)
{
nodeService.addProperties(record, properties);
}
// set the content
if (reader != null)
{
ContentWriter writer = fileFolderService.getWriter(record);
writer.setEncoding(reader.getEncoding());
writer.setMimetype(reader.getMimetype());
writer.putContent(reader);
}
// make record
makeRecord(record);
return record;
}
/**
* Creates a record from the given document
@@ -604,7 +665,7 @@ public class RecordServiceImpl implements RecordService,
// check whether this item is already an item or not
if (isRecord(record) == false)
{
// make the item a recor
// make the item a record
makeRecord(record);
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) 2005-2013 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.report;
import java.io.Serializable;
import java.util.Map;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.namespace.QName;
/**
* Report interface.
*
* @author Roy Wetherall
* @since 2.1
*/
public interface Report
{
QName getReportType();
String getReportName();
Map<QName, Serializable> getReportProperties();
ContentReader getReportContent();
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2005-2013 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.report;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* @author Roy Wetherall
* @since 2.1
*/
public interface ReportGenerator
{
QName getReportType();
Report generateReport(NodeRef reportedUponNodeRef, String mimetype);
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2005-2011 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.report;
import org.alfresco.service.namespace.QName;
/**
* Helper class containing records management report qualified names
*
* @author Roy Wetherall
*/
public interface ReportModel
{
// Namespace details
public static final String RMR_URI = "http://www.alfresco.org/model/recordsmanagementreport/1.0";
public static final String RMR_PREFIX = "rmr";
public static final QName TYPE_REPORT = QName.createQName(RMR_URI, "report");
public static final QName TYPE_DESTRUCTION_REPORT = QName.createQName(RMR_URI, "destructionReport");
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2005-2013 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.report;
import java.util.Set;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* Report service.
*
* @author Roy Wetherall
* @since 2.1
*/
public interface ReportService
{
/**
* Register a report generator with the report service.
*
* @param reportGenerator report generator
*/
void registerReportGenerator(ReportGenerator reportGenerator);
/**
* Get a list of the available report types.
*
* @return
*/
Set<QName> getReportTypes();
/**
*
*
* @param reportType
* @param reportedUponNodeRef
* @return
*/
Report generateReport(QName reportType, NodeRef reportedUponNodeRef);
/**
*
* @param reportType
* @param reportedUponNodeRef
* @return
*/
Report generateReport(QName reportType, NodeRef reportedUponNodeRef, String mimetype);
/**
* File report as unfiled record in a file plan.
*
* @param filePlan file plan
* @param report report
* @return NodeRef node reference of unfiled record
*/
NodeRef fileReport(NodeRef filePlan, Report report);
}

View File

@@ -0,0 +1,164 @@
/*
* Copyright (C) 2005-2013 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.report;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
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.util.ServiceBaseImpl;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.springframework.extensions.surf.util.ParameterCheck;
/**
* Report service implementation.
*
* @author Roy Wetherall
* @since 2.1
*/
public class ReportServiceImpl extends ServiceBaseImpl
implements ReportService
{
/** file folder service */
protected FileFolderService fileFolderService;
/** file plan service */
protected FilePlanService filePlanService;
/** content service */
protected ContentService contentService;
/** record service */
protected RecordService recordService;
/** report generator registry */
private Map<QName, ReportGenerator> registry = new HashMap<QName, ReportGenerator>();
/**
* @param fileFolderService file folder service
*/
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
/**
* @param filePlanService file plan service
*/
public void setFilePlanService(FilePlanService filePlanService)
{
this.filePlanService = filePlanService;
}
/**
* @param contentService content service
*/
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
/**
* @param recordService record service
*/
public void setRecordService(RecordService recordService)
{
this.recordService = recordService;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.report.ReportService#registerReportGenerator(org.alfresco.module.org_alfresco_module_rm.report.ReportGenerator)
*/
@Override
public void registerReportGenerator(ReportGenerator reportGenerator)
{
ParameterCheck.mandatory("reportGenerator", reportGenerator);
registry.put(reportGenerator.getReportType(), reportGenerator);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.report.ReportService#getReportTypes()
*/
@Override
public Set<QName> getReportTypes()
{
return registry.keySet();
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.report.ReportService#generateReport(org.alfresco.service.namespace.QName, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public Report generateReport(QName reportType, NodeRef reportedUponNodeRef)
{
return generateReport(reportType, reportedUponNodeRef, MimetypeMap.MIMETYPE_HTML);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.report.ReportService#generateReport(org.alfresco.service.namespace.QName, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public Report generateReport(QName reportType, NodeRef reportedUponNodeRef, String mimetype)
{
ParameterCheck.mandatory("reportType", reportType);
ParameterCheck.mandatory("reportedUponNodeRef", reportedUponNodeRef);
ParameterCheck.mandatory("mimetype", mimetype);
// get the generator
ReportGenerator generator = registry.get(reportType);
// error is generator not found in registry
if (generator == null)
{
throw new AlfrescoRuntimeException("Unable to generate report, because report type " + reportType.toString() + " does not correspond to a registered report type.");
}
// generate the report
return generator.generateReport(reportedUponNodeRef, mimetype);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.report.ReportService#fileReport(org.alfresco.module.org_alfresco_module_rm.report.Report)
*/
@Override
public NodeRef fileReport(NodeRef filePlan, Report report)
{
ParameterCheck.mandatory("report", report);
ParameterCheck.mandatory("filePlan", filePlan);
// check that the passed node reference is a file plan
if (filePlanService.isFilePlan(filePlan) == false)
{
throw new AlfrescoRuntimeException("Unable to file report, because " + filePlan.toString() + " is not a file plan.");
}
return recordService.createRecord(filePlan,
report.getReportName(),
report.getReportType(),
report.getReportProperties(),
report.getReportContent());
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2005-2011 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.report.action;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.report.Report;
import org.alfresco.module.org_alfresco_module_rm.report.ReportModel;
import org.alfresco.module.org_alfresco_module_rm.report.ReportService;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* File Destruction Report
*
* @author Roy Wetherall
* @since 2.1
*/
public class FileDestructionReport extends RMActionExecuterAbstractBase
implements ReportModel
{
/** Action name */
public static final String NAME = "fileDestructionReport";
/** report service */
protected ReportService reportService;
/** file plan service */
protected FilePlanService filePlanService;
/**
* @param reportService report service
*/
public void setReportService(ReportService reportService)
{
this.reportService = reportService;
}
/**
* @param filePlanService file plan service
*/
public void setFilePlanService(FilePlanService filePlanService)
{
this.filePlanService = filePlanService;
}
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
{
// TODO check that the actionedUponNodeRef is in a state to generate a destruction report
// ie: is it eligable for destruction .. use fileDestructionReport capability!
// TODO allow the mimetype of the report to be specified as a parameter
NodeRef filePlan = filePlanService.getFilePlan(actionedUponNodeRef);
if (filePlan == null)
{
throw new AlfrescoRuntimeException("Unable to file destruction report, because file plan could not be resolved.");
}
Report report = reportService.generateReport(TYPE_DESTRUCTION_REPORT, actionedUponNodeRef);
reportService.fileReport(filePlan, report);
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2005-2013 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.report.generator;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.report.Report;
import org.alfresco.module.org_alfresco_module_rm.report.ReportGenerator;
import org.alfresco.module.org_alfresco_module_rm.report.ReportService;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
/**
* @author Roy Wetherall
* @since 2.1
*/
public abstract class BaseReportGenerator implements ReportGenerator
{
protected ReportService reportService;
protected NamespaceService namespaceService;
protected String reportTypeName;
protected QName reportType;
public void setReportService(ReportService reportService)
{
this.reportService = reportService;
}
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
public void setReportTypeName(String reportTypeName)
{
this.reportTypeName = reportTypeName;
}
@Override
public QName getReportType()
{
return reportType;
}
public void init()
{
// convert type name to QName
reportType = QName.createQName(reportTypeName, namespaceService);
// register report generator
reportService.registerReportGenerator(this);
}
@Override
public Report generateReport(NodeRef reportedUponNodeRef, String mimetype)
{
String reportName = generateReportName(reportedUponNodeRef);
Map<QName, Serializable> reportProperties = generateReportProperties(reportedUponNodeRef);
ContentReader contentReader = generateReportContent(reportedUponNodeRef, mimetype);
return new ReportInfo(reportType, reportName, reportProperties, contentReader);
}
protected abstract String generateReportName(NodeRef reportedUponNodeRef);
protected Map<QName, Serializable> generateReportProperties(NodeRef reportedUponNodeRef)
{
// default implementation
return new HashMap<QName, Serializable>(0);
}
protected abstract ContentReader generateReportContent(NodeRef reportedUponNodeRef, String mimetype);
}

View File

@@ -0,0 +1,159 @@
/*
* Copyright (C) 2005-2013 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.report.generator;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.util.GUID;
/**
* Declarative report generator.
*
* @author Roy Wetherall
* @since 2.1
*/
public class DeclarativeReportGenerator extends BaseReportGenerator
{
protected static final NodeRef TEMPLATE_ROOT = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "rm_report_templates");
/** content service */
protected ContentService contentService;
protected MimetypeService mimetypeService;
protected FileFolderService fileFolderService;
protected TemplateService templateService;
public void setMimetypeService(MimetypeService mimetypeService)
{
this.mimetypeService = mimetypeService;
}
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
public void setTemplateService(TemplateService templateService)
{
this.templateService = templateService;
}
/**
* @param contentService content service
*/
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.report.generator.BaseReportGenerator#generateReportName(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
protected String generateReportName(NodeRef reportedUponNodeRef)
{
// TODO Auto-generated method stub
return GUID.generate();
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.report.generator.BaseReportGenerator#generateReportContent(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
*/
@Override
protected ContentReader generateReportContent(NodeRef reportedUponNodeRef, String mimetype)
{
// get the template
NodeRef reportTemplateNodeRef = getReportTemplate(mimetype);
// get the model
Map<String, Serializable> model = new HashMap<String, Serializable>();
// run the template
String result = templateService.processTemplate("freemarker", reportTemplateNodeRef.toString(), model);
// create the temp content
ContentWriter contentWriter = contentService.getTempWriter();
contentWriter.setEncoding("UTF-8");
contentWriter.setMimetype(mimetype);
contentWriter.putContent(result);
return contentWriter.getReader();
}
/**
*
* @param mimetype
* @return
*/
private NodeRef getReportTemplate(String mimetype)
{
// check that the template root has been correctly bootstraped
if (fileFolderService.exists(TEMPLATE_ROOT) == false)
{
throw new AlfrescoRuntimeException("Unable to get report template, because the template root folder does not exist in the data dictionary.");
}
String reportTemplateName = getReportTemplateName(mimetype);
NodeRef reportTemplateNodeRef = fileFolderService.searchSimple(TEMPLATE_ROOT, reportTemplateName);
if (reportTemplateNodeRef == null)
{
throw new AlfrescoRuntimeException("Unable to get report template, because report template " + reportTemplateName + " does not exist.");
}
// get localise template
return fileFolderService.getLocalizedSibling(reportTemplateNodeRef);
}
/**
*
* @param mimetype
* @return
*/
private String getReportTemplateName(String mimetype)
{
String typePrefixName = reportType.getPrefixedQName(namespaceService).getPrefixString().replace(":", "_");
String extension = mimetypeService.getExtension(mimetype);
StringBuffer sb = new StringBuffer(128)
.append("report_")
.append(typePrefixName)
.append(".")
.append(extension)
.append(".ftl");
return sb.toString();
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2005-2013 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.report.generator;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.report.Report;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.namespace.QName;
import org.springframework.extensions.surf.util.ParameterCheck;
/**
* Report implementation.
*
* @author Roy Wetherall
* @since 2.1
*/
/*package*/ class ReportInfo implements Report
{
/** report type */
private QName reportType;
private String reportName;
private Map<QName, Serializable> reportProperties = new HashMap<QName, Serializable>(21);
/** content reader */
private ContentReader reportContent;
public ReportInfo(QName reportType, String reportName, Map<QName, Serializable> reportProperties, ContentReader reportContent)
{
ParameterCheck.mandatory("reportType", reportType);
ParameterCheck.mandatory("reportName", reportName);
ParameterCheck.mandatory("reportContent", reportContent);
this.reportType = reportType;
this.reportName = reportName;
this.reportProperties = reportProperties;
this.reportContent = reportContent;
}
public QName getReportType()
{
return reportType;
}
@Override
public String getReportName()
{
return reportName;
}
public Map<QName, Serializable> getReportProperties()
{
return reportProperties;
}
@Override
public ContentReader getReportContent()
{
return reportContent;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
* Copyright (C) 2005-2013 Alfresco Software Limited.
*
* This file is part of Alfresco
*

View File

@@ -32,18 +32,21 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
/**
*
* Parameter processor component
*
* @author Roy Wetherall
* @since 2.1
*/
public class ParameterProcessorComponent
{
/** regex used to parse parameters */
private static final String REG_EX = "\\$\\{([^\\$\\{]+)\\}";
/** registry of parameter processors */
private Map<String, ParameterProcessor> processors = new HashMap<String, ParameterProcessor>(5);
/**
* Register parameter processor
*
* @param processor
*/
@@ -70,41 +73,59 @@ public class ParameterProcessorComponent
{
if (DataTypeDefinition.TEXT.equals(def.getType()) == true)
{
// get the parameter value
String parameterValue = (String)entry.getValue();
// match the substitution pattern
Pattern patt = Pattern.compile(REG_EX);
Matcher m = patt.matcher(parameterValue);
StringBuffer sb = new StringBuffer(parameterValue.length());
while (m.find())
{
String text = m.group(1);
// lookup parameter processor to use
ParameterProcessor processor = lookupProcessor(text);
if (processor == null)
{
throw new AlfrescoRuntimeException("A parameter processor has not been found for the substitution string " + text);
}
else
{
// process each substitution value
text = processor.process(text, actionedUponNodeRef);
}
// append new value
m.appendReplacement(sb, Matcher.quoteReplacement(text));
}
m.appendTail(sb);
// set the updated parameter value
ruleItem.setParameterValue(parameterName, sb.toString());
ruleItem.setParameterValue(parameterName, process(parameterValue, actionedUponNodeRef));
}
}
}
}
/**
* Process the value for substitution within the context of the provided node.
*
* @param value value
* @param nodeRef node reference
* @return String resulting value
*/
public String process(String value, NodeRef nodeRef)
{
// match the substitution pattern
Pattern patt = Pattern.compile(REG_EX);
Matcher m = patt.matcher(value);
StringBuffer sb = new StringBuffer(value.length());
while (m.find())
{
String text = m.group(1);
// lookup parameter processor to use
ParameterProcessor processor = lookupProcessor(text);
if (processor == null)
{
throw new AlfrescoRuntimeException("A parameter processor has not been found for the substitution string " + text);
}
else
{
// process each substitution value
text = processor.process(text, nodeRef);
}
// append new value
m.appendReplacement(sb, Matcher.quoteReplacement(text));
}
m.appendTail(sb);
return sb.toString();
}
/**
* Look up parameter processor
*
* @param value
* @return
*/
private ParameterProcessor lookupProcessor(String value)
{
ParameterProcessor result = null;

View File

@@ -33,6 +33,7 @@ import org.alfresco.module.org_alfresco_module_rm.test.service.RecordsManagement
import org.alfresco.module.org_alfresco_module_rm.test.service.RecordsManagementAdminServiceImplTest;
import org.alfresco.module.org_alfresco_module_rm.test.service.RecordsManagementAuditServiceImplTest;
import org.alfresco.module.org_alfresco_module_rm.test.service.RecordsManagementSearchServiceImplTest;
import org.alfresco.module.org_alfresco_module_rm.test.service.ReportServiceImplTest;
import org.alfresco.module.org_alfresco_module_rm.test.service.VitalRecordServiceImplTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -64,7 +65,8 @@ import org.junit.runners.Suite.SuiteClasses;
CapabilityServiceImplTest.class,
FilePlanRoleServiceImplTest.class,
FilePlanServiceImplTest.class,
FilePlanPermissionServiceImplTest.class
FilePlanPermissionServiceImplTest.class,
ReportServiceImplTest.class
})
public class ServicesTestSuite
{

View File

@@ -0,0 +1,129 @@
/*
* Copyright (C) 2005-2011 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.service;
import java.util.Set;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
import org.alfresco.module.org_alfresco_module_rm.action.impl.DestroyAction;
import org.alfresco.module.org_alfresco_module_rm.report.Report;
import org.alfresco.module.org_alfresco_module_rm.report.ReportModel;
import org.alfresco.module.org_alfresco_module_rm.report.ReportService;
import org.alfresco.module.org_alfresco_module_rm.report.action.FileDestructionReport;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* Report service implementation unit test.
*
* @author Roy Wetherall
*/
public class ReportServiceImplTest extends BaseRMTestCase implements ReportModel
{
private ReportService reportService;
private RecordsManagementActionService recordsManagementActionService;
@Override
protected boolean isRecordTest()
{
return false;
}
@Override
protected void initServices()
{
super.initServices();
reportService = (ReportService)applicationContext.getBean("ReportService");
recordsManagementActionService = (RecordsManagementActionService)applicationContext.getBean("RecordsManagementActionService");
}
public void testGetReportTypes() throws Exception
{
doTestInTransaction(new Test<Void>()
{
@Override
public Void run() throws Exception
{
Set<QName> reportTypes = reportService.getReportTypes();
assertNotNull(reportTypes);
assertFalse(reportTypes.isEmpty());
for (QName reportType : reportTypes)
{
System.out.println(reportType.toString());
}
return null;
}
});
}
public void testGenerateReport() throws Exception
{
doTestInTransaction(new Test<Void>()
{
@Override
public Void run() throws Exception
{
Report report = reportService.generateReport(TYPE_DESTRUCTION_REPORT, rmFolder);
System.out.println(report.getReportContent().getContentString());
return null;
}
});
}
public void testFileReport() throws Exception
{
doTestInTransaction(new Test<Void>()
{
@Override
public Void run() throws Exception
{
Report report = reportService.generateReport(TYPE_DESTRUCTION_REPORT, rmFolder);
NodeRef reportNodeRef = reportService.fileReport(filePlan, report);
assertNotNull(reportNodeRef);
assertTrue(recordService.isRecord(reportNodeRef));
assertFalse(recordService.isFiled(reportNodeRef));
assertEquals(TYPE_DESTRUCTION_REPORT, nodeService.getType(reportNodeRef));
return null;
}
});
}
public void testFileDestructionReportAction() throws Exception
{
doTestInTransaction(new Test<Void>()
{
@Override
public Void run() throws Exception
{
recordsManagementActionService.executeRecordsManagementAction(rmFolder, DestroyAction.NAME);
recordsManagementActionService.executeRecordsManagementAction(rmFolder, FileDestructionReport.NAME);
return null;
}
});
}
}