diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/RMDataDictionaryBootstrap.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/RMDataDictionaryBootstrap.xml index ab0eab9ccb..68a61c8775 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/RMDataDictionaryBootstrap.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/RMDataDictionaryBootstrap.xml @@ -185,7 +185,39 @@ - + + + + workspace + SpacesStore + rm_report_templates + Records Management Report Templates + Records Management Report Templates + Records management report templates. + + + + + + + + + + + + workspace + SpacesStore + rmr_destructionReport + Desruction report template. + contentUrl=classpath:alfresco/module/org_alfresco_module_rm/bootstrap/report/report_rmr_destructionReport.html.ftl|mimetype=text/plain|encoding=UTF-8 + Destruction Report Template + report_rmr_destructionReport.html.ftl + + + + + + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/report/report_rmr_destructionReport.html.ftl b/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/report/report_rmr_destructionReport.html.ftl new file mode 100644 index 0000000000..068f7fdc84 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/report/report_rmr_destructionReport.html.ftl @@ -0,0 +1,10 @@ + + + + + + +

Destruction Report

+ + + \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml index 2113dbe123..921eb9cf91 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml @@ -84,6 +84,17 @@ + + + + + + + + + + + + + + + + RECORD_FOLDER + RECORD + + + + + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-record-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-record-context.xml index c9723f6141..67b827eaf0 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-record-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-record-context.xml @@ -283,6 +283,7 @@ + @@ -298,5 +299,27 @@ + + + + + + + + RECORD + RECORD_FOLDER + + + + + + + + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-model.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-model.properties new file mode 100644 index 0000000000..2e0a528dad --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-model.properties @@ -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. \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsPermissionModel.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsPermissionModel.xml index a3138536b5..bc080a360a 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsPermissionModel.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsPermissionModel.xml @@ -83,6 +83,7 @@ + @@ -158,6 +159,7 @@ + @@ -415,6 +417,10 @@ + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/reportModel.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/reportModel.xml new file mode 100644 index 0000000000..eb44c18010 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/reportModel.xml @@ -0,0 +1,46 @@ + + + + + + + + + Records Management Report Model + Roy Wetherall + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + Report + cm:content + + + + Report + rmr:report + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml index a654b96cda..f2bec049c9 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml @@ -113,6 +113,9 @@ + + + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml index 72cb53840f..ec7fc7dd1d 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml @@ -244,7 +244,7 @@ - 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 @@ -253,9 +253,8 @@ - - - + + ${rm.ghosting.enabled} diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-report-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-report-context.xml new file mode 100644 index 0000000000..514c17450b --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-report-context.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + alfresco/module/org_alfresco_module_rm/model/reportModel.xml + + + + + alfresco/module/org_alfresco_module_rm/messages/report-model + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml index 777dad0bfb..382d5ac3a4 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml @@ -1127,6 +1127,7 @@ + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml index 02d4d81323..85b0ebae71 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml @@ -411,7 +411,19 @@ RECORD - + + + + + + + + RECORD_FOLDER + RECORD + + + . + */ +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 conditions; + + /** + * @param conditions capability conditions + */ + public void setConditions(List 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; + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/ModulePatchComponent.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/ModulePatchComponent.java new file mode 100644 index 0000000000..c64cfca7d3 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/ModulePatchComponent.java @@ -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 . + */ +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; +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/NotificationTemplatePatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/NotificationTemplatePatch.java index ada4490556..6d466a412b 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/NotificationTemplatePatch.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/NotificationTemplatePatch.java @@ -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) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/NotificationTemplatePatch_v21.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/NotificationTemplatePatch_v21.java index 062ac05d23..35c586a8a8 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/NotificationTemplatePatch_v21.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/NotificationTemplatePatch_v21.java @@ -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) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21CapabilityPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21CapabilityPatch.java index 149fbc6be3..abd78bbc19 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21CapabilityPatch.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21CapabilityPatch.java @@ -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) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21InPlacePatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21InPlacePatch.java index f08d6ede9a..4ed480f95e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21InPlacePatch.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21InPlacePatch.java @@ -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) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21RecordInheritancePatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21RecordInheritancePatch.java index c8a4e93db3..0152c95238 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21RecordInheritancePatch.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21RecordInheritancePatch.java @@ -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) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21RolesPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21RolesPatch.java index 8b4fb31eb2..8651c8fdfc 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21RolesPatch.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21RolesPatch.java @@ -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 filePlans = filePlanService.getFilePlans(); + + if (logger.isDebugEnabled() == true) + { + logger.debug(" ... updating " + filePlans.size() + " file plans"); + } + for (NodeRef filePlan : filePlans) { boolean parentAddedToZone = false; Set 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) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2FilePlanNodeRefPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2FilePlanNodeRefPatch.java index ffd3623829..0a128715d9 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2FilePlanNodeRefPatch.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2FilePlanNodeRefPatch.java @@ -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) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2ModelPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2ModelPatch.java index b4b1e5368b..7d8fa3549c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2ModelPatch.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2ModelPatch.java @@ -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) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2RMAdminUserPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2RMAdminUserPatch.java index f80238f0af..fee1762f86 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2RMAdminUserPatch.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2RMAdminUserPatch.java @@ -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) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2SavedSearchPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2SavedSearchPatch.java index 24051c605f..49996e0a6f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2SavedSearchPatch.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2SavedSearchPatch.java @@ -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) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java index 9f1d9ac273..e8ae768e8b 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java @@ -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 properties, ContentReader reader); /** * Indicates whether the record is filed or not diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index 314e639e0d..4604d27314 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -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 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 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); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/Report.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/Report.java new file mode 100644 index 0000000000..5c90cd14e8 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/Report.java @@ -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 . + */ +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 getReportProperties(); + + ContentReader getReportContent(); + +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportGenerator.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportGenerator.java new file mode 100644 index 0000000000..044382d736 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportGenerator.java @@ -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 . + */ +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); + +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportModel.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportModel.java new file mode 100644 index 0000000000..07a1134d3b --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportModel.java @@ -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 . + */ +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"); +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportService.java new file mode 100644 index 0000000000..7e98826085 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportService.java @@ -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 . + */ +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 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); +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportServiceImpl.java new file mode 100644 index 0000000000..6d08071293 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/ReportServiceImpl.java @@ -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 . + */ +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 registry = new HashMap(); + + /** + * @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 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()); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/action/FileDestructionReport.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/action/FileDestructionReport.java new file mode 100644 index 0000000000..1732b06250 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/action/FileDestructionReport.java @@ -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 . + */ +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); + + } +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/generator/BaseReportGenerator.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/generator/BaseReportGenerator.java new file mode 100644 index 0000000000..8d05ffb30c --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/generator/BaseReportGenerator.java @@ -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 . + */ +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 reportProperties = generateReportProperties(reportedUponNodeRef); + ContentReader contentReader = generateReportContent(reportedUponNodeRef, mimetype); + return new ReportInfo(reportType, reportName, reportProperties, contentReader); + } + + protected abstract String generateReportName(NodeRef reportedUponNodeRef); + + + protected Map generateReportProperties(NodeRef reportedUponNodeRef) + { + // default implementation + return new HashMap(0); + } + + protected abstract ContentReader generateReportContent(NodeRef reportedUponNodeRef, String mimetype); + +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/generator/DeclarativeReportGenerator.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/generator/DeclarativeReportGenerator.java new file mode 100644 index 0000000000..5379039ee5 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/generator/DeclarativeReportGenerator.java @@ -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 . + */ +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 model = new HashMap(); + + // 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(); + } + +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/generator/ReportInfo.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/generator/ReportInfo.java new file mode 100644 index 0000000000..9f1d262047 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/report/generator/ReportInfo.java @@ -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 . + */ +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 reportProperties = new HashMap(21); + + /** content reader */ + private ContentReader reportContent; + + public ReportInfo(QName reportType, String reportName, Map 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 getReportProperties() + { + return reportProperties; + } + + @Override + public ContentReader getReportContent() + { + return reportContent; + } + +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleService.java index cdf37efd07..61e6f2b498 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2012 Alfresco Software Limited. + * Copyright (C) 2005-2013 Alfresco Software Limited. * * This file is part of Alfresco * diff --git a/rm-server/source/java/org/alfresco/repo/action/parameter/ParameterProcessorComponent.java b/rm-server/source/java/org/alfresco/repo/action/parameter/ParameterProcessorComponent.java index e58bfa3bdb..d3798e3667 100644 --- a/rm-server/source/java/org/alfresco/repo/action/parameter/ParameterProcessorComponent.java +++ b/rm-server/source/java/org/alfresco/repo/action/parameter/ParameterProcessorComponent.java @@ -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 processors = new HashMap(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; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ServicesTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ServicesTestSuite.java index 31d60e7b78..12225298ba 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ServicesTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ServicesTestSuite.java @@ -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 { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/ReportServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/ReportServiceImplTest.java new file mode 100644 index 0000000000..e8d18ddaf4 --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/ReportServiceImplTest.java @@ -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 . + */ +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() + { + @Override + public Void run() throws Exception + { + Set 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() + { + @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() + { + @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() + { + @Override + public Void run() throws Exception + { + recordsManagementActionService.executeRecordsManagementAction(rmFolder, DestroyAction.NAME); + recordsManagementActionService.executeRecordsManagementAction(rmFolder, FileDestructionReport.NAME); + return null; + } + }); + } +}