diff --git a/README.txt b/README.txt index 27ada2f806..15d8f9c13e 100644 --- a/README.txt +++ b/README.txt @@ -25,10 +25,8 @@ Using Eclipse Summary of Available Ant Targets - - configureSolr : Configures Solr for Alfresco - fullBuild : Creates the amp file and applies it to the war file - incrementalBuild : Creates the jar file and copies the jar file with other files like css, js, ftl, etc. files - - prepareEnv : Prepares the development environment (must be run just once) Summary of Available Internal Ant Targets @@ -36,6 +34,7 @@ Summary of Available Internal Ant Targets - alfresco:amp : Creates the amp file using alfresco maven plugin - alfresco:install : Installs the amp file to the war file - assembleIconPackage : Assembles an icons package for the module + - configureSolr : Configures Solr4 for Alfresco - copyDBDriver : Copies the DB driver - copyDevContextFile : Copies the dev-context.xml file - copyWarFileToTomcat : Copies the war file (amp applied) to the webapp folder @@ -46,4 +45,5 @@ Summary of Available Internal Ant Targets - fetchWarFile : Gets the "original" war file - install : Executes the "mvn install" command - package : Executes the "mvn package" command + - prepareEnv : Prepares the development environment (must be run just once) - unitTest : Runs the unit tests \ No newline at end of file diff --git a/pom.xml b/pom.xml index 64a7a3cacd..1f6772f294 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ - 5.0.b + 5.0.c org.postgresql.Driver @@ -79,9 +79,7 @@ false 1.7 UTF-8 - - - ${project.build.directory}/jacoco.exec + -Xmx1024m -XX:MaxPermSize=256m -Duser.language=en -Dcom.sun.management.jmxremote @@ -198,7 +196,6 @@ true alphabetical - -Xmx1024m -XX:MaxPermSize=256m -Duser.language=en -Dcom.sun.management.jmxremote ${db.url} @@ -307,4 +304,4 @@ - \ No newline at end of file + diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml new file mode 100644 index 0000000000..1221af32e3 --- /dev/null +++ b/rm-automation/pom.xml @@ -0,0 +1,312 @@ + + + + org.alfresco + alfresco-rm-parent + 2.3-SNAPSHOT + + 4.0.0 + alfresco-rm-automation + + 2.43.1 + 4.0.5.RELEASE + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-test-source + + add-test-source + + + + src/unit-test/java + + + + + + + maven-surefire-plugin + + false + + + usedefaultlisteners + false + + + listener + org.uncommons.reportng.HTMLReporter, org.uncommons.reportng.JUnitXMLReporter + + + + ${project.build.testOutputDirectory}/testng.xml + + + + + + maven-antrun-plugin + + + default-cli + + + Stopping Alfresco... + + + + + + + + + + + + + org.alfresco + webdrone + 2.6.1 + + + org.seleniumhq.selenium + selenium-java + ${selenium.version} + + + org.seleniumhq.selenium + selenium-server + ${selenium.version} + test + + + org.springframework + spring-beans + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + test + + + org.springframework + spring-test + ${spring.version} + test + + + org.testng + testng + 6.8.8 + test + + + org.uncommons + reportng + 1.1.4 + test + + + ru.yandex.qatools.htmlelements + htmlelements-all + 1.12 + + + ru.yandex.qatools.properties + properties-loader + 1.5 + test + + + + + install-alfresco + + + + + maven-antrun-plugin + + + fetch-installer + generate-test-resources + + run + + + + Recreating database... + drop database if exists alfresco; create database alfresco + Downloading Alfresco installer... + + + + Installing Alfresco... + + + + + + + + + + org.apache.ant + ant-jsch + 1.8.2 + + + postgresql + postgresql + 9.1-901-1.jdbc4 + + + + + maven-dependency-plugin + + + fetch-amps + process-test-resources + + copy + + + + + org.alfresco + alfresco-rm-share + ${project.version} + amp + amp + + + org.alfresco + alfresco-rm-server + ${project.version} + amp + amp + + + ${project.build.directory}/amps + true + + + + + + org.alfresco.maven.plugin + alfresco-maven-plugin + true + + + install-server-amp + + install + + process-test-resources + + true + ${project.build.directory}/amps/alfresco-rm-server-${project.version}-amp.amp + ${project.build.directory}/alf-installation/tomcat/webapps/alfresco.war + amp + + + + install-share-amp + + install + + process-test-resources + + true + ${project.build.directory}/amps/alfresco-rm-share-${project.version}-amp.amp + ${project.build.directory}/alf-installation/tomcat/webapps/share.war + amp + + + + + + + + + run-alfresco + + + + + org.jacoco + jacoco-maven-plugin + 0.6.3.201306030806 + + + prepare-jacoco + + prepare-agent + + + + + + org.alfresco.* + + + + + + maven-antrun-plugin + + + start-alfresco + process-test-classes + + run + + + + Starting Alfresco... + + + + + + + + + + stop-alfresco + post-integration-test + + run + + + + Stopping Alfresco... + + + + + + + + + + + + + \ No newline at end of file diff --git a/rm-server/build.properties b/rm-server/build.properties index 822952c94d..fa6182cc67 100644 --- a/rm-server/build.properties +++ b/rm-server/build.properties @@ -5,16 +5,4 @@ app.war.artifactId=alfresco # Tomcat folder name used by the alfresco application -app.tomcat=tomcat - -# Solr configuration -solr.directory=solr -solr.artifactId=alfresco-solr -solr.packaging=zip -solr.package=${solr.artifactId}.${solr.packaging} - -# DB driver properties -db.driver.groupId=postgresql -db.driver.artifactId=${db.driver.groupId} -db.driver.version=9.1-901.jdbc4 -db.driver.packaging=jar \ No newline at end of file +app.tomcat=tomcat \ No newline at end of file diff --git a/rm-server/build.xml b/rm-server/build.xml index 14109d68ef..38b8d1509c 100644 --- a/rm-server/build.xml +++ b/rm-server/build.xml @@ -10,10 +10,10 @@ - - - - + + + + @@ -24,7 +24,92 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + @@ -32,72 +117,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> - ]]> - - - - - - - - - \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/action-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/action-context.xml index 3f5c40a98b..be1376b68e 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/action-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/action-context.xml @@ -12,7 +12,8 @@ - + + @@ -24,12 +25,25 @@ + + + + + + + + + + {http://www.alfresco.org/model/content/1.0}content + + + - + @@ -40,4 +54,12 @@ + + + + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties index 60f0b0e0d6..358bcbd635 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/alfresco-global.properties @@ -47,3 +47,13 @@ rm.autocompletesuggestion.nodeParameterSuggester.aspectsAndTypes=rma:record,cm:c # Global RM disposition lifecycle trigger cron job expression # rm.dispositionlifecycletrigger.cronexpression=0 0/5 * * * ? + +# +# Records contributors group +# +# if false then record contributor check is ignored and all users can contribute records from +# a collaboration site, if true then a user must be a member of the records contributor group +# in order for them to contribute a record from a collaboration site. Default value 'false'. +rm.record.contributors.group.enabled=false +# record contributors group, default value 'RECORD_CONTRIBUTORS' +rm.record.contributors.group.name=RECORD_CONTRIBUTORS diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/content/recordsCustomModel.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/content/recordsCustomModel.xml index b66fc56088..9e3244ce81 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/content/recordsCustomModel.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/content/recordsCustomModel.xml @@ -74,7 +74,7 @@ - SupersededBy__Supersedes + Superseded By__Supersedes false true @@ -87,7 +87,7 @@ - ObsoletedBy__Obsoletes + Obsoleted By__Obsoletes false true @@ -100,7 +100,7 @@ - VersionedBy__Versions + Next Version__Previous Version false true diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/content/rmEventConfigBootstrap.json b/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/content/rmEventConfigBootstrap.json index d0bb84cc0f..6eb58eff72 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/content/rmEventConfigBootstrap.json +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/bootstrap/content/rmEventConfigBootstrap.json @@ -26,6 +26,11 @@ "eventName" : "superseded", "eventDisplayLabel" : "rmevent.superseded" }, + { + "eventType" : "rmEventType.versioned", + "eventName" : "versioned", + "eventDisplayLabel" : "rmevent.versioned" + }, { "eventType" : "rmEventType.simple", "eventName" : "study_complete", diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-disposition-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-disposition-context.xml index 2688b3c450..ba01166921 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-disposition-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-disposition-context.xml @@ -157,6 +157,30 @@ + + + + + + + + RECORD_FOLDER + RECORD + + + + + + + + + + + + + + - - - - - - - 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 f3e8e1f0c1..77bf507775 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 @@ -108,6 +108,11 @@ parent="declarativeCapability"> + + + RECORD + + @@ -119,6 +124,25 @@ + + + + + + + RECORD + + + + + + + + + + + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-reference-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-reference-context.xml index 39ec906d7a..459b7790a2 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-reference-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-reference-context.xml @@ -20,26 +20,4 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/dod5015/messages/dod5015-model_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/dod5015/messages/dod5015-model_nb.properties new file mode 100644 index 0000000000..94eb04cae4 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/dod5015/messages/dod5015-model_nb.properties @@ -0,0 +1,98 @@ +dod_dod5015.description=DOD5015-innholdsmodell + +dod_dod5015.type.dod_site.title=DOD5015-omr\u00e5de +dod_dod5015.type.dod_site.description=DOD5015-omr\u00e5de + +dod_dod5015.type.dod_filePlan.title=DOD5015-filplan +dod_dod5015.type.dod_filePlan.description=DOD5015-filplan + +dod_dod5015.type.dod_recordSeries.title=Oppf\u00f8ringsserie (avskrevet) +dod_dod5015.type.dod_recordSeries.description=Oppf\u00f8ringsserie (avskrevet) + +dod_dod5015.aspect.dod_dod5015record.title=DOD5015-oppf\u00f8ring +dod_dod5015.aspect.dod_dod5015record.description=DOD5015-oppf\u00f8ring +dod_dod5015.property.dod_publicationDate.title=Publikasjonsdato +dod_dod5015.property.dod_publicationDate.decription=Publikasjonsdato +dod_dod5015.property.dod_originator.title=Avsender +dod_dod5015.property.dod_originator.decription=Avsender +dod_dod5015.property.dod_originatingOrganization.title=Utgangsorganisasjon +dod_dod5015.property.dod_originatingOrganization.decription=Utgangsorganisasjon +dod_dod5015.property.dod_mediaType.title=Medietype +dod_dod5015.property.dod_mediaType.decription=Medietype +dod_dod5015.property.dod_format.title=Format +dod_dod5015.property.dod_format.decription=Format +dod_dod5015.property.dod_dateReceived.title=Dato mottatt +dod_dod5015.property.dod_dateReceived.decription=Dato mottatt +dod_dod5015.property.dod_address.title=Mottaker +dod_dod5015.property.dod_address.decription=Mottaker +dod_dod5015.property.dod_otherAddress.title=Andre mottakere +dod_dod5015.property.dod_otherAddress.decription=Andre mottakere + +dod_dod5015.aspect.dod_scannedRecord.title=Skannet oppf\u00f8ring +dod_dod5015.aspect.dod_scannedRecord.description=Skannet oppf\u00f8ring +dod_dod5015.property.dod_scannedFormat.title=Bildeformat +dod_dod5015.property.dod_scannedFormat.description=Bildeformat +dod_dod5015.property.dod_scannedFormatVersion.title=Bildeformat og -versjon +dod_dod5015.property.dod_scannedFormatVersion.description=Bildeformat og -versjon +dod_dod5015.property.dod_resolutionX.title=Bildeoppl\u00f8sning X +dod_dod5015.property.dod_resolutionX.description=Bildeoppl\u00f8sning X +dod_dod5015.property.dod_resolutionY.title=Bildeoppl\u00f8sning Y +dod_dod5015.property.dod_resolutionY.description=Bildeoppl\u00f8sning Y +dod_dod5015.property.dod_scannedBitDepth.title=Skannet bitdybde +dod_dod5015.property.dod_scannedBitDepth.description=Skannet bitdybde + +dod_dod5015.aspect.dod_pdfRecord.title=PDF-oppf\u00f8ring +dod_dod5015.aspect.dod_pdfRecord.description=PDF-oppf\u00f8ring +dod_dod5015.property.dod_producingApplication.title=Produserende program +dod_dod5015.property.dod_producingApplication.description=Produserende program +dod_dod5015.property.dod_producingApplicationVersion.title=Produserende programversjon +dod_dod5015.property.dod_producingApplicationVersion.description=Produserende programversjon +dod_dod5015.property.dod_pdfVersion.title=PDF-versjon +dod_dod5015.property.dod_pdfVersion.description=PDF-versjon +dod_dod5015.property.dod_creatingApplication.title=Opprette program +dod_dod5015.property.dod_creatingApplication.description=Opprette program +dod_dod5015.property.dod_documentSecuritySettings.title=Innstillinger ved dokumentsikkerhet +dod_dod5015.property.dod_documentSecuritySettings.description=Innstillinger ved dokumentsikkerhet + +dod_dod5015.aspect.dod_digitalPhotographRecord.title=Digital bildeoppf\u00f8ring +dod_dod5015.aspect.dod_digitalPhotographRecord.description=Digital bildeoppf\u00f8ring +dod_dod5015.property.dod_caption.title=Tittel +dod_dod5015.property.dod_caption.description=Tittel +dod_dod5015.property.dod_photographer.title=Fotograf +dod_dod5015.property.dod_photographer.description=Fotograf +dod_dod5015.property.dod_copyright.title=Copyright +dod_dod5015.property.dod_copyright.description=Copyright +dod_dod5015.property.dod_bitDepth.title=Bitdybde +dod_dod5015.property.dod_bitDepth.description=Bitdybde +dod_dod5015.property.dod_imageSizeX.title=Bildest\u00f8rrelse X +dod_dod5015.property.dod_imageSizeX.description=Bildest\u00f8rrelse X +dod_dod5015.property.dod_imageSizeY.title=Bildest\u00f8rrelse Y +dod_dod5015.property.dod_imageSizeY.description=Bildest\u00f8rrelse Y +dod_dod5015.property.dod_imageSource.title=Bildekilde +dod_dod5015.property.dod_imageSource.description=Bildekilde +dod_dod5015.property.dod_compression.title=Komprimering +dod_dod5015.property.dod_compression.description=Komprimering +dod_dod5015.property.dod_iccIcmProfile.title=ICC/ICM-profil +dod_dod5015.property.dod_iccIcmProfile.description=ICC/ICM-profil +dod_dod5015.property.dod_exifInformation.title=EXIF-informasjon +dod_dod5015.property.dod_exifInformation.description=EXIF-informasjon + +dod_dod5015.aspect.dod_webRecord.title=Nettoppf\u00f8ring +dod_dod5015.aspect.dod_webRecord.description=Nettoppf\u00f8ring +dod_dod5015.property.dod_webFileName.title=Nettfilnavn +dod_dod5015.property.dod_webFileName.description=Nettfilnavn +dod_dod5015.property.dod_webPlatform.title=Nettplattform +dod_dod5015.property.dod_webPlatform.description=Nettplattform +dod_dod5015.property.dod_webSiteName.title=Nettstedsnavn +dod_dod5015.property.dod_webSiteName.description=Nettstedsnavn +dod_dod5015.property.dod_webSiteURL.title=Nettstedsadresse +dod_dod5015.property.dod_webSiteURL.description=Nettstedsadresse +dod_dod5015.property.dod_captureMethod.title=Opptaksmetode +dod_dod5015.property.dod_captureMethod.description=Opptaksmetode +dod_dod5015.property.dod_captureDate.title=Opptaksdato +dod_dod5015.property.dod_captureDate.description=Opptaksdato +dod_dod5015.property.dod_contact.title=Kontakt +dod_dod5015.property.dod_contact.description=Kontakt +dod_dod5015.property.dod_contentManagementSystem.title=Innholdsforvaltningssystem +dod_dod5015.property.dod_contentManagementSystem.description= Innholdsforvaltningssystem + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/dod5015/messages/dod5015_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/dod5015/messages/dod5015_nb.properties new file mode 100644 index 0000000000..2b2676732c --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/dod5015/messages/dod5015_nb.properties @@ -0,0 +1,8 @@ +# Classified Records Capabilities +capability.group.classifiedRecords.title=Klassifiserte oppf\u00f8ringer +capability.UpdateClassificationDates.title=Oppdater klassifiseringdatoer +capability.CreateModifyDestroyClassificationGuides.title=Opprett Endre Destruer klassifiseringeveiledninger +capability.UpgradeDowngradeAndDeclassifyRecords.title=Oppgrader, last ned og deklassifiser oppf\u00f8ringer +capability.UpdateExemptionCategories.title=Oppdater unntakskategorier +capability.MapClassificationGuideMetadata.title=Koble klassifiseringsveiledning metadata +capability.CreateModifyDestroyTimeframes.title=Opprett Endre Destruer tidsrammer \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml index e350a5519e..6f589e52b4 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml @@ -134,6 +134,9 @@ + + + @@ -198,7 +201,7 @@ - + @@ -229,20 +232,17 @@ - + false - - - - - ${rm.rule.runasadmin} - - + + + + ${rm.rule.runasadmin} + - - + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties index ebe4271aef..7a14ca27f5 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties @@ -16,7 +16,7 @@ log4j.logger.org.alfresco.module.org_alfresco_module_rm.patch=info log4j.logger.org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityInterceptor=debug # -# RM permission debug +# RM permission debug # #log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.RMEntryVoter=debug #log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.RMAfterInvocationProvider=debug @@ -46,4 +46,13 @@ log4j.logger.org.alfresco.module.org_alfresco_module_rm.behaviour.BaseBehaviourB # # Patch debug # -log4j.logger.org.alfresco.module.org_alfresco_module_rm.patch=info \ No newline at end of file +log4j.logger.org.alfresco.module.org_alfresco_module_rm.patch=info +# +# RM Audit service debug +# +#log4j.logger.org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService=debug + +# +# Job debug +# +#log4j.logger.org.alfresco.module.org_alfresco_module_rm.job=debug \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/action-service_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/action-service_nb.properties new file mode 100644 index 0000000000..3bc5f998cd --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/action-service_nb.properties @@ -0,0 +1,39 @@ +rm.action.not-defined=Oppf\u00f8ringsh\u00e5ndteringshandlingen {0} er ikke definert. +rm.action.no-implicit-noderef=Oppf\u00f8ringsh\u00e5ndteringshandlingen {0} kunne ikke utf\u00f8res fordi implementering av handlingen ikke gir implisitt nodeRef. +rm.action.record-not-declared=Disposisjonshandlingen {0} kunne ikke utf\u00f8re fordi oppf\u00f8ringen ikke er fullf\u00f8rt. (actionedUponNodeRef={1}) +rm.action.expected-record-level=Disposisjonshandlingen {0} kunne ikke utf\u00f8res fordi dette ikke er en oppf\u00f8ring. (actionedUponNodeRef={1}) +rm.action.not-all-records-declared=Disposisjonshandlingen {0} kunne ikke utf\u00f8res fordi ikke alle oppf\u00f8ringsmappene var fullf\u00f8rt. (actionedUponNodeRef={1}) +rm.action.not-eligible=Disposisjonshandlingen {0} kunne ikke utf\u00f8res fordi neste disposisjonshandling p\u00e5 oppf\u00f8ringen eller oppf\u00f8ringsmappen ikke er kvalifisert. (actionedUponNodeRef={1}) +rm.action.no-disposition-instructions=Disposisjonsh\u00e5ndlingen {0} kunne ikke utf\u00f8res fordi ingen disposisjonsinstruksjoner ble funnet. (nodeRef={1}) +rm.action.no-disposition-lisfecycle-set=Disposisjonshandlingen {0} kunne ikke utf\u00f8res fordi det ikke fantes noe tilgjengelig livssyklussett ved disposisjon. (nodeRef={1}) +rm.action.next-disp-not-set=Disposisjonshandlingen {0} kunne ikke utf\u00f8res fordi neste disposisjonshandling ikker er et sett. (nodeRef={1}) +rm.action.not-next-disp=Disposisjonshandlingen {0} kunne ikke utf\u00f8res fordi dette ikker er den neste disposisjonshandlingen til denne oppf\u00f8ringen eller oppf\u00f8ringsmappen. (nodeRef={1}) +rm.action.not-record-folder=Disposisjonshandlingen {0} kunne ikke utf\u00f8res fordi dette ikke er en oppf\u00f8ringsmappe. (nodeRef={1}) +rm.action.actioned-upon-not-record=Disposisjonshandlingen {0} kunne ikke utf\u00f8res fordi dette ikke er en oppf\u00f8ring. (filePlanComponet={1}) +rm.action.custom-aspect-not-recognised=Den tilpassede typen kan ikke brukes fordi den ikke gjenkjennes. (customAspect={0}) +rm.action.event-no-disp-lc=Hendelsen {0} kan ikke fullf\u00f8res fordi den ikke er definert p\u00e5 livssyklusen ved disposisjon. +rm.action.undeclared-only-records=Kun oppf\u00f8ringer kan fullf\u00f8res. (nodeRef={0}) +rm.action.no-declare-mand-prop=Oppf\u00f8ringen kan ikke fullf\u00f8res fordi ikke alle de obligatoriske egenskapene til oppf\u00f8ringene er stilt inn. +rm.action.ghosted-prop-update=Innholdsegenskapen til en oppf\u00f8ring som er destruert tidligere, kan ikke oppdateres. +rm.action.valid-date-disp-asof=Disposisjonshandlingen per en dato m\u00e5 v\u00e6re en gyldig dato. +rm.action.disp-asof-lifecycle-applied=Disposisjonen per en dato til en oppf\u00f8ring eller oppf\u00f8ringsmappe der en livssyklus er p\u00e5f\u00f8rt, kan ikke redigeres. +rm.action.hold-edit-reason-none=Grunnen til holdet kan ikke redigeres fordi ingen grunn er oppgitt. +rm.action.hold-edit-type=Grunnen til holdet kan ikke redigeres fordi handlingen p\u00e5 noden ikke er en type {0}. (nodeRef={1}) +rm.action.specify-avlid-date=Gjennomgangen per en dato m\u00e5 v\u00e6re en gyldig dato. +rm.action.review-details-only=Kun gjennomgangsdetaljene til sv\u00e6rt viktige oppf\u00f8ringer kan redigeres. +rm.action.freeze-no-reason=En oppf\u00f8ring kan ikke settes p\u00e5 hold uten grunn. +rm.action.freeze-only-records-folders=Kun oppf\u00f8ringer eller oppf\u00f8ringsmapper kan settes p\u00e5 hold. +rm.action.no-open-record-folder=Oppf\u00f8ringsmappen kan ikke \u00e5pnes fordi den ikke er definert som oppf\u00f8ringsmappe. (actionedUponNodeRef={0}) +rm.action.not-hold-type=Hold kunne ikke oppheves fordi noden ikke er av typen {0}. (actionedUponNodeRef={1}) +rm.action.no-read-mime-message=Mimetypemeldingen kunne ikke leses fordi {0}. +rm.action.email-declared=E-posten kunne ikke deles fordi oppf\u00f8ringen er fullf\u00f8rt. (actionedUponNodeRef={0}) +rm.action.email-not-record=E-posten kunne ikke deles fordi noden ikke er en oppf\u00f8ring. (actionedUponNodeRef={0}) +rm.action.email-create-child-assoc=Kunne ikke opprette en egendefinert barnassosiasjon. +rm.action.node-already-transfer=Noden overf\u00f8res allerede. +rm.action.node-not-transfer=Noden er ikke et overf\u00f8ringselement. +rm.action.undo-not-last=Cut off kan ikke angres fordi det ikke var cut off ved den siste disposisjonshandlingen. +rm.action.records_only_undeclared=Kun oppf\u00f8ringer kan fullf\u00f8res. +rm.action.event-not-undone=Hendelsen {0} kan ikke angres fordi den ikke er definert i livssyklusen ved disposisjon. +rm.action.node-not-record-category=Disposisjonsplanen kunne ikke opprettes fordi handlingen p\u00e5 noden ({0}) ikke var en oppf\u00f8ringskategori. +rm.action.parameter-not-supplied=Parameteren ''{0}'' er ikke satt opp. +rm.action.delete-not-hold-type=Hold kan ikke slettes fordi noden ikke er av typen {0}. (actionedUponNodeRef={1}) \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/action-service_ru.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/action-service_ru.properties index 64e61bff59..cb5527bdc5 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/action-service_ru.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/action-service_ru.properties @@ -35,5 +35,5 @@ rm.action.undo-not-last=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u rm.action.records_only_undeclared=\u0422\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u043e\u0434\u043b\u0435\u0436\u0430\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044e. rm.action.event-not-undone=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 {0}: \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u0432 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u044f. rm.action.node-not-record-category=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0413\u0440\u0430\u0444\u0438\u043a \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u044f: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 ({0}) \u043d\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438. -rm.action.parameter-not-supplied=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u00ab{0}\u00bb \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d. +rm.action.parameter-not-supplied=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 ''{0}'' \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d. rm.action.delete-not-hold-type=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u044c \u0443\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0435 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u043a \u0442\u0438\u043f\u0443 {0}. (actionedUponNodeRef={1}) \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties index 690be465e8..c2bfb686f4 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties @@ -51,6 +51,10 @@ create-record.title=Declare as record create-record.description=Declares document as a record. create-record.file-plan.display-label=File plan create-record.hide-record.display-label=Hide Record +# Declare As Version Record +declare-as-version-record.title=Declare as version record +declare-as-version-record.description=Declares new version of document as a version record. +declare-as-version-record.file-plan.display-label=File plan # Complete record declareRecord.title=Complete record declareRecord.description=Completes a record. @@ -181,6 +185,10 @@ fileReport.description=File report # Delete Hold deleteHold.title=Delete Hold deleteHold.description=Delete hold +# Recordable version config +recordable-version-config.title=Recordable Version Config +recordable-version-config.description=Recordable Version Config +recordable-version-config.version.display-label=Recorded Versions # Action parameter constraints rm-ac-is-kind-kinds.record_category=Record Category @@ -189,4 +197,8 @@ rm-ac-is-kind-kinds.record=Record rm-ac-disposition-action-relative-positions.next=Next rm-ac-disposition-action-relative-positions.previous=Previous -rm-ac-disposition-action-relative-positions.any=Any \ No newline at end of file +rm-ac-disposition-action-relative-positions.any=Any + +ac-versions.none=None +ac-versions.major_only=Major Revisions Only +ac-versions.all=All Revisions \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_de.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_de.properties index 2ddc435e1d..ace09005ac 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_de.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_de.properties @@ -181,6 +181,10 @@ fileReport.description=Bericht ablegen # Delete Hold deleteHold.title=Sperrbereich l\u00f6schen deleteHold.description=Sperrbereich l\u00f6schen +# Recordable version config +recordable-version-config.title=Konfiguration als Record deklarierbarer Versionen +recordable-version-config.description=Konfiguration als Record deklarierbarer Versionen +recordable-version-config.version.display-label=Als Record deklarierte Versionen # Action parameter constraints rm-ac-is-kind-kinds.record_category=Record-Kategorie @@ -189,4 +193,8 @@ rm-ac-is-kind-kinds.record=Record rm-ac-disposition-action-relative-positions.next=Weiter rm-ac-disposition-action-relative-positions.previous=Vorherige -rm-ac-disposition-action-relative-positions.any=Jede \ No newline at end of file +rm-ac-disposition-action-relative-positions.any=Jede + +ac-versions.none=Keine +ac-versions.major_only=Nur Hauptrevisionen +ac-versions.all=Alle Revisionen \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_es.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_es.properties index 1cdaebd259..2a7f4212e8 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_es.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_es.properties @@ -181,6 +181,10 @@ fileReport.description=Archivar informe # Delete Hold deleteHold.title=Eliminar bloqueo deleteHold.description=Eliminar bloqueo +# Recordable version config +recordable-version-config.title=Config. de versiones para guardar +recordable-version-config.description=Config. de versiones para guardar +recordable-version-config.version.display-label=Versiones guardadas como documento de archivo # Action parameter constraints rm-ac-is-kind-kinds.record_category=Categor\u00eda de documentos de archivo @@ -189,4 +193,8 @@ rm-ac-is-kind-kinds.record=Documento de archivo rm-ac-disposition-action-relative-positions.next=Siguiente rm-ac-disposition-action-relative-positions.previous=Anterior -rm-ac-disposition-action-relative-positions.any=Cualquiera \ No newline at end of file +rm-ac-disposition-action-relative-positions.any=Cualquiera + +ac-versions.none=Ninguno +ac-versions.major_only=Solo revisiones mayores +ac-versions.all=Todas las revisiones \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_fr.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_fr.properties index ae15d9e812..067e296857 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_fr.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_fr.properties @@ -181,6 +181,10 @@ fileReport.description=Archiver le rapport # Delete Hold deleteHold.title=\u5220\u9664\u4fdd\u5b58 deleteHold.description=\u5220\u9664\u4fdd\u5b58 +# Recordable version config +recordable-version-config.title=Configuration de version enregistrable +recordable-version-config.description=Configuration de version enregistrable +recordable-version-config.version.display-label=Versions enregistr\u00e9es # Action parameter constraints rm-ac-is-kind-kinds.record_category=Cat\u00e9gorie de document d'archives @@ -189,4 +193,8 @@ rm-ac-is-kind-kinds.record=Document d'archives rm-ac-disposition-action-relative-positions.next=Suivant rm-ac-disposition-action-relative-positions.previous=Pr\u00e9c\u00e9dent -rm-ac-disposition-action-relative-positions.any=N'importe lequel \ No newline at end of file +rm-ac-disposition-action-relative-positions.any=N'importe lequel + +ac-versions.none=Aucune +ac-versions.major_only=R\u00e9visions majeures uniquement +ac-versions.all=Toutes les r\u00e9visions \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_it.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_it.properties index 896f60c869..5453832baa 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_it.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_it.properties @@ -181,6 +181,10 @@ fileReport.description=Archivia Report # Delete Hold deleteHold.title=Annulla sospensione deleteHold.description=Annulla sospensione +# Recordable version config +recordable-version-config.title=Configurazione versione registrabile +recordable-version-config.description=Configurazione versione registrabile +recordable-version-config.version.display-label=Versioni registrate # Action parameter constraints rm-ac-is-kind-kinds.record_category=Categoria record @@ -189,4 +193,8 @@ rm-ac-is-kind-kinds.record=Record rm-ac-disposition-action-relative-positions.next=Successivo rm-ac-disposition-action-relative-positions.previous=Precedente -rm-ac-disposition-action-relative-positions.any=Qualsiasi \ No newline at end of file +rm-ac-disposition-action-relative-positions.any=Qualsiasi + +ac-versions.none=Nessuna +ac-versions.major_only=Solo revisioni maggiori +ac-versions.all=Tutte le revisioni \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_ja.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_ja.properties index d0966eb080..227fe6ae95 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_ja.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_ja.properties @@ -105,10 +105,6 @@ requestInfo.description=\u30ec\u30b3\u30fc\u30c9\u306e\u8a73\u7d30\u60c5\u5831\u executeScript.title=\u30b9\u30af\u30ea\u30d7\u30c8\u306e\u5b9f\u884c executeScript.description=\u30b9\u30af\u30ea\u30d7\u30c8\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002 executeScript.script-ref.display-label=\u30b9\u30af\u30ea\u30d7\u30c8 -# Delete Hold -deleteHold.title=\u30db\u30fc\u30eb\u30c9\u306e\u524a\u9664 -deleteHold.description=\u30db\u30fc\u30eb\u30c9\u306e\u524a\u9664 - # Send Email sendEmail.title=E\u30e1\u30fc\u30eb\u3092\u9001\u4fe1\u3059\u308b sendEmail.description=E\u30e1\u30fc\u30eb\u3092\u9001\u4fe1\u3059\u308b @@ -182,6 +178,13 @@ addRecordTypes.description=\u9078\u629e\u3057\u305f\u30bf\u30a4\u30d7\u3092\u30e # File report fileReport.title=\u30ec\u30dd\u30fc\u30c8\u306e\u6574\u7406\u4fdd\u7ba1 fileReport.description=\u30ec\u30dd\u30fc\u30c8\u306e\u6574\u7406\u4fdd\u7ba1 +# Delete Hold +deleteHold.title=\u30db\u30fc\u30eb\u30c9\u306e\u524a\u9664 +deleteHold.description=\u30db\u30fc\u30eb\u30c9\u306e\u524a\u9664 +# Recordable version config +recordable-version-config.title=\u8a18\u9332\u53ef\u80fd\u306a\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u8a2d\u5b9a +recordable-version-config.description=\u8a18\u9332\u53ef\u80fd\u306a\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u8a2d\u5b9a +recordable-version-config.version.display-label=\u8a18\u9332\u3055\u308c\u305f\u30d0\u30fc\u30b8\u30e7\u30f3 # Action parameter constraints rm-ac-is-kind-kinds.record_category=\u30ec\u30b3\u30fc\u30c9\u30ab\u30c6\u30b4\u30ea @@ -190,4 +193,8 @@ rm-ac-is-kind-kinds.record=\u30ec\u30b3\u30fc\u30c9 rm-ac-disposition-action-relative-positions.next=\u6b21\u3078 rm-ac-disposition-action-relative-positions.previous=\u524d\u3078 -rm-ac-disposition-action-relative-positions.any=\u4efb\u610f \ No newline at end of file +rm-ac-disposition-action-relative-positions.any=\u4efb\u610f + +ac-versions.none=\u306a\u3057 +ac-versions.major_only=\u5927\u5e45\u306a\u6539\u8a02\u306e\u307f +ac-versions.all=\u3059\u3079\u3066\u306e\u6539\u8a02 \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_nb.properties new file mode 100644 index 0000000000..3d63bcb7ee --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_nb.properties @@ -0,0 +1,200 @@ +# +# i18n for Records Management Action Conditions +# +# Are classified +isClassified.title=Klassifisert etter disposisjonsplan +isClassified.description=Har oppf\u00f8ringene og oppf\u00f8ringsmappene blitt klassifisert etter en disposisjonsplan. + +# Are cutoff +isCutoff.title=Cut off +isCutoff.description=Cut off av oppf\u00f8ringer og oppf\u00f8ringersmapper. + +# Are declared +isDeclared.title=Oppf\u00f8ring fullf\u00f8rt +isDeclared.description=Er oppf\u00f8ringen fullf\u00f8rt. + +# Is on hold +isFrozen.title=P\u00e5 hold +isFrozen.description=Er oppf\u00f8ringen eller oppf\u00f8ringsmappen p\u00e5 hold. + +# Are filed +isRecordFiled.title=Oppf\u00f8ring registrert +isRecordFiled.description=Oppf\u00f8ringen er registrert. + +# Are closed record folders +isRecordFolderClosed.title=Oppf\u00f8ringsmappe lukket. +isRecordFolderClosed.description=Er oppf\u00f8ringsmappen lukket. + +# Are vital +isVital.title=Sv\u00e6rt viktig oppf\u00f8ring +isVital.description=Er oppf\u00f8ringen eller oppf\u00f8ringsmappen sv\u00e6rt viktig. + +# Have Disposition Action +hasDispositionAction.title=Har disposisjonshandling +hasDispositionAction.description=Har nodene de spesifikke assosierte disposisjonshandlingen p\u00e5 den spesifiserte relative posisjonen. + +# Are kind +isKind.title=Type element ved oppf\u00f8ringsh\u00e5ndtering +isKind.description=Er nodene av typen filplandel. +isKind.kind.display-label=Type + +# Are Record Type +isRecordType.title=Har oppf\u00f8ringstype +isRecordType.description=Er oppf\u00f8ringene av den spesifikke typen. + + +# +# i18n for Records Management Actions +# +# Declare As Record +create-record.title=Erkl\u00e6r som oppf\u00f8ring +create-record.description=Erkl\u00e6rer dokumentet som oppf\u00f8ring. +create-record.file-plan.display-label=Filplan +create-record.hide-record.display-label=Skjul oppf\u00f8ring +# Complete record +declareRecord.title=Fullf\u00f8r oppf\u00f8ring +declareRecord.description=Fullf\u00f8rer en oppf\u00f8ring. +# Reopens record +undeclareRecord.title=\u00c5pne oppf\u00f8ring p\u00e5 nytt +undeclareRecord.description=\u00c5pner en oppf\u00f8ring p\u00e5 nytt. +# Open record folder +openRecordFolder.title=\u00c5pne oppf\u00f8ringsmappe +openRecordFolder.description=\u00c5pner en oppf\u00f8ringsmappe. +# Close record folder +closeRecordFolder.title=Lukk oppf\u00f8ringsmappe +closeRecordFolder.description=Lukker en oppf\u00f8ringsmappe. +# Complete event +completeEvent.title=Fullf\u00f8r hendelse +completeEvent.description=Fullf\u00f8rer en hendelse. +completeEvent.eventName.display-label=Hendelse +# Freeze +freeze.title=Frys +freeze.description=Fryser en oppf\u00f8ring. +freeze.reason.display-label=Grunn +# Unfreeze +unfreeze.title=T\u00f8 opp +unfreeze.description=T\u00f8r opp en oppf\u00f8ring. +# File to +fileTo.title=Arkiver i +fileTo.description=En oppf\u00f8ring arkiveres i en bestemt oppf\u00f8ringsmappe. +fileTo.path.display-label=Bane til oppf\u00f8ringsmappe +fileTo.createRecordPath.display-label=Opprett oppf\u00f8ringsbane +# Copy to +copyTo.title=Kopier til +copyTo.description=En oppf\u00f8ring kopieres i en bestemt oppf\u00f8ringsmappe. +copyTo.path.display-label=Bane til oppf\u00f8ringsmappe +copyTo.createRecordPath.display-label=Opprett oppf\u00f8ringsbane +# Move to +moveTo.title=Flytt til +moveTo.description=En oppf\u00f8ring flyttes til i en bestemt oppf\u00f8ringsmappe. +moveTo.path.display-label=Bane til oppf\u00f8ringsmappe +moveTo.createRecordPath.display-label=Opprett oppf\u00f8ringsbane +# Link to +linkTo.title=Koble til +linkTo.description=En oppf\u00f8ring kobles til i en bestemt oppf\u00f8ringsmappe. +linkTo.path.display-label=Bane til oppf\u00f8ringsmappe +linkTo.createRecordPath.display-label=Opprett oppf\u00f8ringsbane +# Reject +reject.title=Avvis +reject.description=En oppf\u00f8ring avvises, og dokumentet flyttes til det opprinnelige stedet +reject.reason.display-label=\u00c5rsak til avvisning +# Request Information +requestInfo.title=Be om informasjon +requestInfo.description=Starter en arbeidsflyt for \u00e5 be om mer informasjon om en oppf\u00f8ring +# Execute script +executeScript.title=Kj\u00f8r skript +executeScript.description=Kj\u00f8r et skript. +executeScript.script-ref.display-label=Skript +# Send Email +sendEmail.title=Send e-post +sendEmail.description=Send en e-post +# Set Property +setPropertyValue.title=Still inn egenskapsverdi +setPropertyValue.description=Still inn en egenskapsverdi + +# Edit Hold Reason +editHoldReason.title=Rediger grunn til holdet +editHoldReason.description=Rediger grunn til holdet +# Relinquish Hold +relinquishHold.title=Avslutt hold +relinquishHold.description=Avslutt hold +# Edit Review As Of Date +editReviewAsOfDate.title=Rediger gjennomgang per datoen +editReviewAsOfDate.description=Rediger gjennomgang per datoen +# Edit Disposition Action As Of Date +editDispositionActionAsOfDate.title=Rediger disposisjonshandling per datoen +editDispositionActionAsOfDate.description=Rediger disposisjonshandling per datoen +# Broadcast Vital Record Definition +broadcastVitalRecordDefinition.title=Kringkast definisjonen til sv\u00e6rt viktig oppf\u00f8ring +broadcastVitalRecordDefinition.description=Kringkast definisjonen til sv\u00e6rt viktig oppf\u00f8ring +# Broadcast Disposition Action Definition Update +broadcastDispositionActionDefinitionUpdate.title=Kringkast oppdatering av definisjonen til disposisjonshandling +broadcastDispositionActionDefinitionUpdate.description=Kringkast oppdatering av definisjonen til disposisjonshandling +# Undo Event +undoEvent.title=Angre hendelse +undoEvent.description=Angre hendelse +# Transfer Complete +transferComplete.title=Overf\u00f8r fullf\u00f8rt +transferComplete.description=Overf\u00f8r fullf\u00f8rt +# Accession Complete +accessionComplete.title=Tilgang fullf\u00f8rt +accessionComplete.description=Tilgang fullf\u00f8rt +# Split Email +splitEmail.title=Delt e-post +splitEmail.description=Delt e-post +# Create Disposition Schedule +createDispositionSchedule.title=Opprett disposisjonsplan +createDispositionSchedule.description=Opprett disposisjonsplan +# File Destruction Report +fileDestructionReport.title=Fildestruksjonsrapport +fileDestructionReport.description=Fildestruksjonsrapport +# Cut off +cutoff.title=Cut off +cutoff.description=Cut off +# Destroy +destroy.title=Destruer +destroy.description=Destruer +# Reviewed +reviewed.title=Gjennomg\u00e5tt +reviewed.description=Gjennomg\u00e5tt +# Hide Record +hide-record.title=Skjul oppf\u00f8ring +hide-record.description=Skjul oppf\u00f8ring +# Transfer +transfer.title=Overf\u00f8r +transfer.description=Overf\u00f8r +# Uncut off +unCutoff.title=Angre cut off +unCutoff.description=Angre cut off +# Accession +accession.title=Tilgang +accession.description=Tilgang +# Retain +retain.title=Behold +retain.description=Behold +# Add Record Types +addRecordTypes.title=Legg til oppf\u00f8ringstyper +addRecordTypes.description=Legger valgt(e) type(r) til oppf\u00f8ringen +# File report +fileReport.title=Registrer rapport +fileReport.description=Registrer rapport +# Delete Hold +deleteHold.title=Slett hold +deleteHold.description=Slett hold +# Recordable version config +recordable-version-config.title=Oppf\u00f8rbar versjonskonfigurasjon +recordable-version-config.description=Oppf\u00f8rbar versjonskonfigurasjon +recordable-version-config.version.display-label=Oppf\u00f8rte versjoner + +# Action parameter constraints +rm-ac-is-kind-kinds.record_category=Oppf\u00f8ringskategori +rm-ac-is-kind-kinds.record_folder=Oppf\u00f8ringsmappe +rm-ac-is-kind-kinds.record=Oppf\u00f8ring + +rm-ac-disposition-action-relative-positions.next=Neste +rm-ac-disposition-action-relative-positions.previous=Forrige +rm-ac-disposition-action-relative-positions.any=Enhver + +ac-versions.none=Ingen +ac-versions.major_only=Kun hovedrevisjoner +ac-versions.all=Alle revisjoner \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_nl.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_nl.properties index 53e5d8ee6e..4ee87d500c 100755 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_nl.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_nl.properties @@ -181,6 +181,10 @@ fileReport.description=Rapport archiveren # Delete Hold deleteHold.title=Wachtstand verwijderen deleteHold.description=Wachtstand verwijderen +# Recordable version config +recordable-version-config.title=Config. vastlegbare versie +recordable-version-config.description=Config. vastlegbare versie +recordable-version-config.version.display-label=Vastgelegde versies # Action parameter constraints rm-ac-is-kind-kinds.record_category=Recordcategorie @@ -189,4 +193,8 @@ rm-ac-is-kind-kinds.record=Record rm-ac-disposition-action-relative-positions.next=Volgende rm-ac-disposition-action-relative-positions.previous=Vorige -rm-ac-disposition-action-relative-positions.any=Willekeurig \ No newline at end of file +rm-ac-disposition-action-relative-positions.any=Willekeurig + +ac-versions.none=Geen +ac-versions.major_only=Alleen primaire revisies +ac-versions.all=Alle revisies \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_ru.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_ru.properties index 50b884d103..70d4ca81e6 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_ru.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/actions_ru.properties @@ -14,8 +14,8 @@ isDeclared.title=\u0417\u0430\u043f\u0438\u0441\u044c \u0437\u0430\u0432\u0435\u isDeclared.description=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442, \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430 \u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044c. # Is on hold -isFrozen.title=\u0417\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u0430 -isFrozen.description=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442, \u0437\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u0430 \u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0438\u043b\u0438 \u043f\u0430\u043f\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439. +isFrozen.title=\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0430 +isFrozen.description=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442, \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0438\u043b\u0438 \u043f\u0430\u043f\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439. # Are filed isRecordFiled.title=\u0417\u0430\u043f\u0438\u0441\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430 \u0432 \u0444\u0430\u0439\u043b @@ -179,8 +179,8 @@ addRecordTypes.description=\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043 fileReport.title=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043e\u0442\u0447\u0435\u0442 \u0432 \u0444\u0430\u0439\u043b fileReport.description=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043e\u0442\u0447\u0435\u0442 \u0432 \u0444\u0430\u0439\u043b # Delete Hold -deleteHold.title=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0443 -deleteHold.description=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0443 +deleteHold.title=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 +deleteHold.description=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 # Action parameter constraints rm-ac-is-kind-kinds.record_category=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439 diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/admin-service_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/admin-service_nb.properties new file mode 100644 index 0000000000..a3eeb23dff --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/admin-service_nb.properties @@ -0,0 +1,16 @@ +rm.admin.service-not-init=Tilpasningstjenesten er ikke staret. +rm.admin.not-customisable=Klassen {0} kan ikke tilpasses. +rm.admin.invalid-custom-aspect=Fant ikke tilpasningsapektet {0} til klassen {1} som kan tilpasses. +rm.admin.property-already-exists=Egenskapen {0} finnes allerede. +rm.admin.cannot-apply-constraint=Kan ikke p\u00e5f\u00f8re restriksjonen {0} p\u00e5 egenskapen {1} med datatype {2}. (forventet datatype = TEKST) +rm.admin.prop-exist=Fant ikke tilpasset egenskap {0}. +rm.admin.custom-prop-exist=Den tilpassede modellen kan ikke inneholde egenskapen {0}. +rm.admin.unknown-aspect=Ukjent aspekt {0}. +rm.admin.constraint-exists=Restriksjonen {0} finnes allerede. +rm.admin.contraint-cannot-find=Finner ikke definisjonen til restriksjonen {0}. +rm.admin.unexpected_type_constraint=Uventet type {0} ved restriksjonen {1}. {2} var forventet... +rm.admin.custom-model-not-found=Fant ikke den tilpassede modellen {0}. +rm.admin.custom-model-no-content=Den tilpassede modellen har ikke innhold. (nodeRef={0}) +rm.admin.error-write-custom-model=Feil ved utskrift av innholdet til den tilpassende modellen. (nodeRef={0}). +rm.admin.error-client-id=Feil ved generering av klient-ID fordi den allerede er i bruk. (clientid={0}) +rm.admin.error-split-id=Kan ikke dele ID {0} fordi skilletegnet {1} mangler. \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/admin-service_ru.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/admin-service_ru.properties index 1b62888025..97ae7d813d 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/admin-service_ru.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/admin-service_ru.properties @@ -6,11 +6,6 @@ rm.admin.cannot-apply-constraint=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u043 rm.admin.prop-exist=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e {0}. rm.admin.custom-prop-exist=\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e {0}. rm.admin.unknown-aspect=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0430\u0441\u043f\u0435\u043a\u0442 {0}. -rm.admin.ref-exist=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 {0}. -rm.admin.ref-label-in-use=\u041d\u0430\u0434\u043f\u0438\u0441\u044c \u0441\u043e \u0441\u0441\u044b\u043b\u043a\u043e\u0439 {0} \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f. -rm.admin.assoc-exists=\u0410\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044f {0} \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. -rm.admin.child-assoc-exists=\u0414\u043e\u0447\u0435\u0440\u043d\u044f\u044f \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044f {0} \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. -rm.admin.cannot-find-assoc-def=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u0438 {0}. rm.admin.constraint-exists=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 {0} \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. rm.admin.contraint-cannot-find=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f {0}. rm.admin.unexpected_type_constraint=\u041d\u0435\u043f\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f {0} \u0434\u043b\u044f \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f {1}. \u041e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f: {2}. diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/audit-service_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/audit-service_nb.properties new file mode 100644 index 0000000000..5f43c123a9 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/audit-service_nb.properties @@ -0,0 +1,16 @@ +rm.audit.updated-metadata=Oppdatert metadata +rm.audit.created-object=Opprettet element +rm.audit.delete-object=Slett element +rm.audit.login-succeeded=Vellykket p\u00e5logging +rm.audit.login-failed=Mislykket p\u00e5logging +rm.audit.create-person=Opprett person +rm.audit.linkTo=Koble til +rm.audit.moveTo=Flytt til +rm.audit.copyTo=Kopier til +rm.audit.fileTo=Arkiver i +rm.audit.audit-start=Revisjonsstart +rm.audit.audit-stop=Revisjonsstopp +rm.audit.audit-clear=Slett revisjon +rm.audit.audit-view=Vis revisjon +rm.audit.trail-file-fail=Kan ikke generere revisjonsrapport. +rm.audit.audit-report=Revisjonsrapport \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service.properties index 39dba8ecf9..52e96cc45d 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service.properties @@ -8,6 +8,7 @@ capability.RequestRecordInformation.title=Request Record Information capability.RejectRecords.title=Reject Records capability.FileUnfiledRecords.title=File Unfiled Records capability.LinkToRecords.title=Link Records +capability.DeleteLinks.title=Unlink Records # Metadata Control capability.group.metadataControl.title=Metadata Control @@ -32,7 +33,6 @@ capability.PlanningReviewCycles.title=Planning Review Cycles # References and Links capability.group.references.title=References capability.ChangeOrDeleteReferences.title=Change or Delete References -capability.DeleteLinks.title=Delete Links # Events capability.group.events.title=Events @@ -56,6 +56,7 @@ capability.DeleteRecords.title=Delete Records capability.TriggerAnEvent.title=Trigger An Event capability.FileDestructionReport.title=File Destruction Report capability.FileTransferReport.title=File Transfer Report +capability.EndRetention.title=End Retention # Hold Controls capability.group.holdControls.title=Hold Controls diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_de.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_de.properties index 6c08118a21..a4ed3cf007 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_de.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_de.properties @@ -8,6 +8,7 @@ capability.RequestRecordInformation.title=Record-Informationen anfordern capability.RejectRecords.title=Records ablehnen capability.FileUnfiledRecords.title=Nicht abgelegte Records ablegen capability.LinkToRecords.title=Records verkn\u00fcpfen +capability.DeleteLinks.title=Verkn\u00fcpfung zu Records aufheben # Metadata Control capability.group.metadataControl.title=Metadaten-Steuerung @@ -32,7 +33,6 @@ capability.PlanningReviewCycles.title=\u00dcberpr\u00fcfungszyklen planen # References and Links capability.group.references.title=Referenzen capability.ChangeOrDeleteReferences.title=Referenzen \u00e4ndern oder l\u00f6schen -capability.DeleteLinks.title=Links l\u00f6schen # Events capability.group.events.title=Ereignisse diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_es.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_es.properties index a9715598df..4f41b4ba5c 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_es.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_es.properties @@ -8,6 +8,7 @@ capability.RequestRecordInformation.title=Solicitar informaci\u00f3n sobre docum capability.RejectRecords.title=Rechazar documentos de archivo capability.FileUnfiledRecords.title=Archivar documentos de archivo no archivados capability.LinkToRecords.title=Enlazar documentos de archivo +capability.DeleteLinks.title=Desvincular documentos de archivo # Metadata Control capability.group.metadataControl.title=Control de metadatos @@ -32,7 +33,6 @@ capability.PlanningReviewCycles.title=Planificaci\u00f3n de ciclos de revisi\u00 # References and Links capability.group.references.title=Referencias capability.ChangeOrDeleteReferences.title=Cambiar o eliminar referencias -capability.DeleteLinks.title=Eliminar enlaces # Events capability.group.events.title=Eventos diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_fr.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_fr.properties index 3996a6b316..657b41e51f 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_fr.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_fr.properties @@ -8,6 +8,7 @@ capability.RequestRecordInformation.title=Demander des informations sur un docum capability.RejectRecords.title=Rejeter des documents d'archives capability.FileUnfiledRecords.title=Classer des documents d'archives non class\u00e9s capability.LinkToRecords.title=Lier des documents d'archives +capability.DeleteLinks.title=Supprimer le lien des enregistrements # Metadata Control capability.group.metadataControl.title=Contr\u00f4le des m\u00e9tadonn\u00e9es @@ -32,7 +33,6 @@ capability.PlanningReviewCycles.title=Planifier les cycles de r\u00e9vision # References and Links capability.group.references.title=R\u00e9f\u00e9rences capability.ChangeOrDeleteReferences.title=Modifier ou supprimer des r\u00e9f\u00e9rences -capability.DeleteLinks.title=Supprimer des liens # Events capability.group.events.title=\u00c9v\u00e9nements diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_it.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_it.properties index e5ab2e69c5..d29dc3d057 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_it.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_it.properties @@ -8,6 +8,7 @@ capability.RequestRecordInformation.title=Richiedi informazioni record capability.RejectRecords.title=Respingi record capability.FileUnfiledRecords.title=Archivia record non archiviati capability.LinkToRecords.title=Collega record +capability.DeleteLinks.title=Scollega record # Metadata Control capability.group.metadataControl.title=Controllo metadati @@ -32,7 +33,6 @@ capability.PlanningReviewCycles.title=Pianificazione cicli di revisione # References and Links capability.group.references.title=Riferimenti capability.ChangeOrDeleteReferences.title=Cambia o elimina riferimenti -capability.DeleteLinks.title=Elimina collegamenti # Events capability.group.events.title=Eventi diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_ja.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_ja.properties index f247997b61..f16367dc3f 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_ja.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_ja.properties @@ -8,6 +8,7 @@ capability.RequestRecordInformation.title=\u30ec\u30b3\u30fc\u30c9\u60c5\u5831\u capability.RejectRecords.title=\u30ec\u30b3\u30fc\u30c9\u306e\u5374\u4e0b capability.FileUnfiledRecords.title=\u672a\u6574\u7406\u306e\u30ec\u30b3\u30fc\u30c9\u306e\u6574\u7406\u4fdd\u7ba1 capability.LinkToRecords.title=\u30ec\u30b3\u30fc\u30c9\u306e\u30ea\u30f3\u30af +capability.DeleteLinks.title=\u30ec\u30b3\u30fc\u30c9\u306e\u30ea\u30f3\u30af\u306e\u89e3\u9664 # Metadata Control capability.group.metadataControl.title=\u30e1\u30bf\u30c7\u30fc\u30bf\u306e\u30b3\u30f3\u30c8\u30ed\u30fc\u30eb @@ -32,7 +33,6 @@ capability.PlanningReviewCycles.title=\u30ec\u30d3\u30e5\u30fc\u30b5\u30a4\u30af # References and Links capability.group.references.title=\u53c2\u7167 capability.ChangeOrDeleteReferences.title=\u53c2\u7167\u306e\u5909\u66f4\u307e\u305f\u306f\u524a\u9664 -capability.DeleteLinks.title=\u30ea\u30f3\u30af\u306e\u524a\u9664 # Events capability.group.events.title=\u30a4\u30d9\u30f3\u30c8 diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_nb.properties new file mode 100644 index 0000000000..a4e1afb6a9 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_nb.properties @@ -0,0 +1,104 @@ +# Records +capability.group.records.title=Oppf\u00f8ringer +capability.DeclareRecords.title=Fullf\u00f8r oppf\u00f8ringer +capability.ViewRecords.title=Vis oppf\u00f8ringer +capability.UndeclareRecords.title=\u00c5pne oppf\u00f8ringer p\u00e5 nytt +capability.CreateRecords.title=Opprett oppf\u00f8ringer +capability.RequestRecordInformation.title=Be om oppf\u00f8ringsinformasjon +capability.RejectRecords.title=Avvis oppf\u00f8ringer +capability.FileUnfiledRecords.title=Registrer oppf\u00f8ringer som ikke er registrert +capability.LinkToRecords.title=Koble oppf\u00f8ringer + +# Metadata Control +capability.group.metadataControl.title=Metadatakontroll +capability.EditRecordMetadata.title=Rediger registrering av metadata +capability.EditDeclaredRecordMetadata.title=Rediger fullf\u00f8rte registrerte metadata +capability.EditNonRecordMetadata.title=Rediger metadata som ikke er registrert +capability.MoveRecords.title=Flytt oppf\u00f8ringer + +# Folder Control +capability.group.folderControl.title=Mappekontroll +capability.CreateModifyDestroyFolders.title=Opprett Endre Destruer mapper +capability.CloseFolders.title=Lukk mapper +capability.ReOpenFolders.title=\u00c5pne mapper p\u00e5 nytt +capability.DeclareRecordsInClosedFolders.title=Fullf\u00f8r oppf\u00f8ringer i lukkede mapper + +# Vital Records +capability.group.vitalRecords.title=Sv\u00e6t viktige oppf\u00f8ringer +capability.UpdateVitalRecordCycleInformation.title=Oppdater syklusinformasjon til de sv\u00e6rt viktige oppf\u00f8ringene +capability.CycleVitalRecords.title=Sirkuler sv\u00e6rt viktige oppf\u00f8ringer +capability.PlanningReviewCycles.title=Planlegge gjennomgangsykluser + +# References and Links +capability.group.references.title=Referanser +capability.ChangeOrDeleteReferences.title=Endre eller slett referanser +capability.DeleteLinks.title=Slett koblinger + +# Events +capability.group.events.title=Hendelser +capability.CreateModifyDestroyEvents.title=Opprett Endre Destruer hendelser +capability.AddModifyEventDates.title=Legg til Endre hendelsesdatoer + +# Cutoff +capability.group.cutoff.title=Cut off +capability.ApproveRecordsScheduledForCutoff.title=Godkjenn oppf\u00f8ringer der planen er cut off +capability.CreateModifyRecordsInCutoffFolders.title=Opprett Endre oppf\u00f8ringer i cut off-mapper + +# Disposition and Transfers +capability.group.dispositionAndTransfers.title=Disposisjoner og overf\u00f8ringer +capability.UpdateTriggerDates.title=Oppdater utl\u00f8serdatoer +capability.ManuallyChangeDispositionDates.title=Endre disposisjonsdatoer manuelt +capability.AuthorizeNominatedTransfers.title=Godkjenn nominerte overf\u00f8ringer +capability.AuthorizeAllTransfers.title=Godkjenn alle overf\u00f8ringer +capability.DestroyRecordsScheduledForDestruction.title=Destruer oppf\u00f8ring eller oppf\u00f8ringsmappe der planen er \u00e5 destruere den +capability.DestroyRecords.title=Destruer oppf\u00f8ringer +capability.DeleteRecords.title=Slett oppf\u00f8ringer +capability.TriggerAnEvent.title=Utl\u00f8s en hendelse +capability.FileDestructionReport.title=Fildestruksjonsrapport +capability.FileTransferReport.title=Filoverf\u00f8ringsrapport + +# Hold Controls +capability.group.holdControls.title=Hold kontroller +capability.ExtendRetentionPeriodOrFreeze.title=Forleng oppbevaringstiden eller frys +capability.Unfreeze.title=T\u00f8 opp +capability.ViewUpdateReasonsForFreeze.title=Vis oppdatering av \u00e5rsaker til \u00e5 fryse +capability.CreateHold.title=Opprett hold +capability.AddToHold.title=Legg til hold +capability.RemoveFromHold.title=Fjern fra hold +capability.FileHoldReport.title=Filholdrapport +capability.DeleteHold.title=Slett hold +capability.EditHold.title=Rediger hold + +# Audit +capability.group.audit.title=Revisjon +capability.DeclareAuditAsRecord.title=Erkl\u00e6r revisjon som oppf\u00f8ring +capability.EnableDisableAuditByTypes.title=Aktiver/Deaktiver revisjon etter typer +capability.DeleteAudit.title=Slett revisjon +capability.SelectAuditMetadata.title=Velg revisjon av metadata +capability.AccessAudit.title=G\u00e5 til revisjon +capability.ExportAudit.title=Eksporter revisjon + +# Security +capability.group.security.title=Sikkerhet +capability.CreateModifyDestroyRoles.title=Opprett Endre Destruer roller +capability.CreateModifyDestroyUsersAndGroups.title=Opprett Endre Destruer brukere og grupper +capability.PasswordControl.title=Passordkontroll +capability.DisplayRightsReport.title=Vis rettighetsrapport +capability.ManageAccessControls.title=Administrer tilgangskontroller +capability.ManageAccessRights.title=Administrer tilgangsrettigheter + +# Configuration +capability.group.config.title=Konfigurasjon +capability.CreateModifyDestroyFileplanMetadata.title=Opprett Endre Destruer filplanmetadata +capability.CreateModifyDestroyFileplanTypes.title=Opprett Endre Destruer filplantyper +capability.CreateModifyDestroyRecordTypes.title=Opprett Endre Destruer oppf\u00f8ringstyper +capability.CreateAndAssociateSelectionLists.title=Opprett og koble valglister +capability.EditSelectionLists.title=Rediger valglister +capability.CreateModifyDestroyReferenceTypes.title=Opprett Endre Destruer referansetyper +capability.AttachRulesToMetadataProperties.title=Legg ved regler til metadataegenskaper +capability.MakeOptionalParametersMandatory.title=P\u00e5legg valgfrie parametere +capability.MapEmailMetadata.title=Koble e-postmetadata + +# Rules +capability.group.rules.title=Regler +capability.ManageRules.title=Administrer regler \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_nl.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_nl.properties index 5caa5e7ee9..f176be8ce2 100755 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_nl.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/capability-service_nl.properties @@ -8,6 +8,7 @@ capability.RequestRecordInformation.title=Recordgegevens opvragen capability.RejectRecords.title=Records afwijzen capability.FileUnfiledRecords.title=Niet gearchiveerde records archiveren capability.LinkToRecords.title=Records koppelen +capability.DeleteLinks.title=Recordkoppeling opheffen # Metadata Control capability.group.metadataControl.title=Metagegevensbeheer @@ -32,7 +33,6 @@ capability.PlanningReviewCycles.title=Planning revisiecycli # References and Links capability.group.references.title=Verwijzingen capability.ChangeOrDeleteReferences.title=Verwijzingen veranderen of verwijderen -capability.DeleteLinks.title=Koppelingen verwijderen # Events capability.group.events.title=Gebeurtenissen diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/dataset-service_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/dataset-service_nb.properties new file mode 100644 index 0000000000..cfcae4568d --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/dataset-service_nb.properties @@ -0,0 +1 @@ +dataset.dod5015.label=DOD 5015 eksempel p\u00e5 data \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/notification-service_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/notification-service_nb.properties new file mode 100644 index 0000000000..38c9c0886f --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/notification-service_nb.properties @@ -0,0 +1,3 @@ +notification.dueforreview.subject=Oppf\u00f8ringer med melding der det skal v\u00e6re gjennomgang +notification.superseded.subject=Oppf\u00f8ring erstattet melding +notification.rejected.subject=Oppf\u00f8ring avviste melding \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties index 58ebfc0ce5..70f6712de5 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service.properties @@ -16,4 +16,6 @@ rm.service.record-folder-type=Can't create record folder, because the provided t rm.service.not-record=The node {0} is not a record. rm.service.vital-def-missing=Vital record definition aspect is not present on node. (nodeRef={0}) rm.service.close-record-folder-not-folder=The record folder couldn't be closed because it's not defined as a record folder.(nodeRef={0}) -rm.service.node-has-aspect=The node {0} has already the aspect {1}. \ No newline at end of file +rm.service.node-has-aspect=The node {0} has already the aspect {1}. +rm.service.final-version=Final +rm.service.final-version-description=The final archived record version \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_de.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_de.properties index cf7d7558d7..bf286e2463 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_de.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_de.properties @@ -16,4 +16,6 @@ rm.service.record-folder-type=Record-Ordner kann nicht erstellt werden, da der a rm.service.not-record=Knoten {0} ist kein Record. rm.service.vital-def-missing=Definitionsaspekt von besonders relevantem Record ist auf dem Knoten nicht vorhanden. (nodeRef={0}) rm.service.close-record-folder-not-folder=Der Record-Ordner konnte nicht geschlossen werden, da er nicht als Record-Ordner definiert ist. (nodeRef={0}) -rm.service.node-has-aspect=Der Knoten {0} hat bereits den Aspekt {1}. \ No newline at end of file +rm.service.node-has-aspect=Der Knoten {0} hat bereits den Aspekt {1}. +rm.service.final-version=Endg\u00fcltig +rm.service.final-version-description=Die endg\u00fcltige archivierte Version des Records \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_es.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_es.properties index b7992f4535..9ee1a9182c 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_es.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_es.properties @@ -16,4 +16,6 @@ rm.service.record-folder-type=No se puede crear una carpeta de documentos de arc rm.service.not-record=El nodo ''{0}'' no es un documento de archivo. rm.service.vital-def-missing=El aspecto de definici\u00f3n de documento de archivo vital no est\u00e1 presenta en el nodo. (nodeRef={0}) rm.service.close-record-folder-not-folder=No se pudo cerrar la carpeta de documentos de archivo porque no est\u00e1 definida como una carpeta de documentos de archivo.(nodeRef={0}) -rm.service.node-has-aspect=El nodo ''{0}'' ya tiene el aspecto {1}. \ No newline at end of file +rm.service.node-has-aspect=El nodo ''{0}'' ya tiene el aspecto {1}. +rm.service.final-version=Final +rm.service.final-version-description=La versi\u00f3n final del documento de archivo archivado \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_fr.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_fr.properties index b9edeae5e9..caf335d70e 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_fr.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_fr.properties @@ -16,4 +16,6 @@ rm.service.record-folder-type=Impossible de cr\u00e9er un dossier d''archives ca rm.service.not-record=Le n\u0153ud {0} n''est pas un document d''archives. rm.service.vital-def-missing=L''aspect de d\u00e9finition de document d''archives essentiel n''est pas pr\u00e9sent sur le n\u0153ud. (nodeRef={0}) rm.service.close-record-folder-not-folder=Le dossier d''archives n''a pas pu \u00eatre ferm\u00e9, car il n''est pas d\u00e9fini comme dossier d''archives.(nodeRef={0}) -rm.service.node-has-aspect=Le n\u0153ud {0} a d\u00e9j\u00e0 l''aspect {1}. \ No newline at end of file +rm.service.node-has-aspect=Le n\u0153ud {0} a d\u00e9j\u00e0 l''aspect {1}. +rm.service.final-version=Finale +rm.service.final-version-description=Version finale du document archiv\u00e9 \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_it.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_it.properties index 8b29afd323..bcbc46434d 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_it.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_it.properties @@ -16,4 +16,6 @@ rm.service.record-folder-type=Impossibile creare una cartella di record, poich\u rm.service.not-record=Il nodo {0} non \u00e8 un record. rm.service.vital-def-missing=L''aspetto di definizione di record fondamentale non \u00e8 presente su nodo. (nodeRef={0}) rm.service.close-record-folder-not-folder=Non \u00e8 stato possibile chiudere la cartella di record, poich\u00e9 non \u00e8 definita come cartella di record.(nodeRef={0}) -rm.service.node-has-aspect=Il nodo {0} presenta gi\u00e0 l''aspetto {1}. \ No newline at end of file +rm.service.node-has-aspect=Il nodo {0} presenta gi\u00e0 l''aspetto {1}. +rm.service.final-version=Finale +rm.service.final-version-description=Versione del record archiviata finale \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_ja.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_ja.properties index e4dc5c2bbd..24e8112470 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_ja.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_ja.properties @@ -16,4 +16,6 @@ rm.service.record-folder-type=\u6307\u5b9a\u3055\u308c\u305f\u30bf\u30a4\u30d7\u rm.service.not-record=\u30ce\u30fc\u30c9 {0} \u306f\u30ec\u30b3\u30fc\u30c9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002 rm.service.vital-def-missing=\u30d0\u30a4\u30bf\u30eb\u30ec\u30b3\u30fc\u30c9\u306e\u5b9a\u7fa9\u30a2\u30b9\u30da\u30af\u30c8\u304c\u30ce\u30fc\u30c9\u306b\u5b58\u5728\u3057\u307e\u305b\u3093\u3002(nodeRef={0}) rm.service.close-record-folder-not-folder=\u30ec\u30b3\u30fc\u30c9\u30d5\u30a9\u30eb\u30c0\u3092\u9589\u3058\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u30ec\u30b3\u30fc\u30c9\u30d5\u30a9\u30eb\u30c0\u3068\u3057\u3066\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u306a\u3044\u305f\u3081\u3067\u3059\u3002(nodeRef={0}) -rm.service.node-has-aspect=\u30ce\u30fc\u30c9{0}\u306b\u306f\u3059\u3067\u306b\u30a2\u30b9\u30da\u30af\u30c8{1}\u304c\u3042\u308a\u307e\u3059\u3002 \ No newline at end of file +rm.service.node-has-aspect=\u30ce\u30fc\u30c9{0}\u306b\u306f\u3059\u3067\u306b\u30a2\u30b9\u30da\u30af\u30c8{1}\u304c\u3042\u308a\u307e\u3059\u3002 +rm.service.final-version=\u6700\u7d42\u7248 +rm.service.final-version-description=\u30a2\u30fc\u30ab\u30a4\u30d6\u3055\u308c\u305f\u30ec\u30b3\u30fc\u30c9\u306e\u6700\u7d42\u30d0\u30fc\u30b8\u30e7\u30f3 \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_nb.properties new file mode 100644 index 0000000000..f05c0cb507 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_nb.properties @@ -0,0 +1,21 @@ +rm.service.error-add-content-container=Innhold kan ikke legges til en oppf\u00f8ringsbeholder. Bruk oppf\u00f8ringsmapper for \u00e5 arkivere innhold. +rm.service.update-disposition-action-def=Definisjonen til disposisjonshandlingen kan ikke oppdateres fordi en oppdatering er publisert. +rm.service.set-id=ID-egenskapsverdien til elementet {0} kan kun leses og ikke stilles inn. +rm.service.path-node=Klarer ikke \u00e5 f\u00e5 banen. (nodeRef={0}) +rm.service.invalid-rm-node=Ugyldig oppf\u00f8ringsh\u00e5ndteringsnode fordi aspektet {0} finnes ikke. +rm.service.no-root=Finner ikke filplanen. +rm.service.dup-root=Kan ikke opprette filplanen fordi det finnes allerede en plan i dette hierarkiet. +rm.service.root-type=Kan ikke opprette filplanen fordi typen {0} ikke er en subtype av rm:recordsManagementRootContainer. +rm.service.container-parent-type=Kan ikke opprette filplanbeholderen fordi overordnede ikke var en subtype av rm:recordsManagement (parentType={0}) +rm.service.container-type=Kan ikke opprette filplanbeholder fordi typen {0} ikke er en subtype av rm:recordsManagementContainer. +rm.service.container-expected=Nodereferanse til en rm:recordsManagementContainer-node utl\u00f8pt. +rm.service.record-folder-expected=Nodereferanse til en rm:recordFolder-node utl\u00f8pt. +rm.service.parent-record-folder-root=Kan ikke opprette en oppf\u00f8ringsmappe fordi den overordnede er en filplan. +rm.service.parent-record-folder-type=Kan ikke opprette en oppf\u00f8ringsmappe fordi den overordnede ikke er en subtype av rm:recordsManagementContainer. (parentType={0}) +rm.service.record-folder-type=Kan ikke opprette oppf\u00f8ringsmappe for den oppgitte typen ikke er en subtype av rm:recordFolder. (type={0}) +rm.service.not-record=Noden {0} er ikke en oppf\u00f8ring. +rm.service.vital-def-missing=Aspektet ved definisjonen til sv\u00e6rt viktige oppf\u00f8ringer finnes ikke p\u00e5 noden. (nodeRef={0}) +rm.service.close-record-folder-not-folder=Oppf\u00f8ringsmappen kan ikke lukkes fordi den ikke er definert som en oppf\u00f8ringsmappe.(nodeRef={0}) +rm.service.node-has-aspect=Noden {0} har allerede aspektet {1}. +rm.service.final-version=Endelig +rm.service.final-version-description=Den endelig arkiverte oppf\u00f8ringsversjonen \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_nl.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_nl.properties index 392e55823e..1a27ccbf3c 100755 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_nl.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-management-service_nl.properties @@ -16,4 +16,6 @@ rm.service.record-folder-type=Kan geen archiefmap maken omdat het geleverde type rm.service.not-record=De node {0} is geen record. rm.service.vital-def-missing=Definitie-aspect van vitale record is niet aanwezig op node. (nodeRef={0}) rm.service.close-record-folder-not-folder=De archiefmap kan niet worden gesloten omdat hij niet als een archiefmap is gedefinieerd.(nodeRef={0}) -rm.service.node-has-aspect=De node {0} heeft al het aspect {1}. \ No newline at end of file +rm.service.node-has-aspect=De node {0} heeft al het aspect {1}. +rm.service.final-version=Definitief +rm.service.final-version-description=De definitieve gearchiveerde recordversie \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-model_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-model_nb.properties new file mode 100644 index 0000000000..09ec7810c3 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-model_nb.properties @@ -0,0 +1,265 @@ +rma_recordsmanagement.description=Oppf\u00f8ringsh\u00e5ndtering av innholdsmodell + +rma_recordsmanagement.type.rma_rmsite.title=Sted til oppf\u00f8ringsh\u00e5ndtering +rma_recordsmanagement.type.rma_rmsite.description=Spesialisert omr\u00e5de til oppf\u00f8ringsh\u00e5ndtering + +rma_recordsmanagement.type.rma_caveatConfig.title=Varselskonfigurasjon +rma_recordsmanagement.type.rma_caveatConfig.decription=Varselskonfigurasjon + +rma_recordsmanagement.type.rma_emailConfig.title=E-postkonfigurasjon +rma_recordsmanagement.type.rma_emailConfig.decription=E-postkonfigurasjon + +rma_recordsmanagement.type.rma_recordsManagementContainer.title=Oppf\u00f8ringsh\u00e5ndteringsbeholder +rma_recordsmanagement.type.rma_recordsManagementContainer.decription=Oppf\u00f8ringsh\u00e5ndteringsbeholder + +rma_recordsmanagement.type.rma_recordsManagementRootContainer.title=Filplanbeholder +rma_recordsmanagement.type.rma_recordsManagementRootContainer.decription=Filplanbeholder + +rma_recordsmanagement.type.rma_dispositionSchedule.title=Disposisjonsplan +rma_recordsmanagement.type.rma_dispositionSchedule.decription=Disposisjonsplan + +rma_recordsmanagement.property.rma_dispositionAuthority.title=Disposisjonsrett +rma_recordsmanagement.property.rma_dispositionAuthority.decription=Disposisjonsrett + +rma_recordsmanagement.property.rma_dispositionInstructions.title=Disposisjonsinstruksjoner +rma_recordsmanagement.property.rma_dispositionInstructions.decription=Disposisjonsinstruksjoner + +rma_recordsmanagement.property.rma_recordLevelDisposition.title=Disposisjonsniv\u00e5 ved oppf\u00f8ringer +rma_recordsmanagement.property.rma_recordLevelDisposition.decription=Disposisjonsniv\u00e5 ved oppf\u00f8ringer + +rma_recordsmanagement.association.rma_dispositionActionDefinitions.title=Disposisjonshandlinger +rma_recordsmanagement.association.rma_dispositionActionDefinitions.decription=Disposisjonshandlinger + +rma_recordsmanagement.type.rma_dispositionActionDefinition.title=Definisjon av disposisjonshandling +rma_recordsmanagement.type.rma_dispositionActionDefinition.decription=Definisjon av disposisjonshandling +rma_recordsmanagement.property.rma_dispositionActionName.title=Navn p\u00e5 disposisjonshandling +rma_recordsmanagement.property.rma_dispositionActionName.decription=Navn p\u00e5 disposisjonshandling +rma_recordsmanagement.property.rma_dispositionDescription.title=Disposisjonsbeskrivelse +rma_recordsmanagement.property.rma_dispositionDescription.decription=Disposisjonsbeskrivelse +rma_recordsmanagement.property.rma_dispositionLocation.title=Disposisjonsplassering +rma_recordsmanagement.property.rma_dispositionLocation.decription=Disposisjonsplassering +rma_recordsmanagement.property.rma_dispositionPeriod.title=Disposisjonstid +rma_recordsmanagement.property.rma_dispositionPeriod.decription=Disposisjonstid +rma_recordsmanagement.property.rma_dispositionPeriodProperty.title=Egenskaper til disposisjonstiden +rma_recordsmanagement.property.rma_dispositionPeriodProperty.decription=Egenskaper til disposisjonstiden +rma_recordsmanagement.property.rma_dispositionEvent.title=Disposisjonshendelse +rma_recordsmanagement.property.rma_dispositionEvent.decription=Disposisjonshendelse +rma_recordsmanagement.property.rma_dispositionEventCombination.title=Kombinasjon av disposisjonshendelse +rma_recordsmanagement.property.rma_dispositionEventCombination.decription=Kombinasjon av disposisjonshendelse + +rma_recordsmanagement.type.rma_recordFolder.title=Oppf\u00f8ringsmappe +rma_recordsmanagement.type.rma_recordFolder.decription=Oppf\u00f8ringsmappe +rma_recordsmanagement.property.rma_isClosed.title=Oppf\u00f8ring +rma_recordsmanagement.property.rma_isClosed.decription=Oppf\u00f8ring + +rma_recordsmanagement.type.rma_recordCategory.title=Oppf\u00f8ringskategori +rma_recordsmanagement.type.rma_recordCategory.decription=Oppf\u00f8ringskategori + +rma_recordsmanagement.type.rma_nonElectronicDocument.title=Ikke-elektronisk dokument +rma_recordsmanagement.type.rma_nonElectronicDocument.decription=Ikke-elektronisk dokument +rma_recordsmanagement.property.rma_physicalSize.title=Fysisk st\u00f8rrelse +rma_recordsmanagement.property.rma_physicalSize.decription=St\u00f8rrelsen p\u00e5 dokumentet m\u00e5lt i line\u00e6re meter. +rma_recordsmanagement.property.rma_numberOfCopies.title=Antall kopier +rma_recordsmanagement.property.rma_numberOfCopies.description=Antall kopier av dokumentet. +rma_recordsmanagement.property.rma_storageLocation.title=Lagringssted +rma_recordsmanagement.property.rma_storageLocation.decription=Det fysiske lagringsstedet til oppf\u00f8ringen. +rma_recordsmanagement.property.rma_shelf.title=Hylle +rma_recordsmanagement.property.rma_shelf.decription=Hyllen som oppf\u00f8ringen befinner seg p\u00e5. +rma_recordsmanagement.property.rma_box.title=Eske +rma_recordsmanagement.property.rma_box.description=Esken som oppf\u00f8ringen befinner seg i. +rma_recordsmanagement.property.rma_file.title=Fil +rma_recordsmanagement.property.rma_file.decription=Filen som oppf\u00f8ringen befinner seg i. + +rma_recordsmanagement.type.rma_dispositionAction.title=Disposisjonshandling +rma_recordsmanagement.type.rma_dispositionAction.decription=Disposisjonshandling +rma_recordsmanagement.property.rma_dispositionActionId.title=ID til disposisjonshandling +rma_recordsmanagement.property.rma_dispositionActionId.decription=ID til disposisjonshandling +rma_recordsmanagement.property.rma_dispositionAction.title=Disposisjonshandling +rma_recordsmanagement.property.rma_dispositionAction.decription=Disposisjonshandling +rma_recordsmanagement.property.rma_dispositionAsOf.title=Disposisjonshandling +rma_recordsmanagement.property.rma_dispositionAsOf.decription=Disposisjonshandling +rma_recordsmanagement.property.rma_dispositionEventsEligible.title=Kvalifiserte disposisjonshendelser +rma_recordsmanagement.property.rma_dispositionEventsEligible.decription=Kvalifiserte disposisjonshendelser +rma_recordsmanagement.property.rma_dispositionActionStartedAt.title=Disposisjonshandling startet den +rma_recordsmanagement.property.rma_dispositionActionStartedAt.decription=Disposisjonshandling startet den +rma_recordsmanagement.property.rma_dispositionActionStartedBy.title=Disposisjonshandling startet av +rma_recordsmanagement.property.rma_dispositionActionStartedBy.decription=Disposisjonshandling startet av +rma_recordsmanagement.property.rma_dispositionActionCompletedAt.title=Disposisjonshandling fullf\u00f8rt p\u00e5 +rma_recordsmanagement.property.rma_dispositionActionCompletedAt.decription=Disposisjonshandling fullf\u00f8rt p\u00e5 +rma_recordsmanagement.property.rma_dispositionActionCompletedBy.title=Disposisjonshandling fullf\u00f8rt av +rma_recordsmanagement.property.rma_dispositionActionCompletedBy.decription=Disposisjonshandling fullf\u00f8rt av +rma_recordsmanagement.association.rma_eventExecutions.title=Utf\u00f8rte hendelser +rma_recordsmanagement.association.rma_eventExecutions.decription=Utf\u00f8rte hendelser + +rma_recordsmanagement.type.rma_eventExecution.title=Utf\u00f8relse av hendelse +rma_recordsmanagement.type.rma_eventExecution.decription=Utf\u00f8relse av hendelse +rma_recordsmanagement.property.rma_eventExecutionName.title=Hendelsenavn +rma_recordsmanagement.property.rma_eventExecutionName.decription=Hendelsenavn +rma_recordsmanagement.property.rma_eventExecutionAutomatic.title=Automatisk hendelse +rma_recordsmanagement.property.rma_eventExecutionAutomatic.decription=Automatisk hendelse +rma_recordsmanagement.property.rma_eventExecutionComplete.title=Fullf\u00f8rt hendelse +rma_recordsmanagement.property.rma_eventExecutionComplete.decription=Fullf\u00f8rt hendelse +rma_recordsmanagement.property.rma_eventExecutionCompletedBy.title=Hendelse fullf\u00f8rt av +rma_recordsmanagement.property.rma_eventExecutionCompletedBy.decription=Hendelse fullf\u00f8rt av +rma_recordsmanagement.property.rma_eventExecutionCompletedAt.title=Hendelse fullf\u00f8rt den +rma_recordsmanagement.property.rma_eventExecutionCompletedAt.decription=Hendelse fullf\u00f8rt den + +rma_recordsmanagement.type.rma_hold.title=Hold +rma_recordsmanagement.type.rma_hold.decription=Hold +rma_recordsmanagement.property.rma_holdReason.title=Grunn til holdet +rma_recordsmanagement.property.rma_holdReason.decription=Grunn til holdet +rma_recordsmanagement.association.rma_frozenRecords.title=Oppf\u00f8ringer p\u00e5 hold +rma_recordsmanagement.association.rma_frozenRecords.decription=Oppf\u00f8ringer p\u00e5 hold + +rma_recordsmanagement.type.rma_transfer.title=Overf\u00f8r +rma_recordsmanagement.type.rma_transfer.decription=Overf\u00f8r +rma_recordsmanagement.property.rma_transferAccessionIndicator.title=Overf\u00f8r tilgangsindikator +rma_recordsmanagement.property.rma_transferAccessionIndicator.decription=Overf\u00f8r tilgangsindikator +rma_recordsmanagement.property.rma_transferPDFIndicator.title=Overf\u00f8r PDF-indikator +rma_recordsmanagement.property.rma_transferPDFIndicator.decription=Overf\u00f8r PDF-indikator +rma_recordsmanagement.property.rma_transferLocation.title=Overf\u00f8r PDF +rma_recordsmanagement.property.rma_transferLocation.decription=Overf\u00f8r PDF +rma_recordsmanagement.association.rma_transferred.title=Overf\u00f8rt +rma_recordsmanagement.association.rma_transferred.decription=Overf\u00f8rt + +rma_recordsmanagement.aspect.rma_filePlanComponent.title=Filplandel +rma_recordsmanagement.aspect.rma_filePlanComponent.decription=Filplandel +rma_recordsmanagement.property.rma_rootNodeRef.title=Rotnode +rma_recordsmanagement.property.rma_rootNodeRef.decription=Rotnode + +rma_recordsmanagement.aspect.rma_recordsManagementRoot.title=Filplan +rma_recordsmanagement.aspect.rma_recordsManagementRoot.decription=Filplan +rma_recordsmanagement.association.rma_holds.title=Hold +rma_recordsmanagement.association.rma_holds.decription=Hold +rma_recordsmanagement.association.rma_transfers.title=Overf\u00f8ringer +rma_recordsmanagement.association.rma_transfers.decription=Overf\u00f8ringer + +rma_recordsmanagement.aspect.rma_declaredRecord.title=Fullf\u00f8rt oppf\u00f8ring +rma_recordsmanagement.aspect.rma_declaredRecord.decription=Fullf\u00f8rt oppf\u00f8ring +rma_recordsmanagement.property.rma_declaredAt.title=Dato fullf\u00f8rt +rma_recordsmanagement.property.rma_declaredAt.decription=Dato fullf\u00f8rt +rma_recordsmanagement.property.rma_declaredBy.title=Fullf\u00f8rt av +rma_recordsmanagement.property.rma_declaredBy.decription=Fullf\u00f8rt av + +rma_recordsmanagement.aspect.rma_recordComponentIdentifier.title=Del-ID til oppf\u00f8ring +rma_recordsmanagement.aspect.rma_recordComponentIdentifier.decription=Del-ID til oppf\u00f8ring +rma_recordsmanagement.property.rma_identifier.title=Identifikator +rma_recordsmanagement.property.rma_identifier.decription=Unik oppf\u00f8rings-ID +rma_recordsmanagement.property.rma_dbUniquenessId.title=Unikt ved database +rma_recordsmanagement.property.rma_dbUniquenessId.decription=Unikt ved database + +rma_recordsmanagement.aspect.rma_vitalRecordDefinition.title=Sv\u00e6rt viktig oppf\u00f8ringsdefinisjon +rma_recordsmanagement.aspect.rma_vitalRecordDefinition.decription=Sv\u00e6rt viktig oppf\u00f8ringsdefinisjon + +rma_recordsmanagement.property.rma_reviewPeriod.title=Gjennomgangsperiode +rma_recordsmanagement.property.rma_reviewPeriod.decription=Gjennomgangsperiode +rma_recordsmanagement.property.rma_vitalRecordIndicator.title=Sv\u00e6rt viktig oppf\u00f8ringsindikator +rma_recordsmanagement.property.rma_vitalRecordIndicator.decription=Sv\u00e6rt viktig oppf\u00f8ringsindikator + +rma_recordsmanagement.aspect.rma_record.title=Oppf\u00f8ring +rma_recordsmanagement.aspect.rma_record.decription=Oppf\u00f8ring +rma_recordsmanagement.property.rma_dateFiled.title=Dato registrert +rma_recordsmanagement.property.rma_dateFiled.decription=Dato registrert +rma_recordsmanagement.property.rma_origionalName=Opprinnelig navn + +rma_recordsmanagement.aspect.rma_recordMetaData.title=Registrer metadata +rma_recordsmanagement.aspect.rma_recordMetaData.description=Mark\u00f8raspekt til registrerte metadata + +rma_recordsmanagement.aspect.rma_commonRecordDetails.title=Felles oppf\u00f8ringsinformasjon +rma_recordsmanagement.aspect.rma_commonRecordDetails.description=Metadata som gjelder alle typer oppf\u00f8ringer +rma_recordsmanagement.property.rma_location.title=Sted +rma_recordsmanagement.property.rma_location.decription=Sted + +rma_recordsmanagement.aspect.rma_vitalRecord.title=Sv\u00e6rt viktig oppf\u00f8ring +rma_recordsmanagement.aspect.rma_vitalRecord.decription=Sv\u00e6rt viktig oppf\u00f8ring +rma_recordsmanagement.property.rma_reviewAsOf.title=Neste gjennomgang +rma_recordsmanagement.property.rma_reviewAsOf.decription=Neste gjennomgang +rma_recordsmanagement.property.rma_notificationIssued.title=Indikerer at en melding om at denne oppf\u00f8ringen skal gjennomg\u00e5s, er blitt utstedt +rma_recordsmanagement.property.rma_notificationIssued.decription=Indikerer at en melding om at denne oppf\u00f8ringen skal gjennomg\u00e5s, er blitt utstedt + +rma_recordsmanagement.aspect.rma_scheduled.title=Planlagt +rma_recordsmanagement.aspect.rma_scheduled.decription=Planlagt +rma_recordsmanagement.association.rma_dispositionSchedule.title=Disposisjonsplan +rma_recordsmanagement.association.rma_dispositionSchedule.decription=Disposisjonsplan + +rma_recordsmanagement.aspect.rma_dispositionLifecycle.title=Livssyklus ved disposisjon +rma_recordsmanagement.aspect.rma_dispositionLifecycle.decription=Livssyklus ved disposisjon +rma_recordsmanagement.association.rma_nextDispositionAction.title=Neste disposisjonshandling +rma_recordsmanagement.association.rma_nextDispositionAction.decription=Neste disposisjonshandling +rma_recordsmanagement.association.rma_dispositionActionHistory.title=Historikk til disposisjonshandlinger +rma_recordsmanagement.association.rma_dispositionActionHistory.decription=Historikk til disposisjonshandlinger + +rma_recordsmanagement.aspect.rma_cutOff.title=Cut off +rma_recordsmanagement.aspect.rma_cutOff.decription=Cut off +rma_recordsmanagement.property.rma_cutOffDate.title=Cut off-dato +rma_recordsmanagement.property.rma_cutOffDate.decription=Cut off-dato + +rma_recordsmanagement.aspect.rma_transferred.title=Overf\u00f8rt +rma_recordsmanagement.aspect.rma_transferred.decription=Overf\u00f8rt + +rma_recordsmanagement.aspect.rma_ascended.title=Stigende +rma_recordsmanagement.aspect.rma_ascended.decription=Stigende + +rma_recordsmanagement.aspect.rma_frozen.title=P\u00e5 hold +rma_recordsmanagement.aspect.rma_frozen.decription=P\u00e5 hold +rma_recordsmanagement.property.rma_frozenAt.title=Holdes ved +rma_recordsmanagement.property.rma_frozenAt.decription=Holdes ved +rma_recordsmanagement.property.rma_frozenBy.title=Holdes av +rma_recordsmanagement.property.rma_frozenBy.decription=Holdes av + +rma_recordsmanagement.aspect.rma_caveatConfigRoot.title=Varselskonfigurasjonsrot +rma_recordsmanagement.aspect.rma_caveatConfigRoot.decription=Varselskonfigurasjonsrot +rma_recordsmanagement.association.rma_caveatConfigAssoc.title=Varselskonfigurasjon +rma_recordsmanagement.association.rma_caveatConfigAssoc.description=Varselskonfigurasjon + +rma_recordsmanagement.aspect.rma_emailConfigRoot.title=E-postkonfigurasjonsrot +rma_recordsmanagement.aspect.rma_emailConfigRoot.decription=E-postkonfigurasjonsrot +rma_recordsmanagement.association.rma_emailConfigAssoc.title=E-postkonfigurasjon +rma_recordsmanagement.association.rma_emailConfigAssoc.description=E-postkonfigurasjon + +rma_recordsmanagement.aspect.rma_recordSearch.title=Oppf\u00f8ringss\u00f8k +rma_recordsmanagement.aspect.rma_recordSearch.decription=Rullet opp s\u00f8keinformasjonen for \u00e5 st\u00f8tte oppf\u00f8ringsh\u00e5ndteringss\u00f8ket +rma_recordsmanagement.property.rma_recordSearchHasDispositionSchedule.title=Har disposisjonsplan +rma_recordsmanagement.property.rma_recordSearchHasDispositionSchedule.description=Indikerer om elementet er forbundet med disposisjonsplanen +rma_recordsmanagement.property.rma_recordSearchDispositionActionName.title=Navn p\u00e5 disposisjonshandling +rma_recordsmanagement.property.rma_recordSearchDispositionActionName.description=Navnet p\u00e5 neste disposisjonshandling +rma_recordsmanagement.property.rma_recordSearchDispositionActionAsOf.title=Disposisjonshandling til +rma_recordsmanagement.property.rma_recordSearchDispositionActionAsOf.description=Datoen n\u00e5r neste disposisjonshandling blir kvalifisert +rma_recordsmanagement.property.rma_recordSearchDispositionPeriod.title=Disposisjonstid +rma_recordsmanagement.property.rma_recordSearchDispositionPeriod.description=Disposisjonstid +rma_recordsmanagement.property.rma_recordSearchDispositionPeriodExpression.title=Uttrykk av disposisjonstid +rma_recordsmanagement.property.rma_recordSearchDispositionPeriodExpression.description=Uttrykk av disposisjonstid +rma_recordsmanagement.property.rma_recordSearchDispositionEventsEligible.title=Kvalifiserte disposisjonshendelser +rma_recordsmanagement.property.rma_recordSearchDispositionEventsEligible.description=Kvalifiserte disposisjonshendelser +rma_recordsmanagement.property.rma_recordSearchDispositionEvents.title=Disposisjonshendelser +rma_recordsmanagement.property.rma_recordSearchDispositionEvents.description=Disposisjonshendelser +rma_recordsmanagement.property.rma_recordSearchDispositionAuthority.title=Disposisjonsrett +rma_recordsmanagement.property.rma_recordSearchDispositionAuthority.description=Disposisjonsrett +rma_recordsmanagement.property.rma_recordSearchDispositionInstructions.title=Disposisjonsinstruksjoner +rma_recordsmanagement.property.rma_recordSearchDispositionInstructions.description=Disposisjonsinstruksjoner +rma_recordsmanagement.property.rma_recordSearchHoldReason.title=Grunn til holdet +rma_recordsmanagement.property.rma_recordSearchHoldReason.description=Grunn til holdet +rma_recordsmanagement.property.rma_recordSearchVitalRecordReviewPeriod.title=Gjennomgangsperiode til den sv\u00e6rt viktige oppf\u00f8ringen +rma_recordsmanagement.property.rma_recordSearchVitalRecordReviewPeriod.description=Gjennomgangsperiode til den sv\u00e6rt viktige oppf\u00f8ringen +rma_recordsmanagement.property.rma_recordSearchVitalRecordReviewPeriodExpression.title=Uttrykk av gjennomgangsperioden +rma_recordsmanagement.property.rma_recordSearchVitalRecordReviewPeriodExpression.description=Uttrykk av gjennomgangsperioden + +rma_recordsmanagement.aspect.rma_versionedRecord.title=Oppf\u00f8ring med versjon +rma_recordsmanagement.aspect.rma_versionedRecord.decription=Oppf\u00f8ring med versjon + +rma_recordsmanagement.aspect.rma_unpublishedUpdate.title=Upublisert oppdatering +rma_recordsmanagement.aspect.rma_unpublishedUpdate.decription=Upublisert oppdatering +rma_recordsmanagement.property.rma_unpublishedUpdate.title=Upublisert oppdatering +rma_recordsmanagement.property.rma_unpublishedUpdate.description=Indikerer om det finnes en upublisert oppdatering +rma_recordsmanagement.property.rma_updateTo.title=Oppdater til +rma_recordsmanagement.property.rma_updateTo.description=M\u00e5let til oppdateringen +rma_recordsmanagement.property.rma_updatedProperties.title=Oppdaterte egenskaper +rma_recordsmanagement.property.rma_updatedProperties.description=De oppdaterte egenskapene +rma_recordsmanagement.property.rma_publishInProgress.title=Publisering p\u00e5g\u00e5r +rma_recordsmanagement.property.rma_publishInProgress.description=Indikerer om en publisering p\u00e5g\u00e5r for tiden + +rma_recordsmanagement.aspect.dod_ghosted.title=Oppf\u00f8ring kun med metadata +rma_recordsmanagement.aspect.dod_ghosted.description=Oppf\u00f8ring kun med metadata + +listconstraint.rmc_tlList.title=Overf\u00f8ringssteder +listconstraint.rmc_smList.title=Tilleggsmarkeringer \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-model_ru.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-model_ru.properties index 02bf8b0709..5831e3cd81 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-model_ru.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/records-model_ru.properties @@ -104,11 +104,12 @@ rma_recordsmanagement.property.rma_eventExecutionCompletedBy.decription=\u041f\u rma_recordsmanagement.property.rma_eventExecutionCompletedAt.title=\u0414\u0430\u0442\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f rma_recordsmanagement.property.rma_eventExecutionCompletedAt.decription=\u0414\u0430\u0442\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f -rma_recordsmanagement.type.rma_hold.title=\u0411\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0430 -rma_recordsmanagement.type.rma_hold.decription=\u0411\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0430 -rma_recordsmanagement.property.rma_holdReason.decription=\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0438 -rma_recordsmanagement.association.rma_frozenRecords.title=\u0417\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 -rma_recordsmanagement.association.rma_frozenRecords.decription=\u0417\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 +rma_recordsmanagement.type.rma_hold.title=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 +rma_recordsmanagement.type.rma_hold.decription=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 +rma_recordsmanagement.property.rma_holdReason.title=\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 +rma_recordsmanagement.property.rma_holdReason.decription=\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 +rma_recordsmanagement.association.rma_frozenRecords.title=\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 +rma_recordsmanagement.association.rma_frozenRecords.decription=\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 rma_recordsmanagement.type.rma_transfer.title=\u041f\u0435\u0440\u0435\u0434\u0430\u0442\u044c rma_recordsmanagement.type.rma_transfer.decription=\u041f\u0435\u0440\u0435\u0434\u0430\u0442\u044c @@ -128,8 +129,8 @@ rma_recordsmanagement.property.rma_rootNodeRef.decription=\u041a\u043e\u0440\u04 rma_recordsmanagement.aspect.rma_recordsManagementRoot.title=\u041a\u043e\u0440\u0435\u043d\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u044f\u043c\u0438 rma_recordsmanagement.aspect.rma_recordsManagementRoot.decription=\u041a\u043e\u0440\u0435\u043d\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u044f\u043c\u0438 -rma_recordsmanagement.association.rma_holds.title=\u0417\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u0437\u0430\u043F\u0438\u0441\u0438 -rma_recordsmanagement.association.rma_holds.decription=\u0417\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u0437\u0430\u043F\u0438\u0441\u0438 +rma_recordsmanagement.association.rma_holds.title=\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 +rma_recordsmanagement.association.rma_holds.decription=\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 rma_recordsmanagement.association.rma_transfers.title=\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 rma_recordsmanagement.association.rma_transfers.decription=\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-model_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-model_nb.properties new file mode 100644 index 0000000000..b37b15af41 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-model_nb.properties @@ -0,0 +1,13 @@ +rmr_recordsmanagementreport.description=Oppf\u00f8ringsh\u00e5ndtering til innholdsmodellen + +rmr_recordsmanagementreport.type.rmr_report.title=Rapport +rmr_recordsmanagementreport.type.rmr_report.description=Oppf\u00f8ringsh\u00e5ndteringsrapport + +rmr_recordsmanagementreport.type.rmr_destructionReport.title=Overf\u00f8ringsrapport +rmr_recordsmanagementreport.type.rmr_destructionReport.description=Oppf\u00f8ringsh\u00e5ndteringsrapport med overf\u00f8ringer. + +rmr_recordsmanagementreport.type.rmr_destructionReport.title=Destruksjonsrapport +rmr_recordsmanagementreport.type.rmr_destructionReport.description=Oppf\u00f8ringsh\u00e5ndteringsrapport med destruksjoner. + +rmr_recordsmanagementreport.type.rmr_holdReport.title=Holdrapport +rmr_recordsmanagementreport.type.rmr_holdReport.description=Oppf\u00f8ringsh\u00e5ndteringsrapport med hold. \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-model_ru.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-model_ru.properties index 1ca6ac6b69..eb1ae4e117 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-model_ru.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-model_ru.properties @@ -9,5 +9,5 @@ rmr_recordsmanagementreport.type.rmr_destructionReport.description=\u041e\u0442\ rmr_recordsmanagementreport.type.rmr_destructionReport.title=\u041e\u0442\u0447\u0435\u0442 \u043e\u0431 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0438 rmr_recordsmanagementreport.type.rmr_destructionReport.description=\u041e\u0442\u0447\u0435\u0442 \u043e\u0431 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u044f\u043c\u0438. -rmr_recordsmanagementreport.type.rmr_holdReport.title=\u041E\u0442\u0447\u0435\u0442 \u043E \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0430\u0445 -rmr_recordsmanagementreport.type.rmr_holdReport.description=\u041E\u0442\u0447\u0435\u0442 \u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0437\u0430\u043F\u0438\u0441\u044F\u043C\u0438 \u043E \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0430\u0445. \ No newline at end of file +rmr_recordsmanagementreport.type.rmr_holdReport.title=\u041e\u0442\u0447\u0435\u0442 \u043e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430\u0445 +rmr_recordsmanagementreport.type.rmr_holdReport.description=\u041e\u0442\u0447\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u044f\u043c\u0438 \u043e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430\u0445. \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-service_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-service_nb.properties new file mode 100644 index 0000000000..ab0349861b --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/report-service_nb.properties @@ -0,0 +1 @@ +report.default=Rapport \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-actions_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-actions_nb.properties new file mode 100644 index 0000000000..467390eb31 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-actions_nb.properties @@ -0,0 +1,8 @@ +# Disposition Actions +cutoff.title=Cut off +cutoff.description=Cut off +retain.title=Behold +retain.description=Behold +destroy.title=Destruer +destroy.description=Destruer + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-events.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-events.properties index 6342449a64..ff7d78eab7 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-events.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-events.properties @@ -3,6 +3,7 @@ rmeventservice.rmEventType.simple=Simple Event rmeventservice.rmEventType.obsolete=Obsoleted Event rmeventservice.rmEventType.superseded=Superseded Event rmeventservice.rmEventType.crossReferencedRecordTransfered=Cross Referenced Record Transferred +rmeventservice.rmEventType.versioned=Versioned Event # Default events rmevent.case_closed=Case Closed @@ -10,6 +11,7 @@ rmevent.abolished=Abolished rmevent.re_designated=Redesignated rmevent.no_longer_needed=No longer needed rmevent.superseded=Superseded +rmevent.versioned=Versioned rmevent.study_complete=Study Complete rmevent.training_complete=Training Complete rmevent.related_record_trasfered_inactive_storage=Related Record Transferred To Inactive Storage diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-events_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-events_nb.properties new file mode 100644 index 0000000000..357505585a --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-events_nb.properties @@ -0,0 +1,20 @@ +# Event Types +rmeventservice.rmEventType.simple=Enkel hendelse +rmeventservice.rmEventType.obsolete=Utg\u00e5tt hendelse +rmeventservice.rmEventType.superseded=Erstattet hendelse +rmeventservice.rmEventType.crossReferencedRecordTransfered=Oppf\u00f8ring med krysshenvisninger er overf\u00f8rt + +# Default events +rmevent.case_closed=Sak avslutt +rmevent.abolished=Avskaffet +rmevent.re_designated=Angitt p\u00e5 nytt +rmevent.no_longer_needed=Ikke lenger n\u00f8dvendig +rmevent.superseded=Erstattet +rmevent.study_complete=Studie fullf\u00f8rt +rmevent.training_complete=Oppl\u00e6ring fullf\u00f8rt +rmevent.related_record_trasfered_inactive_storage=Relatert oppf\u00f8ring overf\u00f8rt til inaktiv lagring +rmevent.obsolete=Utg\u00e5tt +rmevent.all_allowances_granted_are_terminated=Alle tillatelser som er gitt, er avsluttet +rmevent.WGI_action_complete=WGI-handling fullf\u00f8rt +rmevent.separation=Separasjon +rmevent.case_complete=Sak fullf\u00f8rt \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-system_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-system_nb.properties new file mode 100644 index 0000000000..c513682c61 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-system_nb.properties @@ -0,0 +1,25 @@ +rm.hold.name=Hold + +## Defaut roles +rm.role.extendedReaders=P\u00e5 plass lesere +rm.role.extendedWriters=P\u00e5 plass skribenter +rm.role.user=Bruker av oppf\u00f8ringsh\u00e5ndtering +rm.role.powerUser=Priviligert bruker av oppf\u00f8ringsh\u00e5ndtering +rm.role.securityOfficer=Sikkerhetsansvarlig ved oppf\u00f8ringsh\u00e5ndtering +rm.role.recordsManager=Ansvarlig ved oppf\u00f8ringsh\u00e5ndtering +rm.role.administrator=Administrator ved oppf\u00f8ringsh\u00e5ndtering +rm.role.all=Alle oppf\u00f8ringsh\u00e5ndteringsrollene + +## Default searches +rm.savedsearch.vitalRecordsName=Sv\u00e6rt viktige oppf\u00f8ringer som skal gjennomg\u00e5s +rm.savedsearch.vitalRecordsDesc=Alle oppf\u00f8ringer som n\u00e5 skal gjennomg\u00e5s. +rm.savedsearch.incompleteRecordsName=Ufullstendige oppf\u00f8ringer +rm.savedsearch.incompleteRecordsDesc=Alle ufullstendige oppf\u00f8ringer. +rm.savedsearch.cutoffRecordsName=Oppf\u00f8ringer og oppf\u00f8ringsmapper som er kvalifisert til cut off +rm.savedsearch.cutoffRecordsDesc=Alle oppf\u00f8ringer og oppf\u00f8ringsmapper som for tiden er kvalifisert til cut off. +rm.savedsearch.transferRecordsName=Oppf\u00f8ringer og oppf\u00f8ringsmapper som er kvalifisert til overf\u00f8ring +rm.savedsearch.transferRecordsDesc=Alle oppf\u00f8ringmapper og oppf\u00f8ringer som for tiden er kvalifisert til overf\u00f8ring. +rm.savedsearch.destructionRecordsName=Oppf\u00f8ringer og oppf\u00f8ringsmapper som er kvalifisert til destruksjon +rm.savedsearch.destructionRecordsDesc=Alle oppf\u00f8ringer som for tiden er kvalifisert til destruksjon. +rm.savedsearch.frozenRecordsName= Oppf\u00f8ringer og oppf\u00f8ringsmapper p\u00e5 hold +rm.savedsearch.frozenRecordsDesc=Alle oppf\u00f8ringer og oppf\u00f8ringsmapper for tiden p\u00e5 hold. \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-system_ru.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-system_ru.properties index 6edbc98e3f..85244d18e0 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-system_ru.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/rm-system_ru.properties @@ -1,4 +1,4 @@ -rm.hold.name=\u0411\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0430 +rm.hold.name=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 ## Defaut roles rm.role.extendedReaders=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0438 @@ -21,5 +21,5 @@ rm.savedsearch.transferRecordsName=\u0417\u0430\u043f\u0438\u0441\u0438 \u0438 \ rm.savedsearch.transferRecordsDesc=\u0412\u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u043f\u0430\u043f\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442. rm.savedsearch.destructionRecordsName=\u0417\u0430\u043f\u0438\u0441\u0438 \u0438 \u043f\u0430\u043f\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u043b\u044f \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f rm.savedsearch.destructionRecordsDesc=\u0412\u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u043f\u0430\u043f\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u043b\u044f \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442. -rm.savedsearch.frozenRecordsName=\u0417\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u0437\u0430\u043F\u0438\u0441\u0438 \u0438 \u043F\u0430\u043F\u043A\u0438 \u0437\u0430\u043F\u0438\u0441\u0435\u0439 -rm.savedsearch.frozenRecordsDesc=\u0412\u0441\u0435 \u0437\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u0437\u0430\u043F\u0438\u0441\u0438 \u0438 \u043F\u0430\u043F\u043A\u0438 \u0437\u0430\u043F\u0438\u0441\u0435\u0439. \ No newline at end of file +rm.savedsearch.frozenRecordsName=\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u043f\u0430\u043f\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 +rm.savedsearch.frozenRecordsDesc=\u0412\u0441\u0435 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u043f\u0430\u043f\u043a\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439. \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/template_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/template_nb.properties new file mode 100644 index 0000000000..518321dece --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/template_nb.properties @@ -0,0 +1,27 @@ +# File Report Template +file.report.acession.report=Tilgangsrapport +file.report.date.format=EEE MMM dd TT:mm:ss zzz \u00e5\u00e5\u00e5\u00e5 +file.report.declared.by=erkl\u00e6rt av +file.report.declared.on=p\u00e5 +file.report.destroyed=Destruert +file.report.destroyed.records=Destruerte oppf\u00f8ringer +file.report.destruction.report=Destruksjonsrapport +file.report.disposition.authority=Disposisjonsrett +file.report.disposition.instructions=Disposisjonsinstruksjoner +file.report.nara=NARA +file.report.transfer.date=Overf\u00f8ringsdato +file.report.transfer.location=Overf\u00f8ringssted +file.report.transfer.report=Overf\u00f8ringsrapport +file.report.transferred.items=Overf\u00f8rte elementer +file.report.performed.by=Utf\u00f8rt av +file.report.record=Oppf\u00f8ring +file.report.record.folder=Oppf\u00f8ringsmappe +file.report.unique.folder.identifier=Unik mappe-ID +file.report.unique.record.identifier=Unik oppf\u00f8rings-ID +file.report.hold.report=Holdrapport +file.report.hold.name=Holdnavn +file.report.hold.description=Holdbeskrivelse +file.report.hold.reason=Grunn til holdet +file.report.hold.held=Hold +file.report.createdby=Opprettet av +file.report.createdon=Opprettet den \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/template_ru.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/template_ru.properties index 6affcc35a6..88851814d2 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/template_ru.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/messages/template_ru.properties @@ -18,10 +18,10 @@ file.report.record=\u0417\u0430\u043f\u0438\u0441\u044c file.report.record.folder=\u041f\u0430\u043f\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 file.report.unique.folder.identifier=\u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u0430\u043f\u043a\u0438 file.report.unique.record.identifier=\u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u043f\u0438\u0441\u0438 -file.report.hold.report=\u041e\u0442\u0447\u0435\u0442 \u043e \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0435 -file.report.hold.name=\u0418\u043c\u044f \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0438 -file.report.hold.description=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0438 -file.report.hold.reason=\u041F\u0440\u0438\u0447\u0438\u043D\u0430 \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0438 -file.report.hold.held=\u0417\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043E +file.report.hold.report=\u041e\u0442\u0447\u0435\u0442 \u043e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435 +file.report.hold.name=\u0418\u043c\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 +file.report.hold.description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 +file.report.hold.reason=\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 +file.report.hold.held=\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e file.report.createdby=\u0421\u043e\u0437\u0434\u0430\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c file.report.createdon=\u0414\u0430\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordableVersionModel.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordableVersionModel.xml index b3865d3518..6158bea0b5 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordableVersionModel.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordableVersionModel.xml @@ -67,7 +67,7 @@ Recordable Version Policy d:text - disabled + NONE 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 92311a5200..59017fcf50 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 @@ -95,6 +95,7 @@ + @@ -183,6 +184,7 @@ + @@ -486,6 +488,10 @@ + + + + \ 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 e17a8c3935..aa17145c97 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 @@ -16,6 +16,7 @@ parent="module.baseComponent"> + @@ -32,6 +33,13 @@ + + + + + + @@ -49,7 +57,8 @@ - + + @@ -90,6 +99,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -118,36 +162,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -159,6 +174,7 @@ + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-context.xml index 8b43fd854c..784324a4ce 100755 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-context.xml @@ -9,7 +9,7 @@ - + @@ -31,6 +31,7 @@ + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-v23-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-v23-context.xml new file mode 100644 index 0000000000..ac52237135 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-v23-context.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file 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 8824e6275c..f75f4a4ca8 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 @@ -817,7 +817,7 @@ - + @@ -844,6 +844,30 @@ + + + + + + + + + + + + + + + + org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_CAP.0.rma:filePlanComponent.DeleteLinks + org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW + org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW + + + + + + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-public-services-security-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-public-services-security-context.xml index 4937890e4e..b64ade5659 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-public-services-security-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-public-services-security-context.xml @@ -45,7 +45,7 @@ - + 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 3e810cbf49..a1c7152d0d 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 @@ -378,11 +378,12 @@ - + + - - + @@ -444,6 +445,7 @@ + @@ -1044,6 +1046,9 @@ + + + @@ -1097,7 +1102,8 @@ org.alfresco.module.org_alfresco_module_rm.record.RecordService.isDeclared=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.record.RecordService.isFiled=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.record.RecordService.createRecord=RM_ALLOW - org.alfresco.module.org_alfresco_module_rm.record.RecordService.createRecordFromContent=RM.Create.0 + org.alfresco.module.org_alfresco_module_rm.record.RecordService.createRecordFromContent=RM.Create.0 + org.alfresco.module.org_alfresco_module_rm.record.RecordService.createRecordFromCopy=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.record.RecordService.file=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.record.RecordService.isPropertyEditable=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.record.RecordService.isMetadataStub=RM.Read.0 @@ -1106,6 +1112,7 @@ org.alfresco.module.org_alfresco_module_rm.record.RecordService.addRecordType=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.record.RecordService.makeRecord=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.record.RecordService.link=RM_ALLOW + org.alfresco.module.org_alfresco_module_rm.record.RecordService.unlink=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.record.RecordService.*=RM_DENY ]]> @@ -1579,4 +1586,49 @@ + + + + + + + + + + org.alfresco.module.org_alfresco_module_rm.recordableversion.RecordableVersionConfigService + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + + + 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 800e214770..9611d55654 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 @@ -3,13 +3,22 @@ + + - + + + + + + @@ -354,6 +363,17 @@ + + + + + RECORD + + + + + @@ -399,6 +419,7 @@ FILE_PLAN + RECORD RECORD_CATEGORY RECORD_FOLDER UNFILED_RECORD_CONTAINER diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-version-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-version-context.xml index 5245ccc2ea..224648258d 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-version-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-version-context.xml @@ -15,12 +15,10 @@ - - - - + + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml index 9ceeb3a195..7a31fd1b76 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml @@ -466,7 +466,6 @@ - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/security/rm-default-roles-bootstrap.json b/rm-server/config/alfresco/module/org_alfresco_module_rm/security/rm-default-roles-bootstrap.json index 486c1fd0ba..4f42947a85 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/security/rm-default-roles-bootstrap.json +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/security/rm-default-roles-bootstrap.json @@ -143,7 +143,8 @@ "RemoveFromHold", "FileHoldReport", "DeleteHold", - "EditHold" + "EditHold", + "EndRetention" ] }, { @@ -215,7 +216,8 @@ "RemoveFromHold", "FileHoldReport", "DeleteHold", - "EditHold" + "EditHold", + "EndRetention" ] } ] \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/security/rm-method-security_nb.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/security/rm-method-security_nb.properties new file mode 100644 index 0000000000..e4d403c268 --- /dev/null +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/security/rm-method-security_nb.properties @@ -0,0 +1,228 @@ +## +# RM Method security for Alfresco code services +# +# Note: add alfresco/extension/rm-method-security.properties to extend +## + +## Node Service + +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getStores=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.createStore=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.exists=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getNodeStatus=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getAllRootNodes=RM.Read.0,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getRootNode=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.createNode=RM.Create.0.3 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.moveNode=RM.Move.0.1 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.setChildAssociationIndex=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getType=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.setType=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.addAspect=RM.Update.0.1.2 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeAspect=RM.Update.0.1 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.hasAspect=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getAspects=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.deleteNode=RM.Delete.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.addChild=RM.Create.0.1.2 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeChild=RM.Delete.0.1 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeChildAssociation=RM.Delete.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getProperties=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getProperty=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.setProperties=RM.UpdateProperties.0.1 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.addProperties=RM.UpdateProperties.0.1 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.setProperty=RM.UpdateProperties.0.1.2 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeProperty=RM.UpdateProperties.0.1 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getParentAssocs=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getParentAssocs=RM.Read.0.1.2 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildAssocs=RM.Read.0,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildByName=RM.Read.0,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildrenByName=RM.Read.0,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getPrimaryParent=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.createAssociation=RM.Assoc.0.1 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeAssociation=Assoc.0.1 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getTargetAssocs=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getSourceAssocs=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getAssoc=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getPath=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getPaths=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getStoreArchiveNode=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.restoreNode=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildAssocsWithoutParentAssocsOfType=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getNodeRef=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildAssocsByPropertyValue=RM.Read.0,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.countChildAssocs=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getNodeAclId=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.*=RM_DENY + +## File Folder Service + +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.list=RM.Read.0,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.listFiles=RM.Read.0,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.listFolders=RM.Read.0,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.listDeepFolders=RM.Read.0,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.getLocalizedSibling=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.search=RM.Read.0,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.searchSimple=RM.Read.0,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.rename=RM.Update.0 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.move=RM.Move.0.1 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.moveFrom=RM.Move.0.2 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.copy=RM.Read.0,RM.Create.1.0 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.create=RM.Create.0 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.delete=RM.Delete.0 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.getNamePath=RM.Read.1 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.getNameOnlyPath=RM.Read.1 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.resolveNamePath=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.getFileInfo=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.getReader=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.getWriter=RM.WriteContent.0 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.exists=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.getType=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.isHidden=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.setHidden=RM.Update.0 +rm.methodsecurity.org.alfresco.service.cmr.model.FileFolderService.*=RM_DENY + +## Content Service + +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.getStoreTotalSpace=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.getStoreFreeSpace=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.getRawReader=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.getReader=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.getWriter=RM.WriteContent.0 +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.isTransformable=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.getTransformer=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.getMaxSourceSizeBytes=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.getImageTransformer=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.transform=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.getTempWriter=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.repository.ContentService.*=RM_DENY + +## Search Service + +rm.methodsecurity.org.alfresco.service.cmr.search.SearchService.query=RM_QUERY,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.search.SearchService.selectNodes=RM_QUERY,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.search.SearchService.selectProperties=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.SearchService.contains=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.search.SearchService.like=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.search.SearchService.*=RM_DENY + +## Category Service + +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.getChildren=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.getCategories=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.getClassifications=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.getRootCategories=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.getClassificationAspects=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.createClassification=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.createRootCategory=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.createCategory=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.deleteClassification=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.deleteCategory=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.getTopCategories=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.search.CategoryService.*=RM_DENY + +## Lock Service + +rm.methodsecurity.org.alfresco.service.cmr.lock.LockService.lock=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.lock.LockService.unlock=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.lock.LockService.getLockStatus=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.lock.LockService.getLockType=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.lock.LockService.checkForLock=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.lock.LockService.getLocks=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.lock.LockService.*=RM_DENY + +## Multilingual Content Service + +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.getTranslationContainer=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.getTranslations=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.getTranslationForLocale=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.getMissingTranslations=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.getPivotTranslation=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.isTranslation=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.makeTranslation=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.unmakeTranslation=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.addTranslation=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.addEmptyTranslation=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.copyTranslationContainer=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.moveTranslationContainer=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.deleteTranslationContainer=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.MultilingualContentService.*=RM_DENY + +## Edition Service + +rm.methodsecurity.org.alfresco.service.cmr.ml.EditionService.createEdition=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.EditionService.getEditions=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.EditionService.getVersionedTranslations=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.EditionService.getVersionedMetadatas=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.ml.EditionService.*=RM_DENY + +## Check Out Check In Service + +rm.methodsecurity.org.alfresco.service.cmr.coci.CheckOutCheckInService.checkout=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.coci.CheckOutCheckInService.checkin=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.coci.CheckOutCheckInService.cancelCheckout=RM_ABSTAIN +rm.methodsecurity.org.alfresco.service.cmr.coci.CheckOutCheckInService.getWorkingCopy=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.coci.CheckOutCheckInService.getCheckedOut=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.coci.CheckOutCheckInService.isWorkingCopy=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.coci.CheckOutCheckInService.isCheckedOut=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.coci.CheckOutCheckInService.*=RM_DENY + +## Permission Service + +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.getOwnerAuthority=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.getAllAuthorities=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.getAllPermission=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.getPermissions=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.getAllSetPermissions=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.getSettablePermissions=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.hasPermission=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.deletePermissions=RM.Capability.0 +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.deletePermission=RM.Capability.0 +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.setPermission=RM.Capability.0 +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.setInheritParentPermissions=RM.Capability.0 +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.getInheritParentPermissions=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.clearPermission=RM.Capability.0 +rm.methodsecurity.org.alfresco.service.cmr.security.PermissionService.*=RM_DENY + +## Site service + +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.cleanSitePermissions=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.createContainer=RM_ALLOW,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.createSite=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.deleteSite=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.findSites=RM_ALLOW,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.getContainer=RM_ALLOW,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.getMembersRole=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.getMembersRoleInfo=ACL_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.getSite=RM_ALLOW,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.getSiteGroup=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.getSiteRoleGroup=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.getSiteRoles=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.getSiteRoot=RM_ALLOW,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.hasContainer=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.hasCreateSitePermissions=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.isMember=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.listMembers=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.listMembersInfo=ACL_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.listSites=RM_ALLOW,AFTER_RM.FilterNode +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.removeMembership=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.setMembership=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.updateSite=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.listMembersPaged=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.listContainers=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.countAuthoritiesWithRole=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.resolveSite=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.hasSite=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.listSitesPaged=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.getSiteShortName=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.canAddMember=RM_ALLOW +rm.methodsecurity.org.alfresco.service.cmr.site.SiteService.*=RM_ALLOW + +## Form Service + +rm.methodsecurity.org.alfresco.repo.forms.FormService.getForm=RM_ALLOW +rm.methodsecurity.org.alfresco.repo.forms.FormService.saveForm=RM_ALLOW +rm.methodsecurity.org.alfresco.repo.forms.FormService.*=RM_DENY + +## Ownable Service + +rm.methodsecurity.org.alfresco.service.cmr.security.OwnableService.getOwner=RM.Read.0 +rm.methodsecurity.org.alfresco.service.cmr.security.OwnableService.*=RM_DENY \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraint.put_nb.properties b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraint.put_nb.properties new file mode 100644 index 0000000000..7f27bb9c94 --- /dev/null +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraint.put_nb.properties @@ -0,0 +1 @@ +rm.admin.list-already-exists=En liste med navnet ''{0}'' finnes allerede. \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraint.put_ru.properties b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraint.put_ru.properties index 2bd7171a07..9cd2609585 100644 --- a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraint.put_ru.properties +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraint.put_ru.properties @@ -1 +1 @@ -rm.admin.list-already-exists=\u0421\u043f\u0438\u0441\u043e\u043a \u0441 \u0438\u043c\u0435\u043d\u0435\u043c \u00ab{0}\u00bb \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \ No newline at end of file +rm.admin.list-already-exists=\u0421\u043f\u0438\u0441\u043e\u043a \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ''{0}'' \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraints.post_nb.properties b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraints.post_nb.properties new file mode 100644 index 0000000000..7f27bb9c94 --- /dev/null +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraints.post_nb.properties @@ -0,0 +1 @@ +rm.admin.list-already-exists=En liste med navnet ''{0}'' finnes allerede. \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraints.post_ru.properties b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraints.post_ru.properties index 2bd7171a07..9cd2609585 100644 --- a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraints.post_ru.properties +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmconstraint/rmconstraints.post_ru.properties @@ -1 +1 @@ -rm.admin.list-already-exists=\u0421\u043f\u0438\u0441\u043e\u043a \u0441 \u0438\u043c\u0435\u043d\u0435\u043c \u00ab{0}\u00bb \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \ No newline at end of file +rm.admin.list-already-exists=\u0421\u043f\u0438\u0441\u043e\u043a \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ''{0}'' \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmevent/rmeventtypes.get.json.ftl b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmevent/rmeventtypes.get.json.ftl index 21d6c3a7e3..9f8d7bd807 100644 --- a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmevent/rmeventtypes.get.json.ftl +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/admin/rmevent/rmeventtypes.get.json.ftl @@ -8,7 +8,7 @@ "${eventtype.name}": { "eventTypeName" : "${eventtype.name}", - "eventTypeDisplayLabel" : "${eventtype.displayLabel}" + "eventTypeDisplayLabel" : "<#if eventtype.displayLabel??>${eventtype.displayLabel}<#else>" }<#if eventtype_has_next>, } diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationship.delete.desc.xml b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationship.delete.desc.xml new file mode 100644 index 0000000000..2b16d435ac --- /dev/null +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationship.delete.desc.xml @@ -0,0 +1,8 @@ + + Delete records management relationship + Deletes the specified relationship. + /api/node/{store_type}/{store_id}/{id}/targetnode/{target_store_type}/{target_store_id}/{target_id}/uniqueName/{uniqueName} + + user + required + \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationship.delete.json.ftl b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationship.delete.json.ftl new file mode 100644 index 0000000000..3b7961a392 --- /dev/null +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationship.delete.json.ftl @@ -0,0 +1,3 @@ +{ + "success": ${success?string} +} \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationshiplabels.get.desc.xml b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationshiplabels.get.desc.xml new file mode 100644 index 0000000000..4d34693449 --- /dev/null +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationshiplabels.get.desc.xml @@ -0,0 +1,8 @@ + + Records Management Relationship Labels + Gets the list of existing relationship labels. + /api/rma/admin/relationshiplabels + + user + required + \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationshiplabels.get.json.ftl b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationshiplabels.get.json.ftl new file mode 100644 index 0000000000..b000b08c1d --- /dev/null +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationshiplabels.get.json.ftl @@ -0,0 +1,16 @@ +<#escape x as jsonUtils.encodeJSONString(x)> +{ + "data": + { + "relationshipLabels": + [ + <#list relationshipLabels as relationshipLabel> + { + "label": "${relationshipLabel.label}", + "uniqueName": "${relationshipLabel.uniqueName}" + }<#if relationshipLabel_has_next>, + + ] + } +} + \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationships.get.desc.xml b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationships.get.desc.xml new file mode 100644 index 0000000000..ea306912b1 --- /dev/null +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationships.get.desc.xml @@ -0,0 +1,8 @@ + + Records Management Relationships + Gets the list of existing relationships on the specified node. + /api/node/{store_type}/{store_id}/{id}/relationships + + user + required + \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationships.get.json.ftl b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationships.get.json.ftl new file mode 100644 index 0000000000..ede191397c --- /dev/null +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/relationships.get.json.ftl @@ -0,0 +1,15 @@ +<#escape x as jsonUtils.encodeJSONString(x)> +{ + "data": + { + "items": + [ + <#list relationships as relationship> + { + "node": <#noescape>${relationship} + }<#if relationship_has_next>, + + ] + } +} + \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.desc.xml b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.desc.xml deleted file mode 100644 index cd90572016..0000000000 --- a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.desc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - Records Management Permissions - Retrieve the Permissions set against a Records Management node. - /api/node/{store_type}/{store_id}/{id}/rmpermissions - argument - user - required - internal - \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.js b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.js deleted file mode 100644 index 439a2654ac..0000000000 --- a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Entry point for rmpermissions GET data webscript. - * Queries the permissions from an RM node and constructs the data-model for the template. - * - * @method main - */ -function main() -{ - // Get the node from the URL - var pathSegments = url.match.split("/"); - var reference = [ url.templateArgs.store_type, url.templateArgs.store_id ].concat(url.templateArgs.id.split("/")); - var node = search.findNode(pathSegments[2], reference); - - // 404 if the node is not found - if (node == null) - { - status.setCode(status.STATUS_NOT_FOUND, "The node could not be found"); - return; - } - - // retrieve permissions applied to this node - var permissions = node.getFullPermissions(); - - // split tokens - results are in the format: - // [ALLOWED|DENIED];[USERNAME|GROUPNAME];PERMISSION;[INHERITED|DIRECT] - var result = []; - for (var i=0; i -{ - "data": - { - "permissions": - [ - <#list permissions as perm> - { - "id": "${perm.id}", - "authority": - { - "id": "${perm.authority.id}", - "label": "${perm.authority.label}" - }, - "inherited": ${perm.inherited?string} - }<#if perm_has_next>, - - ], - "inherited": ${inherited?string} - } -} - \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.post.json.js b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.post.json.js index 6aa731567e..a29ec41b13 100644 --- a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.post.json.js +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.post.json.js @@ -1,7 +1,7 @@ /** * Entry point for rmpermissions POST data webscript. * Applies supplied RM permissions to an RM node. - * + * * @method main */ function main() @@ -10,41 +10,46 @@ function main() var pathSegments = url.match.split("/"); var reference = [ url.templateArgs.store_type, url.templateArgs.store_id ].concat(url.templateArgs.id.split("/")); var node = search.findNode(pathSegments[2], reference); - + // 404 if the node is not found if (node == null) { status.setCode(status.STATUS_NOT_FOUND, "The node could not be found"); return; } - + if (json.has("permissions") == false) { status.setCode(status.STATUS_BAD_REQUEST, "Permissions value missing from request."); } - + + if (json.has("isInherited")) + { + node.setInheritsPermissions(json.getBoolean("isInherited")); + } + var permissions = json.getJSONArray("permissions"); for (var i=0; i applicableKinds = new HashSet(); /** - * Set the namespace service + * Get the transaction service + */ + protected TransactionService getTransactionService() + { + return this.transactionService; + } + + /** + * Set the transaction service */ public void setTransactionService(TransactionService transactionService) { this.transactionService = transactionService; } + /** + * Gets the namespace service + */ + protected NamespaceService getNamespaceService() + { + return this.namespaceService; + } + /** * Set the namespace service */ @@ -136,6 +152,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.namespaceService = namespaceService; } + /** + * Gets the node service + */ + protected NodeService getNodeService() + { + return this.nodeService; + } + /** * Set node service */ @@ -144,6 +168,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.nodeService = nodeService; } + /** + * Gets the dictionary service + */ + protected DictionaryService getDictionaryService() + { + return this.dictionaryService; + } + /** * Set the dictionary service */ @@ -152,6 +184,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.dictionaryService = dictionaryService; } + /** + * Gets the content service + */ + protected ContentService getContentService() + { + return this.contentService; + } + /** * Set the content service */ @@ -160,6 +200,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.contentService = contentService; } + /** + * Gets the action service + */ + protected ActionService getActionService() + { + return this.actionService; + } + /** * Set action service */ @@ -168,6 +216,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.actionService = actionService; } + /** + * Gets the records management audit service + */ + protected RecordsManagementAuditService getRecordsManagementAuditService() + { + return this.recordsManagementAuditService; + } + /** * Set the audit service that action details will be sent to */ @@ -176,6 +232,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.recordsManagementAuditService = recordsManagementAuditService; } + /** + * Gets the records management action service + */ + protected RecordsManagementActionService getRecordsManagementActionService() + { + return this.recordsManagementActionService; + } + /** * Set records management service */ @@ -184,6 +248,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.recordsManagementActionService = recordsManagementActionService; } + /** + * Gets the disposition service + */ + protected DispositionService getDispositionService() + { + return this.dispositionService; + } + /** * Set the disposition service */ @@ -192,6 +264,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.dispositionService = dispositionService; } + /** + * Gets the vital record service + */ + protected VitalRecordService getVitalRecordService() + { + return this.vitalRecordService; + } + /** * @param vitalRecordService vital record service */ @@ -200,6 +280,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.vitalRecordService = vitalRecordService; } + /** + * Gets the records management event service + */ + protected RecordsManagementEventService getRecordsManagementEventService() + { + return this.recordsManagementEventService; + } + /** * Set records management event service */ @@ -208,6 +296,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.recordsManagementEventService = recordsManagementEventService; } + /** + * Gets the ownable service + */ + protected OwnableService getOwnableService() + { + return this.ownableService; + } + /** * Set the ownable service * @param ownableSerice @@ -217,6 +313,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.ownableService = ownableService; } + /** + * Gets the freeze service + */ + protected FreezeService getFreezeService() + { + return this.freezeService; + } + /** * Set freeze service * @@ -227,6 +331,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.freezeService = freezeService; } + /** + * Gets the record service + */ + protected RecordService getRecordService() + { + return this.recordService; + } + /** * Set record service * @@ -237,6 +349,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.recordService = recordService; } + /** + * @return records management admin service + */ + protected RecordsManagementAdminService getRecordsManagementAdminService() + { + return recordsManagementAdminService; + } + /** * @param recordsManagementAdminService records management admin service */ @@ -246,11 +366,11 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe } /** - * @return records management admin service + * Gets the model security service */ - public RecordsManagementAdminService getRecordsManagementAdminService() + protected ModelSecurityService getModelSecurityService() { - return recordsManagementAdminService; + return this.modelSecurityService; } /** @@ -261,6 +381,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.modelSecurityService = modelSecurityService; } + /** + * Gets the record folder service + */ + protected RecordFolderService getRecordFolderService() + { + return this.recordFolderService; + } + /** * @param recordFolderService record folder service */ @@ -269,6 +397,14 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe this.recordFolderService = recordFolderService; } + /** + * Gets the hold service + */ + protected HoldService getHoldService() + { + return this.holdService; + } + /** * @param holdService hold service */ diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMDispositionActionExecuterAbstractBase.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMDispositionActionExecuterAbstractBase.java index bac84fd8dc..aeda1c56c8 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMDispositionActionExecuterAbstractBase.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMDispositionActionExecuterAbstractBase.java @@ -117,28 +117,28 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx { // Check the eligibility of the action if (!checkEligibility(actionedUponNodeRef) || - dispositionService.isNextDispositionActionEligible(actionedUponNodeRef)) + getDispositionService().isNextDispositionActionEligible(actionedUponNodeRef)) { if (di.isRecordLevelDisposition()) { // Check that we do indeed have a record - if (recordService.isRecord(actionedUponNodeRef)) + if (getRecordService().isRecord(actionedUponNodeRef)) { // Can only execute disposition action on record if declared - if (recordService.isDeclared(actionedUponNodeRef)) + if (getRecordService().isDeclared(actionedUponNodeRef)) { // Indicate that the disposition action is underway - nodeService.setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_STARTED_AT, new Date()); - nodeService.setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_STARTED_BY, AuthenticationUtil.getRunAsUser()); + getNodeService().setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_STARTED_AT, new Date()); + getNodeService().setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_STARTED_BY, AuthenticationUtil.getRunAsUser()); // Execute record level disposition executeRecordLevelDisposition(action, actionedUponNodeRef); - if (nodeService.exists(nextDispositionActionNodeRef) && + if (getNodeService().exists(nextDispositionActionNodeRef) && getSetDispositionActionComplete()) { - nodeService.setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_AT, new Date()); - nodeService.setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_BY, AuthenticationUtil.getRunAsUser()); + getNodeService().setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_AT, new Date()); + getNodeService().setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_BY, AuthenticationUtil.getRunAsUser()); } } else @@ -153,22 +153,22 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx } else { - if (recordFolderService.isRecordFolder(actionedUponNodeRef)) + if (getRecordFolderService().isRecordFolder(actionedUponNodeRef)) { - if (recordFolderService.isRecordFolderDeclared(actionedUponNodeRef)) + if (getRecordFolderService().isRecordFolderDeclared(actionedUponNodeRef)) { // Indicate that the disposition action is underway - nodeService.setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_STARTED_AT, new Date()); - nodeService.setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_STARTED_BY, AuthenticationUtil.getRunAsUser()); + getNodeService().setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_STARTED_AT, new Date()); + getNodeService().setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_STARTED_BY, AuthenticationUtil.getRunAsUser()); executeRecordFolderLevelDisposition(action, actionedUponNodeRef); // Indicate that the disposition action is compelte - if (nodeService.exists(nextDispositionActionNodeRef) && + if (getNodeService().exists(nextDispositionActionNodeRef) && getSetDispositionActionComplete()) { - nodeService.setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_AT, new Date()); - nodeService.setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_BY, AuthenticationUtil.getRunAsUser()); + getNodeService().setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_AT, new Date()); + getNodeService().setProperty(nextDispositionActionNodeRef, PROP_DISPOSITION_ACTION_COMPLETED_BY, AuthenticationUtil.getRunAsUser()); } } @@ -184,10 +184,10 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx } - if (nodeService.exists(actionedUponNodeRef) && getSetDispositionActionComplete()) + if (getNodeService().exists(actionedUponNodeRef) && getSetDispositionActionComplete()) { // Update the disposition schedule - dispositionService.updateNextDispositionAction(actionedUponNodeRef); + getDispositionService().updateNextDispositionAction(actionedUponNodeRef); } } else @@ -225,7 +225,7 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx protected DispositionSchedule checkDispositionActionExecutionValidity(NodeRef nodeRef, NodeRef nextDispositionActionNodeRef, boolean throwError) { // Check the node has associated disposition instructions - DispositionSchedule di = dispositionService.getDispositionSchedule(nodeRef); + DispositionSchedule di = getDispositionService().getDispositionSchedule(nodeRef); if (di == null) { if (throwError) @@ -239,7 +239,7 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx } // Check the node has the disposition schedule aspect applied - if (!nodeService.hasAspect(nodeRef, ASPECT_DISPOSITION_LIFECYCLE)) + if (!getNodeService().hasAspect(nodeRef, ASPECT_DISPOSITION_LIFECYCLE)) { if (throwError) { @@ -266,7 +266,7 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx return null; } } - String actionName = (String) nodeService.getProperty(nextDispositionAction, PROP_DISPOSITION_ACTION); + String actionName = (String) getNodeService().getProperty(nextDispositionAction, PROP_DISPOSITION_ACTION); if (actionName == null || !actionName.equals(getName())) { if (throwError) @@ -293,7 +293,7 @@ public abstract class RMDispositionActionExecuterAbstractBase extends RMActionEx private NodeRef getNextDispostionAction(NodeRef nodeRef) { NodeRef result = null; - List assocs = nodeService.getChildAssocs(nodeRef, ASSOC_NEXT_DISPOSITION_ACTION, RegexQNamePattern.MATCH_ALL); + List assocs = getNodeService().getChildAssocs(nodeRef, ASSOC_NEXT_DISPOSITION_ACTION, RegexQNamePattern.MATCH_ALL); if (assocs.size() != 0) { result = assocs.get(0).getChildRef(); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/ScheduledDispositionJob.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/ScheduledDispositionJob.java index 397239c9d5..be14759848 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/ScheduledDispositionJob.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/ScheduledDispositionJob.java @@ -84,7 +84,7 @@ public class ScheduledDispositionJob implements Job String query = "+ASPECT:\"rma:record\" +ASPECT:\"rma:dispositionSchedule\" +@rma\\:dispositionAsOf:" + dateRange; SearchService search = (SearchService)context.getJobDetail().getJobDataMap().get("searchService"); - ResultSet results = search.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, query); + ResultSet results = search.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_FTS_ALFRESCO, query); List resultNodes = results.getNodeRefs(); results.close(); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/constraint/VersionParameterConstraint.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/constraint/VersionParameterConstraint.java new file mode 100644 index 0000000000..c1677f84d8 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/constraint/VersionParameterConstraint.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.action.constraint; + +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy; +import org.alfresco.repo.action.constraint.BaseParameterConstraint; + +/** + * Recordable version config constraint + * + * @author Tuna Aksoy + * @since 2.3 + */ +public class VersionParameterConstraint extends BaseParameterConstraint +{ + /** + * @see org.alfresco.repo.action.constraint.BaseParameterConstraint#getAllowableValuesImpl() + */ + @Override + protected Map getAllowableValuesImpl() + { + RecordableVersionPolicy[] recordableVersionPolicies = RecordableVersionPolicy.values(); + Map allowableValues = new HashMap(recordableVersionPolicies.length); + for (RecordableVersionPolicy recordableVersionPolicy : recordableVersionPolicies) + { + String policy = recordableVersionPolicy.toString(); + allowableValues.put(policy, getI18NLabel(policy)); + } + return allowableValues; + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/DeclareAsVersionRecordAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/DeclareAsVersionRecordAction.java new file mode 100644 index 0000000000..844940b7a6 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/DeclareAsVersionRecordAction.java @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.action.dm; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.action.AuditableActionExecuterAbstractBase; +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.version.RecordableVersionServiceImpl; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.repo.version.VersionModel; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.action.ParameterDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.version.Version; +import org.alfresco.service.cmr.version.VersionService; +import org.alfresco.service.cmr.version.VersionType; +import org.alfresco.service.namespace.QName; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Creates a new record from the 'current' document version. + * + * Note: This is a 'normal' dm action, rather than a records management action. + * + * @author Roy Wetherall + */ +public class DeclareAsVersionRecordAction extends AuditableActionExecuterAbstractBase + implements RecordsManagementModel +{ + /** Logger */ + private static Log logger = LogFactory.getLog(DeclareAsVersionRecordAction.class); + + /** Action name */ + public static final String NAME = "declare-version-record"; + + /** Parameter names */ + public static final String PARAM_FILE_PLAN = "file-plan"; + + /** Sync Model URI */ + static final String SYNC_MODEL_1_0_URI = "http://www.alfresco.org/model/sync/1.0"; + + /** Synced aspect */ + static final QName ASPECT_SYNCED = QName.createQName(SYNC_MODEL_1_0_URI, "synced"); + + /** Node service */ + private NodeService nodeService; + + /** File plan service */ + private FilePlanService filePlanService; + + /** Dictionary service */ + private DictionaryService dictionaryService; + + /** version service */ + private VersionService versionService; + + /** + * @param nodeService node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @param filePlanService file plan service + */ + public void setFilePlanService(FilePlanService filePlanService) + { + this.filePlanService = filePlanService; + } + + /** + * @param dictionaryService dictionary service + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * @param versionService version service + */ + public void setVersionService(VersionService versionService) + { + this.versionService = versionService; + } + + /** + * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + protected void executeImpl(final Action action, final NodeRef actionedUponNodeRef) + { + if (!nodeService.exists(actionedUponNodeRef)) + { + // do not create record if the actioned upon node does not exist! + if (logger.isDebugEnabled()) + { + logger.debug("Can not declare version as record, because " + actionedUponNodeRef.toString() + " does not exist."); + } + } + else if (!dictionaryService.isSubClass(nodeService.getType(actionedUponNodeRef), ContentModel.TYPE_CONTENT)) + { + // TODO eventually we should support other types .. either as record folders or as composite records + if (logger.isDebugEnabled()) + { + logger.debug("Can not declare version as record, because " + actionedUponNodeRef.toString() + " is not a supported type."); + } + } + else if (!nodeService.hasAspect(actionedUponNodeRef, ContentModel.ASPECT_VERSIONABLE)) + { + if (logger.isDebugEnabled()) + { + logger.debug("Can not declare version record, because " + actionedUponNodeRef.toString() + " does not have the versionable aspect applied."); + } + } + else if (nodeService.hasAspect(actionedUponNodeRef, ASPECT_RECORD)) + { + // Do not declare version record if the actioned upon node is already a record! + if (logger.isDebugEnabled()) + { + logger.debug("Can not declare version record, because " + actionedUponNodeRef.toString() + " is already a record."); + } + } + else if (nodeService.hasAspect(actionedUponNodeRef, ContentModel.ASPECT_WORKING_COPY)) + { + // We can not create records from working copies + if (logger.isDebugEnabled()) + { + logger.debug("Can not declare version record, because " + actionedUponNodeRef.toString() + " is a working copy."); + } + + } + else if (nodeService.hasAspect(actionedUponNodeRef, ASPECT_RECORD_REJECTION_DETAILS)) + { + // can not create a record from a previously rejected one + if (logger.isDebugEnabled()) + { + logger.debug("Can not declare version record, because " + actionedUponNodeRef.toString() + " has previously been rejected."); + } + } + else if (nodeService.hasAspect(actionedUponNodeRef, ASPECT_SYNCED)) + { + // can't declare the record if the node is sync'ed + if (logger.isDebugEnabled()) + { + logger.debug("Can't declare version record, because " + actionedUponNodeRef.toString() + " is synched content."); + } + } + else + { + NodeRef filePlan = (NodeRef)action.getParameterValue(PARAM_FILE_PLAN); + if (filePlan == null) + { + // TODO .. eventually make the file plan parameter required + + filePlan = AuthenticationUtil.runAs(new RunAsWork() + { + @Override + public NodeRef doWork() + { + return filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID); + } + }, AuthenticationUtil.getAdminUserName()); + + // if the file plan is still null, raise an exception + if (filePlan == null) + { + if (logger.isDebugEnabled()) + { + logger.debug("Can not declare version record, because the default file plan can not be determined. Make sure at least one file plan has been created."); + } + throw new AlfrescoRuntimeException("Can not declare version record, because the default file plan can not be determined."); + } + } + else + { + // verify that the provided file plan is actually a file plan + if (!filePlanService.isFilePlan(filePlan)) + { + if (logger.isDebugEnabled()) + { + logger.debug("Can not declare version record, because the provided file plan node reference is not a file plan."); + } + throw new AlfrescoRuntimeException("Can not declare version record, because the provided file plan node reference is not a file plan."); + } + } + + // create version properties + Map versionProperties = new HashMap(4); + versionProperties.put(Version.PROP_DESCRIPTION, "Recorded version"); // TODO make this a configurable option of the action + versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR); // TODO make this a configurable option of the action + versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true); + versionProperties.put(RecordableVersionServiceImpl.KEY_FILE_PLAN, filePlan); + + // create recordable version + versionService.createVersion(actionedUponNodeRef, versionProperties); + } + } + + /** + * @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List) + */ + @Override + protected void addParameterDefinitions(List params) + { + // NOTE: commented out for now so that it doesn't appear in the UI ... enable later when multi-file plan support is added + //params.add(new ParameterDefinitionImpl(PARAM_FILE_PLAN, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_FILE_PLAN))); + } + +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/RecordableVersionConfigAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/RecordableVersionConfigAction.java new file mode 100644 index 0000000000..9acea4eb60 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/RecordableVersionConfigAction.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.action.dm; + +import static org.alfresco.model.ContentModel.ASPECT_VERSIONABLE; +import static org.alfresco.model.ContentModel.TYPE_CONTENT; +import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.ASPECT_RECORD; +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY; +import static org.alfresco.service.cmr.dictionary.DataTypeDefinition.TEXT; +import static org.apache.commons.logging.LogFactory.getLog; + +import java.util.List; + +import org.alfresco.module.org_alfresco_module_rm.action.AuditableActionExecuterAbstractBase; +import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy; +import org.alfresco.repo.action.ParameterDefinitionImpl; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.action.ParameterDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; +import org.apache.commons.logging.Log; + +/** + * Sets the recordable version config for a document within a collaboration site. + * + * Note: This is a 'normal' dm action, rather than a records management action. + * + * @author Tuna Aksoy + * @since 2.3 + */ +public class RecordableVersionConfigAction extends AuditableActionExecuterAbstractBase +{ + /** Logger */ + private static Log LOGGER = getLog(RecordableVersionConfigAction.class); + + /** Action name */ + public static final String NAME = "recordable-version-config"; + + /** Parameter names */ + public static final String PARAM_VERSION = "version"; + + /** Node service */ + private NodeService nodeService; + + /** Dictionary service */ + private DictionaryService dictionaryService; + + /** + * Gets the node service + * + * @return The node service + */ + protected NodeService getNodeService() + { + return this.nodeService; + } + + /** + * Sets the node service + * + * @param nodeService The node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * Gets the dictionary service + * + * @return The dictionary service + */ + protected DictionaryService getDictionaryService() + { + return this.dictionaryService; + } + + /** + * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#setDictionaryService(org.alfresco.service.cmr.dictionary.DictionaryService) + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * @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) + { + if (passedChecks(actionedUponNodeRef)) + { + String version = (String) action.getParameterValue(PARAM_VERSION); + getNodeService().setProperty(actionedUponNodeRef, PROP_RECORDABLE_VERSION_POLICY, RecordableVersionPolicy.valueOf(version)); + } + } + + /** + * @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List) + */ + @Override + protected void addParameterDefinitions(List paramList) + { + paramList.add(new ParameterDefinitionImpl(PARAM_VERSION, TEXT, true, getParamDisplayLabel(PARAM_VERSION), false, "ac-versions")); + } + + /** + * Helper method to do checks on the actioned upon node reference + * + * @param actionedUponNodeRef The actioned upon node reference + * @return true if the actioned upon node reference passes the checks, false otherwise + */ + private boolean passedChecks(NodeRef actionedUponNodeRef) + { + boolean passedChecks = true; + + if (!getNodeService().exists(actionedUponNodeRef)) + { + passedChecks = false; + if (LOGGER.isDebugEnabled()) + { + String message = buildLogMessage(actionedUponNodeRef, "' because the node does not exist."); + LOGGER.debug(message); + } + } + + QName type = getNodeService().getType(actionedUponNodeRef); + if (!getDictionaryService().isSubClass(type, TYPE_CONTENT)) + { + passedChecks = false; + if (LOGGER.isDebugEnabled()) + { + String message = buildLogMessage(actionedUponNodeRef, "' because the type of the node '" + type.getLocalName() + "' is not supported."); + LOGGER.debug(message); + } + } + + if (getNodeService().hasAspect(actionedUponNodeRef, ASPECT_RECORD)) + { + passedChecks = false; + if (LOGGER.isDebugEnabled()) + { + String message = buildLogMessage(actionedUponNodeRef, "' because the rule cannot be applied to records."); + LOGGER.debug(message); + } + } + + if (!getNodeService().hasAspect(actionedUponNodeRef, ASPECT_VERSIONABLE)) + { + passedChecks = false; + if (LOGGER.isDebugEnabled()) + { + String buildLogMessage = buildLogMessage(actionedUponNodeRef, "' because the rule cannot be applied to records."); + LOGGER.debug(buildLogMessage); + } + } + + return passedChecks; + } + + /** + * Helper method to construct log message + * + * @param actionedUponNodeRef The actioned upon node reference + * @param messagePart The message which should be appended. + * @return The constructed log message + */ + private String buildLogMessage(NodeRef actionedUponNodeRef, String messagePart) + { + StringBuilder sb = new StringBuilder(); + sb.append("Cannot set recordable version config for '"); + sb.append(actionedUponNodeRef.toString()); + sb.append(messagePart); + return sb.toString(); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/AddRecordTypeAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/AddRecordTypeAction.java index 7ae40752bb..61281dbd6c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/AddRecordTypeAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/AddRecordTypeAction.java @@ -65,7 +65,7 @@ public class AddRecordTypeAction extends RMActionExecuterAbstractBase { for (String type : getRecordTypes(action)) { - recordService.addRecordType(actionedUponNodeRef, QName.createQName(type, namespaceService)); + getRecordService().addRecordType(actionedUponNodeRef, QName.createQName(type, getNamespaceService())); } } else if (logger.isWarnEnabled()) @@ -88,10 +88,10 @@ public class AddRecordTypeAction extends RMActionExecuterAbstractBase private boolean eligibleForAction(NodeRef actionedUponNodeRef) { boolean result = false; - if (nodeService.exists(actionedUponNodeRef) && - !freezeService.isFrozen(actionedUponNodeRef) && - recordService.isRecord(actionedUponNodeRef) && - !recordService.isDeclared(actionedUponNodeRef)) + if (getNodeService().exists(actionedUponNodeRef) && + !getFreezeService().isFrozen(actionedUponNodeRef) && + getRecordService().isRecord(actionedUponNodeRef) && + !getRecordService().isDeclared(actionedUponNodeRef)) { result = true; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/ApplyCustomTypeAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/ApplyCustomTypeAction.java index bbcdfd156f..c9d78a3080 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/ApplyCustomTypeAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/ApplyCustomTypeAction.java @@ -55,7 +55,7 @@ public class ApplyCustomTypeAction extends RMActionExecuterAbstractBase public void setCustomTypeAspect(String customTypeAspect) { - this.customTypeAspect = QName.createQName(customTypeAspect, namespaceService); + this.customTypeAspect = QName.createQName(customTypeAspect, getNamespaceService()); } /** @@ -69,11 +69,11 @@ public class ApplyCustomTypeAction extends RMActionExecuterAbstractBase logger.debug("Executing action [" + action.getActionDefinitionName() + "] on " + actionedUponNodeRef); } - if (recordService.isRecord(actionedUponNodeRef)) + if (getRecordService().isRecord(actionedUponNodeRef)) { // Apply the appropriate aspect and set the properties. Map aspectProps = getPropertyValues(action); - this.nodeService.addAspect(actionedUponNodeRef, customTypeAspect, aspectProps); + this.getNodeService().addAspect(actionedUponNodeRef, customTypeAspect, aspectProps); } else if (logger.isWarnEnabled()) { @@ -88,7 +88,7 @@ public class ApplyCustomTypeAction extends RMActionExecuterAbstractBase @Override protected final void addParameterDefinitions(List paramList) { - AspectDefinition aspectDef = dictionaryService.getAspect(customTypeAspect); + AspectDefinition aspectDef = getDictionaryService().getAspect(customTypeAspect); for (PropertyDefinition propDef : aspectDef.getProperties().values()) { QName propName = propDef.getName(); @@ -109,7 +109,7 @@ public class ApplyCustomTypeAction extends RMActionExecuterAbstractBase Map result = new HashMap(paramValues.size()); for (Map.Entry entry : paramValues.entrySet()) { - QName propQName = QName.createQName(entry.getKey(), this.namespaceService); + QName propQName = QName.createQName(entry.getKey(), this.getNamespaceService()); result.put(propQName, entry.getValue()); } @@ -122,7 +122,7 @@ public class ApplyCustomTypeAction extends RMActionExecuterAbstractBase // We can take these parameter definitions from the properties defined in the dod model. if (this.parameterDefinitions == null) { - AspectDefinition aspectDefinition = dictionaryService.getAspect(customTypeAspect); + AspectDefinition aspectDefinition = getDictionaryService().getAspect(customTypeAspect); if (aspectDefinition == null) { throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_CUSTOM_ASPECT_NOT_RECOGNISED, customTypeAspect)); @@ -134,7 +134,7 @@ public class ApplyCustomTypeAction extends RMActionExecuterAbstractBase for (Map.Entry entry : props.entrySet()) { - String paramName = entry.getKey().toPrefixString(namespaceService); + String paramName = entry.getKey().toPrefixString(getNamespaceService()); PropertyDefinition value = entry.getValue(); QName paramType = value.getDataType().getName(); boolean paramIsMandatory = value.isMandatory(); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/BroadcastDispositionActionDefinitionUpdateAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/BroadcastDispositionActionDefinitionUpdateAction.java index a1597f2e36..fcd70bad1c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/BroadcastDispositionActionDefinitionUpdateAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/BroadcastDispositionActionDefinitionUpdateAction.java @@ -69,7 +69,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (!RecordsManagementModel.TYPE_DISPOSITION_ACTION_DEFINITION.equals(nodeService.getType(actionedUponNodeRef))) + if (!RecordsManagementModel.TYPE_DISPOSITION_ACTION_DEFINITION.equals(getNodeService().getType(actionedUponNodeRef))) { return; } @@ -77,14 +77,14 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx List changedProps = (List)action.getParameterValue(CHANGED_PROPERTIES); // Navigate up the containment hierarchy to get the record category grandparent and schedule. - NodeRef dispositionScheduleNode = nodeService.getPrimaryParent(actionedUponNodeRef).getParentRef(); - NodeRef rmContainer = nodeService.getPrimaryParent(dispositionScheduleNode).getParentRef(); - DispositionSchedule dispositionSchedule = dispositionService.getAssociatedDispositionSchedule(rmContainer); + NodeRef dispositionScheduleNode = getNodeService().getPrimaryParent(actionedUponNodeRef).getParentRef(); + NodeRef rmContainer = getNodeService().getPrimaryParent(dispositionScheduleNode).getParentRef(); + DispositionSchedule dispositionSchedule = getDispositionService().getAssociatedDispositionSchedule(rmContainer); behaviourFilter.disableBehaviour(); try { - List disposableItems = dispositionService.getDisposableItems(dispositionSchedule); + List disposableItems = getDispositionService().getDisposableItems(dispositionSchedule); for (NodeRef disposableItem : disposableItems) { updateDisposableItem(dispositionSchedule, disposableItem, actionedUponNodeRef, changedProps); @@ -107,11 +107,11 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx { // We need to check that this folder is under the management of the disposition schedule that // has been updated - DispositionSchedule itemDs = dispositionService.getDispositionSchedule(disposableItem); + DispositionSchedule itemDs = getDispositionService().getDispositionSchedule(disposableItem); if (itemDs != null && itemDs.getNodeRef().equals(ds.getNodeRef())) { - if (nodeService.hasAspect(disposableItem, ASPECT_DISPOSITION_LIFECYCLE)) + if (getNodeService().hasAspect(disposableItem, ASPECT_DISPOSITION_LIFECYCLE)) { // disposition lifecycle already exists for node so process changes processActionDefinitionChanges(dispositionActionDefinition, changedProps, disposableItem); @@ -119,7 +119,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx else { // disposition lifecycle does not exist on the node so setup disposition - dispositionService.updateNextDispositionAction(disposableItem); + getDispositionService().updateNextDispositionAction(disposableItem); } // update rolled up search information @@ -134,14 +134,14 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx */ private void rollupSearchProperties(NodeRef disposableItem) { - DispositionAction da = dispositionService.getNextDispositionAction(disposableItem); + DispositionAction da = getDispositionService().getNextDispositionAction(disposableItem); if (da != null) { - Map props = nodeService.getProperties(disposableItem); + Map props = getNodeService().getProperties(disposableItem); props.put(PROP_RS_DISPOSITION_ACTION_NAME, da.getName()); props.put(PROP_RS_DISPOSITION_ACTION_AS_OF, da.getAsOfDate()); - props.put(PROP_RS_DISPOSITION_EVENTS_ELIGIBLE, nodeService.getProperty(da.getNodeRef(), PROP_DISPOSITION_EVENTS_ELIGIBLE)); + props.put(PROP_RS_DISPOSITION_EVENTS_ELIGIBLE, getNodeService().getProperty(da.getNodeRef(), PROP_DISPOSITION_EVENTS_ELIGIBLE)); DispositionActionDefinition daDefinition = da.getDispositionActionDefinition(); Period period = daDefinition.getPeriod(); @@ -164,7 +164,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx } props.put(PROP_RS_DISPOSITION_EVENTS, (Serializable)list); - nodeService.setProperties(disposableItem, props); + getNodeService().setProperties(disposableItem, props); } } @@ -180,7 +180,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx { // check that the step being edited is the current step for the folder, // if not, the change has no effect on the current step so ignore - DispositionAction nextAction = dispositionService.getNextDispositionAction(recordOrFolder); + DispositionAction nextAction = getDispositionService().getNextDispositionAction(recordOrFolder); if (doesChangedStepAffectNextAction(dispositionActionDef, nextAction)) { // the change does effect the nextAction for this node @@ -197,8 +197,8 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx if (changedProps.contains(PROP_DISPOSITION_ACTION_NAME)) { - String action = (String)nodeService.getProperty(dispositionActionDef, PROP_DISPOSITION_ACTION_NAME); - nodeService.setProperty(nextAction.getNodeRef(), PROP_DISPOSITION_ACTION, action); + String action = (String)getNodeService().getProperty(dispositionActionDef, PROP_DISPOSITION_ACTION_NAME); + getNodeService().setProperty(nextAction.getNodeRef(), PROP_DISPOSITION_ACTION, action); } } } @@ -240,7 +240,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx private void persistPeriodChanges(NodeRef dispositionActionDef, DispositionAction nextAction) { Date newAsOfDate = null; - Period dispositionPeriod = (Period) nodeService.getProperty(dispositionActionDef, PROP_DISPOSITION_PERIOD); + Period dispositionPeriod = (Period) getNodeService().getProperty(dispositionActionDef, PROP_DISPOSITION_PERIOD); if (dispositionPeriod != null) { @@ -255,7 +255,7 @@ public class BroadcastDispositionActionDefinitionUpdateAction extends RMActionEx "' (" + nextAction.getNodeRef() + ") to: " + newAsOfDate); } - nodeService.setProperty(nextAction.getNodeRef(), PROP_DISPOSITION_AS_OF, newAsOfDate); + getNodeService().setProperty(nextAction.getNodeRef(), PROP_DISPOSITION_AS_OF, newAsOfDate); } @Override diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CloseRecordFolderAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CloseRecordFolderAction.java index 561ecb5b32..b53e55fd4c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CloseRecordFolderAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CloseRecordFolderAction.java @@ -49,7 +49,7 @@ public class CloseRecordFolderAction extends RMActionExecuterAbstractBase @Override public Void doWork() { - recordFolderService.closeRecordFolder(actionedUponNodeRef); + getRecordFolderService().closeRecordFolder(actionedUponNodeRef); return null; } @@ -69,9 +69,9 @@ public class CloseRecordFolderAction extends RMActionExecuterAbstractBase private boolean eligibleForAction(NodeRef actionedUponNodeRef) { boolean result = false; - if (nodeService.exists(actionedUponNodeRef) && - !freezeService.isFrozen(actionedUponNodeRef) && - !TYPE_UNFILED_RECORD_FOLDER.equals(nodeService.getType(actionedUponNodeRef))) + if (getNodeService().exists(actionedUponNodeRef) && + !getFreezeService().isFrozen(actionedUponNodeRef) && + !TYPE_UNFILED_RECORD_FOLDER.equals(getNodeService().getType(actionedUponNodeRef))) { result = true; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CompleteEventAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CompleteEventAction.java index e4c81799d7..97c31045bd 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CompleteEventAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CompleteEventAction.java @@ -39,7 +39,7 @@ public class CompleteEventAction extends RMActionExecuterAbstractBase { /** action name */ public static final String NAME = "completeEvent"; - + /** action parameter names */ public static final String PARAM_EVENT_NAME = "eventName"; public static final String PARAM_EVENT_COMPLETED_BY = "eventCompletedBy"; @@ -51,11 +51,11 @@ public class CompleteEventAction extends RMActionExecuterAbstractBase @Override protected void addParameterDefinitions(List paramList) { - paramList.add(new ParameterDefinitionImpl(PARAM_EVENT_NAME, - DataTypeDefinition.TEXT, + paramList.add(new ParameterDefinitionImpl(PARAM_EVENT_NAME, + DataTypeDefinition.TEXT, true, - getParamDisplayLabel(PARAM_EVENT_NAME), - false, + getParamDisplayLabel(PARAM_EVENT_NAME), + false, "rm-ac-manual-events")); } @@ -66,18 +66,18 @@ public class CompleteEventAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (nodeService.exists(actionedUponNodeRef) && - !freezeService.isFrozen(actionedUponNodeRef)) + if (getNodeService().exists(actionedUponNodeRef) && + !getFreezeService().isFrozen(actionedUponNodeRef)) { /** get parameter values */ String eventName = (String)action.getParameterValue(PARAM_EVENT_NAME); String eventCompletedBy = (String)action.getParameterValue(PARAM_EVENT_COMPLETED_BY); Date eventCompletedAt = (Date)action.getParameterValue(PARAM_EVENT_COMPLETED_AT); - if (this.nodeService.hasAspect(actionedUponNodeRef, ASPECT_DISPOSITION_LIFECYCLE)) + if (this.getNodeService().hasAspect(actionedUponNodeRef, ASPECT_DISPOSITION_LIFECYCLE)) { // Get the next disposition action - DispositionAction da = this.dispositionService.getNextDispositionAction(actionedUponNodeRef); + DispositionAction da = this.getDispositionService().getNextDispositionAction(actionedUponNodeRef); if (da != null) { // complete event diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyMoveLinkFileToBaseAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyMoveLinkFileToBaseAction.java index 55fb6adf81..b879c733a0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyMoveLinkFileToBaseAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyMoveLinkFileToBaseAction.java @@ -108,7 +108,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr String actionName = action.getActionDefinitionName(); if (isOkToProceedWithAction(actionedUponNodeRef, actionName)) { - QName actionedUponType = nodeService.getType(actionedUponNodeRef); + QName actionedUponType = getNodeService().getType(actionedUponNodeRef); boolean targetIsUnfiledRecords; if (ACTION_FILETO.equals(action.getActionDefinitionName())) @@ -117,7 +117,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr } else { - targetIsUnfiledRecords = (dictionaryService.isSubClass(actionedUponType, ContentModel.TYPE_CONTENT) && !recordService.isFiled(actionedUponNodeRef)) + targetIsUnfiledRecords = (getDictionaryService().isSubClass(actionedUponType, ContentModel.TYPE_CONTENT) && !getRecordService().isFiled(actionedUponNodeRef)) || TYPE_UNFILED_RECORD_FOLDER.equals(actionedUponType); } @@ -150,7 +150,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr } else if(getMode() == CopyMoveLinkFileToActionMode.LINK) { - recordService.link(actionedUponNodeRef, finalRecordFolder); + getRecordService().link(actionedUponNodeRef, finalRecordFolder); } } catch (FileNotFoundException fileNotFound) @@ -178,13 +178,13 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr { // Check that the incoming parameters are valid prior to performing any action boolean okToProceed = false; - if(nodeService.exists(actionedUponNodeRef) && !freezeService.isFrozen(actionedUponNodeRef)) + if(getNodeService().exists(actionedUponNodeRef) && !getFreezeService().isFrozen(actionedUponNodeRef)) { - QName actionedUponType = nodeService.getType(actionedUponNodeRef); + QName actionedUponType = getNodeService().getType(actionedUponNodeRef); if(ACTION_FILETO.equals(actionName)) { // file to action can only be performed on unfiled records - okToProceed = !recordService.isFiled(actionedUponNodeRef) && dictionaryService.isSubClass(actionedUponType, ContentModel.TYPE_CONTENT); + okToProceed = !getRecordService().isFiled(actionedUponNodeRef) && getDictionaryService().isSubClass(actionedUponType, ContentModel.TYPE_CONTENT); if(!okToProceed && logger.isDebugEnabled()) { logger.debug("Unable to run " + actionName + " action on a node that isn't unfiled and a sub-class of content type"); @@ -193,7 +193,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr else if(ACTION_LINKTO.equals(actionName)) { // link to action can only be performed on filed records - okToProceed = recordService.isFiled(actionedUponNodeRef) && dictionaryService.isSubClass(actionedUponType, ContentModel.TYPE_CONTENT); + okToProceed = getRecordService().isFiled(actionedUponNodeRef) && getDictionaryService().isSubClass(actionedUponType, ContentModel.TYPE_CONTENT); if(!okToProceed && logger.isDebugEnabled()) { logger.debug("Unable to run " + actionName + " action on a node that isn't filed and a sub-class of content type"); @@ -217,7 +217,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr */ private void validateActionPostPathResolution(NodeRef actionedUponNodeRef, NodeRef target, String actionName, boolean targetIsUnfiledRecords) { - QName actionedUponType = nodeService.getType(actionedUponNodeRef); + QName actionedUponType = getNodeService().getType(actionedUponNodeRef); // now we have the reference to the target folder we can do some final checks to see if the action is valid if (target == null) { @@ -225,7 +225,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr } if(targetIsUnfiledRecords) { - QName targetFolderType = nodeService.getType(target); + QName targetFolderType = getNodeService().getType(target); if(!TYPE_UNFILED_RECORD_CONTAINER.equals(targetFolderType) && !TYPE_UNFILED_RECORD_FOLDER.equals(targetFolderType)) { throw new AlfrescoRuntimeException("Unable to run " + actionName + " action, because the destination record folder is an inappropriate type."); @@ -233,11 +233,11 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr } else { - if(recordFolderService.isRecordFolder(target) && !dictionaryService.isSubClass(actionedUponType, ContentModel.TYPE_CONTENT) && (recordFolderService.isRecordFolder(actionedUponNodeRef) || filePlanService.isRecordCategory(actionedUponNodeRef))) + if(getRecordFolderService().isRecordFolder(target) && !getDictionaryService().isSubClass(actionedUponType, ContentModel.TYPE_CONTENT) && (getRecordFolderService().isRecordFolder(actionedUponNodeRef) || filePlanService.isRecordCategory(actionedUponNodeRef))) { throw new AlfrescoRuntimeException("Unable to run " + actionName + " action, because the destination record folder is an inappropriate type. A record folder cannot contain another folder or a category"); } - else if(filePlanService.isRecordCategory(target) && dictionaryService.isSubClass(actionedUponType, ContentModel.TYPE_CONTENT)) + else if(filePlanService.isRecordCategory(target) && getDictionaryService().isSubClass(actionedUponType, ContentModel.TYPE_CONTENT)) { throw new AlfrescoRuntimeException("Unable to run " + actionName + " action, because the destination record folder is an inappropriate type. A record category cannot contain a record"); } @@ -299,7 +299,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr if(create) { creating = true; - boolean lastAsFolder = lastPathElement && (dictionaryService.isSubClass(nodeService.getType(actionedUponNodeRef), ContentModel.TYPE_CONTENT) || RecordsManagementModel.TYPE_NON_ELECTRONIC_DOCUMENT.equals(nodeService.getType(actionedUponNodeRef))); + boolean lastAsFolder = lastPathElement && (getDictionaryService().isSubClass(getNodeService().getType(actionedUponNodeRef), ContentModel.TYPE_CONTENT) || RecordsManagementModel.TYPE_NON_ELECTRONIC_DOCUMENT.equals(getNodeService().getType(actionedUponNodeRef))); nodeRef = createChild(action, parent, childName, targetisUnfiledRecords, lastAsFolder); } else @@ -309,7 +309,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr } else { - QName nodeType = nodeService.getType(nodeRef); + QName nodeType = getNodeService().getType(nodeRef); if(nodeType.equals(RecordsManagementModel.TYPE_HOLD_CONTAINER) || nodeType.equals(RecordsManagementModel.TYPE_TRANSFER_CONTAINER) || nodeType.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER)) @@ -334,10 +334,11 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr private NodeRef getChild(NodeRef parent, String childName) { NodeRef child = null; - List children = nodeService.getChildAssocs(parent); - for (ChildAssociationRef childAssoc : children) { + List children = getNodeService().getChildAssocs(parent); + for (ChildAssociationRef childAssoc : children) + { NodeRef childNodeRef = childAssoc.getChildRef(); - String existingChildName = (String)nodeService.getProperty(childNodeRef, ContentModel.PROP_NAME); + String existingChildName = (String)getNodeService().getProperty(childNodeRef, ContentModel.PROP_NAME); if(existingChildName.equals(childName)) { child = childNodeRef; @@ -371,11 +372,11 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr } else if(lastAsFolder) { - child = recordFolderService.createRecordFolder(parent, childName); + child = getRecordFolderService().createRecordFolder(parent, childName); } else { - if(RecordsManagementModel.TYPE_RECORD_FOLDER.equals(nodeService.getType(parent))) + if(RecordsManagementModel.TYPE_RECORD_FOLDER.equals(getNodeService().getType(parent))) { throw new AlfrescoRuntimeException("Unable to execute " + action.getActionDefinitionName() + " action, because the destination path could not be created."); } @@ -397,11 +398,11 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr private NodeRef getContext(Action action, NodeRef actionedUponNodeRef, boolean targetisUnfiledRecords) { NodeRef context = filePlanService.getFilePlan(actionedUponNodeRef); - if(targetisUnfiledRecords && (context != null) && nodeService.exists(context)) + if(targetisUnfiledRecords && (context != null) && getNodeService().exists(context)) { context = filePlanService.getUnfiledContainer(context); } - if((context == null) || (!nodeService.exists(context))) + if((context == null) || (!getNodeService().exists(context))) { throw new AlfrescoRuntimeException("Unable to execute " + action.getActionDefinitionName() + " action, because the path resolution context could not be determined."); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CreateDispositionScheduleAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CreateDispositionScheduleAction.java index c3551c9cb0..f04f0c77ff 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CreateDispositionScheduleAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CreateDispositionScheduleAction.java @@ -55,7 +55,7 @@ public class CreateDispositionScheduleAction extends RMActionExecuterAbstractBas if (eligibleForAction(actionedUponNodeRef)) { // Create the disposition schedule - dispositionService.createDispositionSchedule(actionedUponNodeRef, null); + getDispositionService().createDispositionSchedule(actionedUponNodeRef, null); } else { @@ -75,7 +75,7 @@ public class CreateDispositionScheduleAction extends RMActionExecuterAbstractBas private boolean eligibleForAction(NodeRef actionedUponNodeRef) { boolean result = false; - if (nodeService.exists(actionedUponNodeRef) && + if (getNodeService().exists(actionedUponNodeRef) && filePlanService.isRecordCategory(actionedUponNodeRef)) { result = true; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CutOffAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CutOffAction.java index 1c542990d7..09b35c9b71 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CutOffAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CutOffAction.java @@ -42,7 +42,7 @@ public class CutOffAction extends RMDispositionActionExecuterAbstractBase if(checkUncutOffStatus(action, recordFolder)) { // Mark the folder as cut off - dispositionService.cutoffDisposableItem(recordFolder); + getDispositionService().cutoffDisposableItem(recordFolder); } } @@ -55,7 +55,7 @@ public class CutOffAction extends RMDispositionActionExecuterAbstractBase if(checkUncutOffStatus(action, record)) { // Mark the record as cut off - dispositionService.cutoffDisposableItem(record); + getDispositionService().cutoffDisposableItem(record); } } @@ -71,7 +71,7 @@ public class CutOffAction extends RMDispositionActionExecuterAbstractBase private boolean checkUncutOffStatus(Action action, NodeRef recordOrFolder) { boolean okToCutOff = true; - if(nodeService.hasAspect(recordOrFolder, ASPECT_UNCUT_OFF)) + if(getNodeService().hasAspect(recordOrFolder, ASPECT_UNCUT_OFF)) { if(action.getParameterValue(PARAM_NO_ERROR_CHECK) != null) { @@ -81,7 +81,7 @@ public class CutOffAction extends RMDispositionActionExecuterAbstractBase } else { - nodeService.removeAspect(recordOrFolder, ASPECT_UNCUT_OFF); + getNodeService().removeAspect(recordOrFolder, ASPECT_UNCUT_OFF); } } return okToCutOff; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DeclareRecordAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DeclareRecordAction.java index fc7eb74eb3..1d946695fb 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DeclareRecordAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DeclareRecordAction.java @@ -61,24 +61,24 @@ public class DeclareRecordAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(final Action action, final NodeRef actionedUponNodeRef) { - if (nodeService.exists(actionedUponNodeRef) && - recordService.isRecord(actionedUponNodeRef) && - !freezeService.isFrozen(actionedUponNodeRef)) + if (getNodeService().exists(actionedUponNodeRef) && + getRecordService().isRecord(actionedUponNodeRef) && + !getFreezeService().isFrozen(actionedUponNodeRef)) { - if (!recordService.isDeclared(actionedUponNodeRef)) + if (!getRecordService().isDeclared(actionedUponNodeRef)) { List missingProperties = new ArrayList(5); // Aspect not already defined - check mandatory properties then add if (mandatoryPropertiesSet(actionedUponNodeRef, missingProperties)) { - recordService.disablePropertyEditableCheck(); + getRecordService().disablePropertyEditableCheck(); try { // Add the declared aspect Map declaredProps = new HashMap(2); declaredProps.put(PROP_DECLARED_AT, new Date()); declaredProps.put(PROP_DECLARED_BY, AuthenticationUtil.getRunAsUser()); - this.nodeService.addAspect(actionedUponNodeRef, ASPECT_DECLARED_RECORD, declaredProps); + this.getNodeService().addAspect(actionedUponNodeRef, ASPECT_DECLARED_RECORD, declaredProps); AuthenticationUtil.runAsSystem(new RunAsWork() { @@ -86,14 +86,14 @@ public class DeclareRecordAction extends RMActionExecuterAbstractBase public Void doWork() { // remove all owner related rights - ownableService.setOwner(actionedUponNodeRef, OwnableService.NO_OWNER); + getOwnableService().setOwner(actionedUponNodeRef, OwnableService.NO_OWNER); return null; } }); } finally { - recordService.enablePropertyEditableCheck(); + getRecordService().enablePropertyEditableCheck(); } } else @@ -134,11 +134,11 @@ public class DeclareRecordAction extends RMActionExecuterAbstractBase { boolean result = true; - Map nodeRefProps = this.nodeService.getProperties(nodeRef); + Map nodeRefProps = this.getNodeService().getProperties(nodeRef); - QName nodeRefType = this.nodeService.getType(nodeRef); + QName nodeRefType = this.getNodeService().getType(nodeRef); - TypeDefinition typeDef = this.dictionaryService.getType(nodeRefType); + TypeDefinition typeDef = this.getDictionaryService().getType(nodeRefType); for (PropertyDefinition propDef : typeDef.getProperties().values()) { if (propDef.isMandatory() && nodeRefProps.get(propDef.getName()) == null) @@ -152,10 +152,10 @@ public class DeclareRecordAction extends RMActionExecuterAbstractBase if (result) { - Set aspects = this.nodeService.getAspects(nodeRef); + Set aspects = this.getNodeService().getAspects(nodeRef); for (QName aspect : aspects) { - AspectDefinition aspectDef = this.dictionaryService.getAspect(aspect); + AspectDefinition aspectDef = this.getDictionaryService().getAspect(aspect); for (PropertyDefinition propDef : aspectDef.getProperties().values()) { if (propDef.isMandatory() && nodeRefProps.get(propDef.getName()) == null) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DelegateAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DelegateAction.java index 22bd3b2f86..efa55760e1 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DelegateAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DelegateAction.java @@ -64,8 +64,8 @@ public class DelegateAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (nodeService.exists(actionedUponNodeRef) && - (!checkFrozen || !freezeService.isFrozen(actionedUponNodeRef))) + if (getNodeService().exists(actionedUponNodeRef) && + (!checkFrozen || !getFreezeService().isFrozen(actionedUponNodeRef))) { // do the property subs (if any exist) if (isAllowParameterSubstitutions()) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DeleteHoldAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DeleteHoldAction.java index e8f52ab40b..d06c792991 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DeleteHoldAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DeleteHoldAction.java @@ -41,9 +41,9 @@ public class DeleteHoldAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (holdService.isHold(actionedUponNodeRef)) + if (getHoldService().isHold(actionedUponNodeRef)) { - holdService.deleteHold(actionedUponNodeRef); + getHoldService().deleteHold(actionedUponNodeRef); } else { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DestroyAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DestroyAction.java index cad671872d..27b0805122 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DestroyAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DestroyAction.java @@ -121,18 +121,18 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase @Override protected void executeRecordFolderLevelDisposition(Action action, NodeRef recordFolder) { - List records = recordService.getRecords(recordFolder); + List records = getRecordService().getRecords(recordFolder); for (NodeRef record : records) { executeRecordLevelDisposition(action, record); } if (isGhostOnDestroySetForAction(action, recordFolder)) { - nodeService.addAspect(recordFolder, ASPECT_GHOSTED, Collections. emptyMap()); + getNodeService().addAspect(recordFolder, ASPECT_GHOSTED, Collections. emptyMap()); } else { - nodeService.deleteNode(recordFolder); + getNodeService().deleteNode(recordFolder); } } @@ -151,12 +151,12 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase if (isGhostOnDestroySetForAction(action, record)) { // Add the ghosted aspect - nodeService.addAspect(record, ASPECT_GHOSTED, null); + getNodeService().addAspect(record, ASPECT_GHOSTED, null); } else { // If ghosting is not enabled, delete the node - nodeService.deleteNode(record); + getNodeService().deleteNode(record); } } @@ -167,15 +167,15 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase */ private void clearAllContent(NodeRef nodeRef) { - Set props = this.nodeService.getProperties(nodeRef).keySet(); - props.retainAll(this.dictionaryService.getAllProperties(DataTypeDefinition.CONTENT)); + Set props = this.getNodeService().getProperties(nodeRef).keySet(); + props.retainAll(this.getDictionaryService().getAllProperties(DataTypeDefinition.CONTENT)); for (QName prop : props) { // Clear the content clearContent(nodeRef, prop); // Remove the property - this.nodeService.removeProperty(nodeRef, prop); + this.getNodeService().removeProperty(nodeRef, prop); } } @@ -196,19 +196,19 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase // We want to remove the rn:renditioned aspect, but due to the possibility // that there is Alfresco 3.2-era data with the cm:thumbnailed aspect // applied, we must consider removing it too. - if (nodeService.hasAspect(nodeRef, RenditionModel.ASPECT_RENDITIONED) || - nodeService.hasAspect(nodeRef, ContentModel.ASPECT_THUMBNAILED)) + if (getNodeService().hasAspect(nodeRef, RenditionModel.ASPECT_RENDITIONED) || + getNodeService().hasAspect(nodeRef, ContentModel.ASPECT_THUMBNAILED)) { // Add the ghosted aspect to all the renditioned children, so that they will not be archived when the // renditioned aspect is removed - Set childAssocTypes = dictionaryService.getAspect(RenditionModel.ASPECT_RENDITIONED).getChildAssociations().keySet(); - for (ChildAssociationRef child : nodeService.getChildAssocs(nodeRef)) + Set childAssocTypes = getDictionaryService().getAspect(RenditionModel.ASPECT_RENDITIONED).getChildAssociations().keySet(); + for (ChildAssociationRef child : getNodeService().getChildAssocs(nodeRef)) { if (childAssocTypes.contains(child.getTypeQName())) { // Clear the content and delete the rendition clearAllContent(child.getChildRef()); - nodeService.deleteNode(child.getChildRef()); + getNodeService().deleteNode(child.getChildRef()); } } } @@ -223,7 +223,7 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase private void clearContent(NodeRef nodeRef, QName contentProperty) { // Ensure the content is cleaned at the end of the transaction - ContentData contentData = (ContentData)nodeService.getProperty(nodeRef, contentProperty); + ContentData contentData = (ContentData)getNodeService().getProperty(nodeRef, contentProperty); if (contentData != null && contentData.getContentUrl() != null) { eagerContentStoreCleaner.registerOrphanedContentUrl(contentData.getContentUrl(), true); @@ -233,7 +233,7 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase /** * Return true if the ghost on destroy property is set against the * definition for the passed action on the specified node - * + * * @param action * @param nodeRef * @return @@ -244,7 +244,7 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase String actionDefinitionName = action.getActionDefinitionName(); if (!StringUtils.isEmpty(actionDefinitionName)) { - DispositionSchedule dispositionSchedule = this.dispositionService.getDispositionSchedule(nodeRef); + DispositionSchedule dispositionSchedule = this.getDispositionService().getDispositionSchedule(nodeRef); if (dispositionSchedule != null) { DispositionActionDefinition actionDefinition = dispositionSchedule diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditDispositionActionAsOfDateAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditDispositionActionAsOfDateAction.java index e17427ff46..2e9badd71f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditDispositionActionAsOfDateAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditDispositionActionAsOfDateAction.java @@ -48,7 +48,7 @@ public class EditDispositionActionAsOfDateAction extends RMActionExecuterAbstrac @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (this.nodeService.hasAspect(actionedUponNodeRef, ASPECT_DISPOSITION_LIFECYCLE)) + if (this.getNodeService().hasAspect(actionedUponNodeRef, ASPECT_DISPOSITION_LIFECYCLE)) { // Get the action parameter Date asOfDate = (Date)action.getParameterValue(PARAM_AS_OF_DATE); @@ -58,10 +58,10 @@ public class EditDispositionActionAsOfDateAction extends RMActionExecuterAbstrac } // Set the dispostion action as of date - DispositionAction da = dispositionService.getNextDispositionAction(actionedUponNodeRef); + DispositionAction da = getDispositionService().getNextDispositionAction(actionedUponNodeRef); if (da != null) { - nodeService.setProperty(da.getNodeRef(), PROP_DISPOSITION_AS_OF, asOfDate); + getNodeService().setProperty(da.getNodeRef(), PROP_DISPOSITION_AS_OF, asOfDate); } } else diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditHoldReasonAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditHoldReasonAction.java index 02402acff6..786cf4ffac 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditHoldReasonAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditHoldReasonAction.java @@ -27,7 +27,7 @@ import org.springframework.extensions.surf.util.I18NUtil; /** * Edit freeze reason Action - * + * * @author Roy Wetherall */ public class EditHoldReasonAction extends RMActionExecuterAbstractBase @@ -45,7 +45,7 @@ public class EditHoldReasonAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (freezeService.isHold(actionedUponNodeRef)) + if (getFreezeService().isHold(actionedUponNodeRef)) { // Get the property values String reason = (String) action.getParameterValue(PARAM_REASON); @@ -55,7 +55,7 @@ public class EditHoldReasonAction extends RMActionExecuterAbstractBase } // Update hold reason - freezeService.updateReason(actionedUponNodeRef, reason); + getFreezeService().updateReason(actionedUponNodeRef, reason); } else { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditReviewAsOfDateAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditReviewAsOfDateAction.java index 694a08d142..6c91a5087e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditReviewAsOfDateAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/EditReviewAsOfDateAction.java @@ -47,8 +47,8 @@ public class EditReviewAsOfDateAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (recordService.isRecord(actionedUponNodeRef) && - nodeService.hasAspect(actionedUponNodeRef, ASPECT_VITAL_RECORD)) + if (getRecordService().isRecord(actionedUponNodeRef) && + getNodeService().hasAspect(actionedUponNodeRef, ASPECT_VITAL_RECORD)) { // Get the action parameter Date reviewAsOf = (Date)action.getParameterValue(PARAM_AS_OF_DATE); @@ -58,7 +58,7 @@ public class EditReviewAsOfDateAction extends RMActionExecuterAbstractBase } // Set the as of date - this.nodeService.setProperty(actionedUponNodeRef, PROP_REVIEW_AS_OF, reviewAsOf); + this.getNodeService().setProperty(actionedUponNodeRef, PROP_REVIEW_AS_OF, reviewAsOf); } else diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileReportAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileReportAction.java index 4859a9280b..d28d8d84b2 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileReportAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileReportAction.java @@ -132,7 +132,7 @@ public class FileReportAction extends RMActionExecuterAbstractBase implements Re }); // return the report name - String filedReportName = (String) nodeService.getProperty(filedReport, ContentModel.PROP_NAME); + String filedReportName = (String) getNodeService().getProperty(filedReport, ContentModel.PROP_NAME); action.setParameterValue(ActionExecuterAbstractBase.PARAM_RESULT, filedReportName); } @@ -186,6 +186,6 @@ public class FileReportAction extends RMActionExecuterAbstractBase implements Re private QName getReportType(Action action) { String reportType = getParameterValue(action, REPORT_TYPE); - return QName.createQName(reportType, namespaceService); + return QName.createQName(reportType, getNamespaceService()); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FreezeAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FreezeAction.java index bb44ad8ba3..dc21f4ec54 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FreezeAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FreezeAction.java @@ -55,13 +55,13 @@ public class FreezeAction extends RMActionExecuterAbstractBase protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { // NOTE: we can only freeze records and record folders so ignore everything else - if (nodeService.exists(actionedUponNodeRef) && - !nodeService.hasAspect(actionedUponNodeRef, ContentModel.ASPECT_PENDING_DELETE) && - (recordService.isRecord(actionedUponNodeRef) || - recordFolderService.isRecordFolder(actionedUponNodeRef)) && - !freezeService.isFrozen(actionedUponNodeRef)) + if (getNodeService().exists(actionedUponNodeRef) && + !getNodeService().hasAspect(actionedUponNodeRef, ContentModel.ASPECT_PENDING_DELETE) && + (getRecordService().isRecord(actionedUponNodeRef) || + getRecordFolderService().isRecordFolder(actionedUponNodeRef)) && + !getFreezeService().isFrozen(actionedUponNodeRef)) { - freezeService.freeze((String) action.getParameterValue(PARAM_REASON), actionedUponNodeRef); + getFreezeService().freeze((String) action.getParameterValue(PARAM_REASON), actionedUponNodeRef); } } } \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/OpenRecordFolderAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/OpenRecordFolderAction.java index bf0f3e6bd1..481e609b2a 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/OpenRecordFolderAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/OpenRecordFolderAction.java @@ -50,28 +50,28 @@ public class OpenRecordFolderAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (nodeService.exists(actionedUponNodeRef) && - !freezeService.isFrozen(actionedUponNodeRef) && - !(dictionaryService.isSubClass(nodeService.getType(actionedUponNodeRef), ContentModel.TYPE_CONTENT) && !recordService.isFiled(actionedUponNodeRef))) + if (getNodeService().exists(actionedUponNodeRef) && + !getFreezeService().isFrozen(actionedUponNodeRef) && + !(getDictionaryService().isSubClass(getNodeService().getType(actionedUponNodeRef), ContentModel.TYPE_CONTENT) && !getRecordService().isFiled(actionedUponNodeRef))) { // TODO move re-open logic into a service method // TODO check that the user in question has the correct permission to re-open a records folder - if (recordService.isRecord(actionedUponNodeRef)) + if (getRecordService().isRecord(actionedUponNodeRef)) { - ChildAssociationRef assocRef = nodeService.getPrimaryParent(actionedUponNodeRef); + ChildAssociationRef assocRef = getNodeService().getPrimaryParent(actionedUponNodeRef); if (assocRef != null) { actionedUponNodeRef = assocRef.getParentRef(); } } - if (recordFolderService.isRecordFolder(actionedUponNodeRef)) + if (getRecordFolderService().isRecordFolder(actionedUponNodeRef)) { - Boolean isClosed = (Boolean) nodeService.getProperty(actionedUponNodeRef, PROP_IS_CLOSED); + Boolean isClosed = (Boolean) getNodeService().getProperty(actionedUponNodeRef, PROP_IS_CLOSED); if (Boolean.TRUE.equals(isClosed)) { - nodeService.setProperty(actionedUponNodeRef, PROP_IS_CLOSED, false); + getNodeService().setProperty(actionedUponNodeRef, PROP_IS_CLOSED, false); } } else diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RejectAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RejectAction.java index 4c3314f6f7..47a54503bd 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RejectAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RejectAction.java @@ -47,11 +47,11 @@ public class RejectAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (nodeService.exists(actionedUponNodeRef) && - !freezeService.isFrozen(actionedUponNodeRef) && - nodeService.getProperty(actionedUponNodeRef, PROP_RECORD_ORIGINATING_LOCATION) != null) + if (getNodeService().exists(actionedUponNodeRef) && + !getFreezeService().isFrozen(actionedUponNodeRef) && + getNodeService().getProperty(actionedUponNodeRef, PROP_RECORD_ORIGINATING_LOCATION) != null) { - recordService.rejectRecord(actionedUponNodeRef, (String) action.getParameterValue(PARAM_REASON)); + getRecordService().rejectRecord(actionedUponNodeRef, (String) action.getParameterValue(PARAM_REASON)); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RelinquishHoldAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RelinquishHoldAction.java index f0fd5ce1e6..cbf320a50e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RelinquishHoldAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RelinquishHoldAction.java @@ -26,7 +26,7 @@ import org.springframework.extensions.surf.util.I18NUtil; /** * Relinquish Hold Action - * + * * @author Roy Wetherall */ public class RelinquishHoldAction extends RMActionExecuterAbstractBase @@ -41,9 +41,9 @@ public class RelinquishHoldAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (freezeService.isHold(actionedUponNodeRef)) + if (getFreezeService().isHold(actionedUponNodeRef)) { - freezeService.relinquish(actionedUponNodeRef); + getFreezeService().relinquish(actionedUponNodeRef); } else { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RequestInfoAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RequestInfoAction.java index 3b6154f48f..925eceeb5e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RequestInfoAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/RequestInfoAction.java @@ -79,10 +79,10 @@ public class RequestInfoAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (nodeService.exists(actionedUponNodeRef) && - !nodeService.hasAspect(actionedUponNodeRef, ContentModel.ASPECT_PENDING_DELETE) && - recordService.isRecord(actionedUponNodeRef) && - !recordService.isDeclared(actionedUponNodeRef)) + if (getNodeService().exists(actionedUponNodeRef) && + !getNodeService().hasAspect(actionedUponNodeRef, ContentModel.ASPECT_PENDING_DELETE) && + getRecordService().isRecord(actionedUponNodeRef) && + !getRecordService().isDeclared(actionedUponNodeRef)) { String workflowDefinitionId = workflowService.getDefinitionByName(REQUEST_INFO_WORKFLOW_DEFINITION_NAME).getId(); Map parameters = new HashMap(); @@ -120,10 +120,10 @@ public class RequestInfoAction extends RMActionExecuterAbstractBase */ private NodeRef getWorkflowPackage(Action action, NodeRef actionedUponNodeRef) { - NodeRef workflowPackage = (NodeRef) action.getParameterValue(WorkflowModel.ASSOC_PACKAGE.toPrefixString(namespaceService)); + NodeRef workflowPackage = (NodeRef) action.getParameterValue(WorkflowModel.ASSOC_PACKAGE.toPrefixString(getNamespaceService())); workflowPackage = workflowService.createPackage(workflowPackage); - ChildAssociationRef childAssoc = nodeService.getPrimaryParent(actionedUponNodeRef); - nodeService.addChild(workflowPackage, actionedUponNodeRef, WorkflowModel.ASSOC_PACKAGE_CONTAINS, childAssoc.getQName()); + ChildAssociationRef childAssoc = getNodeService().getPrimaryParent(actionedUponNodeRef); + getNodeService().addChild(workflowPackage, actionedUponNodeRef, WorkflowModel.ASSOC_PACKAGE_CONTAINS, childAssoc.getQName()); return workflowPackage; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/SplitEmailAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/SplitEmailAction.java index 6d8a13861e..8a25b62c0c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/SplitEmailAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/SplitEmailAction.java @@ -137,23 +137,23 @@ public class SplitEmailAction extends RMActionExecuterAbstractBase protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { // get node type - nodeService.getType(actionedUponNodeRef); + getNodeService().getType(actionedUponNodeRef); if (logger.isDebugEnabled()) { logger.debug("split email:" + actionedUponNodeRef); } - if (recordService.isRecord(actionedUponNodeRef)) + if (getRecordService().isRecord(actionedUponNodeRef)) { - if (!recordService.isDeclared(actionedUponNodeRef)) + if (!getRecordService().isDeclared(actionedUponNodeRef)) { - ChildAssociationRef parent = nodeService.getPrimaryParent(actionedUponNodeRef); + ChildAssociationRef parent = getNodeService().getPrimaryParent(actionedUponNodeRef); /** * Check whether the email message has already been split - do nothing if it has already been split */ - List refs = nodeService.getTargetAssocs(actionedUponNodeRef, ImapModel.ASSOC_IMAP_ATTACHMENT); + List refs = getNodeService().getTargetAssocs(actionedUponNodeRef, ImapModel.ASSOC_IMAP_ATTACHMENT); if(refs.size() > 0) { if (logger.isDebugEnabled()) @@ -168,7 +168,7 @@ public class SplitEmailAction extends RMActionExecuterAbstractBase */ try { - ContentReader reader = contentService.getReader(actionedUponNodeRef, ContentModel.PROP_CONTENT); + ContentReader reader = getContentService().getReader(actionedUponNodeRef, ContentModel.PROP_CONTENT); InputStream is = reader.getContentInputStream(); MimeMessage mimeMessage = new MimeMessage(null, is); Object content = mimeMessage.getContent(); @@ -225,7 +225,7 @@ public class SplitEmailAction extends RMActionExecuterAbstractBase } } - Map messageProperties = nodeService.getProperties(messageNodeRef); + Map messageProperties = getNodeService().getProperties(messageNodeRef); String messageTitle = (String)messageProperties.get(ContentModel.PROP_NAME); if(messageTitle == null) { @@ -245,7 +245,7 @@ public class SplitEmailAction extends RMActionExecuterAbstractBase /** * Create an attachment node in the same folder as the message */ - ChildAssociationRef attachmentRef = nodeService.createNode(parentNodeRef, + ChildAssociationRef attachmentRef = getNodeService().createNode(parentNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, fileName), ContentModel.TYPE_CONTENT, @@ -254,7 +254,7 @@ public class SplitEmailAction extends RMActionExecuterAbstractBase /** * Write the content into the new attachment node */ - ContentWriter writer = contentService.getWriter(attachmentRef.getChildRef(), ContentModel.PROP_CONTENT, true); + ContentWriter writer = getContentService().getWriter(attachmentRef.getChildRef(), ContentModel.PROP_CONTENT, true); writer.setMimetype(contentType.getBaseType()); OutputStream os = writer.getContentOutputStream(); FileCopyUtils.copy(part.getInputStream(), os); @@ -281,7 +281,7 @@ public class SplitEmailAction extends RMActionExecuterAbstractBase getRelationshipService().addRelationship(relationshipUniqueName, parentRef, childRef); // add the IMAP attachment aspect - nodeService.createAssociation( + getNodeService().createAssociation( parentRef, childRef, ImapModel.ASSOC_IMAP_ATTACHMENT); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java index dbaba86616..3c02ba59fe 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferAction.java @@ -101,9 +101,9 @@ public class TransferAction extends RMDispositionActionExecuterAbstractBase action.setParameterValue(ActionExecuter.PARAM_RESULT, transferNodeRef); // Cut off the disposable item if it's not cut off already - if (!dispositionService.isDisposableItemCutoff(dispositionLifeCycleNodeRef)) + if (!getDispositionService().isDisposableItemCutoff(dispositionLifeCycleNodeRef)) { - dispositionService.cutoffDisposableItem(dispositionLifeCycleNodeRef); + getDispositionService().cutoffDisposableItem(dispositionLifeCycleNodeRef); } } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferCompleteAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferCompleteAction.java index 679786b3fd..0304e1521b 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferCompleteAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/TransferCompleteAction.java @@ -73,8 +73,8 @@ public class TransferCompleteAction extends RMActionExecuterAbstractBase */ private void checkTransferSubClass(NodeRef actionedUponNodeRef) { - QName type = nodeService.getType(actionedUponNodeRef); - if (!dictionaryService.isSubClass(type, TYPE_TRANSFER)) + QName type = getNodeService().getType(actionedUponNodeRef); + if (!getDictionaryService().isSubClass(type, TYPE_TRANSFER)) { throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_NODE_NOT_TRANSFER)); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnCutoffAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnCutoffAction.java index d0efeba546..f60db31934 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnCutoffAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnCutoffAction.java @@ -43,11 +43,11 @@ public class UnCutoffAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (nodeService.hasAspect(actionedUponNodeRef, ASPECT_DISPOSITION_LIFECYCLE) && - nodeService.hasAspect(actionedUponNodeRef, ASPECT_CUT_OFF)) + if (getNodeService().hasAspect(actionedUponNodeRef, ASPECT_DISPOSITION_LIFECYCLE) && + getNodeService().hasAspect(actionedUponNodeRef, ASPECT_CUT_OFF)) { // Get the last disposition action - DispositionAction da = dispositionService.getLastCompletedDispostionAction(actionedUponNodeRef); + DispositionAction da = getDispositionService().getLastCompletedDispostionAction(actionedUponNodeRef); // Check that the last disposition action was a cutoff if (da == null || !da.getName().equals("cutoff")) @@ -57,33 +57,33 @@ public class UnCutoffAction extends RMActionExecuterAbstractBase } // Remove the cutoff aspect and add the uncutoff aspect - nodeService.removeAspect(actionedUponNodeRef, ASPECT_CUT_OFF); - nodeService.addAspect(actionedUponNodeRef, ASPECT_UNCUT_OFF, null); - if (recordFolderService.isRecordFolder(actionedUponNodeRef)) + getNodeService().removeAspect(actionedUponNodeRef, ASPECT_CUT_OFF); + getNodeService().addAspect(actionedUponNodeRef, ASPECT_UNCUT_OFF, null); + if (getRecordFolderService().isRecordFolder(actionedUponNodeRef)) { - List records = recordService.getRecords(actionedUponNodeRef); + List records = getRecordService().getRecords(actionedUponNodeRef); for (NodeRef record : records) { - nodeService.removeAspect(record, ASPECT_CUT_OFF); - nodeService.addAspect(record, ASPECT_UNCUT_OFF, null); + getNodeService().removeAspect(record, ASPECT_CUT_OFF); + getNodeService().addAspect(record, ASPECT_UNCUT_OFF, null); } } // Delete the current disposition action - DispositionAction currentDa = dispositionService.getNextDispositionAction(actionedUponNodeRef); + DispositionAction currentDa = getDispositionService().getNextDispositionAction(actionedUponNodeRef); if (currentDa != null) { - nodeService.deleteNode(currentDa.getNodeRef()); + getNodeService().deleteNode(currentDa.getNodeRef()); } // Move the previous (cutoff) disposition back to be current - nodeService.moveNode(da.getNodeRef(), actionedUponNodeRef, ASSOC_NEXT_DISPOSITION_ACTION, ASSOC_NEXT_DISPOSITION_ACTION); + getNodeService().moveNode(da.getNodeRef(), actionedUponNodeRef, ASSOC_NEXT_DISPOSITION_ACTION, ASSOC_NEXT_DISPOSITION_ACTION); // Reset the started and completed property values - nodeService.setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_STARTED_AT, null); - nodeService.setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_STARTED_BY, null); - nodeService.setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_COMPLETED_AT, null); - nodeService.setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_COMPLETED_BY, null); + getNodeService().setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_STARTED_AT, null); + getNodeService().setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_STARTED_BY, null); + getNodeService().setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_COMPLETED_AT, null); + getNodeService().setProperty(da.getNodeRef(), PROP_DISPOSITION_ACTION_COMPLETED_BY, null); } } } \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndeclareRecordAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndeclareRecordAction.java index 5bb9408f25..9c5aba4ea3 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndeclareRecordAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndeclareRecordAction.java @@ -44,16 +44,16 @@ public class UndeclareRecordAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - if (nodeService.exists(actionedUponNodeRef)) + if (getNodeService().exists(actionedUponNodeRef)) { - if (recordService.isRecord(actionedUponNodeRef)) + if (getRecordService().isRecord(actionedUponNodeRef)) { // repoen if already complete and not frozen - if (recordService.isDeclared(actionedUponNodeRef) && - !freezeService.isFrozen(actionedUponNodeRef)) + if (getRecordService().isDeclared(actionedUponNodeRef) && + !getFreezeService().isFrozen(actionedUponNodeRef)) { // Remove the declared aspect - this.nodeService.removeAspect(actionedUponNodeRef, ASPECT_DECLARED_RECORD); + this.getNodeService().removeAspect(actionedUponNodeRef, ASPECT_DECLARED_RECORD); } } else diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndoEventAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndoEventAction.java index 655e27443f..e27f4589e0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndoEventAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UndoEventAction.java @@ -45,10 +45,10 @@ public class UndoEventAction extends RMActionExecuterAbstractBase { String eventName = (String)action.getParameterValue(PARAM_EVENT_NAME); - if (this.nodeService.hasAspect(actionedUponNodeRef, ASPECT_DISPOSITION_LIFECYCLE)) + if (this.getNodeService().hasAspect(actionedUponNodeRef, ASPECT_DISPOSITION_LIFECYCLE)) { // Get the next disposition action - DispositionAction da = this.dispositionService.getNextDispositionAction(actionedUponNodeRef); + DispositionAction da = this.getDispositionService().getNextDispositionAction(actionedUponNodeRef); if (da != null) { // undo completed event diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnfreezeAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnfreezeAction.java index 779e08e5a3..a69c4478be 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnfreezeAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnfreezeAction.java @@ -24,7 +24,7 @@ import org.alfresco.service.cmr.repository.NodeRef; /** * Unfreeze Action - * + * * @author Roy Wetherall */ public class UnfreezeAction extends RMActionExecuterAbstractBase @@ -36,6 +36,6 @@ public class UnfreezeAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - freezeService.unFreeze(actionedUponNodeRef); + getFreezeService().unFreeze(actionedUponNodeRef); } } \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnlinkFromAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnlinkFromAction.java new file mode 100644 index 0000000000..91e492ad19 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnlinkFromAction.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.action.impl; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * Unlink from action implementation. + * + * @author Roy Wetherall + * @since 2.3 + */ +public class UnlinkFromAction extends RMActionExecuterAbstractBase +{ + /** action name */ + public static final String NAME = "unlinkFrom"; + + /** action parameters */ + public static final String PARAM_RECORD_FOLDER = "recordFolder"; + + /** + * @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) + { + // check that the actioned upon node reference exists and is of the correct type + if (getNodeService().exists(actionedUponNodeRef) && + !getNodeService().hasAspect(actionedUponNodeRef, ContentModel.ASPECT_PENDING_DELETE) && + getRecordService().isRecord(actionedUponNodeRef)) + { + // get the record folder we are unlinking from + String recordFolderValue = (String)action.getParameterValue(PARAM_RECORD_FOLDER); + if (recordFolderValue == null || recordFolderValue.isEmpty()) + { + // indicate that the record folder is mandatory + throw new AlfrescoRuntimeException("Can't unlink, because no record folder was provided."); + } + NodeRef recordFolder = new NodeRef(recordFolderValue); + + // unlink record from record folder + getRecordService().unlink(actionedUponNodeRef, recordFolder); + } + } +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminBase.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminBase.java index f2b18f844e..32a0c37f5c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminBase.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminBase.java @@ -239,7 +239,7 @@ public class RecordsManagementAdminBase implements RecordsManagementCustomModel } catch (DictionaryException de) { - logger.warn("readCustomContentModel: skip model ("+modelRef+") whilst searching for uri ("+uri+"): "+de); + logger.warn("readCustomContentModel: skip model ("+modelRef+") whilst searching for uri ("+uri+"): ", de); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java index 9110b7a391..2008fd8851 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/admin/RecordsManagementAdminServiceImpl.java @@ -831,7 +831,8 @@ public class RecordsManagementAdminServiceImpl extends RecordsManagementAdminBas M2Property targetProperty = findProperty(propQName, deserializedModel); // Need to count backwards to remove constraints - for (int i = targetProperty.getConstraints().size() - 1; i >= 0; i--) { + for (int i = targetProperty.getConstraints().size() - 1; i >= 0; i--) + { String ref = targetProperty.getConstraints().get(i).getRef(); targetProperty.removeConstraintRef(ref); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/BootstrapImporterModuleComponent.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/BootstrapImporterModuleComponent.java index 1daccbddeb..f204829fe6 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/BootstrapImporterModuleComponent.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/BootstrapImporterModuleComponent.java @@ -40,6 +40,9 @@ public class BootstrapImporterModuleComponent extends ImporterModuleComponent /** module patch executer */ private ModulePatchExecuter modulePatchExecuter; + + /** record contributors group bootstrap component */ + private RecordContributorsGroupBootstrapComponent recordContributorsGroupBootstrapComponent; /** * @param nodeService node service @@ -57,6 +60,14 @@ public class BootstrapImporterModuleComponent extends ImporterModuleComponent this.modulePatchExecuter = modulePatchExecuter; } + /** + * @param recordContributorsGroupBootstrapComponent record contributors group bootstrap component + */ + public void setRecordContributorsGroupBootstrapComponent(RecordContributorsGroupBootstrapComponent recordContributorsGroupBootstrapComponent) + { + this.recordContributorsGroupBootstrapComponent = recordContributorsGroupBootstrapComponent; + } + /** * Need to check whether this module has already been executed. * @@ -69,6 +80,9 @@ public class BootstrapImporterModuleComponent extends ImporterModuleComponent if (!nodeService.exists(nodeRef)) { super.executeInternal(); + + // bootstrap the record contributors group + recordContributorsGroupBootstrapComponent.createRecordContributorsGroup(); // init module schema number modulePatchExecuter.initSchemaVersion(); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordContributorsGroupBootstrapComponent.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordContributorsGroupBootstrapComponent.java new file mode 100644 index 0000000000..14482708b4 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordContributorsGroupBootstrapComponent.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.bootstrap; + +import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil; +import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.cmr.security.AuthorityType; + +/** + * Record contributors group bootstrap component + * + * @author Roy Wetherall + * @since 2.3 + */ +public class RecordContributorsGroupBootstrapComponent +{ + // default record contributors group + public static final String RECORD_CONTRIBUTORS = "RECORD_CONTRIBUTORS"; + public static final String GROUP_RECORD_CONTRIBUTORS = "GROUP_" + RECORD_CONTRIBUTORS; + + /** authority service */ + private AuthorityService authorityService; + + /** authentication utils */ + private AuthenticationUtil authenticationUtil; + + /** + * @param authorityService authority service + */ + public void setAuthorityService(AuthorityService authorityService) + { + this.authorityService = authorityService; + } + + /** + * @param authenticationUtil authentication util + */ + public void setAuthenticationUtil(AuthenticationUtil authenticationUtil) + { + this.authenticationUtil = authenticationUtil; + } + + /** + * Create record contributor group + */ + public void createRecordContributorsGroup() + { + if (!authorityService.authorityExists(GROUP_RECORD_CONTRIBUTORS)) + { + // create record contributors group + authorityService.createAuthority(AuthorityType.GROUP, RECORD_CONTRIBUTORS); + + // add the admin user + authorityService.addAuthority(GROUP_RECORD_CONTRIBUTORS, authenticationUtil.getAdminUserName()); + } + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java index 295059ead3..f061d07a4c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordsManagementBootstrap.java @@ -22,6 +22,7 @@ import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminSe import org.alfresco.module.org_alfresco_module_rm.action.impl.SplitEmailAction; import org.alfresco.module.org_alfresco_module_rm.caveat.RMCaveatConfigService; import org.alfresco.module.org_alfresco_module_rm.email.CustomEmailMappingService; +import org.alfresco.repo.action.parameter.NodeParameterSuggesterBootstrap; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; @@ -41,6 +42,17 @@ public class RecordsManagementBootstrap extends AbstractLifecycleBean private RMCaveatConfigService caveatConfigService; private CustomEmailMappingService customEmailMappingService; private RecordsManagementAdminService adminService; + private NodeParameterSuggesterBootstrap suggesterBootstrap; + + public NodeParameterSuggesterBootstrap getSuggesterBootstrap() + { + return suggesterBootstrap; + } + + public void setSuggesterBootstrap(NodeParameterSuggesterBootstrap suggesterBootstrap) + { + this.suggesterBootstrap = suggesterBootstrap; + } public void setTransactionService(TransactionService transactionService) { @@ -84,6 +96,10 @@ public class RecordsManagementBootstrap extends AbstractLifecycleBean // Initialise the custom model adminService.initialiseCustomModel(); + + // Initialize the suggester after the model + // in case it contains namespaces from custom models + suggesterBootstrap.init(); // Initialise the SplitEmailAction SplitEmailAction action = (SplitEmailAction)getApplicationContext().getBean("splitEmail"); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMAfterInvocationProvider.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMAfterInvocationProvider.java index b16c065f2a..60431bb697 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMAfterInvocationProvider.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMAfterInvocationProvider.java @@ -215,8 +215,7 @@ public class RMAfterInvocationProvider extends RMSecurityCommon { if (logger.isDebugEnabled()) { - logger.debug("Access denied"); - ade.printStackTrace(); + logger.debug("Access denied: " + ade.getMessage()); } throw ade; } @@ -224,8 +223,7 @@ public class RMAfterInvocationProvider extends RMSecurityCommon { if (logger.isDebugEnabled()) { - logger.debug("Access denied by runtime exception"); - re.printStackTrace(); + logger.debug("Access denied by runtime exception: " + re.getMessage()); } throw re; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMPermissionModel.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMPermissionModel.java index fab4ab40de..f002c507d5 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMPermissionModel.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMPermissionModel.java @@ -19,6 +19,7 @@ package org.alfresco.module.org_alfresco_module_rm.capability; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; /** @@ -34,133 +35,93 @@ public interface RMPermissionModel String FILE_RECORDS = "FileRecords"; // Roles - String ROLE_NAME_USER = "User"; - String ROLE_NAME_POWER_USER = "PowerUser"; - String ROLE_NAME_SECURITY_OFFICER = "SecurityOfficer"; - String ROLE_NAME_RECORDS_MANAGER = "RecordsManager"; - - String ROLE_NAME_ADMINISTRATOR = "Administrator"; - String ROLE_ADMINISTRATOR = SimplePermissionReference.getPermissionReference(RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT, ROLE_NAME_ADMINISTRATOR).toString(); + /** + * @deprecated as of 2.1.0.3, please use {@link FilePlanRoleService.ROLE_USER} instead + */ + @Deprecated + String ROLE_NAME_USER = FilePlanRoleService.ROLE_USER; + /** + * @deprecated as of 2.1.0.3, please use {@link FilePlanRoleService.ROLE_POWER_USER} instead + */ + @Deprecated + String ROLE_NAME_POWER_USER = FilePlanRoleService.ROLE_POWER_USER; + /** + * @deprecated as of 2.1.0.3, please use {@link FilePlanRoleService.ROLE_SECURITY_OFFICER} instead + */ + @Deprecated + String ROLE_NAME_SECURITY_OFFICER = FilePlanRoleService.ROLE_SECURITY_OFFICER; + /** + * @deprecated as of 2.1.0.3, please use {@link FilePlanRoleService.ROLE_RECORDS_MANAGER} instead + */ + @Deprecated + String ROLE_NAME_RECORDS_MANAGER = FilePlanRoleService.ROLE_RECORDS_MANAGER; + /** + * @deprecated as of 2.1.0.3, please use {@link FilePlanRoleService.ROLE_ADMIN} instead + */ + @Deprecated + String ROLE_NAME_ADMINISTRATOR = FilePlanRoleService.ROLE_ADMIN; + String ROLE_ADMINISTRATOR = SimplePermissionReference.getPermissionReference(RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT, FilePlanRoleService.ROLE_ADMIN).toString(); // Capability permissions - String DECLARE_RECORDS = "DeclareRecords"; - - String VIEW_RECORDS = "ViewRecords"; - + String VIEW_RECORDS = "ViewRecords"; String CREATE_MODIFY_DESTROY_FOLDERS = "CreateModifyDestroyFolders"; - String EDIT_RECORD_METADATA = "EditRecordMetadata"; - String EDIT_NON_RECORD_METADATA = "EditNonRecordMetadata"; - String ADD_MODIFY_EVENT_DATES = "AddModifyEventDates"; - String CLOSE_FOLDERS = "CloseFolders"; - String DECLARE_RECORDS_IN_CLOSED_FOLDERS = "DeclareRecordsInClosedFolders"; - String RE_OPEN_FOLDERS = "ReOpenFolders"; - String CYCLE_VITAL_RECORDS = "CycleVitalRecords"; - String PLANNING_REVIEW_CYCLES = "PlanningReviewCycles"; - String UPDATE_TRIGGER_DATES = "UpdateTriggerDates"; - String CREATE_MODIFY_DESTROY_EVENTS = "CreateModifyDestroyEvents"; - String MANAGE_ACCESS_RIGHTS = "ManageAccessRights"; - String MOVE_RECORDS = "MoveRecords"; - String CHANGE_OR_DELETE_REFERENCES = "ChangeOrDeleteReferences"; - String DELETE_LINKS = "DeleteLinks"; - String EDIT_DECLARED_RECORD_METADATA = "EditDeclaredRecordMetadata"; - String MANUALLY_CHANGE_DISPOSITION_DATES = "ManuallyChangeDispositionDates"; - String APPROVE_RECORDS_SCHEDULED_FOR_CUTOFF = "ApproveRecordsScheduledForCutoff"; - String CREATE_MODIFY_RECORDS_IN_CUTOFF_FOLDERS = "CreateModifyRecordsInCutoffFolders"; - String EXTEND_RETENTION_PERIOD_OR_FREEZE = "ExtendRetentionPeriodOrFreeze"; - String UNFREEZE = "Unfreeze"; - String VIEW_UPDATE_REASONS_FOR_FREEZE = "ViewUpdateReasonsForFreeze"; - String DESTROY_RECORDS_SCHEDULED_FOR_DESTRUCTION = "DestroyRecordsScheduledForDestruction"; - String DESTROY_RECORDS = "DestroyRecords"; - String UPDATE_VITAL_RECORD_CYCLE_INFORMATION = "UpdateVitalRecordCycleInformation"; - String UNDECLARE_RECORDS = "UndeclareRecords"; - String DECLARE_AUDIT_AS_RECORD = "DeclareAuditAsRecord"; - String DELETE_AUDIT = "DeleteAudit"; - String CREATE_MODIFY_DESTROY_TIMEFRAMES = "CreateModifyDestroyTimeframes"; - String AUTHORIZE_NOMINATED_TRANSFERS = "AuthorizeNominatedTransfers"; - String EDIT_SELECTION_LISTS = "EditSelectionLists"; - String AUTHORIZE_ALL_TRANSFERS = "AuthorizeAllTransfers"; - String CREATE_MODIFY_DESTROY_FILEPLAN_METADATA = "CreateModifyDestroyFileplanMetadata"; - String CREATE_AND_ASSOCIATE_SELECTION_LISTS = "CreateAndAssociateSelectionLists"; - String ATTACH_RULES_TO_METADATA_PROPERTIES = "AttachRulesToMetadataProperties"; - String CREATE_MODIFY_DESTROY_FILEPLAN_TYPES = "CreateModifyDestroyFileplanTypes"; - String CREATE_MODIFY_DESTROY_RECORD_TYPES = "CreateModifyDestroyRecordTypes"; - String MAKE_OPTIONAL_PARAMETERS_MANDATORY = "MakeOptionalParametersMandatory"; - String MAP_EMAIL_METADATA = "MapEmailMetadata"; - String DELETE_RECORDS = "DeleteRecords"; - String TRIGGER_AN_EVENT = "TriggerAnEvent"; - String CREATE_MODIFY_DESTROY_ROLES = "CreateModifyDestroyRoles"; - String CREATE_MODIFY_DESTROY_USERS_AND_GROUPS = "CreateModifyDestroyUsersAndGroups"; - String PASSWORD_CONTROL = "PasswordControl"; - String ENABLE_DISABLE_AUDIT_BY_TYPES = "EnableDisableAuditByTypes"; - String SELECT_AUDIT_METADATA = "SelectAuditMetadata"; - String DISPLAY_RIGHTS_REPORT = "DisplayRightsReport"; - String ACCESS_AUDIT = "AccessAudit"; - String EXPORT_AUDIT = "ExportAudit"; - String CREATE_MODIFY_DESTROY_REFERENCE_TYPES = "CreateModifyDestroyReferenceTypes"; - String UPDATE_CLASSIFICATION_DATES = "UpdateClassificationDates"; - String CREATE_MODIFY_DESTROY_CLASSIFICATION_GUIDES = "CreateModifyDestroyClassificationGuides"; - String UPGRADE_DOWNGRADE_AND_DECLASSIFY_RECORDS = "UpgradeDowngradeAndDeclassifyRecords"; - String UPDATE_EXEMPTION_CATEGORIES = "UpdateExemptionCategories"; - String MAP_CLASSIFICATION_GUIDE_METADATA = "MapClassificationGuideMetadata"; - String MANAGE_ACCESS_CONTROLS = "ManageAccessControls"; - String CREATE_HOLD = "CreateHold"; String ADD_TO_HOLD = "AddToHold"; String REMOVE_FROM_HOLD = "RemoveFromHold"; -} +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java index f004cec040..c97016896c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java @@ -18,14 +18,17 @@ */ package org.alfresco.module.org_alfresco_module_rm.capability; +import java.util.Map; + import net.sf.acegisecurity.vote.AccessDecisionVoter; +import org.alfresco.module.org_alfresco_module_rm.capability.impl.ViewRecordsCapability; import org.alfresco.module.org_alfresco_module_rm.caveat.RMCaveatConfigComponent; 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.security.RMMethodSecurityInterceptor; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; +import org.alfresco.repo.transaction.TransactionalResourceHelper; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; @@ -33,6 +36,7 @@ import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.util.Pair; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -201,54 +205,82 @@ public class RMSecurityCommon implements ApplicationContextAware } /** + * Core RM read check * - * @param nodeRef - * @return + * @param nodeRef node reference + * @return int see {@link AccessDecisionVoter} */ public int checkRmRead(NodeRef nodeRef) { - int result = getTransactionCache("checkRmRead", nodeRef); - if (result != NOSET_VALUE) - { - return result; - } + int result = AccessDecisionVoter.ACCESS_ABSTAIN; - if (permissionService.hasPermission(nodeRef, RMPermissionModel.READ_RECORDS) == AccessStatus.DENIED) - { - // log message - RMMethodSecurityInterceptor.addMessage("User does not have read record permission on node, access denied. (nodeRef={0}, user={1})", nodeRef, AuthenticationUtil.getRunAsUser()); + Map, Integer> transactionCache = TransactionalResourceHelper.getMap("rm.security.checkRMRead"); + Pair key = new Pair(AuthenticationUtil.getRunAsUser(), nodeRef); - if (logger.isDebugEnabled()) - { - logger.debug("\t\tUser does not have read record permission on node, access denied. (nodeRef=" + nodeRef.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")"); - } + if (transactionCache.containsKey(key)) + { + result = transactionCache.get(key); + } + else + { + if (permissionService.hasPermission(nodeRef, RMPermissionModel.READ_RECORDS) == AccessStatus.DENIED) + { + if (logger.isDebugEnabled()) + { + logger.debug("\t\tUser does not have read record permission on node, access denied. (nodeRef=" + nodeRef.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")"); + } + result = AccessDecisionVoter.ACCESS_DENIED; + } + else + { + // Get the file plan for the node + NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef); + if (hasViewCapability(filePlan) == AccessStatus.DENIED) + { + if (logger.isDebugEnabled()) + { + logger.debug("\t\tUser does not have view records capability permission on node, access denied. (filePlan=" + filePlan.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")"); + } + result = AccessDecisionVoter.ACCESS_DENIED; + } + else if (!caveatConfigComponent.hasAccess(nodeRef)) + { + result = AccessDecisionVoter.ACCESS_DENIED; + } + else + { + result = AccessDecisionVoter.ACCESS_GRANTED; + } + } - return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_DENIED); - } - - // Get the file plan for the node - NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef); - if (permissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS) == AccessStatus.DENIED) - { - // log capability details - RMMethodSecurityInterceptor.reportCapabilityStatus(RMPermissionModel.VIEW_RECORDS, AccessDecisionVoter.ACCESS_DENIED); + // cache result + transactionCache.put(key, result); + } - if (logger.isDebugEnabled()) - { - logger.debug("\t\tUser does not have view records capability permission on node, access denied. (filePlan=" + filePlan.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")"); - } - return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_DENIED); - } + return result; + } - if (caveatConfigComponent.hasAccess(nodeRef)) - { - return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_GRANTED); - } - else - { - return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_DENIED); - } + /** + * Helper method to determine whether the current user has view capability on the file plan + * + * @param filePlan file plan + * @return {@link AccessStatus} + */ + private AccessStatus hasViewCapability(NodeRef filePlan) + { + Map, AccessStatus> transactionCache = TransactionalResourceHelper.getMap("rm.security.hasViewCapability"); + Pair key = new Pair(AuthenticationUtil.getRunAsUser(), filePlan); + if (transactionCache.containsKey(key)) + { + return transactionCache.get(key); + } + else + { + AccessStatus result = permissionService.hasPermission(filePlan, ViewRecordsCapability.NAME); + transactionCache.put(key, result); + return result; + } } @SuppressWarnings("rawtypes") diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/DeclarativeCapability.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/DeclarativeCapability.java index c5225f5247..25dd968865 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/DeclarativeCapability.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/DeclarativeCapability.java @@ -30,6 +30,8 @@ import org.alfresco.module.org_alfresco_module_rm.capability.AbstractCapability; import org.alfresco.module.org_alfresco_module_rm.capability.Capability; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; import org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityInterceptor; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.transaction.TransactionalResourceHelper; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; import org.apache.commons.logging.Log; @@ -289,29 +291,41 @@ public class DeclarativeCapability extends AbstractCapability { int result = AccessDecisionVoter.ACCESS_ABSTAIN; - // Check we are dealing with a file plan component - if (getFilePlanService().isFilePlanComponent(nodeRef)) + // check transaction cache + Map map = TransactionalResourceHelper.getMap("rm.declarativeCapability"); + String key = getName() + "|" + nodeRef.toString() + "|" + AuthenticationUtil.getRunAsUser(); + if (map.containsKey(key)) { - // Check the kind of the object, the permissions and the conditions - if (checkKinds(nodeRef) && checkPermissions(nodeRef) && checkConditions(nodeRef)) - { - // Opportunity for child implementations to extend - result = evaluateImpl(nodeRef); - } - else - { - result = AccessDecisionVoter.ACCESS_DENIED; - } + result = map.get(key); } - - // Last chance for child implementations to veto/change the result - result = onEvaluate(nodeRef, result); - - // log access denied to help with debug - if (LOGGER.isDebugEnabled() && AccessDecisionVoter.ACCESS_DENIED == result) + else { - LOGGER.debug("FAIL: Capability " + getName() + " returned an Access Denied result during evaluation of node " + nodeRef.toString()); - } + // Check we are dealing with a file plan component + if (getFilePlanService().isFilePlanComponent(nodeRef)) + { + // Check the kind of the object, the permissions and the conditions + if (checkKinds(nodeRef) && checkPermissions(nodeRef) && checkConditions(nodeRef)) + { + // Opportunity for child implementations to extend + result = evaluateImpl(nodeRef); + } + else + { + result = AccessDecisionVoter.ACCESS_DENIED; + } + } + + // Last chance for child implementations to veto/change the result + result = onEvaluate(nodeRef, result); + + // log access denied to help with debug + if (LOGGER.isDebugEnabled() && AccessDecisionVoter.ACCESS_DENIED == result) + { + LOGGER.debug("Capability " + getName() + " returned an Access Denied result during evaluation of node " + nodeRef.toString()); + } + + map.put(key, result); + } return result; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java index 4e3c80baf3..5283e84e6c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java @@ -43,6 +43,11 @@ public class AtLeastOneCondition extends AbstractCapabilityCondition this.conditions = conditions; } + /** + * Don't use the transaction cache for the composite condition + * + * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.AbstractCapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) + */ @Override public boolean evaluate(NodeRef nodeRef) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java index 00483e911c..3ed855e322 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java @@ -34,6 +34,7 @@ public class IsPropertySetCondition extends AbstractCapabilityCondition { /** property name (eg: rma:location) */ private String propertyName; + private QName propertyQName; /** namespace service */ private NamespaceService namespaceService; @@ -59,7 +60,11 @@ public class IsPropertySetCondition extends AbstractCapabilityCondition */ protected QName getPropertyQName() { - return QName.createQName(propertyName, namespaceService); + if (propertyQName == null) + { + propertyQName = QName.createQName(propertyName, namespaceService); + } + return propertyQName; } /** diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/CreateCapability.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/CreateCapability.java index 77e2f8cc6d..05aec4b7b6 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/CreateCapability.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/impl/CreateCapability.java @@ -120,7 +120,14 @@ public class CreateCapability extends DeclarativeCapability conditions.put("capabilityCondition.frozen", Boolean.FALSE); conditions.put("capabilityCondition.closed", Boolean.FALSE); conditions.put("capabilityCondition.cutoff", Boolean.FALSE); - + + // if the destination folder is not a record folder and the user has filling capability on it, grant access to create the record + if (checkConditions(destination, conditions) && + !recordFolderService.isRecordFolder(destination) ) + { + return AccessDecisionVoter.ACCESS_GRANTED; + } + if (checkConditions(destination, conditions) && recordFolderService.isRecordFolder(destination) && permissionService.hasPermission(destination, RMPermissionModel.FILE_RECORDS) == AccessStatus.ALLOWED) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/AssocPolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/AssocPolicy.java index 657831e395..0db6c2f053 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/AssocPolicy.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/AssocPolicy.java @@ -18,7 +18,7 @@ */ package org.alfresco.module.org_alfresco_module_rm.capability.policy; -import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.capability.impl.ViewRecordsCapability; import org.alfresco.service.cmr.repository.NodeRef; import org.aopalliance.intercept.MethodInvocation; @@ -32,7 +32,7 @@ public class AssocPolicy extends AbstractBasePolicy ConfigAttributeDefinition cad) { NodeRef testNodeRef = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); - return getCapabilityService().getCapability(RMPermissionModel.VIEW_RECORDS).evaluate(testNodeRef); + return getCapabilityService().getCapability(ViewRecordsCapability.NAME).evaluate(testNodeRef); } } \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ReadPolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ReadPolicy.java index decc5e51e2..d86971029e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ReadPolicy.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ReadPolicy.java @@ -18,7 +18,7 @@ */ package org.alfresco.module.org_alfresco_module_rm.capability.policy; -import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.capability.impl.ViewRecordsCapability; import org.alfresco.service.cmr.repository.NodeRef; import org.aopalliance.intercept.MethodInvocation; @@ -38,6 +38,6 @@ public class ReadPolicy extends AbstractBasePolicy ConfigAttributeDefinition cad) { NodeRef testNodeRef = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); - return getCapabilityService().getCapability(RMPermissionModel.VIEW_RECORDS).evaluate(testNodeRef); + return getCapabilityService().getCapability(ViewRecordsCapability.NAME).evaluate(testNodeRef); } } \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/dataset/DataSetServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/dataset/DataSetServiceImpl.java index 28c32fe0cb..54ce6c8c74 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/dataset/DataSetServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/dataset/DataSetServiceImpl.java @@ -386,7 +386,7 @@ public class DataSetServiceImpl implements DataSetService, RecordsManagementMode } // Make sure all the containers do not inherit permissions - ResultSet rs = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, + ResultSet rs = searchService.query(SPACES_STORE, SearchService.LANGUAGE_FTS_ALFRESCO, "TYPE:\"rma:recordsManagementContainer\""); try { @@ -412,7 +412,7 @@ public class DataSetServiceImpl implements DataSetService, RecordsManagementMode // fix up the test dataset to fire initial events for // disposition // schedules - rs = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, "TYPE:\"rma:recordFolder\""); + rs = searchService.query(SPACES_STORE, SearchService.LANGUAGE_FTS_ALFRESCO, "TYPE:\"rma:recordFolder\""); try { logger.info("Bootstraping " + rs.length() + " record folders ..."); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java index 3883e7a097..c302937ae1 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java @@ -1004,6 +1004,10 @@ public class DispositionServiceImpl extends ServiceBaseImpl recordFolderService.closeRecordFolder(nodeRef); } } + else + { + throw new AlfrescoRuntimeException("unable to perform cutoff, because node is frozen or has frozen children"); + } } else { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java index 40c9ae9c7d..e42b3131b4 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java @@ -30,12 +30,18 @@ import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; -import org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService; +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +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.security.ExtendedReaderDynamicAuthority; +import org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority; import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; +import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.domain.node.NodeDAO; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.site.SiteInfo; import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.namespace.NamespaceService; @@ -52,7 +58,8 @@ import org.springframework.extensions.surf.util.I18NUtil; * @since 2.1 */ public class FilePlanServiceImpl extends ServiceBaseImpl - implements FilePlanService + implements FilePlanService, + RecordsManagementModel { /** I18N */ private static final String MSG_DUP_ROOT = "rm.service.dup-root"; @@ -72,34 +79,75 @@ public class FilePlanServiceImpl extends ServiceBaseImpl /** RM site file plan container */ private static final String FILE_PLAN_CONTAINER = "documentLibrary"; - /** node DAO */ + /** root container cache */ + private SimpleCache, NodeRef> rootContainerCache; + + /** File plan role service */ + private FilePlanRoleService filePlanRoleService; + + /** Permission service */ + private PermissionService permissionService; + + /** Node DAO */ private NodeDAO nodeDAO; - /** file plan permission service */ - private FilePlanPermissionService filePlanPermissionService; + /** Site service */ + private SiteService siteService; /** - * @param nodeDAO node DAO + * Gets the file plan role service + * + * @return The file plan role service */ - public void setNodeDAO(NodeDAO nodeDAO) + public FilePlanRoleService getFilePlanRoleService() { - this.nodeDAO = nodeDAO; + if (filePlanRoleService == null) + { + filePlanRoleService = (FilePlanRoleService) applicationContext.getBean("FilePlanRoleService"); + } + return filePlanRoleService; } /** - * @return site service + * Gets the permission service + * + * @return The permission service */ - protected SiteService getSiteService() + public PermissionService getPermissionService() { - return (SiteService)applicationContext.getBean("siteService"); + if (permissionService == null) + { + permissionService = (PermissionService) applicationContext.getBean("permissionService"); + } + return permissionService; } /** - * @param filePlanPermissionService file plan permission service + * Gets the node DAO + * + * @return The node DAO */ - public void setFilePlanPermissionService(FilePlanPermissionService filePlanPermissionService) + public NodeDAO getNodeDAO() { - this.filePlanPermissionService = filePlanPermissionService; + if (nodeDAO == null) + { + nodeDAO = (NodeDAO) applicationContext.getBean("nodeDAO"); + } + return nodeDAO; + } + + /** + * Gets the site service + * + * @return The site service + */ + public SiteService getSiteService() + { + if (siteService == null) + { + siteService = (SiteService) applicationContext.getBean("SiteService"); + } + return siteService; } /** @@ -111,6 +159,14 @@ public class FilePlanServiceImpl extends ServiceBaseImpl return getFilePlans(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); } + /** + * @param rootContainerCache root container cache + */ + public void setRootContainerCache(SimpleCache, NodeRef> rootContainerCache) + { + this.rootContainerCache = rootContainerCache; + } + /** * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#getFilePlans(org.alfresco.service.cmr.repository.StoreRef) */ @@ -122,7 +178,7 @@ public class FilePlanServiceImpl extends ServiceBaseImpl final Set results = new HashSet(); Set aspects = new HashSet(1); aspects.add(ASPECT_RECORDS_MANAGEMENT_ROOT); - nodeDAO.getNodesWithAspects(aspects, Long.MIN_VALUE, Long.MAX_VALUE, new NodeDAO.NodeRefQueryCallback() + getNodeDAO().getNodesWithAspects(aspects, Long.MIN_VALUE, Long.MAX_VALUE, new NodeDAO.NodeRefQueryCallback() { @Override public boolean handle(Pair nodePair) @@ -146,12 +202,11 @@ public class FilePlanServiceImpl extends ServiceBaseImpl public NodeRef getFilePlanBySiteId(String siteId) { NodeRef filePlan = null; - SiteService siteService = getSiteService(); - SiteInfo siteInfo = siteService.getSite(siteId); - if (siteInfo != null && siteService.hasContainer(siteId, FILE_PLAN_CONTAINER)) + SiteInfo siteInfo = getSiteService().getSite(siteId); + if (siteInfo != null && getSiteService().hasContainer(siteId, FILE_PLAN_CONTAINER)) { - NodeRef nodeRef = siteService.getContainer(siteId, FILE_PLAN_CONTAINER); + NodeRef nodeRef = getSiteService().getContainer(siteId, FILE_PLAN_CONTAINER); if (instanceOf(nodeRef, TYPE_FILE_PLAN)) { filePlan = nodeRef; @@ -198,10 +253,11 @@ public class FilePlanServiceImpl extends ServiceBaseImpl } /** + * Get the file root container for the given type. * - * @param filePlan - * @param containerName - * @return + * @param filePlan file plan + * @param containerName container type + * @return {@link NodeRef} file plan container */ private NodeRef getFilePlanRootContainer(NodeRef filePlan, String containerName) { @@ -212,16 +268,25 @@ public class FilePlanServiceImpl extends ServiceBaseImpl } NodeRef result = null; + Pair key = new Pair(filePlan, containerName); - // try and get the unfiled record container - List assocs = nodeService.getChildAssocs(filePlan, ContentModel.ASSOC_CONTAINS, QName.createQName(RM_URI, containerName)); - if (assocs.size() > 1) + if (!rootContainerCache.contains(key)) { - throw new AlfrescoRuntimeException("Unable to get unfiled conatiner " + containerName + "."); + // try and get the unfiled record container + List assocs = nodeService.getChildAssocs(filePlan, ContentModel.ASSOC_CONTAINS, QName.createQName(RM_URI, containerName)); + if (assocs.size() > 1) + { + throw new AlfrescoRuntimeException("Unable to get unfiled conatiner " + containerName + "."); + } + else if (assocs.size() == 1) + { + result = assocs.get(0).getChildRef(); + rootContainerCache.put(key, result); + } } - else if (assocs.size() == 1) + else { - result = assocs.get(0).getChildRef(); + result = rootContainerCache.get(key); } return result; @@ -269,6 +334,8 @@ public class FilePlanServiceImpl extends ServiceBaseImpl throw new AlfrescoRuntimeException("Unable to create file plan root container, because passed node is not a file plan."); } + String allRoles = getFilePlanRoleService().getAllRolesContainerGroup(filePlan); + // create the properties map Map properties = new HashMap(1); properties.put(ContentModel.PROP_NAME, containerName); @@ -281,8 +348,23 @@ public class FilePlanServiceImpl extends ServiceBaseImpl containerType, properties).getChildRef(); - // setup the permissions - filePlanPermissionService.setupPermissions(filePlan, container); + // if (!inheritPermissions) + // { + // set inheritance to false + getPermissionService().setInheritParentPermissions(container, false); + getPermissionService().setPermission(container, allRoles, RMPermissionModel.READ_RECORDS, true); + getPermissionService().setPermission(container, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true); + getPermissionService().setPermission(container, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true); + + // TODO set the admin users to have filing permissions on the unfiled container!!! + // TODO we will need to be able to get a list of the admin roles from the service + // } + // else + // { + // just inherit eveything + // TODO will change this when we are able to set permissions on holds and transfers! + // getPermissionService().setInheritParentPermissions(container, true); + // } return container; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java index f814b3def7..4bc3466ab5 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java @@ -38,7 +38,6 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.ParameterCheck; import org.apache.commons.lang.StringUtils; @@ -107,109 +106,6 @@ public class FreezeServiceImpl extends ServiceBaseImpl return nodeService.hasAspect(nodeRef, ASPECT_FROZEN); } - /** - * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public boolean hasFrozenChildren(final NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - - boolean result = false; - - // check that we are dealing with a record folder - if (isRecordFolder(nodeRef)) - { - int heldCount = 0; - - if (nodeService.hasAspect(nodeRef, ASPECT_HELD_CHILDREN)) - { - heldCount = (Integer)getInternalNodeService().getProperty(nodeRef, PROP_HELD_CHILDREN_COUNT); - } - else - { - final TransactionService transactionService = (TransactionService)applicationContext.getBean("transactionService"); - - heldCount = AuthenticationUtil.runAsSystem(new RunAsWork() - { - @Override - public Integer doWork() - { - return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() - { - public Integer execute() throws Throwable - { - int heldCount = 0; - - // NOTE: this process remains to 'patch' older systems to improve performance next time around - List childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, - RegexQNamePattern.MATCH_ALL); - if (childAssocs != null && !childAssocs.isEmpty()) - { - for (ChildAssociationRef childAssociationRef : childAssocs) - { - NodeRef record = childAssociationRef.getChildRef(); - if (childAssociationRef.isPrimary() && isRecord(record) && isFrozen(record)) - { - heldCount ++; - } - } - } - - // add aspect and set count - Map props = new HashMap(1); - props.put(PROP_HELD_CHILDREN_COUNT, heldCount); - getInternalNodeService().addAspect(nodeRef, ASPECT_HELD_CHILDREN, props); - - return heldCount; - } - }, - false, true); - } - }); - } - - // true if more than one child held - result = (heldCount > 0); - } - - return result; - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeDate(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public Date getFreezeDate(NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - - if (isFrozen(nodeRef)) - { - Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_AT); - if (property != null) { return (Date) property; } - } - - return null; - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeInitiator(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public String getFreezeInitiator(NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - - if (isFrozen(nodeRef)) - { - Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_BY); - if (property != null) { return (String) property; } - } - - return null; - } - /** * Deprecated Method Implementations */ @@ -357,6 +253,112 @@ public class FreezeServiceImpl extends ServiceBaseImpl return new HashSet(getHoldService().getHolds(filePlan)); } + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public boolean hasFrozenChildren(final NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + boolean result = false; + + // check that we are dealing with a record folder + if (isRecordFolder(nodeRef)) + { + int heldCount = 0; + + if (nodeService.hasAspect(nodeRef, ASPECT_HELD_CHILDREN)) + { + heldCount = (Integer)getInternalNodeService().getProperty(nodeRef, PROP_HELD_CHILDREN_COUNT); + } + else + { + final TransactionService transactionService = (TransactionService)applicationContext.getBean("transactionService"); + + heldCount = AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Integer doWork() + { + return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() + { + public Integer execute() throws Throwable + { + int heldCount = 0; + + // NOTE: this process remains to 'patch' older systems to improve performance next time around + List childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, null); + if (childAssocs != null && !childAssocs.isEmpty()) + { + for (ChildAssociationRef childAssociationRef : childAssocs) + { + NodeRef record = childAssociationRef.getChildRef(); + if (childAssociationRef.isPrimary() && isRecord(record) && isFrozen(record)) + { + heldCount ++; + } + } + } + + // add aspect and set count + Map props = new HashMap(1); + props.put(PROP_HELD_CHILDREN_COUNT, heldCount); + getInternalNodeService().addAspect(nodeRef, ASPECT_HELD_CHILDREN, props); + + return heldCount; + } + }, + false, true); + } + }); + } + + // true if more than one child held + result = (heldCount > 0); + } + + return result; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeDate(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public Date getFreezeDate(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + if (isFrozen(nodeRef)) + { + Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_AT); + if (property != null) { return (Date) property; } + } + + return null; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeInitiator(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public String getFreezeInitiator(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + if (isFrozen(nodeRef)) + { + Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_BY); + if (property != null) { return (String) property; } + } + + return null; + } + + /** + * Helper Methods + */ + /** * Creates a hold using the given nodeRef and reason * diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImpl.java index 6702abc7e0..68f57529bd 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImpl.java @@ -73,7 +73,7 @@ public class HoldServiceImpl extends ServiceBaseImpl { /** Logger */ private static Log logger = LogFactory.getLog(HoldServiceImpl.class); - + /** Audit event keys */ private static final String AUDIT_ADD_TO_HOLD = "addToHold"; private static final String AUDIT_REMOVE_FROM_HOLD = "removeFromHold"; @@ -89,7 +89,7 @@ public class HoldServiceImpl extends ServiceBaseImpl /** Permission service */ private PermissionService permissionService; - + /** records management audit service */ private RecordsManagementAuditService recordsManagementAuditService; @@ -142,7 +142,7 @@ public class HoldServiceImpl extends ServiceBaseImpl { this.permissionService = permissionService; } - + /** * @param recordsManagementAuditService records management audit service */ @@ -150,7 +150,7 @@ public class HoldServiceImpl extends ServiceBaseImpl { this.recordsManagementAuditService = recordsManagementAuditService; } - + /** * Initialise hold service */ @@ -256,7 +256,7 @@ public class HoldServiceImpl extends ServiceBaseImpl for (ChildAssociationRef holdAssoc : holdsAssocs) { NodeRef hold = holdAssoc.getChildRef(); - if (isHold(hold)) + if (isHold(hold)) { // add to list of holds holds.add(hold); @@ -471,7 +471,7 @@ public class HoldServiceImpl extends ServiceBaseImpl } catch (AccessDeniedException ade) { - throw new AlfrescoRuntimeException("Can't delete hold, because you don't have filling permissions on all the items held within the hold."); + throw new AlfrescoRuntimeException("Can't delete hold, because you don't have filling permissions on all the items held within the hold.", ade); } } @@ -586,7 +586,7 @@ public class HoldServiceImpl extends ServiceBaseImpl // Link the record to the hold nodeService.addChild(hold, nodeRef, ASSOC_FROZEN_RECORDS, ASSOC_FROZEN_RECORDS); - + // audit item being added to the hold recordsManagementAuditService.auditEvent(nodeRef, AUDIT_ADD_TO_HOLD); @@ -691,14 +691,14 @@ public class HoldServiceImpl extends ServiceBaseImpl { // remove from hold nodeService.removeChild(hold, nodeRef); - + // audit that the node has been remove from the hold // TODO add details of the hold that the node was removed from recordsManagementAuditService.auditEvent(nodeRef, AUDIT_REMOVE_FROM_HOLD); - + return null; } - }); + }); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java index 272375cc2f..94ada57f76 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuter.java @@ -114,8 +114,8 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute { StringBuilder sb = new StringBuilder(); - sb.append("+TYPE:\"rma:dispositionAction\" "); - sb.append("+(@rma\\:dispositionAction:("); + sb.append("TYPE:\"rma:dispositionAction\" + "); + sb.append("(@rma\\:dispositionAction:("); boolean bFirst = true; for (String dispositionAction : dispositionActions) @@ -133,8 +133,8 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute } sb.append("))"); - sb.append("+ISNULL:\"rma:dispositionActionCompletedAt\" "); - sb.append("+( "); + sb.append(" AND ISNULL:\"rma:dispositionActionCompletedAt\" "); + sb.append(" + ( "); sb.append("@rma\\:dispositionEventsEligible:true "); sb.append("OR @rma\\:dispositionAsOf:[MIN TO NOW] "); sb.append(") "); @@ -157,7 +157,7 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute if (dispositionActions != null && !dispositionActions.isEmpty()) { // execute search - ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, getQuery()); + ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_FTS_ALFRESCO, getQuery()); List resultNodes = results.getNodeRefs(); results.close(); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/NotifyOfRecordsDueForReviewJobExecuter.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/NotifyOfRecordsDueForReviewJobExecuter.java index 3297f7b3ee..61bf37c158 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/NotifyOfRecordsDueForReviewJobExecuter.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/NotifyOfRecordsDueForReviewJobExecuter.java @@ -91,7 +91,7 @@ public class NotifyOfRecordsDueForReviewJobExecuter extends RecordsManagementJob queryBuffer.append(") "); String query = queryBuffer.toString(); - ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, query); + ResultSet results = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_FTS_ALFRESCO, query); final List resultNodes = results.getNodeRefs(); results.close(); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/PublishUpdatesJobExecuter.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/PublishUpdatesJobExecuter.java index 1f130520af..ff5a985dad 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/PublishUpdatesJobExecuter.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/job/PublishUpdatesJobExecuter.java @@ -99,12 +99,12 @@ public class PublishUpdatesJobExecuter extends RecordsManagementJobExecuter } /** - * @param dictionaryService dictionary service + * @param dictionaryService dictionary service */ public void setDictionaryService(DictionaryService dictionaryService) { - this.dictionaryService = dictionaryService; - } + this.dictionaryService = dictionaryService; + } /** * @see org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJobExecuter#executeImpl() @@ -130,7 +130,7 @@ public class PublishUpdatesJobExecuter extends RecordsManagementJobExecuter { if (nodeService.exists(nodeRef)) { - boolean publishing = (Boolean)nodeService.getProperty(nodeRef, PROP_PUBLISH_IN_PROGRESS); + boolean publishing = ((Boolean)nodeService.getProperty(nodeRef, PROP_PUBLISH_IN_PROGRESS)).booleanValue(); if (!publishing) { // Mark the update node as publishing in progress @@ -144,11 +144,11 @@ public class PublishUpdatesJobExecuter extends RecordsManagementJobExecuter logger.debug(" - for " + nodeRef.toString()); logger.debug(" - at " + start.toString()); } - + // Publish updates publishUpdates(nodeRef); - - + + if (logger.isDebugEnabled()) { Date end = new Date(); @@ -189,7 +189,7 @@ public class PublishUpdatesJobExecuter extends RecordsManagementJobExecuter // ensure that the rm content model has been loaded if (dictionaryService != null && - dictionaryService.getAspect(ASPECT_UNPUBLISHED_UPDATE) != null) + dictionaryService.getAspect(ASPECT_UNPUBLISHED_UPDATE) != null) { result = true; } @@ -221,24 +221,24 @@ public class PublishUpdatesJobExecuter extends RecordsManagementJobExecuter // Execute query to find updates awaiting publishing List resultNodes = null; - + SearchParameters searchParameters = new SearchParameters(); searchParameters.setQueryConsistency(QueryConsistency.TRANSACTIONAL); searchParameters.setQuery(query); searchParameters.addStore(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); searchParameters.setLanguage(SearchService.LANGUAGE_FTS_ALFRESCO); - + try { ResultSet results = searchService.query(searchParameters); - try - { - resultNodes = results.getNodeRefs(); - } - finally - { - results.close(); - } + try + { + resultNodes = results.getNodeRefs(); + } + finally + { + results.close(); + } } catch (AlfrescoRuntimeException exception) { @@ -294,7 +294,7 @@ public class PublishUpdatesJobExecuter extends RecordsManagementJobExecuter return null; } }; - retryingTransactionHelper.doInTransaction(execution, false, true); + retryingTransactionHelper.doInTransaction(execution); } /** diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java index 239af0c1ff..862335a0c0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java @@ -19,15 +19,21 @@ package org.alfresco.module.org_alfresco_module_rm.jscript.app; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService; -import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.capability.impl.ViewRecordsCapability; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; 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.record.RecordService; +import org.alfresco.repo.cache.SimpleCache; +import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.policy.JavaBehaviour; +import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.dictionary.DictionaryService; @@ -35,6 +41,9 @@ import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.site.SiteInfo; +import org.alfresco.service.cmr.site.SiteService; +import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.util.PathUtil; import org.apache.commons.lang.ArrayUtils; @@ -46,8 +55,23 @@ import org.json.simple.JSONObject; * * @author Roy Wetherall */ -public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONConversionComponent +public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONConversionComponent + implements NodeServicePolicies.OnDeleteNodePolicy, + NodeServicePolicies.OnCreateNodePolicy { + /** JSON values */ + private static final String IS_RM_NODE = "isRmNode"; + private static final String RM_NODE = "rmNode"; + private static final String IS_RM_SITE_CREATED = "isRmSiteCreated"; + private static final String IS_RECORD_CONTRIBUTOR_GROUP_ENABLED = "isRecordContributorGroupEnabled"; + private static final String RECORD_CONTRIBUTOR_GROUP_NAME = "recordContributorGroupName"; + + /** true if record contributor group is enabled, false otherwise */ + private boolean isRecordContributorsGroupEnabled = false; + + /** record contributors group */ + private String recordContributorsGroupName = "RECORD_CONTRIBUTORS"; + /** Record service */ private RecordService recordService; @@ -60,12 +84,40 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC /** dictionary service */ private DictionaryService dictionaryService; + /** site service */ + private SiteService siteService; + /** Indicators */ private List indicators = new ArrayList(); /** Actions */ private List actions = new ArrayList(); + /** The policy component */ + private PolicyComponent policyComponent; + + /** JSON conversion component cache */ + private SimpleCache jsonConversionComponentCache; + + /** Constant for checking the cache */ + private static final String RM_SITE_EXISTS = "rmSiteExists"; + + /** + * @param enabled true if enabled, false otherwise + */ + public void setRecordContributorsGroupEnabled(boolean enabled) + { + isRecordContributorsGroupEnabled = enabled; + } + + /** + * @param recordContributorsGroupName record contributors group name + */ + public void setRecordContributorsGroupName(String recordContributorsGroupName) + { + this.recordContributorsGroupName = recordContributorsGroupName; + } + /** * @param recordService record service */ @@ -98,6 +150,14 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC this.dictionaryService = dictionaryService; } + /** + * @param siteService site service + */ + public void setSiteService(SiteService siteService) + { + this.siteService = siteService; + } + /** * @param indicator registered indicator */ @@ -114,6 +174,50 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC actions.add(action); } + /** + * @param policyComponent policy component + */ + public void setPolicyComponent(PolicyComponent policyComponent) + { + this.policyComponent = policyComponent; + } + + /** + * Gets the json conversion component cache + * + * @return The json conversion component cache + */ + protected SimpleCache getJsonConversionComponentCache() + { + return this.jsonConversionComponentCache; + } + + /** + * Sets the json conversion component cache + * + * @param jsonConversionComponentCache The json conversion component cache + */ + public void setJsonConversionComponentCache(SimpleCache jsonConversionComponentCache) + { + this.jsonConversionComponentCache = jsonConversionComponentCache; + } + + /** + * The initialise method + */ + public void init() + { + policyComponent.bindClassBehaviour( + QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"), + RecordsManagementModel.TYPE_RM_SITE, + new JavaBehaviour(this, "onDeleteNode")); + + policyComponent.bindClassBehaviour( + QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"), + RecordsManagementModel.TYPE_RM_SITE, + new JavaBehaviour(this, "onCreateNode")); + } + /** * @see org.alfresco.repo.jscript.app.JSONConversionComponent#setRootValues(org.alfresco.service.cmr.model.FileInfo, * org.json.simple.JSONObject, boolean) @@ -127,19 +231,25 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC // Set the base root values super.setRootValues(nodeInfo, rootJSONObject, useShortQNames); + // check the exisitance of the RM site + checkRmSiteExistence(rootJSONObject); + + // get the record contributor information + rootJSONObject.put(IS_RECORD_CONTRIBUTOR_GROUP_ENABLED, isRecordContributorsGroupEnabled); + rootJSONObject.put(RECORD_CONTRIBUTOR_GROUP_NAME, recordContributorsGroupName); + // Get the node reference for convenience NodeRef nodeRef = nodeInfo.getNodeRef(); - if (AccessStatus.ALLOWED.equals(capabilityService.getCapabilityAccessState(nodeRef, - RMPermissionModel.VIEW_RECORDS))) + if (AccessStatus.ALLOWED.equals(capabilityService.getCapabilityAccessState(nodeRef, ViewRecordsCapability.NAME))) { // Indicate whether the node is a RM object or not boolean isFilePlanComponent = filePlanService.isFilePlanComponent(nodeInfo.getNodeRef()); - rootJSONObject.put("isRmNode", isFilePlanComponent); + rootJSONObject.put(IS_RM_NODE, isFilePlanComponent); if (isFilePlanComponent) { - rootJSONObject.put("rmNode", setRmNodeValues(nodeRef, useShortQNames)); + rootJSONObject.put(RM_NODE, setRmNodeValues(nodeRef, useShortQNames)); // FIXME: Is this the right place to add the information? addInfo(nodeInfo, rootJSONObject); @@ -148,6 +258,34 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC } } + /** + * Checks for the existance of the RM site + * + * @param rootJSONObject the root JSON object + */ + @SuppressWarnings("unchecked") + private void checkRmSiteExistence(JSONObject rootJSONObject) + { + if (!getJsonConversionComponentCache().contains(RM_SITE_EXISTS)) + { + SiteInfo site = siteService.getSite(FilePlanService.DEFAULT_RM_SITE_ID); + if (site != null) + { + getJsonConversionComponentCache().put(RM_SITE_EXISTS, true); + rootJSONObject.put(IS_RM_SITE_CREATED, true); + } + else + { + getJsonConversionComponentCache().put(RM_SITE_EXISTS, false); + rootJSONObject.put(IS_RM_SITE_CREATED, false); + } + } + else + { + rootJSONObject.put(IS_RM_SITE_CREATED, getJsonConversionComponentCache().get(RM_SITE_EXISTS)); + } + } + /** * Helper method to add information about node * @@ -196,8 +334,9 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC if (originatingLocation != null) { + // add the originating location (if there is one) String pathSeparator = "/"; - String displayPath = PathUtil.getDisplayPath(nodeService.getPath(originatingLocation), true); + String displayPath = getDisplayPath(originatingLocation); String[] displayPathElements = displayPath.split(pathSeparator); Object[] subPath = ArrayUtils.subarray(displayPathElements, 5, displayPathElements.length); StringBuffer originatingLocationPath = new StringBuffer(); @@ -208,14 +347,33 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC rootJSONObject.put("originatingLocationPath", originatingLocationPath.toString()); } } + + /** + * Helper method to get the display path. + * + * @param nodeRef node reference + * @return String display path + */ + private String getDisplayPath(final NodeRef nodeRef) + { + return AuthenticationUtil.runAs(new RunAsWork() + { + public String doWork() throws Exception + { + return PathUtil.getDisplayPath(nodeService.getPath(nodeRef), true); + } + }, AuthenticationUtil.getAdminUserName()); + } /** - * @param nodeRef - * @param useShortQName - * @return + * Helper method to set the RM node values + * + * @param nodeRef node reference + * @param useShortQName indicates whether the short QName are used or not + * @return {@link JSONObject} JSON object containing values */ @SuppressWarnings("unchecked") - private JSONObject setRmNodeValues(NodeRef nodeRef, boolean useShortQName) + private JSONObject setRmNodeValues(final NodeRef nodeRef, final boolean useShortQName) { JSONObject rmNodeValues = new JSONObject(); @@ -225,20 +383,39 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC // Get the 'kind' of the file plan component FilePlanComponentKind kind = filePlanService.getFilePlanComponentKind(nodeRef); rmNodeValues.put("kind", kind.toString()); - - // File plan node reference - NodeRef filePlan = filePlanService.getFilePlan(nodeRef); - rmNodeValues.put("filePlan", filePlan.toString()); - - // Unfiled container node reference - NodeRef unfiledRecordContainer = filePlanService.getUnfiledContainer(filePlan); - if (unfiledRecordContainer != null) + + // set the primary parent node reference + ChildAssociationRef assoc = nodeService.getPrimaryParent(nodeRef); + if (assoc != null) { - rmNodeValues.put("unfiledRecordContainer", unfiledRecordContainer.toString()); - rmNodeValues.put("properties", propertiesToJSON(unfiledRecordContainer, nodeService.getProperties(unfiledRecordContainer), useShortQName)); - QName type = fileFolderService.getFileInfo(unfiledRecordContainer).getType(); - rmNodeValues.put("type", useShortQName ? type.toPrefixString(namespaceService) : type.toString()); + rmNodeValues.put("primaryParentNodeRef", assoc.getParentRef().toString()); } + + Map values = AuthenticationUtil.runAsSystem(new RunAsWork>() + { + public Map doWork() throws Exception + { + Map result = new HashMap(); + + // File plan node reference + NodeRef filePlan = filePlanService.getFilePlan(nodeRef); + result.put("filePlan", filePlan.toString()); + + // Unfiled container node reference + NodeRef unfiledRecordContainer = filePlanService.getUnfiledContainer(filePlan); + if (unfiledRecordContainer != null) + { + result.put("unfiledRecordContainer", unfiledRecordContainer.toString()); + result.put("properties", propertiesToJSON(unfiledRecordContainer, nodeService.getProperties(unfiledRecordContainer), useShortQName)); + QName type = fileFolderService.getFileInfo(unfiledRecordContainer).getType(); + result.put("type", useShortQName ? type.toPrefixString(namespaceService) : type.toString()); + } + + return result; + } + }); + + rmNodeValues.putAll(values); // Set the indicators array setIndicators(rmNodeValues, nodeRef); @@ -286,20 +463,20 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC rmNodeValues.put("actions", jsonActions); } } - + /** * @see org.alfresco.repo.jscript.app.JSONConversionComponent#permissionsToJSON(org.alfresco.service.cmr.repository.NodeRef) */ protected JSONObject permissionsToJSON(final NodeRef nodeRef) { - JSONObject permissionsJSON = null; + JSONObject permissionsJSON = null; if (!filePlanService.isFilePlanComponent(nodeRef)) { permissionsJSON = super.permissionsToJSON(nodeRef); } else { - permissionsJSON = new JSONObject(); + permissionsJSON = new JSONObject(); } return permissionsJSON; } @@ -381,4 +558,22 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC return result; } + + /** + * @see org.alfresco.repo.node.NodeServicePolicies.OnDeleteNodePolicy#onDeleteNode(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean) + */ + @Override + public void onDeleteNode(ChildAssociationRef childAssocRef, boolean isNodeArchived) + { + getJsonConversionComponentCache().put(RM_SITE_EXISTS, false); + } + + /** + * @see org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy#onCreateNode(org.alfresco.service.cmr.repository.ChildAssociationRef) + */ + @Override + public void onCreateNode(ChildAssociationRef childAssocRef) + { + getJsonConversionComponentCache().put(RM_SITE_EXISTS, true); + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/evaluator/MultiParentEvaluator.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/evaluator/MultiParentEvaluator.java index 5eb1211921..a3c3ca8d29 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/evaluator/MultiParentEvaluator.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/evaluator/MultiParentEvaluator.java @@ -32,27 +32,34 @@ import org.alfresco.service.namespace.RegexQNamePattern; * Determines whether a node has multiple parents within a file plan * * @author Roy Wetherall + * @since 2.0 */ public class MultiParentEvaluator extends BaseEvaluator { + /** + * @see org.alfresco.module.org_alfresco_module_rm.jscript.app.BaseEvaluator#evaluateImpl(org.alfresco.service.cmr.repository.NodeRef) + */ @Override protected boolean evaluateImpl(final NodeRef nodeRef) { return AuthenticationUtil.runAsSystem(new RunAsWork() { - @Override public Boolean doWork() { + + // get parent associations List parents = nodeService.getParentAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); int count = 0; for (ChildAssociationRef parent : parents) { + // count file plan component parents if (nodeService.hasAspect(parent.getParentRef(), ASPECT_FILE_PLAN_COMPONENT)) { count++; } } + // return true if more than one return (count > 1); } }); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java index 388f9d1de4..481afd29cd 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java @@ -262,7 +262,7 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel // @since 2.2 QName ASPECT_HELD_CHILDREN = QName.createQName(RM_URI, "heldChildren"); QName PROP_HELD_CHILDREN_COUNT = QName.createQName(RM_URI, "heldChildrenCount"); - + // Countable aspect QName ASPECT_COUNTABLE = QName.createQName(RM_URI, "countable"); QName PROP_COUNT = QName.createQName(RM_URI, "count"); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/DispositionLifecycleAspect.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/DispositionLifecycleAspect.java index b3e923051f..fce16e9a4b 100755 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/DispositionLifecycleAspect.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/DispositionLifecycleAspect.java @@ -77,7 +77,7 @@ public class DispositionLifecycleAspect extends BaseBehaviourBean @Behaviour ( kind = BehaviourKind.CLASS, - notificationFrequency = NotificationFrequency.FIRST_EVENT + notificationFrequency = NotificationFrequency.EVERY_EVENT ) public void onAddAspect(final NodeRef nodeRef, final QName aspect) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java index c68d2bcf93..38214b000d 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java @@ -48,6 +48,9 @@ import org.alfresco.service.namespace.QName; public class RecordsManagementContainerType extends BaseBehaviourBean implements NodeServicePolicies.OnCreateChildAssociationPolicy { + /** behaviour name */ + private static final String BEHAVIOUR_NAME = "onCreateContainerType"; + /** identifier service */ protected IdentifierService identifierService; @@ -80,6 +83,26 @@ public class RecordsManagementContainerType extends BaseBehaviourBean { this.recordFolderService = recordFolderService; } + + /** + * Disable the behaviours for this transaction + * + * @since 2.3 + */ + public void disable() + { + getBehaviour(BEHAVIOUR_NAME).disable(); + } + + /** + * Enable behaviours for this transaction + * + * @since 2.3 + */ + public void enable() + { + getBehaviour(BEHAVIOUR_NAME).enable(); + } /** * @see org.alfresco.module.org_alfresco_module_rm.model.BaseTypeBehaviour#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean) @@ -87,7 +110,8 @@ public class RecordsManagementContainerType extends BaseBehaviourBean @Behaviour ( kind = BehaviourKind.ASSOCIATION, - notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT, + name = BEHAVIOUR_NAME ) public void onCreateChildAssociation(final ChildAssociationRef childAssocRef, boolean isNewNode) { @@ -165,8 +189,9 @@ public class RecordsManagementContainerType extends BaseBehaviourBean } /** + * Set the identifier property * - * @param nodeRef + * @param nodeRef node reference */ protected void setIdenifierProperty(final NodeRef nodeRef) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v21/RMv21BehaviorScriptsPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v21/RMv21BehaviorScriptsPatch.java index dd6748d44f..a66a16aa5f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v21/RMv21BehaviorScriptsPatch.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v21/RMv21BehaviorScriptsPatch.java @@ -18,6 +18,8 @@ */ package org.alfresco.module.org_alfresco_module_rm.patch.v21; +import static org.apache.commons.logging.LogFactory.getLog; + import java.io.Serializable; import java.util.HashMap; import java.util.List; @@ -34,6 +36,7 @@ import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; +import org.apache.commons.logging.Log; import org.springframework.beans.factory.BeanNameAware; /** @@ -44,9 +47,11 @@ import org.springframework.beans.factory.BeanNameAware; * @author Craig Tan * @since 2.1 */ -@SuppressWarnings("deprecation") public class RMv21BehaviorScriptsPatch extends RMv21PatchComponent implements BeanNameAware { + /** Logger */ + private static final Log LOGGER = getLog(RMv21BehaviorScriptsPatch.class); + /** rm config folder root lookup */ protected static final NodeRef RM_CONFIG = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "rm_config_folder"); @@ -54,7 +59,7 @@ public class RMv21BehaviorScriptsPatch extends RMv21PatchComponent implements Be protected static final NodeRef OLD_BEHAVIOR_SCRIPTS_FOLDER = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "rm_scripts"); /** new behavior scripts folder root lookup */ - protected static NodeRef newBehaviorScriptsFolder = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "rm_behavior_scripts"); + private static NodeRef newBehaviorScriptsFolder = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "rm_behavior_scripts"); /** name of example script */ protected static final String IS_CLOSED_JS = "rma_isClosed.js"; @@ -123,6 +128,7 @@ public class RMv21BehaviorScriptsPatch extends RMv21PatchComponent implements Be // run the following code as System AuthenticationUtil.runAs(new RunAsWork() { + @SuppressWarnings("deprecation") public Object doWork() { RetryingTransactionCallback callback = new RetryingTransactionCallback() diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v23/RMv23EndRetentionCapabilityPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v23/RMv23EndRetentionCapabilityPatch.java new file mode 100644 index 0000000000..9fe8ee707b --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v23/RMv23EndRetentionCapabilityPatch.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.patch.v23; + +import org.alfresco.module.org_alfresco_module_rm.patch.common.CapabilityPatch; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * RM v2.3 patch to add new end retention capability. + * + * @author Alex Balan + * @since 2.3 + */ +public class RMv23EndRetentionCapabilityPatch extends CapabilityPatch +{ + /** + * @see org.alfresco.module.org_alfresco_module_rm.patch.common.CapabilityPatch#applyCapabilityPatch(org.alfresco.service.cmr.repository.NodeRef) + */ + protected void applyCapabilityPatch(NodeRef filePlan) + { + // add new capability + addCapability(filePlan, + "EndRetention", + FilePlanRoleService.ROLE_ADMIN, + FilePlanRoleService.ROLE_RECORDS_MANAGER); + + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v23/RMv23RecordContributorsGroupPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v23/RMv23RecordContributorsGroupPatch.java new file mode 100644 index 0000000000..ab9d387b53 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v23/RMv23RecordContributorsGroupPatch.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.patch.v23; + +import org.alfresco.module.org_alfresco_module_rm.bootstrap.RecordContributorsGroupBootstrapComponent; +import org.alfresco.module.org_alfresco_module_rm.patch.AbstractModulePatch; + +/** + * RM v2.3 patch that creates the record contributors group. + * + * @author Roy Wetherall + * @since 2.3 + */ +public class RMv23RecordContributorsGroupPatch extends AbstractModulePatch +{ + /** record contributors group bootstrap component */ + private RecordContributorsGroupBootstrapComponent recordContributorsGroupBootstrapComponent; + + /** + * @param recordContributorsGroupBootstrapComponent record contributors group bootstrap component + */ + public void setRecordContributorsGroupBootstrapComponent(RecordContributorsGroupBootstrapComponent recordContributorsGroupBootstrapComponent) + { + this.recordContributorsGroupBootstrapComponent = recordContributorsGroupBootstrapComponent; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.patch.AbstractModulePatch#applyInternal() + */ + @Override + public void applyInternal() + { + // create record contributors group + recordContributorsGroupBootstrapComponent.createRecordContributorsGroup(); + } + +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v23/RMv23VersionsEventPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v23/RMv23VersionsEventPatch.java new file mode 100644 index 0000000000..696183e5ac --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/v23/RMv23VersionsEventPatch.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.patch.v23; + +import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEventService; +import org.alfresco.module.org_alfresco_module_rm.patch.AbstractModulePatch; +import org.springframework.extensions.surf.util.I18NUtil; + +/** + * RM v2.3 patch that creates the versions event. + * + * @author Roy Wetherall + * @since 2.3 + */ +public class RMv23VersionsEventPatch extends AbstractModulePatch +{ + /** event details */ + private static final String EVENT_TYPE = "rmEventType.versioned"; + private static final String EVENT_NAME = "versioned"; + private static final String EVENT_I18N = "rmevent.versioned"; + + /** records management event service */ + private RecordsManagementEventService recordsManagementEventService; + + /** + * @param recordsManagementEventService records management event service + */ + public void setRecordsManagementEventService(RecordsManagementEventService recordsManagementEventService) + { + this.recordsManagementEventService = recordsManagementEventService; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.patch.AbstractModulePatch#applyInternal() + */ + @Override + public void applyInternal() + { + // add versions event + recordsManagementEventService.addEvent(EVENT_TYPE, EVENT_NAME, I18NUtil.getMessage(EVENT_I18N)); + } + +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/InplaceRecordServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/InplaceRecordServiceImpl.java index 6c4ee8e816..e90693e924 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/InplaceRecordServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/InplaceRecordServiceImpl.java @@ -19,6 +19,7 @@ package org.alfresco.module.org_alfresco_module_rm.record; import java.util.List; +import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; @@ -159,11 +160,18 @@ public class InplaceRecordServiceImpl extends ServiceBaseImpl implements Inplace { try { + // Get the extended readers/writers + Set extendedReaders = extendedSecurityService.getExtendedReaders(nodeRef); + Set extendedWriters = extendedSecurityService.getExtendedWriters(nodeRef); + // Move the record fileFolderService.moveFrom(nodeRef, source, targetNodeRef, null); // Update the originating location property nodeService.setProperty(nodeRef, PROP_RECORD_ORIGINATING_LOCATION, targetNodeRef); + + // Set the extended readers/writers + extendedSecurityService.addExtendedSecurity(nodeRef, extendedReaders, extendedWriters); } catch (FileExistsException | FileNotFoundException ex) { 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 fd284c3e30..9b33b71687 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 @@ -54,6 +54,8 @@ public interface RecordService /** * Disables the property editable check. + * + * @since 2.2 */ void disablePropertyEditableCheck(); @@ -61,6 +63,7 @@ public interface RecordService * Disables the property editable check for a given node in this transaction only. * * @param nodeRef node reference + * * @since 2.2 */ void disablePropertyEditableCheck(NodeRef nodeRef); @@ -164,6 +167,14 @@ public interface RecordService * @see #createRecord(NodeRef, NodeRef, boolean) */ void createRecord(NodeRef filePlan, NodeRef nodeRef); + + /** + * Creates a record from a copy of the node reference provided. + * + * @param filePlan file plan + * @param nodeRef node reference + */ + NodeRef createRecordFromCopy(NodeRef filePlan, NodeRef nodeRef); /** * Creates a new document in the unfiled records container if the given node reference is a file plan @@ -241,10 +252,20 @@ public interface RecordService void makeRecord(NodeRef nodeRef); /** - * Creates a link for the specified document in target + * Links a record to a record folder * - * @param nodeRef The document node reference for which a link will be created - * @param folder The folder in which the link will be created + * @param record the record to link + * @param recordFolder the record folder to link it to */ - void link(NodeRef nodeRef, NodeRef folder); + void link(NodeRef record, NodeRef recordFolder); + + /** + * Unlinks a record from a specified record folder. + * + * @param record the record to unlink + * @param recordFolder the record folder to unlink it from + * + * @since 2.3 + */ + void unlink(NodeRef record, NodeRef recordFolder); } 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 9a621f42ea..e0513e1b17 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 @@ -18,8 +18,13 @@ */ package org.alfresco.module.org_alfresco_module_rm.record; +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel.PROP_VERSIONED_NODEREF; +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel.PROP_VERSION_LABEL; +import static org.apache.commons.lang.StringUtils.isNotBlank; + import java.io.Serializable; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; @@ -44,14 +49,17 @@ import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementCustomModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.model.rma.type.RecordsManagementContainerType; import org.alfresco.module.org_alfresco_module_rm.model.security.ModelAccessDeniedException; import org.alfresco.module.org_alfresco_module_rm.notification.RecordsManagementNotificationHelper; import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService; import org.alfresco.module.org_alfresco_module_rm.report.ReportModel; import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.role.Role; import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService; import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel; +import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImpl; import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.ClassPolicyDelegate; @@ -70,7 +78,9 @@ import org.alfresco.service.cmr.dictionary.ClassDefinition; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.model.FileExistsException; import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.model.FileNotFoundException; +import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentReader; @@ -82,11 +92,15 @@ import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.version.Version; +import org.alfresco.service.cmr.version.VersionHistory; +import org.alfresco.service.cmr.version.VersionService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.EqualsHelper; import org.alfresco.util.ParameterCheck; +import org.alfresco.util.PropertyMap; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; @@ -107,7 +121,8 @@ public class RecordServiceImpl extends BaseBehaviourBean NodeServicePolicies.OnCreateChildAssociationPolicy, NodeServicePolicies.OnAddAspectPolicy, NodeServicePolicies.OnRemoveAspectPolicy, - NodeServicePolicies.OnUpdatePropertiesPolicy + NodeServicePolicies.OnUpdatePropertiesPolicy, + NodeServicePolicies.BeforeDeleteNodePolicy { /** Logger */ private static Log logger = LogFactory.getLog(RecordServiceImpl.class); @@ -117,6 +132,8 @@ public class RecordServiceImpl extends BaseBehaviourBean /** I18N */ private static final String MSG_NODE_HAS_ASPECT = "rm.service.node-has-aspect"; + private static final String FINAL_VERSION = "rm.service.final-version"; + private static final String FINAL_DESCRIPTION = "rm.service.final-version-description"; /** Always edit property array */ private static final QName[] ALWAYS_EDIT_PROPERTIES = new QName[] @@ -138,14 +155,14 @@ public class RecordServiceImpl extends BaseBehaviourBean }; /** record model URI's */ - public static final String[] RECORD_MODEL_URIS = new String[] - { - RM_URI, - RM_CUSTOM_URI, - ReportModel.RMR_URI, - RecordableVersionModel.RMV_URI, - DOD5015Model.DOD_URI - }; + public static final List RECORD_MODEL_URIS = Collections.unmodifiableList( + Arrays.asList( + RM_URI, + RM_CUSTOM_URI, + ReportModel.RMR_URI, + RecordableVersionModel.RMV_URI, + DOD5015Model.DOD_URI + )); /** non-record model URI's */ private static final String[] NON_RECORD_MODEL_URIS = new String[] @@ -198,6 +215,15 @@ public class RecordServiceImpl extends BaseBehaviourBean /** Permission service */ private PermissionService permissionService; + /** Version service */ + private VersionService versionService; + + /** Relationship service */ + private RelationshipService relationshipService; + + /** records management container type */ + private RecordsManagementContainerType recordsManagementContainerType; + /** list of available record meta-data aspects and the file plan types the are applicable to */ private Map> recordMetaDataAspects; @@ -319,6 +345,27 @@ public class RecordServiceImpl extends BaseBehaviourBean this.permissionService = permissionService; } + /** + * @param versionService version service + */ + public void setVersionService(VersionService versionService) + { + this.versionService = versionService; + } + + /** + * @param relationshipService relationship service + */ + public void setRelationshipService(RelationshipService relationshipService) + { + this.relationshipService = relationshipService; + } + + public void setRecordsManagementContainerType(RecordsManagementContainerType recordsManagementContainerType) + { + this.recordsManagementContainerType = recordsManagementContainerType; + } + /** * Init method */ @@ -694,15 +741,15 @@ public class RecordServiceImpl extends BaseBehaviourBean { return getRecordMetadataAspectsMap().containsKey(aspect); } - + /** * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isRecordMetadataProperty(org.alfresco.service.namespace.QName) */ @Override public boolean isRecordMetadataProperty(QName property) { - boolean result = false; - PropertyDefinition propertyDefinition = dictionaryService.getProperty(property); + boolean result = false; + PropertyDefinition propertyDefinition = dictionaryService.getProperty(property); if (propertyDefinition != null) { ClassDefinition classDefinition = propertyDefinition.getContainerClass(); @@ -714,7 +761,7 @@ public class RecordServiceImpl extends BaseBehaviourBean } return result; } - + /** * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#getRecordMetaDataAspects(org.alfresco.service.cmr.repository.NodeRef) */ @@ -813,6 +860,9 @@ public class RecordServiceImpl extends BaseBehaviourBean // get the documents primary parent assoc ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(nodeRef); + // get the latest version record, if there is one + NodeRef latestVersionRecord = getLatestVersionRecord(nodeRef); + behaviourFilter.disableBehaviour(); try { @@ -830,9 +880,21 @@ public class RecordServiceImpl extends BaseBehaviourBean aspectProperties.put(PROP_RECORD_ORIGINATING_USER_ID, owner); aspectProperties.put(PROP_RECORD_ORIGINATING_CREATION_DATE, new Date()); nodeService.addAspect(nodeRef, ASPECT_RECORD_ORIGINATING_DETAILS, aspectProperties); - + // make the document a record makeRecord(nodeRef); + + if (latestVersionRecord != null) + { + // indicate that this is the 'final' record version + PropertyMap versionRecordProps = new PropertyMap(2); + versionRecordProps.put(RecordableVersionModel.PROP_VERSION_LABEL, I18NUtil.getMessage(FINAL_VERSION)); + versionRecordProps.put(RecordableVersionModel.PROP_VERSION_DESCRIPTION, I18NUtil.getMessage(FINAL_DESCRIPTION)); + nodeService.addAspect(nodeRef, RecordableVersionModel.ASPECT_VERSION_RECORD, versionRecordProps); + + // link to previous version + relationshipService.addRelationship("versions", nodeRef, latestVersionRecord); + } if (isLinked) { @@ -866,6 +928,130 @@ public class RecordServiceImpl extends BaseBehaviourBean } }); } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecordFromCopy(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public NodeRef createRecordFromCopy(final NodeRef filePlan, final NodeRef nodeRef) + { + return authenticationUtil.runAsSystem(new RunAsWork() + { + public NodeRef doWork() throws Exception + { + // get the unfiled record folder + final NodeRef unfiledRecordFolder = filePlanService.getUnfiledContainer(filePlan); + + // get the documents readers + Long aclId = nodeService.getNodeAclId(nodeRef); + Set readers = extendedPermissionService.getReaders(aclId); + Set writers = extendedPermissionService.getWriters(aclId); + + // add the current owner to the list of extended writers + Set modifiedWrtiers = new HashSet(writers); + if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_OWNABLE)) + { + String owner = ownableService.getOwner(nodeRef); + if (owner != null && !owner.isEmpty() && !owner.equals(OwnableService.NO_OWNER)) + { + modifiedWrtiers.add(owner); + } + } + + // add the current user as extended writer + modifiedWrtiers.add(authenticationUtil.getFullyAuthenticatedUser()); + + // copy version state and create record + NodeRef record = null; + try + { + List originalAssocs = null; + if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_COPIEDFROM)) + { + // take a note of any copyFrom information already on the node + originalAssocs = nodeService.getTargetAssocs(nodeRef, ContentModel.ASSOC_ORIGINAL); + } + + recordsManagementContainerType.disable(); + try + { + // create a copy of the original state and add it to the unfiled record container + FileInfo recordInfo = fileFolderService.copy(nodeRef, unfiledRecordFolder, null); + record = recordInfo.getNodeRef(); + } + finally + { + recordsManagementContainerType.enable(); + } + + // make record + makeRecord(record); + + // remove added copy assocs + List recordAssocs = nodeService.getTargetAssocs(record, ContentModel.ASSOC_ORIGINAL); + for (AssociationRef recordAssoc : recordAssocs) + { + nodeService.removeAssociation( + recordAssoc.getSourceRef(), + recordAssoc.getTargetRef(), + ContentModel.ASSOC_ORIGINAL); + } + + // re-add origional assocs or remove aspect + if (originalAssocs == null) + { + nodeService.removeAspect(record, ContentModel.ASPECT_COPIEDFROM); + } + else + { + for (AssociationRef originalAssoc : originalAssocs) + { + nodeService.createAssociation(originalAssoc.getSourceRef(), originalAssoc.getTargetRef(), ContentModel.ASSOC_ORIGINAL); + } + } + } + catch (FileNotFoundException e) + { + throw new AlfrescoRuntimeException("Can't create recorded version, because copy fails.", e); + } + + // set extended security on record + extendedSecurityService.addExtendedSecurity(record, readers, writers); + + return record; + } + }); + } + + /** + * Helper to get the latest version record for a given document (ie non-record) + * + * @param nodeRef node reference + * @return NodeRef latest version record, null otherwise + */ + private NodeRef getLatestVersionRecord(NodeRef nodeRef) + { + NodeRef versionRecord = null; + + // wire record up to previous record + VersionHistory versionHistory = versionService.getVersionHistory(nodeRef); + if (versionHistory != null) + { + Collection previousVersions = versionHistory.getAllVersions(); + for (Version previousVersion : previousVersions) + { + // look for the associated record + final NodeRef previousRecord = (NodeRef)previousVersion.getVersionProperties().get(RecordableVersionServiceImpl.PROP_VERSION_RECORD); + if (previousRecord != null) + { + versionRecord = previousRecord; + break; + } + } + } + + return versionRecord; + } /** * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createNewRecord(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, org.alfresco.service.namespace.QName, java.util.Map, org.alfresco.service.cmr.repository.ContentReader) @@ -876,7 +1062,7 @@ public class RecordServiceImpl extends BaseBehaviourBean ParameterCheck.mandatory("nodeRef", parent); ParameterCheck.mandatory("name", name); - NodeRef record = null; + NodeRef result = null; NodeRef destination = parent; if (isFilePlan(parent)) @@ -903,7 +1089,7 @@ public class RecordServiceImpl extends BaseBehaviourBean try { // create the new record - record = fileFolderService.create(destination, name, type).getNodeRef(); + final NodeRef record = fileFolderService.create(destination, name, type).getNodeRef(); // set the properties if (properties != null) @@ -919,23 +1105,32 @@ public class RecordServiceImpl extends BaseBehaviourBean writer.setMimetype(reader.getMimetype()); writer.putContent(reader); } + + result = authenticationUtil.runAsSystem(new RunAsWork() + { + public NodeRef doWork() throws Exception + { + // Check if the "record" aspect has been applied already. + // In case of filing a report the created node will be made + // a record within the "onCreateChildAssociation" method if + // a destination for the report has been selected. + if (!nodeService.hasAspect(record, ASPECT_RECORD)) + { + // make record + makeRecord(record); + } + + return record; + } + + }); } finally { enablePropertyEditableCheck(); } - // Check if the "record" aspect has been applied already. - // In case of filing a report the created node will be made - // a record within the "onCreateChildAssociation" method if - // a destination for the report has been selected. - if (!nodeService.hasAspect(record, ASPECT_RECORD)) - { - // make record - makeRecord(record); - } - - return record; + return result; } /** @@ -989,7 +1184,7 @@ public class RecordServiceImpl extends BaseBehaviourBean props.put(PROP_IDENTIFIER, recordId); props.put(PROP_ORIGIONAL_NAME, name); nodeService.addAspect(document, RecordsManagementModel.ASPECT_RECORD, props); - + // remove versionable aspect(s) nodeService.removeAspect(document, RecordableVersionModel.ASPECT_VERSIONABLE); } @@ -1363,7 +1558,7 @@ public class RecordServiceImpl extends BaseBehaviourBean else { // check the URI's - result = ArrayUtils.contains(RECORD_MODEL_URIS, property.getNamespaceURI()); + result = RECORD_MODEL_URIS.contains(property.getNamespaceURI()); // check the custom model if (!result && !ArrayUtils.contains(NON_RECORD_MODEL_URIS, property.getNamespaceURI())) @@ -1466,14 +1661,91 @@ public class RecordServiceImpl extends BaseBehaviourBean * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#link(NodeRef, NodeRef) */ @Override - public void link(NodeRef nodeRef, NodeRef folder) + public void link(NodeRef record, NodeRef recordFolder) { - ParameterCheck.mandatory("nodeRef", nodeRef); - ParameterCheck.mandatory("folder", folder); + ParameterCheck.mandatory("record", record); + ParameterCheck.mandatory("recordFolder", recordFolder); - if(isRecord(nodeRef) && isRecordFolder(folder)) + // ensure we are linking a record to a record folder + if(isRecord(record) && isRecordFolder(recordFolder)) { - nodeService.addChild(folder, nodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, nodeService.getProperty(nodeRef, ContentModel.PROP_NAME).toString())); + // ensure that we are not linking a record to an exisiting location + List parents = nodeService.getParentAssocs(record); + for (ChildAssociationRef parent : parents) + { + if (parent.getParentRef().equals(recordFolder)) + { + // we can not link a record to the same location more than once + throw new AlfrescoRuntimeException("Can not link a record to the same record folder more than once"); + } + } + + // get the current name of the record + String name = nodeService.getProperty(record, ContentModel.PROP_NAME).toString(); + + // create a secondary link to the record folder + nodeService.addChild( + recordFolder, + record, + ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name)); + } + else + { + // can only link a record to a record folder + throw new AlfrescoRuntimeException("Can only link a record to a record folder."); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#unlink(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public void unlink(NodeRef record, NodeRef recordFolder) + { + ParameterCheck.mandatory("record", record); + ParameterCheck.mandatory("recordFolder", recordFolder); + + // ensure we are unlinking a record from a record folder + if(isRecord(record) && isRecordFolder(recordFolder)) + { + // check that we are not trying to unlink the primary parent + NodeRef primaryParent = nodeService.getPrimaryParent(record).getParentRef(); + if (primaryParent.equals(recordFolder)) + { + throw new AlfrescoRuntimeException("Can't unlink a record from it's owning record folder."); + } + + // remove the link + nodeService.removeChild(recordFolder, record); + } + else + { + // can only unlink a record from a record folder + throw new AlfrescoRuntimeException("Can only unlink a record from a record folder."); + } + } + + /** + * @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + type = "rma:record" + ) + public void beforeDeleteNode(NodeRef nodeRef) + { + NodeRef versionedNodeRef = (NodeRef) nodeService.getProperty(nodeRef, PROP_VERSIONED_NODEREF); + if (versionedNodeRef != null) + { + String versionLabel = (String) nodeService.getProperty(nodeRef, PROP_VERSION_LABEL); + if (isNotBlank(versionLabel)) + { + Version version = versionService.getVersionHistory(versionedNodeRef).getVersion(versionLabel); + versionService.deleteVersion(versionedNodeRef, version); + } } } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/recordableversion/RecordableVersionConfigService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/recordableversion/RecordableVersionConfigService.java new file mode 100644 index 0000000000..1d5b759e45 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/recordableversion/RecordableVersionConfigService.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.recordableversion; + +import java.util.List; + +import org.alfresco.module.org_alfresco_module_rm.script.slingshot.Version; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * Recordable version config service interface + * + * @author Tuna Aksoy + * @since 2.3 + */ +public interface RecordableVersionConfigService +{ + /** + * Gets the recordable versions + * + * @param nodeRef The node reference for which the recordable versions should be retrieved + * @return The list of recordable versions + */ + List getVersions(NodeRef nodeRef); + + /** + * Sets the recordable version for the given node + * + * @param nodeRef The node reference for which the recorable version should be set + * @param version The version to be set + */ + void setVersion(NodeRef nodeRef, String version); +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/recordableversion/RecordableVersionConfigServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/recordableversion/RecordableVersionConfigServiceImpl.java new file mode 100644 index 0000000000..a73e03a06c --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/recordableversion/RecordableVersionConfigServiceImpl.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.recordableversion; + +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy.NONE; +import static org.alfresco.util.ParameterCheck.mandatory; +import static org.alfresco.util.ParameterCheck.mandatoryString; +import static org.apache.commons.lang.StringUtils.isNotBlank; + +import java.util.ArrayList; +import java.util.List; + +import org.alfresco.module.org_alfresco_module_rm.script.slingshot.Version; +import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel; +import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; + +/** + * Recordable version config service + * + * @author Tuna Aksoy + * @since 2.3 + */ +public class RecordableVersionConfigServiceImpl implements RecordableVersionConfigService, RecordableVersionModel +{ + /** Node service */ + private NodeService nodeService; + + /** + * Gets the node service + * + * @return The node service + */ + protected NodeService getNodeService() + { + return this.nodeService; + } + + /** + * Sets the node service + * + * @param nodeService The node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.recordableversion.RecordableVersionConfigService#getVersions(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public List getVersions(NodeRef nodeRef) + { + mandatory("nodeRef", nodeRef); + + RecordableVersionPolicy[] recordableVersionPolicies = RecordableVersionPolicy.values(); + List versions = new ArrayList(recordableVersionPolicies.length); + + for (RecordableVersionPolicy recordableVersionPolicy : recordableVersionPolicies) + { + String policy = recordableVersionPolicy.toString(); + boolean selected = isVersionPolicySelected(recordableVersionPolicy, nodeRef); + versions.add(new Version(policy, selected)); + } + + return versions; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.recordableversion.RecordableVersionConfigService#setVersion(org.alfresco.service.cmr.repository.NodeRef, java.lang.String) + */ + @Override + public void setVersion(NodeRef nodeRef, String version) + { + mandatory("nodeRef", nodeRef); + mandatoryString("recordedVersion", version); + + RecordableVersionPolicy recordableVersionPolicy = RecordableVersionPolicy.valueOf(version); + getNodeService().setProperty(nodeRef, PROP_RECORDABLE_VERSION_POLICY, recordableVersionPolicy); + } + + /** + * Checks if the specified recordable version policy has been selected for the document + * + * @param recordableVersionPolicy The recordable version policy + * @param nodeRef Node reference of the document + * @return true if the specified recordable version policy has been selected for the document, false otherwise + */ + private boolean isVersionPolicySelected(RecordableVersionPolicy recordableVersionPolicy, NodeRef nodeRef) + { + boolean isVersionPolicySelected = false; + String policy = (String) getNodeService().getProperty(nodeRef, PROP_RECORDABLE_VERSION_POLICY); + if (isNotBlank(policy)) + { + if (RecordableVersionPolicy.valueOf(policy).equals(recordableVersionPolicy)) + { + isVersionPolicySelected = true; + } + } + else + { + if (recordableVersionPolicy.equals(NONE)) + { + isVersionPolicySelected = true; + } + } + return isVersionPolicySelected; + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java index ba7b3964a2..ece19b58b3 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/relationship/RelationshipServiceImpl.java @@ -487,8 +487,9 @@ public class RelationshipServiceImpl extends RecordsManagementAdminBase implemen // Get the association definition name final QName associationDefinitionName = associationDefinition.getName(); final NodeRef targetNode = target; + final NodeRef sourceNode = source; - invokeBeforeRemoveReference(source, targetNode, associationDefinitionName); + invokeBeforeRemoveReference(sourceNode, targetNode, associationDefinitionName); if (associationDefinition.isChild()) { @@ -497,7 +498,7 @@ public class RelationshipServiceImpl extends RecordsManagementAdminBase implemen @Override public Void doWork() { - List children = getNodeService().getChildAssocs(targetNode); + List children = getNodeService().getChildAssocs(sourceNode); for (ChildAssociationRef chRef : children) { if (associationDefinitionName.equals(chRef.getTypeQName()) && chRef.getChildRef().equals(targetNode)) @@ -557,17 +558,9 @@ public class RelationshipServiceImpl extends RecordsManagementAdminBase implemen { type = RelationshipType.PARENTCHILD; } - else if (associationDefinition instanceof AssociationDefinition) - { - type = RelationshipType.BIDIRECTIONAL; - } else { - StringBuilder sb = new StringBuilder(); - sb.append("Unsupported association definition: '") - .append(associationDefinition.getName().getLocalName()) - .append("'."); - throw new AlfrescoRuntimeException(sb.toString()); + type = RelationshipType.BIDIRECTIONAL; } return type; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java index 89193d0def..b9c65bcf43 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java @@ -68,7 +68,7 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService, /** Location of bootstrap role JSON */ private static final String BOOTSTRAP_ROLE_JSON_LOCATION = "alfresco/module/org_alfresco_module_rm/security/rm-default-roles-bootstrap.json"; - + /** JSON names */ private static final String JSON_NAME = "name"; private static final String JSON_DISPLAY_LABEL = "displayLabel"; @@ -242,7 +242,7 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService, /** * Bootstraps the default roles - * + * * @param filePlan file plan * @param systemContainers system containers */ @@ -327,7 +327,7 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService, // Add any additional admin permissions if (isAdmin) - { + { // Admin has filing permissionService.setPermission(filePlan, role.getRoleGroupName(), RMPermissionModel.FILING, true); if (systemContainers != null) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/BootstrapTestDataGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/BootstrapTestDataGet.java index ed9c05763a..9524c4bbdc 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/BootstrapTestDataGet.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/BootstrapTestDataGet.java @@ -276,7 +276,7 @@ public class BootstrapTestDataGet extends DeclarativeWebScript } // Make sure all the containers do not inherit permissions - ResultSet rs = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, "TYPE:\"rma:recordsManagementContainer\""); + ResultSet rs = searchService.query(SPACES_STORE, SearchService.LANGUAGE_FTS_ALFRESCO, "TYPE:\"rma:recordsManagementContainer\""); try { logger.info("Bootstraping " + rs.length() + " record containers ..."); @@ -299,7 +299,7 @@ public class BootstrapTestDataGet extends DeclarativeWebScript } // fix up the test dataset to fire initial events for disposition schedules - rs = searchService.query(SPACES_STORE, SearchService.LANGUAGE_LUCENE, "TYPE:\"rma:recordFolder\""); + rs = searchService.query(SPACES_STORE, SearchService.LANGUAGE_FTS_ALFRESCO, "TYPE:\"rma:recordFolder\""); try { logger.info("Bootstraping " + rs.length() + " record folders ..."); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/DataSetPost.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/DataSetPost.java index 9a3df3bfda..26ac093d52 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/DataSetPost.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/DataSetPost.java @@ -9,7 +9,6 @@ import org.alfresco.module.org_alfresco_module_rm.model.rma.type.RmSiteType; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.site.SiteService; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.extensions.webscripts.Cache; @@ -22,7 +21,7 @@ public class DataSetPost extends DeclarativeWebScript implements RecordsManageme { /** Constant for the site name parameter */ private static final String ARG_SITE_NAME = "site"; - + /** Constant for the data set id parameter */ private static final String ARG_DATA_SET_ID = "dataSetId"; @@ -37,7 +36,7 @@ public class DataSetPost extends DeclarativeWebScript implements RecordsManageme /** * Set site service - * + * * @param siteService the site service */ public void setSiteService(SiteService siteService) @@ -47,7 +46,7 @@ public class DataSetPost extends DeclarativeWebScript implements RecordsManageme /** * Data set service - * + * * @param dataSetService the data set service */ public void setDataSetService(DataSetService dataSetService) @@ -77,21 +76,21 @@ public class DataSetPost extends DeclarativeWebScript implements RecordsManageme throw new WebScriptException(Status.STATUS_NOT_FOUND, "A data set with the id '" + dataSetId + "'" + " does not exist."); } - + // Resolve RM site String siteName = req.getParameter(ARG_SITE_NAME); if (StringUtils.isBlank(siteName)) { siteName = RmSiteType.DEFAULT_SITE_NAME; } - + // Check the site if it exists if (siteService.getSite(siteName) == null) { throw new WebScriptException(Status.STATUS_BAD_REQUEST, "A Records Management site with the name '" + siteName + "' does not exist."); } - + // Resolve documentLibrary (filePlan) container NodeRef filePlan = siteService.getContainer(siteName, RmSiteType.COMPONENT_DOCUMENT_LIBRARY); if (filePlan == null) @@ -99,7 +98,7 @@ public class DataSetPost extends DeclarativeWebScript implements RecordsManageme filePlan = siteService.createContainer(siteName, RmSiteType.COMPONENT_DOCUMENT_LIBRARY, TYPE_FILE_PLAN, null); } - + // Load data set in to the file plan dataSetService.loadDataSet(filePlan, dataSetId); @@ -110,7 +109,7 @@ public class DataSetPost extends DeclarativeWebScript implements RecordsManageme { model.put("success", false); model.put("message", ex.getMessage()); - logger.error(ExceptionUtils.getFullStackTrace(ex)); + logger.error("Error while importing data set: " + ex); } return model; diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/RelationshipDelete.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/RelationshipDelete.java new file mode 100644 index 0000000000..93237056f6 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/RelationshipDelete.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.script; + +import static org.alfresco.util.WebScriptUtils.getRequestParameterValue; +import static org.alfresco.util.WebScriptUtils.getTemplateVars; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; + +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Implementation for Java backed webscript to delete a relationship from a node. + * + * @author Tuna Aksoy + * @since 2.3 + */ +public class RelationshipDelete extends AbstractRmWebScript +{ + /** Constants */ + private static final String STORE_TYPE = "target_store_type"; + private static final String STORE_ID = "target_store_id"; + private static final String ID = "target_id"; + private static final String UNIQUE_NAME = "uniqueName"; + + /** Relationship service */ + private RelationshipService relationshipService; + + /** + * Gets the relationship service + * + * @return The relationship service + */ + protected RelationshipService getRelationshipService() + { + return this.relationshipService; + } + + /** + * Sets the relationship service + * + * @param relationshipService The relationship service + */ + public void setRelationshipService(RelationshipService relationshipService) + { + this.relationshipService = relationshipService; + } + + /** + * @see org.springframework.extensions.webscripts.DeclarativeWebScript#executeImpl(org.springframework.extensions.webscripts.WebScriptRequest, + * org.springframework.extensions.webscripts.Status, + * org.springframework.extensions.webscripts.Cache) + */ + @Override + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + { + String uniqueName = getRequestParameterValue(req, UNIQUE_NAME); + NodeRef source = parseRequestForNodeRef(req); + NodeRef target = parseRequestForTargetNodeRef(req); + + getRelationshipService().removeRelationship(uniqueName, source, target); + getRelationshipService().removeRelationship(uniqueName, target, source); + + Map model = new HashMap(1); + model.put(SUCCESS, true); + return model; + } + + /** + * Gets the node reference of target + * + * @param req The webscript request + * @return The node reference of the target + */ + private NodeRef parseRequestForTargetNodeRef(WebScriptRequest req) + { + Map templateVars = getTemplateVars(req); + String storeType = templateVars.get(STORE_TYPE); + String storeId = templateVars.get(STORE_ID); + String nodeId = templateVars.get(ID); + + NodeRef nodeRef = new NodeRef(storeType, storeId, nodeId); + + if (!getNodeService().exists(nodeRef)) + { + throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find node: '" + + nodeRef.toString() + "'."); + } + + return nodeRef; + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/RelationshipLabelsGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/RelationshipLabelsGet.java new file mode 100644 index 0000000000..3f52761471 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/RelationshipLabelsGet.java @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.script; + +import static org.alfresco.util.ParameterCheck.mandatoryString; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDefinition; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDisplayName; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipType; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Implementation for Java backed webscript to get the relationship labels. + * + * @author Tuna Aksoy + * @since 2.3 + */ +public class RelationshipLabelsGet extends AbstractRmWebScript +{ + /** Constants */ + private static final String RELATIONSHIP_LABELS = "relationshipLabels"; + + /** Relationship service */ + private RelationshipService relationshipService; + + /** + * Gets the relationship service + * + * @return The relationship service + */ + protected RelationshipService getRelationshipService() + { + return this.relationshipService; + } + + /** + * Sets the relationship service + * + * @param relationshipService The relationship service + */ + public void setRelationshipService(RelationshipService relationshipService) + { + this.relationshipService = relationshipService; + } + + /** + * @see org.springframework.extensions.webscripts.DeclarativeWebScript#executeImpl(org.springframework.extensions.webscripts.WebScriptRequest, + * org.springframework.extensions.webscripts.Status, + * org.springframework.extensions.webscripts.Cache) + */ + @Override + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + { + Map model = new HashMap(1); + model.put(RELATIONSHIP_LABELS, getRelationshipsLabels()); + return model; + } + + /** + * Gets the list of available relationship labels + * + * @return The list of available relationship labels + */ + private List getRelationshipsLabels() + { + List relationshipLabels = new ArrayList(); + + Set relationshipDefinitions = getRelationshipService().getRelationshipDefinitions(); + for (RelationshipDefinition relationshipDefinition : relationshipDefinitions) + { + RelationshipType type = relationshipDefinition.getType(); + String uniqueName = relationshipDefinition.getUniqueName(); + RelationshipDisplayName displayName = relationshipDefinition.getDisplayName(); + String sourceText = displayName.getSourceText(); + String targetText = displayName.getTargetText(); + + if (RelationshipType.PARENTCHILD.equals(type)) + { + relationshipLabels.add(new RelationshipLabel(sourceText, uniqueName)); + relationshipLabels.add(new RelationshipLabel(targetText, uniqueName)); + } + else if (RelationshipType.BIDIRECTIONAL.equals(type)) + { + if (!sourceText.equals(targetText)) + { + throw new WebScriptException( + Status.STATUS_BAD_REQUEST, + "The source '" + + sourceText + + "' and target text '" + + targetText + + "' must be the same for a bidirectional relationship."); + } + relationshipLabels.add(new RelationshipLabel(sourceText, uniqueName)); + } + else + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Unknown relationship type '" + type + "'."); + } + } + + return sortRelationshipLabelsByName(relationshipLabels); + } + + /** + * Helper method to sort the relationship labels by their names + * + * @param relationshipLabels Relationship labels to sort + * @return Sorted list of relationship labels + */ + private List sortRelationshipLabelsByName(List relationshipLabels) + { + Collections.sort(relationshipLabels, new Comparator() + { + @Override + public int compare(RelationshipLabel r1, RelationshipLabel r2) + { + return r1.getLabel().toLowerCase().compareTo(r2.getLabel().toLowerCase()); + } + }); + return relationshipLabels; + } + + /** + * Relationship label helper class + */ + public class RelationshipLabel + { + /** Label of the relationship */ + private String label; + + /** Unique name of the relationship */ + private String uniqueName; + + /** + * Constructor + * + * @param label Label of the relationship + * @param uniqueName Unique name of the relationship + */ + public RelationshipLabel(String label, String uniqueName) + { + mandatoryString("label", label); + mandatoryString("uniqueName", uniqueName); + + setLabel(label); + setUniqueName(uniqueName); + } + + /** + * Gets the label of the relationship + * + * @return The label of the relationship + */ + public String getLabel() + { + return this.label; + } + + /** + * Sets the label of the relationship + * + * @param label The label of the relationship + */ + private void setLabel(String label) + { + this.label = label; + } + + /** + * Gets the unique name of the relationship + * + * @return The unique name of the relationship + */ + public String getUniqueName() + { + return this.uniqueName; + } + + /** + * Sets the unique name of the relationship + * + * @param uniqueName The unique name of the relationship + */ + private void setUniqueName(String uniqueName) + { + this.uniqueName = uniqueName; + } + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/RelationshipsGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/RelationshipsGet.java new file mode 100644 index 0000000000..630c9f0ddf --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/RelationshipsGet.java @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.script; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.alfresco.module.org_alfresco_module_rm.jscript.app.JSONConversionComponent; +import org.alfresco.module.org_alfresco_module_rm.relationship.Relationship; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDefinition; +import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.util.WebScriptUtils; +import org.json.JSONObject; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Implementation for Java backed webscript to get the relationships for a node. + * + * @author Tuna Aksoy + * @since 2.3 + */ +public class RelationshipsGet extends AbstractRmWebScript +{ + /** Constants */ + private static final String RELATIONSHIPS = "relationships"; + private static final String RELATIONSHIP_LABEL = "relationshipLabel"; + private static final String RELATIONSHIP_UNIQUE_NAME = "relationshipUniqueName"; + + /** The relationship end point */ + private enum RelationshipEndPoint + { + SOURCE, TARGET + }; + + /** Relationship service */ + private RelationshipService relationshipService; + + /** JSON conversion component */ + private JSONConversionComponent jsonConversionComponent; + + /** + * Gets the relationship service + * + * @return The relationship service + */ + protected RelationshipService getRelationshipService() + { + return this.relationshipService; + } + + /** + * Gets the JSON conversion component + * + * @return The JSON conversion component + */ + protected JSONConversionComponent getJsonConversionComponent() + { + return this.jsonConversionComponent; + } + + /** + * Sets the relationship service + * + * @param relationshipService The relationship service + */ + public void setRelationshipService(RelationshipService relationshipService) + { + this.relationshipService = relationshipService; + } + + /** + * Sets the JSON conversion component + * + * @param jsonConversionComponent The JSON conversion component + */ + public void setJsonConversionComponent(JSONConversionComponent jsonConversionComponent) + { + this.jsonConversionComponent = jsonConversionComponent; + } + + /** + * @see org.springframework.extensions.webscripts.DeclarativeWebScript#executeImpl(org.springframework.extensions.webscripts.WebScriptRequest, + * org.springframework.extensions.webscripts.Status, + * org.springframework.extensions.webscripts.Cache) + */ + @Override + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + { + Map model = new HashMap(1); + NodeRef nodeRef = parseRequestForNodeRef(req); + model.put(RELATIONSHIPS, getRelationships(nodeRef)); + return model; + } + + /** + * Gets the relationships of a node + * + * @param nodeRef The node reference + * + * @return The list of relationships of a node + */ + private List getRelationships(NodeRef nodeRef) + { + List relationships = new ArrayList(); + + Set relationshipsFrom = getRelationshipService().getRelationshipsFrom(nodeRef); + relationships.addAll(buildRelationshipData(relationshipsFrom, RelationshipEndPoint.TARGET)); + + Set relationshipsTo = getRelationshipService().getRelationshipsTo(nodeRef); + relationships.addAll(buildRelationshipData(relationshipsTo, RelationshipEndPoint.SOURCE)); + + return relationships; + } + + /** + * Creates the relationship data + * + * @param relationships The {@link Set} of relationships + * @param relationshipEndPoint The end point of the relationship, which is either {@link RelationshipEndpoint#SOURCE} or {@link RelationshipEndpoint#TARGET} + * @return The relationship data as {@link List} + */ + private List buildRelationshipData(Set relationships, RelationshipEndPoint relationshipEndPoint) + { + List result = new ArrayList(); + + for (Relationship relationship : relationships) + { + String uniqueName = relationship.getUniqueName(); + RelationshipDefinition relationshipDefinition = getRelationshipService().getRelationshipDefinition(uniqueName); + if (relationshipDefinition != null) + { + NodeRef node; + String label; + + if (RelationshipEndPoint.SOURCE.equals(relationshipEndPoint)) + { + node = relationship.getSource(); + label = relationshipDefinition.getDisplayName().getSourceText(); + } + else if (RelationshipEndPoint.TARGET.equals(relationshipEndPoint)) + { + node = relationship.getTarget(); + label = relationshipDefinition.getDisplayName().getTargetText(); + } + else + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Unknown relationship end point type '" + relationshipEndPoint + "'."); + } + + String nodeDetails = getJsonConversionComponent().toJSON(node, true); + JSONObject jsonObject = WebScriptUtils.createJSONObject(nodeDetails); + WebScriptUtils.putValuetoJSONObject(jsonObject, RELATIONSHIP_LABEL, label); + WebScriptUtils.putValuetoJSONObject(jsonObject, RELATIONSHIP_UNIQUE_NAME, relationshipDefinition.getUniqueName()); + + result.add(jsonObject.toString()); + } + } + + return result; + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RMSearchGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RMSearchGet.java index a190e8f40a..3313032e8a 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RMSearchGet.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RMSearchGet.java @@ -33,10 +33,7 @@ import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearch import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService; import org.alfresco.module.org_alfresco_module_rm.search.SavedSearchDetailsCompatibility; import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.PermissionService; @@ -44,6 +41,7 @@ import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; +import org.alfresco.util.Pair; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.springframework.extensions.webscripts.Cache; @@ -86,9 +84,6 @@ public class RMSearchGet extends DeclarativeWebScript /** Person service */ protected PersonService personService; - /** Content service */ - protected ContentService contentService; - /** Person data cache */ private Map personDataCache = null; @@ -148,14 +143,6 @@ public class RMSearchGet extends DeclarativeWebScript this.personService = personService; } - /** - * @param contentService content service - */ - public void setContentService(ContentService contentService) - { - this.contentService = contentService; - } - /* * @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.Status, org.alfresco.web.scripts.Cache) */ @@ -199,20 +186,20 @@ public class RMSearchGet extends DeclarativeWebScript } // Execute search - List results = recordsManagementSearchService.search(siteId, query, searchParameters); + List> results = recordsManagementSearchService.search(siteId, query, searchParameters); // Reset person data cache personDataCache = new HashMap(57); // Process the result items List items = new ArrayList(results.size()); - for (NodeRef nodeRef : results) + for (Pair pair : results) { // FIXME: See RM-478 // TC 3-3 Create User Groups try { - Item item = new Item(nodeRef); + Item item = new Item(pair.getFirst(), pair.getSecond()); items.add(item); } catch(Exception e) {} @@ -245,7 +232,7 @@ public class RMSearchGet extends DeclarativeWebScript private Map nodeProperties; private Map properties; - public Item(NodeRef nodeRef) + public Item(NodeRef parent, NodeRef nodeRef) { // Set node ref this.nodeRef = nodeRef; @@ -265,12 +252,12 @@ public class RMSearchGet extends DeclarativeWebScript } // Get parent node reference - NodeRef parent = null; - ChildAssociationRef assoc = nodeService.getPrimaryParent(nodeRef); - if (assoc != null) - { - parent = assoc.getParentRef(); - } +// NodeRef parent = null; +// ChildAssociationRef assoc = nodeService.getPrimaryParent(nodeRef); +// if (assoc != null) +// { +// parent = assoc.getParentRef(); +// } if (isContainer) { @@ -334,16 +321,6 @@ public class RMSearchGet extends DeclarativeWebScript if (!NamespaceService.SYSTEM_MODEL_1_0_URI.equals(qName.getNamespaceURI())) { String prefixName = qName.getPrefixString().replace(":", "_"); - Serializable value = entry.getValue(); - if (value instanceof NodeRef) - { - value = value.toString(); - } - else if (value instanceof ContentData) - { - ContentReader contentReader = contentService.getReader(nodeRef, qName); - value = contentReader.getContentString(); - } properties.put(prefixName, entry.getValue()); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RecordedVersionConfigGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RecordedVersionConfigGet.java index fbb37d6f46..d3b8eb3ee0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RecordedVersionConfigGet.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RecordedVersionConfigGet.java @@ -18,16 +18,13 @@ */ package org.alfresco.module.org_alfresco_module_rm.script.slingshot; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.alfresco.module.org_alfresco_module_rm.recordableversion.RecordableVersionConfigService; import org.alfresco.module.org_alfresco_module_rm.script.AbstractRmWebScript; -import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel; -import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy; import org.alfresco.service.cmr.repository.NodeRef; -import org.apache.commons.lang.StringUtils; import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptRequest; @@ -38,68 +35,41 @@ import org.springframework.extensions.webscripts.WebScriptRequest; * @author Tuna Aksoy * @since 2.3 */ -public class RecordedVersionConfigGet extends AbstractRmWebScript implements RecordableVersionModel +public class RecordedVersionConfigGet extends AbstractRmWebScript { + /** Recordable version config service */ + private RecordableVersionConfigService recordableVersionConfigService; + + /** + * Gets the recordable version config service + * + * @return The recordable version config service + */ + protected RecordableVersionConfigService getRecordableVersionConfigService() + { + return this.recordableVersionConfigService; + } + + /** + * Sets the recordable version config service + * + * @param recordableVersionConfigService The recordable version config service + */ + public void setRecordableVersionConfigService(RecordableVersionConfigService recordableVersionConfigService) + { + this.recordableVersionConfigService = recordableVersionConfigService; + } + /** * @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.Status, org.alfresco.web.scripts.Cache) */ @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { - RecordableVersionPolicy[] recordableVersionPolicies = RecordableVersionPolicy.values(); - List> recordableVersions = new ArrayList>(recordableVersionPolicies.length); - NodeRef documentNodeRef = parseRequestForNodeRef(req); - - for (RecordableVersionPolicy recordableVersionPolicy : recordableVersionPolicies) - { - recordableVersions.add(buildRecordableVersionData(recordableVersionPolicy, documentNodeRef)); - } - Map model = new HashMap(1); + NodeRef nodeRef = parseRequestForNodeRef(req); + List recordableVersions = getRecordableVersionConfigService().getVersions(nodeRef); model.put("recordableVersions", recordableVersions); return model; } - - /** - * Builds the recordable version data - * - * @param recordableVersionPolicy The recordable version policy - * @param nodeRef Node reference of the document - * @return A map containing the information about recordable version policy and if this policy is selected for the document - */ - private Map buildRecordableVersionData(RecordableVersionPolicy recordableVersionPolicy, NodeRef nodeRef) - { - Map recordableVersionData = new HashMap(2); - recordableVersionData.put("policy", recordableVersionPolicy.toString()); - recordableVersionData.put("selected", isVersionPolicySelected(recordableVersionPolicy, nodeRef)); - return recordableVersionData; - } - - /** - * Checks if the specified recordable version policy has been selected for the document - * - * @param recordableVersionPolicy The recordable version policy - * @param nodeRef Node reference of the document - * @return true if the specified recordable version policy has been selected for the document, false otherwise - */ - private boolean isVersionPolicySelected(RecordableVersionPolicy recordableVersionPolicy, NodeRef nodeRef) - { - boolean isVersionPolicySelected = false; - String policy = (String) getNodeService().getProperty(nodeRef, PROP_RECORDABLE_VERSION_POLICY); - if (StringUtils.isNotBlank(policy)) - { - if (RecordableVersionPolicy.valueOf(policy).equals(recordableVersionPolicy)) - { - isVersionPolicySelected = true; - } - } - else - { - if (recordableVersionPolicy.equals(RecordableVersionPolicy.NONE)) - { - isVersionPolicySelected = true; - } - } - return isVersionPolicySelected; - } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RecordedVersionConfigPost.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RecordedVersionConfigPost.java index 2cec963e2f..2d6a24a6cb 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RecordedVersionConfigPost.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RecordedVersionConfigPost.java @@ -24,9 +24,8 @@ import static org.alfresco.util.WebScriptUtils.getStringValueFromJSONObject; import java.util.HashMap; import java.util.Map; +import org.alfresco.module.org_alfresco_module_rm.recordableversion.RecordableVersionConfigService; import org.alfresco.module.org_alfresco_module_rm.script.AbstractRmWebScript; -import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel; -import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy; import org.alfresco.service.cmr.repository.NodeRef; import org.json.JSONObject; import org.springframework.extensions.webscripts.Cache; @@ -39,11 +38,34 @@ import org.springframework.extensions.webscripts.WebScriptRequest; * @author Tuna Aksoy * @since 2.3 */ -public class RecordedVersionConfigPost extends AbstractRmWebScript implements RecordableVersionModel +public class RecordedVersionConfigPost extends AbstractRmWebScript { - // Constant for recorded version parameter + /** Constant for recorded version parameter */ public static final String RECORDED_VERSION = "recordedVersion"; + /** Recordable version config service */ + private RecordableVersionConfigService recordableVersionConfigService; + + /** + * Gets the recordable version config service + * + * @return The recordable version config service + */ + protected RecordableVersionConfigService getRecordableVersionConfigService() + { + return this.recordableVersionConfigService; + } + + /** + * Sets the recordable version config service + * + * @param recordableVersionConfigService The recordable version config service + */ + public void setRecordableVersionConfigService(RecordableVersionConfigService recordableVersionConfigService) + { + this.recordableVersionConfigService = recordableVersionConfigService; + } + /** * @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.Status, org.alfresco.web.scripts.Cache) */ @@ -51,8 +73,8 @@ public class RecordedVersionConfigPost extends AbstractRmWebScript implements Re protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { NodeRef nodeRef = parseRequestForNodeRef(req); - RecordableVersionPolicy recordableVersionPolicy = getRecordableVersionPolicy(req); - getNodeService().setProperty(nodeRef, PROP_RECORDABLE_VERSION_POLICY, recordableVersionPolicy); + String policy = getRecordableVersionPolicy(req); + getRecordableVersionConfigService().setVersion(nodeRef, policy); return new HashMap(1); } @@ -62,10 +84,9 @@ public class RecordedVersionConfigPost extends AbstractRmWebScript implements Re * @param The webscript request * @return The recordable version policy */ - private RecordableVersionPolicy getRecordableVersionPolicy(WebScriptRequest req) + private String getRecordableVersionPolicy(WebScriptRequest req) { JSONObject requestContent = getRequestContentAsJsonObject(req); - String recordedVersion = getStringValueFromJSONObject(requestContent, RECORDED_VERSION); - return RecordableVersionPolicy.valueOf(recordedVersion); + return getStringValueFromJSONObject(requestContent, RECORDED_VERSION); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/Version.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/Version.java new file mode 100644 index 0000000000..0e6f430132 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/Version.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.script.slingshot; + +import static org.alfresco.util.ParameterCheck.mandatory; +import static org.alfresco.util.ParameterCheck.mandatoryString; + +/** + * Recordable version class + * + * @author Tuna Aksoy + * @since 2.3 + */ +public class Version +{ + /** The version policy */ + private String policy; + + /** Is the version selected */ + private boolean selected; + + /** + * Constructor + * + * @param policy The version policy + * @param selected Is the version selected + */ + public Version(String policy, boolean selected) + { + mandatoryString("policy", policy); + mandatory("selected", selected); + + setPolicy(policy); + setSelected(selected); + } + + /** + * Gets the version policy + * + * @return The version policy + */ + public String getPolicy() + { + return this.policy; + } + + /** + * Sets the version policy + * + * @param policy The version policy + */ + private void setPolicy(String policy) + { + this.policy = policy; + } + + /** + * Is the version selected + * + * @return true if the version is selected, false otherwise + */ + public boolean isSelected() + { + return this.selected; + } + + /** + * Sets the version as selected + * + * @param selected true if the version should be selected, false otherwise + */ + private void setSelected(boolean selected) + { + this.selected = selected; + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchService.java index 3257ffdf76..22c3c7cc8f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchService.java @@ -21,6 +21,7 @@ package org.alfresco.module.org_alfresco_module_rm.search; import java.util.List; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.util.Pair; /** * Records management search service. @@ -33,10 +34,10 @@ public interface RecordsManagementSearchService * Execute a records management search * @param siteId the id of the rm site to query * @param query search query string - * @param searchParameters search parameters - * @return {@link List}<{@link NodeRef}> search results + * @param searchParameters search parameters + * @return {@link List}<{@link Pair}<{@link NodeRef}, {@link NodeRef}> search results as pairs for parent and child nodes */ - List search(String siteId, String query, RecordsManagementSearchParameters searchParameters); + List> search(String siteId, String query, RecordsManagementSearchParameters searchParameters); /** * Get all the searches saved on the given records management site. diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchServiceImpl.java index e0962ae8a0..5eed77b551 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchServiceImpl.java @@ -30,6 +30,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; +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; @@ -41,6 +42,7 @@ import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.util.ISO9075; +import org.alfresco.util.Pair; import org.alfresco.util.ParameterCheck; import org.json.JSONArray; import org.json.JSONException; @@ -173,7 +175,7 @@ public class RecordsManagementSearchServiceImpl implements RecordsManagementSear * @see org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService#search(java.lang.String, java.lang.String, org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchParameters) */ @Override - public List search(String siteId, String query, RecordsManagementSearchParameters rmSearchParameters) + public List> search(String siteId, String query, RecordsManagementSearchParameters rmSearchParameters) { // build the full RM query StringBuilder fullQuery = new StringBuilder(1024); @@ -206,9 +208,16 @@ public class RecordsManagementSearchServiceImpl implements RecordsManagementSear // execute query ResultSet resultSet = searchService.query(searchParameters); + + // process results + List> result = new ArrayList>(resultSet.length()); + for (ChildAssociationRef childAssoc : resultSet.getChildAssocRefs()) + { + result.add(new Pair(childAssoc.getParentRef(), childAssoc.getChildRef())); + } // return results - return resultSet.getNodeRefs(); + return result; } /** diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedReaderDynamicAuthority.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedReaderDynamicAuthority.java index 3e932652a7..443414e66d 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedReaderDynamicAuthority.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedReaderDynamicAuthority.java @@ -18,8 +18,12 @@ */ package org.alfresco.module.org_alfresco_module_rm.security; +import java.util.Collections; +import java.util.Map; import java.util.Set; +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.repo.security.permissions.PermissionReference; import org.alfresco.service.cmr.repository.NodeRef; /** @@ -40,13 +44,45 @@ public class ExtendedReaderDynamicAuthority extends ExtendedSecurityBaseDynamicA public String getAuthority() { return EXTENDED_READER; + } + + /** + * @see org.alfresco.repo.security.permissions.DynamicAuthority#requiredFor() + */ + @Override + public Set requiredFor() + { + if (requiredFor == null) + { + requiredFor = Collections.singleton(getModelDAO().getPermissionReference(null, RMPermissionModel.READ_RECORDS)); + } + + return requiredFor; } /** * @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getAuthorites(org.alfresco.service.cmr.repository.NodeRef) */ - protected Set getAuthorites(NodeRef nodeRef) + @SuppressWarnings("unchecked") + protected Set getAuthorites(NodeRef nodeRef) { - return getExtendedSecurityService().getExtendedReaders(nodeRef); + Set result = null; + + Map readerMap = (Map)getNodeService().getProperty(nodeRef, PROP_READERS); + if (readerMap != null) + { + result = readerMap.keySet(); + } + + return result; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getTransactionCacheName() + */ + @Override + protected String getTransactionCacheName() + { + return "rm.extendedreaderdynamicauthority"; } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java index 170af81010..8f3cb2f44d 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java @@ -24,10 +24,12 @@ import java.util.Set; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.repo.security.permissions.DynamicAuthority; import org.alfresco.repo.security.permissions.PermissionReference; +import org.alfresco.repo.security.permissions.impl.ModelDAO; import org.alfresco.repo.transaction.TransactionalResourceHelper; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.util.Pair; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -41,9 +43,6 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut RecordsManagementModel, ApplicationContextAware { - /** transaction cache key */ - private static final String KEY_HAS_AUTHORITY_CACHE = "rm.transaction.hasAuthority"; - /** Authority service */ private AuthorityService authorityService; @@ -56,6 +55,12 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut /** Application context */ protected ApplicationContext applicationContext; + /** model DAO */ + protected ModelDAO modelDAO; + + /** permission reference */ + protected Set requiredFor; + // NOTE: we get the services directly from the application context in this way to avoid // cyclic relationships and issues when loading the application context @@ -95,6 +100,23 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut return nodeService; } + /** + * @return model DAO + */ + protected ModelDAO getModelDAO() + { + if (modelDAO == null) + { + modelDAO = (ModelDAO)applicationContext.getBean("permissionsModelDAO"); + } + return modelDAO; + } + + /** + * @return String transaction cache name + */ + protected abstract String getTransactionCacheName(); + /** * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) */ @@ -121,63 +143,40 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut { boolean result = false; - if (getNodeService().hasAspect(nodeRef, ASPECT_EXTENDED_SECURITY)) + Map, Boolean> transactionCache = TransactionalResourceHelper.getMap(getTransactionCacheName()); + Pair key = new Pair(nodeRef, userName); + + if (transactionCache.containsKey(key)) { - Set authorities = getAuthorites(nodeRef); - if (authorities != null) - { - for (String authority : authorities) - { - if ("GROUP_EVERYONE".equals(authority)) - { - // 'eveyone' is there so break - result = true; - break; - } - else if (authority.startsWith("GROUP_")) - { - Map transactionCache = TransactionalResourceHelper.getMap(KEY_HAS_AUTHORITY_CACHE); - String key = authority + "|" + userName; - if (transactionCache.containsKey(key)) - { - result = transactionCache.get(key); - break; - } - else - { - Set contained = getAuthorityService().getAuthoritiesForUser(userName); - if (contained.contains(authority)) - { - result = true; - transactionCache.put(key, result); - break; - } - } - } - else - { - // presume we have a user - if (authority.equals(userName)) - { - result = true; - break; - } - } - } - } + result = transactionCache.get(key); + } + else + { + if (getNodeService().hasAspect(nodeRef, ASPECT_EXTENDED_SECURITY)) + { + Set authorities = getAuthorites(nodeRef); + if (authorities != null) + { + // check for everyone or the user + if (authorities.contains("GROUP_EVEYONE") || + authorities.contains(userName)) + { + result = true; + } + else + { + // determine whether any of the users groups are in the extended security + Set contained = getAuthorityService().getAuthoritiesForUser(userName); + authorities.retainAll(contained); + result = (authorities.size() != 0); + } + } + } + + // cache result + transactionCache.put(key, result); } return result; } - - /** - * Base implementation - * - * @see org.alfresco.repo.security.permissions.DynamicAuthority#requiredFor() - */ - @Override - public Set requiredFor() - { - return null; - } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedWriterDynamicAuthority.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedWriterDynamicAuthority.java index e5ab5ab1ea..c27faa6edf 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedWriterDynamicAuthority.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedWriterDynamicAuthority.java @@ -18,8 +18,13 @@ */ package org.alfresco.module.org_alfresco_module_rm.security; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; import java.util.Set; +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.repo.security.permissions.PermissionReference; import org.alfresco.service.cmr.repository.NodeRef; /** @@ -41,12 +46,48 @@ public class ExtendedWriterDynamicAuthority extends ExtendedSecurityBaseDynamicA { return EXTENDED_WRITER; } + + /** + * @see org.alfresco.repo.security.permissions.DynamicAuthority#requiredFor() + */ + @Override + public Set requiredFor() + { + if (requiredFor == null) + { + requiredFor = new HashSet(3); + Collections.addAll(requiredFor, + getModelDAO().getPermissionReference(null, RMPermissionModel.READ_RECORDS), + getModelDAO().getPermissionReference(null, RMPermissionModel.FILING), + getModelDAO().getPermissionReference(null, RMPermissionModel.FILE_RECORDS)); + } + + return requiredFor; + } /** * @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getAuthorites(org.alfresco.service.cmr.repository.NodeRef) */ - protected Set getAuthorites(NodeRef nodeRef) + @SuppressWarnings("unchecked") + protected Set getAuthorites(NodeRef nodeRef) { - return getExtendedSecurityService().getExtendedWriters(nodeRef); - } + Set result = null; + + Map map = (Map)getNodeService().getProperty(nodeRef, PROP_WRITERS); + if (map != null) + { + result = map.keySet(); + } + + return result; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getTransactionCacheName() + */ + @Override + protected String getTransactionCacheName() + { + return "rm.extendedwriterdynamicauthority"; + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionService.java index 18ff94f3e4..a34b4b7da5 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionService.java @@ -29,8 +29,9 @@ import org.alfresco.service.cmr.repository.NodeRef; public interface FilePlanPermissionService { /** + * Setup permissions for a record category * - * @param nodeRef + * @param nodeRef record category node reference */ void setupRecordCategoryPermissions(NodeRef recordCategory); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionServiceImpl.java index 8e5d4734aa..dd9a9d0b9e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionServiceImpl.java @@ -18,31 +18,37 @@ */ package org.alfresco.module.org_alfresco_module_rm.security; +import static org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamicAuthority.EXTENDED_READER; +import static org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority.EXTENDED_WRITER; +import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.TRANSACTION_COMMIT; +import static org.alfresco.repo.policy.annotation.BehaviourKind.CLASS; +import static org.alfresco.repo.security.authentication.AuthenticationUtil.getSystemUserName; +import static org.alfresco.service.cmr.security.OwnableService.NO_OWNER; +import static org.alfresco.util.ParameterCheck.mandatory; +import static org.apache.commons.lang.BooleanUtils.isTrue; + import java.util.HashSet; -import java.util.List; import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; -import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; import org.alfresco.repo.node.NodeServicePolicies; -import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.policy.annotation.Behaviour; import org.alfresco.repo.policy.annotation.BehaviourBean; -import org.alfresco.repo.policy.annotation.BehaviourKind; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.ParameterCheck; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -59,30 +65,43 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl RMPermissionModel { /** Permission service */ - protected PermissionService permissionService; + private PermissionService permissionService; /** Ownable service */ - protected OwnableService ownableService; + private OwnableService ownableService; /** Policy component */ - protected PolicyComponent policyComponent; + private PolicyComponent policyComponent; + + /** Authority service */ + private AuthorityService authorityService; /** Logger */ - protected static final Log LOGGER = LogFactory.getLog(FilePlanPermissionServiceImpl.class); + private static final Log LOGGER = LogFactory.getLog(FilePlanPermissionServiceImpl.class); /** * Initialisation method */ public void init() { - policyComponent.bindClassBehaviour( + getPolicyComponent().bindClassBehaviour( NodeServicePolicies.OnAddAspectPolicy.QNAME, ASPECT_RECORD, - new JavaBehaviour(this, "onAddRecord", NotificationFrequency.TRANSACTION_COMMIT)); - policyComponent.bindClassBehaviour( + new JavaBehaviour(this, "onAddRecord", TRANSACTION_COMMIT)); + getPolicyComponent().bindClassBehaviour( NodeServicePolicies.OnMoveNodePolicy.QNAME, ASPECT_RECORD, - new JavaBehaviour(this, "onMoveRecord", NotificationFrequency.TRANSACTION_COMMIT)); + new JavaBehaviour(this, "onMoveRecord", TRANSACTION_COMMIT)); + } + + /** + * Gets the permission service + * + * @return The permission service + */ + protected PermissionService getPermissionService() + { + return this.permissionService; } /** @@ -93,6 +112,16 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl this.permissionService = permissionService; } + /** + * Gets the policy component + * + * @return The policy component + */ + protected PolicyComponent getPolicyComponent() + { + return this.policyComponent; + } + /** * @param policyComponent policy component */ @@ -101,6 +130,16 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl this.policyComponent = policyComponent; } + /** + * Gets the ownable service + * + * @return The ownable service + */ + protected OwnableService getOwnableService() + { + return this.ownableService; + } + /** * @param ownableService ownable service */ @@ -109,13 +148,33 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl this.ownableService = ownableService; } + /** + * Gets the authority service + * + * @return The authority service + */ + public AuthorityService getAuthorityService() + { + return this.authorityService; + } + + /** + * Sets the authority service + * + * @param authorityService The authority service + */ + public void setAuthorityService(AuthorityService authorityService) + { + this.authorityService = authorityService; + } + /** * @see org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService#setupRecordCategoryPermissions(org.alfresco.service.cmr.repository.NodeRef) */ @Override public void setupRecordCategoryPermissions(final NodeRef recordCategory) { - ParameterCheck.mandatory("recordCategory", recordCategory); + mandatory("recordCategory", recordCategory); // assert that we have a record category in our hands if (!instanceOf(recordCategory, TYPE_RECORD_CATEGORY)) @@ -136,12 +195,13 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl @Behaviour ( type = "rma:unfiledRecordFolder", - kind = BehaviourKind.CLASS, + kind = CLASS, policy = "alf:onCreateNode", - notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + notificationFrequency = TRANSACTION_COMMIT ) public void onCreateUnfiledRecordFolder(ChildAssociationRef childAssocRef) { + mandatory("childAssocRef", childAssocRef); setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef()); } @@ -153,12 +213,13 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl @Behaviour ( type = "rma:recordFolder", - kind = BehaviourKind.CLASS, + kind = CLASS, policy = "alf:onCreateNode", - notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + notificationFrequency = TRANSACTION_COMMIT ) public void onCreateRecordFolder(ChildAssociationRef childAssocRef) { + mandatory("childAssocRef", childAssocRef); setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef()); } @@ -170,12 +231,13 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl @Behaviour ( type = "rma:hold", - kind = BehaviourKind.CLASS, + kind = CLASS, policy = "alf:onCreateNode", - notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + notificationFrequency = TRANSACTION_COMMIT ) public void onCreateHold(final ChildAssociationRef childAssocRef) { + mandatory("childAssocRef", childAssocRef); setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef()); } @@ -187,13 +249,14 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl @Behaviour ( type = "rma:transfer", - kind = BehaviourKind.CLASS, + kind = CLASS, policy = "alf:onCreateNode", - notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + notificationFrequency = TRANSACTION_COMMIT ) public void onCreateTransfer(final ChildAssociationRef childAssocRef) { - setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef(), false); + mandatory("childAssocRef", childAssocRef); + setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef()); } /** @@ -204,90 +267,75 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl */ public void setupPermissions(final NodeRef parent, final NodeRef nodeRef) { - ParameterCheck.mandatory("parent", parent); - ParameterCheck.mandatory("nodeRef", nodeRef); - setupPermissions(parent, nodeRef, true); - } - - /** - * Helper method to setup permissions. - * - * @param parent parent node reference - * @param nodeRef child node reference - * @param includeInPlace true if in-place permissions should be included, false otherwise - */ - private void setupPermissions(final NodeRef parent, final NodeRef nodeRef, final boolean includeInPlace) - { - if (nodeService.exists(nodeRef)) - { - // initialise permissions - initPermissions(nodeRef, includeInPlace); + mandatory("parent", parent); + mandatory("nodeRef", nodeRef); - if (nodeService.exists(parent)) + if (nodeService.exists(nodeRef) && nodeService.exists(parent)) + { + authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork() { - authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork() + public Object doWork() { - public Object doWork() + // set inheritance + boolean isParentNodeFilePlan = isRecordCategory(nodeRef) && isFilePlan(parent); + boolean inheritanceAllowed = isInheritanceAllowed(nodeRef, isParentNodeFilePlan); + getPermissionService().setInheritParentPermissions(nodeRef, inheritanceAllowed); + + // clear all existing permissions + getPermissionService().clearPermission(nodeRef, null); + + if (!inheritanceAllowed) + { + getPermissionService().setPermission(nodeRef, EXTENDED_READER, READ_RECORDS, true); + getPermissionService().setPermission(nodeRef, EXTENDED_WRITER, FILING, true); + String adminRole = getAdminRole(nodeRef); + getPermissionService().setPermission(nodeRef, adminRole, RMPermissionModel.FILING, true); + } + + // remove owner + getOwnableService().setOwner(nodeRef, NO_OWNER); + + if (isParentNodeFilePlan) { - // setup inherited permissions Set perms = permissionService.getAllSetPermissions(parent); for (AccessPermission perm : perms) { - // only copy filling permissions if the parent is the file plan - if (!inheritFillingOnly(parent, nodeRef) || - RMPermissionModel.FILING.equals(perm.getPermission())) + if (RMPermissionModel.FILING.equals(perm.getPermission())) { - // don't copy the extended reader or writer permissions as they have already been set - if (!ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(perm.getAuthority()) && - !ExtendedWriterDynamicAuthority.EXTENDED_WRITER.equals(perm.getAuthority())) + AccessStatus accessStatus = perm.getAccessStatus(); + boolean allow = false; + if (AccessStatus.ALLOWED.equals(accessStatus)) { - // get the access status details - AccessStatus accessStatus = perm.getAccessStatus(); - boolean allow = false; - if (AccessStatus.ALLOWED.equals(accessStatus)) - { - allow = true; - } - - // set the permission on the target node - permissionService.setPermission( - nodeRef, - perm.getAuthority(), - perm.getPermission(), - allow); + allow = true; } + permissionService.setPermission( + nodeRef, + perm.getAuthority(), + perm.getPermission(), + allow); } } - - return null; } - }); - } + + return null; + } + }); } } - /** - * Helper method to determine whether all or just filling permissions should be inherited. - * - * @param parent parent node - * @param child child node - * @return boolean true if inherit filling only, false otherwise - */ - private boolean inheritFillingOnly(NodeRef parent, NodeRef child) + private String getAdminRole(NodeRef nodeRef) { - boolean result = false; - - // if root category or - // if in root of unfiled container or - // if in root of hold container - if ((isFilePlan(parent) && isRecordCategory(child)) || - FilePlanComponentKind.UNFILED_RECORD_CONTAINER.equals(getFilePlanComponentKind(parent)) || - FilePlanComponentKind.HOLD_CONTAINER.equals(getFilePlanComponentKind(parent))) + NodeRef filePlan = getFilePlan(nodeRef); + if (filePlan == null) { - result = true; + throw new AlfrescoRuntimeException("The file plan could not be found for the give node: '" + nodeRef + "'."); } + return authorityService.getName(AuthorityType.GROUP, FilePlanRoleService.ROLE_ADMIN + filePlan.getId()); + } - return result; + private boolean isInheritanceAllowed(NodeRef nodeRef, Boolean isParentNodeFilePlan) + { + return !(isFilePlan(nodeRef) || isTransfer(nodeRef) || isHold(nodeRef) || isUnfiledRecordsContainer(nodeRef) || (isRecordCategory(nodeRef) && isTrue(isParentNodeFilePlan))); } /** @@ -300,6 +348,9 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl */ public void onAddRecord(final NodeRef record, final QName aspectTypeQName) { + mandatory("childAssocRef", record); + mandatory("childAssocRef", aspectTypeQName); + authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork() { public Object doWork() @@ -323,27 +374,32 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl */ public void onMoveRecord(final ChildAssociationRef sourceAssocRef, final ChildAssociationRef destinationAssocRef) { - AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + mandatory("sourceAssocRef", sourceAssocRef); + mandatory("destinationAssocRef", destinationAssocRef); + + authenticationUtil.runAs(new AuthenticationUtil.RunAsWork() { public Void doWork() { NodeRef record = sourceAssocRef.getChildRef(); if (nodeService.exists(record) && nodeService.hasAspect(record, ASPECT_RECORD)) { - Set keepPerms = new HashSet(5); + boolean inheritParentPermissions = permissionService.getInheritParentPermissions(record); - // record any permissions specifically set on the record (ie any filling or record_file permisions not on the parent) - Set origionalParentPerms = permissionService.getAllSetPermissions(sourceAssocRef.getParentRef()); + Set keepPerms = new HashSet(5); Set origionalRecordPerms= permissionService.getAllSetPermissions(record); - for (AccessPermission perm : origionalRecordPerms) + + for (AccessPermission recordPermission : origionalRecordPerms) { - if (!ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(perm.getAuthority()) && - !ExtendedWriterDynamicAuthority.EXTENDED_WRITER.equals(perm.getAuthority()) && - (perm.getPermission().equals(RMPermissionModel.FILING) || perm.getPermission().equals(RMPermissionModel.FILE_RECORDS)) && - !origionalParentPerms.contains(perm)) + String permission = recordPermission.getPermission(); + String authority = recordPermission.getAuthority(); + if ((RMPermissionModel.FILING.equals(permission) || RMPermissionModel.READ_RECORDS.equals(permission)) && + recordPermission.isSetDirectly() && + !ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(authority) && + !ExtendedWriterDynamicAuthority.EXTENDED_WRITER.equals(authority)) { // then we can assume this is a permission we want to preserve - keepPerms.add(perm); + keepPerms.add(recordPermission); } } @@ -358,47 +414,13 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl { setPermission(record, keeper.getAuthority(), keeper.getPermission()); } + + permissionService.setInheritParentPermissions(record, inheritParentPermissions); } return null; } - }, AuthenticationUtil.getSystemUserName()); - } - - /** - * Init the permissions for the given node. - * - * @param nodeRef node reference - * @param includeInPlace true if in-place - */ - private void initPermissions(final NodeRef nodeRef, final boolean includeInPlace) - { - if (nodeService.exists(nodeRef)) - { - authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork() - { - public Object doWork() - { - // break inheritance - permissionService.setInheritParentPermissions(nodeRef, false); - - // clear all existing permissions - permissionService.clearPermission(nodeRef, null); - - if (includeInPlace) - { - // set extended reader permissions - permissionService.setPermission(nodeRef, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true); - permissionService.setPermission(nodeRef, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true); - } - - // remove owner - ownableService.setOwner(nodeRef, OwnableService.NO_OWNER); - - return null; - } - }); - } + }, getSystemUserName()); } /** @@ -414,21 +436,10 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl { public Void doWork() { - if (isFilePlan(nodeRef)) + if (canPerformPermissionAction(nodeRef)) { - // set the permission down the file plan hierarchy - setPermissionDown(nodeRef, authority, permission); - } - else if (isFilePlanContainer(nodeRef) || - isRecordFolder(nodeRef) || - isRecord(nodeRef) || - isHold(nodeRef)) - { - // set read permission to the parents of the node - setReadPermissionUp(nodeRef, authority); - - // set the permission on the node and it's children - setPermissionDown(nodeRef, authority, permission); + // Set the permission on the node + getPermissionService().setPermission(nodeRef, authority, permission, true); } else { @@ -443,146 +454,29 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl }); } - /** - * Helper method to set the read permission up the hierarchy - * - * @param nodeRef node reference - * @param authority authority - */ - private void setReadPermissionUp(NodeRef nodeRef, String authority) - { - NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef(); - if (parent != null && isFilePlanComponent(parent)) - { - setReadPermissionUpImpl(parent, authority); - } - } - - /** - * Helper method used to set the read permission up the hierarchy - * - * @param nodeRef node reference - * @param authority authority - */ - private void setReadPermissionUpImpl(NodeRef nodeRef, String authority) - { - setPermissionImpl(nodeRef, authority, RMPermissionModel.READ_RECORDS); - - NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef(); - if (parent != null && isFilePlanComponent(parent)) - { - setReadPermissionUpImpl(parent, authority); - } - } - - /** - * Helper method to set the permission down the hierarchy - * - * @param nodeRef node reference - * @param authority authority - * @param permission permission - */ - private void setPermissionDown(NodeRef nodeRef, String authority, String permission) - { - // skip out node's that inherit (for example hold and transfer) - if (!permissionService.getInheritParentPermissions(nodeRef)) - { - // set permissions - setPermissionImpl(nodeRef, authority, permission); - - if (isFilePlanContainer(nodeRef) || - isRecordFolder(nodeRef)) - { - List assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef assoc : assocs) - { - NodeRef child = assoc.getChildRef(); - if (isFilePlanContainer(child) || - isRecordFolder(child) || - isRecord(child) || - isHold(child) || - instanceOf(child, TYPE_TRANSFER)) - { - setPermissionDown(child, authority, permission); - } - } - } - } - } - - /** - * Set the permission, taking into account that filing is a superset of read - * - * @param nodeRef node reference - * @param authority authority - * @param permission permission - */ - private void setPermissionImpl(NodeRef nodeRef, String authority, String permission) - { - boolean hasRead = false; - boolean hasFilling = false; - - Set perms = permissionService.getAllSetPermissions(nodeRef); - for (AccessPermission perm : perms) - { - if (perm.getAuthority().equals(authority)) - { - if (perm.getPermission().equals(FILING)) - { - hasFilling = true; - } - else if (perm.getPermission().equals(READ_RECORDS)) - { - hasRead = true; - } - } - } - - if (FILING.equals(permission) && hasRead) - { - // remove read permission - permissionService.deletePermission(nodeRef, authority, RMPermissionModel.READ_RECORDS); - hasRead = false; - } - - if (!hasRead && !hasFilling) - { - // add permission - permissionService.setPermission(nodeRef, authority, permission, true); - } - } - /** * @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#deletePermission(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.lang.String) */ public void deletePermission(final NodeRef nodeRef, final String authority, final String permission) { + ParameterCheck.mandatory("nodeRef", nodeRef); + ParameterCheck.mandatory("authority", authority); + ParameterCheck.mandatory("permission", permission); + authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork() { public Void doWork() { - // can't delete permissions if inherited (eg hold and transfer containers) - if (!permissionService.getInheritParentPermissions(nodeRef)) + if (canPerformPermissionAction(nodeRef)) { // Delete permission on this node - permissionService.deletePermission(nodeRef, authority, permission); - - if (isFilePlanContainer(nodeRef) || - isRecordFolder(nodeRef)) + getPermissionService().deletePermission(nodeRef, authority, permission); + } + else + { + if (LOGGER.isWarnEnabled()) { - List assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef assoc : assocs) - { - NodeRef child = assoc.getChildRef(); - if (isFilePlanContainer(child) || - isRecordFolder(child) || - isRecord(child)|| - isHold(child) || - instanceOf(child, TYPE_TRANSFER)) - { - deletePermission(child, authority, permission); - } - } + LOGGER.warn("Deleting permissions for this node is not supported. (nodeRef=" + nodeRef + ", authority=" + authority + ", permission=" + permission + ")"); } } @@ -590,4 +484,9 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl } }); } + + private boolean canPerformPermissionAction(NodeRef nodeRef) + { + return isFilePlanContainer(nodeRef) || isRecordFolder(nodeRef) || isRecord(nodeRef); + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/AuthenticationUtil.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/AuthenticationUtil.java index d40dd28420..ab38e037fc 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/AuthenticationUtil.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/AuthenticationUtil.java @@ -69,7 +69,7 @@ public class AuthenticationUtil /** * Helper method that gets the admin user name. *

- * Usefule when testing using mocks. + * Useful when testing using mocks. * * @see org.alfresco.repo.security.authentication.AuthenticationUtil#getAdminUserName() */ @@ -77,5 +77,14 @@ public class AuthenticationUtil { return org.alfresco.repo.security.authentication.AuthenticationUtil.getAdminUserName(); } - + + /** + * Helper method that gets the system user name. + * + * @see org.alfresco.repo.security.authentication.AuthenticationUtil#getSystemUserName() + */ + public String getSystemUserName() + { + return org.alfresco.repo.security.authentication.AuthenticationUtil.getSystemUserName(); + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java index 99d7bbea6d..f2d9b38525 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java @@ -53,10 +53,10 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte /** Application context */ protected ApplicationContext applicationContext; - + /** internal node service */ private NodeService internalNodeService; - + /** authentication helper */ protected AuthenticationUtil authenticationUtil; @@ -84,7 +84,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { this.dictionaryService = dictionaryService; } - + /** * @param authenticationUtil authentication util helper */ @@ -92,7 +92,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { this.authenticationUtil = authenticationUtil; } - + /** * Helper to get internal node service. *

@@ -104,10 +104,10 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { internalNodeService = (NodeService)applicationContext.getBean("dbNodeService"); } - + return internalNodeService; } - + /** * Gets the file plan component kind from the given node reference * @@ -127,7 +127,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte if (isFilePlanComponent(nodeRef)) { result = FilePlanComponentKind.FILE_PLAN_COMPONENT; - + if (isFilePlan(nodeRef)) { result = FilePlanComponentKind.FILE_PLAN; @@ -173,7 +173,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte result = FilePlanComponentKind.UNFILED_RECORD_FOLDER; } } - + if (result != null) { map.put(nodeRef, result); @@ -319,7 +319,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte ParameterCheck.mandatory("nodeRef", nodeRef); boolean isHold = false; - if (getInternalNodeService().exists(nodeRef) && + if (getInternalNodeService().exists(nodeRef) && instanceOf(nodeRef, TYPE_HOLD)) { isHold = true; @@ -338,10 +338,23 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte return instanceOf(nodeRef, TYPE_TRANSFER); } - + + /** + * Indicates whether the given node reference is an unfiled records container or not. + * + * @param nodeRef node reference + * @return boolean true if rma:unfiledRecordContainer or sub-type, false otherwise + */ + public boolean isUnfiledRecordsContainer(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + return instanceOf(nodeRef, TYPE_UNFILED_RECORD_CONTAINER); + } + /** * Indicates whether a record is complete or not. - * + * * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isDeclared(org.alfresco.service.cmr.repository.NodeRef) */ public boolean isDeclared(NodeRef record) @@ -361,22 +374,33 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { NodeRef result = null; if (nodeRef != null) - { - result = (NodeRef)getInternalNodeService().getProperty(nodeRef, PROP_ROOT_NODEREF); - if (result == null || !instanceOf(result, TYPE_FILE_PLAN)) + { + Map transactionCache = TransactionalResourceHelper.getMap("rm.servicebase.getFilePlan"); + if (transactionCache.containsKey(nodeRef)) { - if (instanceOf(nodeRef, TYPE_FILE_PLAN)) + result = transactionCache.get(nodeRef); + } + else + { + result = (NodeRef)getInternalNodeService().getProperty(nodeRef, PROP_ROOT_NODEREF); + if (result == null || !instanceOf(result, TYPE_FILE_PLAN)) { - result = nodeRef; - } - else - { - ChildAssociationRef parentAssocRef = getInternalNodeService().getPrimaryParent(nodeRef); - if (parentAssocRef != null) + if (instanceOf(nodeRef, TYPE_FILE_PLAN)) { - result = getFilePlan(parentAssocRef.getParentRef()); + result = nodeRef; + } + else + { + ChildAssociationRef parentAssocRef = getInternalNodeService().getPrimaryParent(nodeRef); + if (parentAssocRef != null) + { + result = getFilePlan(parentAssocRef.getParentRef()); + } } } + + // cache result in transaction + transactionCache.put(nodeRef, result); } } @@ -392,11 +416,11 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte protected boolean instanceOf(NodeRef nodeRef, QName ofClassName) { ParameterCheck.mandatory("nodeRef", nodeRef); - ParameterCheck.mandatory("ofClassName", ofClassName); - QName className = getInternalNodeService().getType(nodeRef); + ParameterCheck.mandatory("ofClassName", ofClassName); + QName className = getInternalNodeService().getType(nodeRef); return instanceOf(className, ofClassName); } - + private static Map instanceOfCache = new HashMap(); /** @@ -410,25 +434,25 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { ParameterCheck.mandatory("className", className); ParameterCheck.mandatory("ofClassName", ofClassName); - + boolean result = false; - + String key = className.toString() + "|" + ofClassName.toString(); if (instanceOfCache.containsKey(key)) { result = instanceOfCache.get(key); } else - { + { if (ofClassName.equals(className) || dictionaryService.isSubClass(className, ofClassName)) { result = true; } - + instanceOfCache.put(key, result); } - + return result; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionNodeServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionNodeServiceImpl.java index 9396a4b0d7..c90dc17da9 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionNodeServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionNodeServiceImpl.java @@ -18,6 +18,8 @@ */ package org.alfresco.module.org_alfresco_module_rm.version; +import static org.alfresco.module.org_alfresco_module_rm.record.RecordServiceImpl.RECORD_MODEL_URIS; + import java.io.Serializable; import java.util.Date; import java.util.HashMap; @@ -28,19 +30,17 @@ import java.util.Set; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; -import org.alfresco.module.org_alfresco_module_rm.record.RecordServiceImpl; import org.alfresco.repo.version.Node2ServiceImpl; import org.alfresco.repo.version.Version2Model; import org.alfresco.repo.version.common.VersionUtil; import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; -import org.apache.commons.lang.ArrayUtils; /** - * Extended version node service implementation that supports the retrieval of + * Extended version node service implementation that supports the retrieval of * recorded version state. - * + * * @author Roy Wetherall * @since 2.3 */ @@ -49,7 +49,7 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl { /** record service */ private RecordService recordService; - + /** * @param recordService record service */ @@ -57,7 +57,7 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl { this.recordService = recordService; } - + /** * @see org.alfresco.repo.version.Node2ServiceImpl#getProperties(org.alfresco.service.cmr.repository.NodeRef) */ @@ -65,7 +65,7 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl public Map getProperties(NodeRef nodeRef) throws InvalidNodeRefException { // TODO only supported for Version2 - + NodeRef converted = VersionUtil.convertNodeRef(nodeRef); if (dbNodeService.hasAspect(converted, ASPECT_RECORDED_VERSION)) { @@ -78,41 +78,41 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl return super.getProperties(nodeRef); } } - + /** * Process properties map before returning as frozen state. - * + * * @param properties properties map * @return {@link Map}<{@link QName}, {@link Serializable}> processed property map */ protected Map processProperties(NodeRef version, Map properties) { Map cloneProperties = new HashMap(properties); - + // revert modified record name properties.put(ContentModel.PROP_NAME, properties.get(RecordsManagementModel.PROP_ORIGIONAL_NAME)); - + // remove all rma, rmc, rmr and rmv properties for (QName property : cloneProperties.keySet()) { if (!PROP_RECORDABLE_VERSION_POLICY.equals(property) && - !PROP_FILE_PLAN.equals(property) && - (recordService.isRecordMetadataProperty(property) || - ArrayUtils.contains(RecordServiceImpl.RECORD_MODEL_URIS, property.getNamespaceURI()))) + !PROP_FILE_PLAN.equals(property) && + (recordService.isRecordMetadataProperty(property) || + RECORD_MODEL_URIS.contains(property.getNamespaceURI()))) { - properties.remove(property); + properties.remove(property); } } - + // do standard property processing processVersionProperties(version, properties); - + return properties; } - + /** * Process version properties. - * + * * @param version version node reference * @param properties properties map */ @@ -120,12 +120,12 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl { // get version properties Map versionProperties = dbNodeService.getProperties(version); - + if (versionProperties != null) { String versionLabel = (String)versionProperties.get(Version2Model.PROP_QNAME_VERSION_LABEL); properties.put(ContentModel.PROP_VERSION_LABEL, versionLabel); - + // Convert frozen sys:referenceable properties NodeRef nodeRef = (NodeRef)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF); if (nodeRef != null) @@ -134,42 +134,42 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl properties.put(ContentModel.PROP_STORE_IDENTIFIER, nodeRef.getStoreRef().getIdentifier()); properties.put(ContentModel.PROP_NODE_UUID, nodeRef.getId()); } - + Long dbid = (Long)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_NODE_DBID); properties.put(ContentModel.PROP_NODE_DBID, dbid); - + // Convert frozen cm:auditable properties String creator = (String)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_CREATOR); if (creator != null) { properties.put(ContentModel.PROP_CREATOR, creator); } - + Date created = (Date)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_CREATED); if (created != null) { properties.put(ContentModel.PROP_CREATED, created); } - + // TODO - check use-cases for get version, revert, restore .... String modifier = (String)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_MODIFIER); if (modifier != null) { properties.put(ContentModel.PROP_MODIFIER, modifier); } - + Date modified = (Date)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_MODIFIED); if (modified != null) { properties.put(ContentModel.PROP_MODIFIED, modified); } - + Date accessed = (Date)versionProperties.get(Version2Model.PROP_QNAME_FROZEN_ACCESSED); if (accessed != null) { properties.put(ContentModel.PROP_ACCESSED, accessed); - } - + } + String owner = (String)versionProperties.get(PROP_FROZEN_OWNER); if (owner != null) { @@ -177,7 +177,7 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl } } } - + /** * @see org.alfresco.repo.version.Node2ServiceImpl#getAspects(org.alfresco.service.cmr.repository.NodeRef) */ @@ -185,7 +185,7 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl public Set getAspects(NodeRef nodeRef) throws InvalidNodeRefException { // TODO only supported for Version2 - + NodeRef converted = VersionUtil.convertNodeRef(nodeRef); if (dbNodeService.hasAspect(converted, ASPECT_RECORDED_VERSION)) { @@ -198,34 +198,34 @@ public class RecordableVersionNodeServiceImpl extends Node2ServiceImpl return super.getAspects(nodeRef); } } - + /** * Process frozen aspects. - * + * * @param aspects aspect set * @return {@link Set}<{@link QName}> processed aspect set */ protected Set processAspects(Set aspects) { Set result = new HashSet(aspects); - + // remove version aspects result.remove(ASPECT_VERSION); result.remove(ASPECT_RECORDED_VERSION); - + // remove rm aspects for (QName aspect : aspects) { if (!ASPECT_VERSIONABLE.equals(aspect) && - (recordService.isRecordMetadataAspect(aspect) || - ArrayUtils.contains(RecordServiceImpl.RECORD_MODEL_URIS, aspect.getNamespaceURI()))) + (recordService.isRecordMetadataAspect(aspect) || + RECORD_MODEL_URIS.contains(aspect.getNamespaceURI()))) { - result.remove(aspect); + result.remove(aspect); } } - + // remove custom record meta-data aspects - + return result; } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java index 374a06db1f..bf6f64c1fc 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImpl.java @@ -18,34 +18,28 @@ */ package org.alfresco.module.org_alfresco_module_rm.version; +import static org.codehaus.plexus.util.StringUtils.isNotBlank; + import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; -import java.util.List; import java.util.Map; -import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; +import org.alfresco.module.org_alfresco_module_rm.model.security.ModelSecurityService; +import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService; -import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService; import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil; import org.alfresco.repo.policy.PolicyScope; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.security.permissions.impl.ExtendedPermissionService; import org.alfresco.repo.version.Version2Model; import org.alfresco.repo.version.Version2ServiceImpl; import org.alfresco.repo.version.VersionModel; -import org.alfresco.service.cmr.model.FileFolderService; -import org.alfresco.service.cmr.model.FileInfo; -import org.alfresco.service.cmr.model.FileNotFoundException; -import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.version.ReservedVersionNameException; import org.alfresco.service.cmr.version.Version; import org.alfresco.service.cmr.version.VersionHistory; @@ -70,30 +64,24 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl /** key used to indicate a recordable version */ public static final String KEY_RECORDABLE_VERSION = "recordable-version"; public static final String KEY_FILE_PLAN = "file-plan"; - + /** version record property */ public static final String PROP_VERSION_RECORD = "RecordVersion"; /** file plan service */ - protected FilePlanService filePlanService; - - /** file folder service */ - protected FileFolderService fileFolderService; - - /** extended permission service */ - protected ExtendedPermissionService extendedPermissionService; - - /** ownable service */ - protected OwnableService ownableService; - - /** extended security service */ - protected ExtendedSecurityService extendedSecurityService; + private FilePlanService filePlanService; /** authentication util helper */ - protected AuthenticationUtil authenticationUtil; - + private AuthenticationUtil authenticationUtil; + /** relationship service */ - protected RelationshipService relationshipService; + private RelationshipService relationshipService; + + /** record service */ + private RecordService recordService; + + /** model security service */ + private ModelSecurityService modelSecurityService; /** * @param filePlanService file plan service @@ -103,38 +91,6 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl this.filePlanService = filePlanService; } - /** - * @param fileFolderService file folder service - */ - public void setFileFolderService(FileFolderService fileFolderService) - { - this.fileFolderService = fileFolderService; - } - - /** - * @param extendedPermissionService extended permission service - */ - public void setExtendedPermissionService(ExtendedPermissionService extendedPermissionService) - { - this.extendedPermissionService = extendedPermissionService; - } - - /** - * @param ownableService ownable service - */ - public void setOwnableService(OwnableService ownableService) - { - this.ownableService = ownableService; - } - - /** - * @param extendedSecurityService extended security service - */ - public void setExtendedSecurityService(ExtendedSecurityService extendedSecurityService) - { - this.extendedSecurityService = extendedSecurityService; - } - /** * @param authenticationUtil authentication util helper */ @@ -142,7 +98,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl { this.authenticationUtil = authenticationUtil; } - + /** * @param relationshipService relationship service */ @@ -150,6 +106,22 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl { this.relationshipService = relationshipService; } + + /** + * @param recordService record service + */ + public void setRecordService(RecordService recordService) + { + this.recordService = recordService; + } + + /** + * @param modelSecurityService model security service + */ + public void setModelSecurityService(ModelSecurityService modelSecurityService) + { + this.modelSecurityService = modelSecurityService; + } /** * @see org.alfresco.repo.version.Version2ServiceImpl#createVersion(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, int) @@ -217,12 +189,19 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl */ private NodeRef getFilePlan() { - NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID); - if (filePlan == null) + return authenticationUtil.runAsSystem(new RunAsWork() { - throw new AlfrescoRuntimeException("Can't create a recorded version, because there is no file plan."); - } - return filePlan; + @Override + public NodeRef doWork() throws Exception + { + NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID); + if (filePlan == null) + { + throw new AlfrescoRuntimeException("Can't create a recorded version, because there is no file plan."); + } + return filePlan; + } + }); } /** @@ -306,6 +285,12 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl // disable other behaviours that we don't want to trigger during this process policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT); policyBehaviourFilter.disableBehaviour(ContentModel.TYPE_MULTILINGUAL_CONTAINER); + + // disable model security check + modelSecurityService.disable(); + + // disable property editable check + recordService.disablePropertyEditableCheck(); try { @@ -320,46 +305,23 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl final NodeRef nodeRef = (NodeRef)standardVersionProperties.get(Version2Model.PROP_QNAME_FROZEN_NODE_REF); // create record - final NodeRef record = createRecord(nodeRef, filePlan); - + final NodeRef record = recordService.createRecordFromCopy(filePlan, nodeRef); + // apply version record aspect to record PropertyMap versionRecordProps = new PropertyMap(3); versionRecordProps.put(PROP_VERSIONED_NODEREF, nodeRef); - versionRecordProps.put(RecordableVersionModel.PROP_VERSION_LABEL, + versionRecordProps.put(RecordableVersionModel.PROP_VERSION_LABEL, standardVersionProperties.get( QName.createQName(Version2Model.NAMESPACE_URI, Version2Model.PROP_VERSION_LABEL))); - versionRecordProps.put(RecordableVersionModel.PROP_VERSION_DESCRIPTION, + versionRecordProps.put(RecordableVersionModel.PROP_VERSION_DESCRIPTION, standardVersionProperties.get( QName.createQName(Version2Model.NAMESPACE_URI, Version2Model.PROP_VERSION_DESCRIPTION))); nodeService.addAspect(record, ASPECT_VERSION_RECORD, versionRecordProps); - - // wire record up to previous record - VersionHistory versionHistory = getVersionHistory(nodeRef); - if (versionHistory != null) - { - Collection previousVersions = versionHistory.getAllVersions(); - for (Version previousVersion : previousVersions) - { - // look for the associated record - final NodeRef previousRecord = (NodeRef)previousVersion.getVersionProperties().get(PROP_VERSION_RECORD); - if (previousRecord != null) - { - authenticationUtil.runAsSystem(new RunAsWork() - { - @Override - public Void doWork() throws Exception - { - // indicate that the new record versions the previous record - relationshipService.addRelationship("versions", record, previousRecord); - return null; - } - }); - break; - } - } - } + + // wire record up to previous record + linkToPreviousVersionRecord(nodeRef, record); // create version nodeRef ChildAssociationRef childAssocRef = dbNodeService.createNode( @@ -381,6 +343,12 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl } finally { + // enable model security check + modelSecurityService.enable(); + + // enable property editable check + recordService.enablePropertyEditableCheck(); + // Enable behaviours this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_VERSIONABLE); this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT); @@ -388,7 +356,7 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl } // If the auditable aspect is not there then add it to the 'version' node (after original aspects have been frozen) - if (dbNodeService.hasAspect(versionNodeRef, ContentModel.ASPECT_AUDITABLE) == false) + if (!dbNodeService.hasAspect(versionNodeRef, ContentModel.ASPECT_AUDITABLE)) { dbNodeService.addAspect(versionNodeRef, ContentModel.ASPECT_AUDITABLE, null); } @@ -400,91 +368,59 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl return versionNodeRef; } - + /** - * Create record from current version - * - * @param nodeRef state to freeze - * @param filePlan destination file plan - * @return {@link NodeRef} versioned record + * Helper method to link the record to the previous version record + * + * @param nodeRef noderef source node reference + * @param record record record node reference */ - private NodeRef createRecord(final NodeRef nodeRef, final NodeRef filePlan) + private void linkToPreviousVersionRecord(final NodeRef nodeRef, final NodeRef record) { - return authenticationUtil.runAs(new RunAsWork() + final NodeRef latestRecordVersion = getLatestVersionRecord(nodeRef); + if (latestRecordVersion != null) { - public NodeRef doWork() throws Exception + authenticationUtil.runAsSystem(new RunAsWork() { - // get the unfiled record folder - final NodeRef unfiledRecordFolder = filePlanService.getUnfiledContainer(filePlan); - - // get the documents readers - Long aclId = dbNodeService.getNodeAclId(nodeRef); - Set readers = extendedPermissionService.getReaders(aclId); - Set writers = extendedPermissionService.getWriters(aclId); - - // add the current owner to the list of extended writers - Set modifiedWrtiers = new HashSet(writers); - if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_OWNABLE)) + @Override + public Void doWork() throws Exception { - String owner = ownableService.getOwner(nodeRef); - if (owner != null && !owner.isEmpty() && !owner.equals(OwnableService.NO_OWNER)) - { - modifiedWrtiers.add(owner); - } + // indicate that the new record versions the previous record + relationshipService.addRelationship("versions", record, latestRecordVersion); + return null; } - - // add the current user as extended writer - modifiedWrtiers.add(authenticationUtil.getFullyAuthenticatedUser()); - - // copy version state and create record - NodeRef record = null; - try + }); + } + } + + /** + * Helper to get the latest version record for a given document (ie non-record) + * + * @param nodeRef node reference + * @return NodeRef latest version record, null otherwise + */ + private NodeRef getLatestVersionRecord(NodeRef nodeRef) + { + NodeRef versionRecord = null; + + // wire record up to previous record + VersionHistory versionHistory = getVersionHistory(nodeRef); + if (versionHistory != null) + { + Collection previousVersions = versionHistory.getAllVersions(); + for (Version previousVersion : previousVersions) + { + // look for the associated record + final NodeRef previousRecord = (NodeRef)previousVersion.getVersionProperties().get(PROP_VERSION_RECORD); + if (previousRecord != null) { - List originalAssocs = null; - if (dbNodeService.hasAspect(nodeRef, ContentModel.ASPECT_COPIEDFROM)) - { - // take a note of any copyFrom information already on the node - originalAssocs = dbNodeService.getTargetAssocs(nodeRef, ContentModel.ASSOC_ORIGINAL); - } - - // create a copy of the original state and add it to the unfiled record container - FileInfo recordInfo = fileFolderService.copy(nodeRef, unfiledRecordFolder, null); - record = recordInfo.getNodeRef(); - - // remove added copy assocs - List recordAssocs = dbNodeService.getTargetAssocs(record, ContentModel.ASSOC_ORIGINAL); - for (AssociationRef recordAssoc : recordAssocs) - { - dbNodeService.removeAssociation( - recordAssoc.getSourceRef(), - recordAssoc.getTargetRef(), - ContentModel.ASSOC_ORIGINAL); - } - - // re-add origional assocs or remove aspect - if (originalAssocs == null) - { - dbNodeService.removeAspect(record, ContentModel.ASPECT_COPIEDFROM); - } - else - { - for (AssociationRef originalAssoc : originalAssocs) - { - dbNodeService.createAssociation(originalAssoc.getSourceRef(), originalAssoc.getTargetRef(), ContentModel.ASSOC_ORIGINAL); - } - } + versionRecord = previousRecord; + break; } - catch (FileNotFoundException e) - { - throw new AlfrescoRuntimeException("Can't create recorded version, because copy fails.", e); - } - - // set extended security on record - extendedSecurityService.addExtendedSecurity(record, readers, writers); - - return record; } - }, authenticationUtil.getAdminUserName()); + } + + return versionRecord; } /** @@ -526,4 +462,20 @@ public class RecordableVersionServiceImpl extends Version2ServiceImpl return version; } + + /** + * @see org.alfresco.repo.version.Version2ServiceImpl#revert(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.version.Version, boolean) + */ + @Override + public void revert(NodeRef nodeRef, Version version, boolean deep) + { + String versionPolicy = (String) dbNodeService.getProperty(nodeRef, PROP_RECORDABLE_VERSION_POLICY); + + super.revert(nodeRef, version, deep); + + if (isNotBlank(versionPolicy)) + { + dbNodeService.setProperty(nodeRef, PROP_RECORDABLE_VERSION_POLICY, versionPolicy); + } + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/BroadcastVitalRecordDefinitionAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/BroadcastVitalRecordDefinitionAction.java index 74d199459b..b7957d7b71 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/BroadcastVitalRecordDefinitionAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/BroadcastVitalRecordDefinitionAction.java @@ -78,7 +78,7 @@ public class BroadcastVitalRecordDefinitionAction extends RMActionExecuterAbstra */ private void propagateChangeToChildrenOf(NodeRef actionedUponNodeRef) { - Map parentProps = nodeService.getProperties(actionedUponNodeRef); + Map parentProps = getNodeService().getProperties(actionedUponNodeRef); // parent vital record indicator, default to null if not set boolean parentVri = false; @@ -90,41 +90,41 @@ public class BroadcastVitalRecordDefinitionAction extends RMActionExecuterAbstra Period parentReviewPeriod = (Period) parentProps.get(PROP_REVIEW_PERIOD); - List assocs = this.nodeService.getChildAssocs(actionedUponNodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); + List assocs = this.getNodeService().getChildAssocs(actionedUponNodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); for (ChildAssociationRef nextAssoc : assocs) { NodeRef nextChild = nextAssoc.getChildRef(); if (filePlanService.isFilePlanComponent(nextChild) && - !freezeService.isFrozen(nextChild)) + !getFreezeService().isFrozen(nextChild)) { // If the child is a record, then the VitalRecord aspect needs to be applied or updated - if (recordService.isRecord(nextChild)) + if (getRecordService().isRecord(nextChild)) { if (parentVri) { - VitalRecordDefinition vrDefn = vitalRecordService.getVitalRecordDefinition(nextChild); + VitalRecordDefinition vrDefn = getVitalRecordService().getVitalRecordDefinition(nextChild); Map aspectProps = new HashMap(); aspectProps.put(PROP_REVIEW_AS_OF, vrDefn.getNextReviewDate()); - nodeService.addAspect(nextChild, RecordsManagementModel.ASPECT_VITAL_RECORD, aspectProps); + getNodeService().addAspect(nextChild, RecordsManagementModel.ASPECT_VITAL_RECORD, aspectProps); } else { - nodeService.removeAspect(nextChild, RecordsManagementModel.ASPECT_VITAL_RECORD); + getNodeService().removeAspect(nextChild, RecordsManagementModel.ASPECT_VITAL_RECORD); } } else // copy the vitalRecordDefinition properties from the parent to the child { - Map childProps = nodeService.getProperties(nextChild); + Map childProps = getNodeService().getProperties(nextChild); childProps.put(PROP_REVIEW_PERIOD, parentReviewPeriod); childProps.put(PROP_VITAL_RECORD_INDICATOR, parentVri); - nodeService.setProperties(nextChild, childProps); + getNodeService().setProperties(nextChild, childProps); } // Recurse down the containment hierarchy to all containers - if (!recordService.isRecord(nextChild)) + if (!getRecordService().isRecord(nextChild)) { this.propagateChangeToChildrenOf(nextChild); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/ReviewedAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/ReviewedAction.java index 79c4633567..7f3b517f26 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/ReviewedAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/ReviewedAction.java @@ -43,16 +43,16 @@ public class ReviewedAction extends RMActionExecuterAbstractBase @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { - VitalRecordDefinition vrDef = vitalRecordService.getVitalRecordDefinition(actionedUponNodeRef); + VitalRecordDefinition vrDef = getVitalRecordService().getVitalRecordDefinition(actionedUponNodeRef); if (vrDef != null && vrDef.isEnabled()) { - if (recordService.isRecord(actionedUponNodeRef)) + if (getRecordService().isRecord(actionedUponNodeRef)) { reviewRecord(actionedUponNodeRef, vrDef); } - else if (recordFolderService.isRecordFolder(actionedUponNodeRef)) + else if (getRecordFolderService().isRecordFolder(actionedUponNodeRef)) { - for (NodeRef record : recordService.getRecords(actionedUponNodeRef)) + for (NodeRef record : getRecordService().getRecords(actionedUponNodeRef)) { reviewRecord(record, vrDef); } @@ -83,7 +83,7 @@ public class ReviewedAction extends RMActionExecuterAbstractBase logger.debug(msg.toString()); } - this.nodeService.setProperty(nodeRef, PROP_REVIEW_AS_OF, reviewAsOf); + this.getNodeService().setProperty(nodeRef, PROP_REVIEW_AS_OF, reviewAsOf); //TODO And record previous review date, time, user } } diff --git a/rm-server/source/java/org/alfresco/repo/action/parameter/DateParameterProcessor.java b/rm-server/source/java/org/alfresco/repo/action/parameter/DateParameterProcessor.java index e8c61e95e0..1c475bc5bd 100644 --- a/rm-server/source/java/org/alfresco/repo/action/parameter/DateParameterProcessor.java +++ b/rm-server/source/java/org/alfresco/repo/action/parameter/DateParameterProcessor.java @@ -221,7 +221,8 @@ public class DateParameterProcessor extends ParameterProcessor implements Parame String namePrefix = this.getName() + "."; if(StringUtils.isBlank(substitutionFragment) || this.getName().toLowerCase().contains(substitutionFragment.toLowerCase())) { - for(String field: ALL_FIELDS_FOR_SUBSTITUTION_QUERY) { + for(String field: ALL_FIELDS_FOR_SUBSTITUTION_QUERY) + { suggestions.add(namePrefix + field); if(suggestions.size() >= maximumNumberSuggestions) { @@ -231,7 +232,8 @@ public class DateParameterProcessor extends ParameterProcessor implements Parame } else { - for(String field: ALL_FIELDS_FOR_SUBSTITUTION_QUERY) { + for(String field: ALL_FIELDS_FOR_SUBSTITUTION_QUERY) + { String prefixFieldName = namePrefix + field; if(prefixFieldName.toLowerCase().contains(substitutionFragment.toLowerCase())) { diff --git a/rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java b/rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java index cb887449ae..e01c1be439 100644 --- a/rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java +++ b/rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java @@ -18,18 +18,25 @@ */ package org.alfresco.repo.security.permissions.impl; +import static org.apache.commons.lang.StringUtils.isNotBlank; + import java.io.Serializable; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +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.security.ExtendedReaderDynamicAuthority; +import org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority; import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.security.permissions.AccessControlEntry; import org.alfresco.repo.security.permissions.AccessControlList; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.util.PropertyCheck; import org.springframework.context.ApplicationEvent; @@ -48,6 +55,29 @@ public class RMPermissionServiceImpl extends PermissionServiceImpl /** Writers simple cache */ protected SimpleCache> writersCache; + /** File plan service */ + private FilePlanService filePlanService; + + /** + * Gets the file plan service + * + * @return the filePlanService + */ + public FilePlanService getFilePlanService() + { + return this.filePlanService; + } + + /** + * Sets the file plan service + * + * @param filePlanService the filePlanService to set + */ + public void setFilePlanService(FilePlanService filePlanService) + { + this.filePlanService = filePlanService; + } + /** * @see org.alfresco.repo.security.permissions.impl.PermissionServiceImpl#setAnyDenyDenies(boolean) */ @@ -263,4 +293,31 @@ public class RMPermissionServiceImpl extends PermissionServiceImpl writersCache.put((Serializable)acl.getProperties(), aclWriters); return aclWriters; } + + /** + * @see org.alfresco.repo.security.permissions.impl.PermissionServiceImpl#setInheritParentPermissions(org.alfresco.service.cmr.repository.NodeRef, boolean) + */ + @Override + public void setInheritParentPermissions(final NodeRef nodeRef, boolean inheritParentPermissions) + { + final String adminRole = getAdminRole(nodeRef); + if (nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT) && isNotBlank(adminRole) && !inheritParentPermissions) + { + setPermission(nodeRef, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true); + setPermission(nodeRef, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true); + setPermission(nodeRef, adminRole, RMPermissionModel.FILING, true); + } + super.setInheritParentPermissions(nodeRef, inheritParentPermissions); + } + + private String getAdminRole(NodeRef nodeRef) + { + String adminRole = null; + NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef); + if (filePlan != null) + { + adminRole = authorityService.getName(AuthorityType.GROUP, FilePlanRoleService.ROLE_ADMIN + filePlan.getId()); + } + return adminRole; + } } diff --git a/rm-server/source/java/org/alfresco/repo/web/scripts/substitutionsuggestions/RmSubstitutionSuggestionsGet.java b/rm-server/source/java/org/alfresco/repo/web/scripts/substitutionsuggestions/RmSubstitutionSuggestionsGet.java index dfc6fffdda..29249ec9fb 100644 --- a/rm-server/source/java/org/alfresco/repo/web/scripts/substitutionsuggestions/RmSubstitutionSuggestionsGet.java +++ b/rm-server/source/java/org/alfresco/repo/web/scripts/substitutionsuggestions/RmSubstitutionSuggestionsGet.java @@ -163,7 +163,8 @@ public class RmSubstitutionSuggestionsGet extends DeclarativeWebScript * @param fragment * @return */ - private List getSubPathSuggestions(WebScriptRequest req, final String path, final String fragment, boolean unfiled) { + private List getSubPathSuggestions(WebScriptRequest req, final String path, final String fragment, boolean unfiled) + { List pathSuggestions = new ArrayList(); if((path != null) && path.startsWith("/") && (fragment != null)) { @@ -177,7 +178,8 @@ public class RmSubstitutionSuggestionsGet extends DeclarativeWebScript { boolean foundThisPathFragment = false; List children = nodeService.getChildAssocs(currentNode); - for (ChildAssociationRef childAssoc : children) { + for (ChildAssociationRef childAssoc : children) + { NodeRef childNodeRef = childAssoc.getChildRef(); String fileName = (String) nodeService.getProperty(childNodeRef, ContentModel.PROP_NAME); if(fileName.equals(pathFragment) && isNodeRefAppropriateForPathSuggestion(childNodeRef, unfiled)) @@ -199,7 +201,8 @@ public class RmSubstitutionSuggestionsGet extends DeclarativeWebScript { String lowerCaseFragment = fragment.toLowerCase(); List children = nodeService.getChildAssocs(currentNode); - for (ChildAssociationRef childAssoc : children) { + for (ChildAssociationRef childAssoc : children) + { NodeRef childNodeRef = childAssoc.getChildRef(); String fileName = (String) nodeService.getProperty(childNodeRef, ContentModel.PROP_NAME); if((fragment.isEmpty() || fileName.toLowerCase().startsWith(lowerCaseFragment)) && isNodeRefAppropriateForPathSuggestion(childNodeRef, unfiled)) diff --git a/rm-server/source/java/org/alfresco/util/WebScriptUtils.java b/rm-server/source/java/org/alfresco/util/WebScriptUtils.java index 79806c52ea..131687fe7a 100644 --- a/rm-server/source/java/org/alfresco/util/WebScriptUtils.java +++ b/rm-server/source/java/org/alfresco/util/WebScriptUtils.java @@ -267,7 +267,7 @@ public final class WebScriptUtils } catch (JSONException error) { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not put the key '" + key + "' with the value '" + value + "' to the json object."); + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not put the key '" + key + "' with the value '" + value + "' to the json object.", error); } } @@ -295,4 +295,28 @@ public final class WebScriptUtils return value; } + + /** + * Creates a json object from the given {@link String} + * + * @param json The json object as {@link String} + * @return The json object created from the given {@link String} + */ + public static JSONObject createJSONObject(String json) + { + mandatory("json", json); + + JSONObject jsonObject; + + try + { + jsonObject = new JSONObject(json); + } + catch (JSONException error) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Cannot create a json object from the given string '" + json + "'.", error); + } + + return jsonObject; + } } diff --git a/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoUtils.java b/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoUtils.java index d7aa24145a..ce435543da 100644 --- a/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoUtils.java +++ b/rm-server/source/java/org/alfresco/workflow/requestInfo/RequestInfoUtils.java @@ -23,6 +23,7 @@ import java.util.List; import org.activiti.engine.delegate.DelegateTask; import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.activiti.engine.impl.context.Context; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.workflow.activiti.ActivitiConstants; @@ -61,7 +62,7 @@ public final class RequestInfoUtils ServiceRegistry registry = (ServiceRegistry) config.getBeans().get(ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY); if (registry == null) { - throw new RuntimeException( + throw new AlfrescoRuntimeException( "Service-registry not present in ProcessEngineConfiguration beans, expected ServiceRegistry with key" + ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY); } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/IntegrationTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/IntegrationTestSuite.java index 0a675eb2b8..2c7c2b723a 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/IntegrationTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/IntegrationTestSuite.java @@ -26,6 +26,7 @@ import org.alfresco.module.org_alfresco_module_rm.test.integration.issue.IssueTe import org.alfresco.module.org_alfresco_module_rm.test.integration.job.JobTestSuite; import org.alfresco.module.org_alfresco_module_rm.test.integration.record.RecordTestSuite; import org.alfresco.module.org_alfresco_module_rm.test.integration.recordfolder.RecordFolderTestSuite; +import org.alfresco.module.org_alfresco_module_rm.test.integration.relationship.RelationshipTestSuite; import org.alfresco.module.org_alfresco_module_rm.test.integration.report.ReportTestSuite; import org.alfresco.module.org_alfresco_module_rm.test.integration.version.VersionTestSuite; import org.junit.runner.RunWith; @@ -51,7 +52,8 @@ import org.junit.runners.Suite.SuiteClasses; RecordFolderTestSuite.class, JobTestSuite.class, HoldTestSuite.class, - VersionTestSuite.class + VersionTestSuite.class, + RelationshipTestSuite.class }) public class IntegrationTestSuite { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java index 68c94d1e80..2c11e9689e 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java @@ -40,7 +40,9 @@ import org.junit.runners.Suite.SuiteClasses; RM1464Test.class, RM452Test.class, RM804Test.class, - RM994Test.class + RM994Test.class, + RM1039Test.class, + RM1799Test.class }) public class IssueTestSuite { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1008Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1008Test.java index 4c611c7477..0066a3ea58 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1008Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1008Test.java @@ -181,8 +181,9 @@ public class RM1008Test extends BaseRMTestCase Capability viewRecords = capabilityService.getCapability("ViewRecords"); assertNotNull(viewRecords); - assertEquals(AccessStatus.ALLOWED, viewRecords.hasPermission(hold)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(hold, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, viewRecords.hasPermission(hold)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(hold, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(hold, RMPermissionModel.FILING)); return null; } @@ -292,7 +293,7 @@ public class RM1008Test extends BaseRMTestCase Capability viewRecords = capabilityService.getCapability("ViewRecords"); assertNotNull(viewRecords); - assertEquals(AccessStatus.ALLOWED, viewRecords.hasPermission(transfer)); + assertEquals(AccessStatus.DENIED, viewRecords.hasPermission(transfer)); assertEquals(AccessStatus.DENIED, permissionService.hasPermission(transfer, RMPermissionModel.FILING)); return null; @@ -318,8 +319,9 @@ public class RM1008Test extends BaseRMTestCase Capability viewRecords = capabilityService.getCapability("ViewRecords"); assertNotNull(viewRecords); - assertEquals(AccessStatus.ALLOWED, viewRecords.hasPermission(transfer)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(transfer, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, viewRecords.hasPermission(transfer)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(transfer, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(transfer, RMPermissionModel.FILING)); return null; } @@ -344,7 +346,7 @@ public class RM1008Test extends BaseRMTestCase Capability viewRecords = capabilityService.getCapability("ViewRecords"); assertNotNull(viewRecords); - assertEquals(AccessStatus.ALLOWED, viewRecords.hasPermission(transfer)); + assertEquals(AccessStatus.DENIED, viewRecords.hasPermission(transfer)); assertEquals(AccessStatus.DENIED, permissionService.hasPermission(transfer, RMPermissionModel.FILING)); return null; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1039Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1039Test.java new file mode 100644 index 0000000000..512d16709d --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1039Test.java @@ -0,0 +1,186 @@ +/* + * 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.test.integration.issue; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import net.sf.acegisecurity.vote.AccessDecisionVoter; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.action.impl.CompleteEventAction; +import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; +import org.alfresco.module.org_alfresco_module_rm.capability.Capability; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils; +import org.alfresco.service.cmr.repository.NodeRef; + + +/** + * Unit test for RM-1039 ... can't move a folder into a category with a disposition schedule + * + * @author Roy Wetherall + * @since 2.1 + */ +public class RM1039Test extends BaseRMTestCase +{ + @Override + protected boolean isRecordTest() + { + return true; + } + + // try and move a folder from no disposition schedule to a disposition schedule + public void testMoveRecordFolderFromNoDisToDis() throws Exception + { + final NodeRef recordFolder = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create a record category (no disposition schedule) + NodeRef recordCategory = filePlanService.createRecordCategory(filePlan, "Caitlin Reed"); + + // create a record folder + return recordFolderService.createRecordFolder(recordCategory, "Grace Wetherall"); + } + + @Override + public void test(NodeRef result) throws Exception + { + assertNotNull(result); + assertNull(dispositionService.getDispositionSchedule(result)); + assertFalse(nodeService.hasAspect(result, ASPECT_DISPOSITION_LIFECYCLE)); + } + }); + + final NodeRef record = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create a record + return fileFolderService.create(recordFolder, "mytest.txt", ContentModel.TYPE_CONTENT).getNodeRef(); + } + + @Override + public void test(NodeRef result) throws Exception + { + assertNotNull(result); + assertNull(dispositionService.getDispositionSchedule(result)); + assertFalse(nodeService.hasAspect(result, ASPECT_DISPOSITION_LIFECYCLE)); + } + }); + + doTestInTransaction(new Test() + { + @Override + public NodeRef run() throws Exception + { + Capability capability = capabilityService.getCapability("CreateModifyDestroyFolders"); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, capability.evaluate(recordFolder)); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, capability.evaluate(recordFolder, rmContainer)); + + // take a look at the move capability + Capability moveCapability = capabilityService.getCapability("Move"); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, moveCapability.evaluate(recordFolder, rmContainer)); + + // move the node + return fileFolderService.move(recordFolder, rmContainer, null).getNodeRef(); + } + + @Override + public void test(NodeRef result) throws Exception + { + assertNotNull(result); + assertNotNull(dispositionService.getDispositionSchedule(result)); + assertTrue(nodeService.hasAspect(result, ASPECT_DISPOSITION_LIFECYCLE)); + + DispositionAction dispositionAction = dispositionService.getNextDispositionAction(result); + assertNotNull(dispositionAction); + + assertNull(dispositionAction.getAsOfDate()); + assertEquals("cutoff", dispositionAction.getName()); + assertEquals(1, dispositionAction.getEventCompletionDetails().size()); + + // take a look at the record and check things are as we would expect + assertFalse(nodeService.hasAspect(record, ASPECT_DISPOSITION_LIFECYCLE)); + } + }); + } + + // move from a disposition schedule to another .. both record folder level + + // move from a disposition schedule to another .. from record to folder level + + + // try and move a cutoff folder + public void testMoveCutoffRecordFolder() throws Exception + { + final NodeRef destination = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create a record category (no disposition schedule) + return filePlanService.createRecordCategory(filePlan, "Caitlin Reed"); + } + }); + + final NodeRef testFolder = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create folder + NodeRef testFolder = recordFolderService.createRecordFolder(rmContainer, "Peter Edward Francis"); + + // complete event + Map params = new HashMap(1); + params.put(CompleteEventAction.PARAM_EVENT_NAME, CommonRMTestUtils.DEFAULT_EVENT_NAME); + rmActionService.executeRecordsManagementAction(testFolder, CompleteEventAction.NAME, params); + + // cutoff folder + rmActionService.executeRecordsManagementAction(testFolder, CutOffAction.NAME); + + return testFolder; + } + + @Override + public void test(NodeRef result) throws Exception + { + // take a look at the move capability + Capability moveCapability = capabilityService.getCapability("Move"); + assertEquals(AccessDecisionVoter.ACCESS_DENIED, moveCapability.evaluate(result, destination)); + + } + }); + + doTestInTransaction(new FailureTest() + { + @Override + public void run() throws Exception + { + fileFolderService.move(testFolder, destination, null).getNodeRef(); + } + }); + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java index 5d164ec3b7..78eacc5927 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java @@ -23,6 +23,7 @@ import java.util.List; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; 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.test.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; @@ -65,7 +66,7 @@ public class RM1424Test extends DeleteHoldTest assertEquals(HOLD1_DESC, (String) nodeService.getProperty(hold1, PROP_DESCRIPTION)); // Add the user to the RM Manager role - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_RECORDS_MANAGER, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER, userName); return null; } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java index 1f86f34344..96e835729d 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java @@ -20,6 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; @@ -43,7 +44,7 @@ public class RM1429Test extends DeleteHoldTest public Void run() { // Add the user to the RM Manager role - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_RECORDS_MANAGER, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER, userName); // Give the user filing permissions on the hold permissionService.setPermission(hold, userName, RMPermissionModel.FILING, true); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java index b3cb232051..074eb27e83 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java @@ -20,6 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; @@ -43,7 +44,7 @@ public class RM1463Test extends DeleteHoldTest public Void run() { // Add the user to the RM Manager role - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_RECORDS_MANAGER, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER, userName); // Give the user filing permissions on the hold permissionService.setPermission(hold, userName, RMPermissionModel.FILING, true); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java index 4220dbc896..5a009bb620 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java @@ -20,6 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; @@ -43,7 +44,7 @@ public class RM1464Test extends DeleteHoldTest public Void run() { // Add the user to the RM Manager role - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_RECORDS_MANAGER, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER, userName); // Give the user read permissions on the hold permissionService.setPermission(hold, userName, RMPermissionModel.READ_RECORDS, true); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1799Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1799Test.java new file mode 100644 index 0000000000..5a1253ade4 --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1799Test.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2005-2015 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.integration.issue; + +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.util.GUID; + +/** + * Test for RM-1799 + * + * @author Tuna Aksoy + * @since 2.3 + */ +public class RM1799Test extends BaseRMTestCase +{ + private String myUser; + private NodeRef category; + + @Override + protected boolean isRecordTest() + { + return true; + } + + @Override + protected boolean isUserTest() + { + return true; + } + + @Override + protected void setupTestUsersImpl(NodeRef filePlan) + { + super.setupTestUsersImpl(filePlan); + + myUser = GUID.generate(); + createPerson(myUser); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER, myUser); + } + + public void testRM1799() throws Exception + { + doTestInTransaction(new Test() + { + @Override + public Void run() + { + filePlanPermissionService.setPermission(filePlan, myUser, RMPermissionModel.FILING); + return null; + } + }, ADMIN_USER); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + category = filePlanService.createRecordCategory(filePlan, GUID.generate()); + return null; + } + }, myUser); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category, RMPermissionModel.FILING)); + return null; + } + }, myUser); + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM804Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM804Test.java index 99e012d2a1..a8c96e8df2 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM804Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM804Test.java @@ -19,6 +19,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.site.SiteRole; @@ -142,7 +143,7 @@ public class RM804Test extends BaseRMTestCase @Override public Void run() { - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_USER, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_USER, userName); return null; } @@ -167,7 +168,7 @@ public class RM804Test extends BaseRMTestCase @Override public Void run() { - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_ADMINISTRATOR, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_ADMIN, userName); return null; } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/job/AutomaticDispositionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/job/AutomaticDispositionTest.java index c3c732dcf5..d2491dcd28 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/job/AutomaticDispositionTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/job/AutomaticDispositionTest.java @@ -30,7 +30,7 @@ import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; -import org.springframework.extensions.webscripts.GUID; +import org.alfresco.util.GUID; /** * Test automatic disposition via scheduled job. @@ -68,63 +68,63 @@ public class AutomaticDispositionTest extends BaseRMTestCase * Given there is a complete record eligible for cut off, when the correct frequency of time passes, then * the record will be automatically cut off */ -// FIXME!!!: Commented out. Will be fixed. -// public void testAutomaticCutOff() -// { -// doBehaviourDrivenTest(new BehaviourDrivenTest() -// { -// NodeRef sourceCategory; -// NodeRef sourceRecordFolder; -// NodeRef record; + public void testAutomaticCutOff() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + NodeRef sourceCategory; + NodeRef sourceRecordFolder; + NodeRef record; + + public void given() + { + // create test data + sourceCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + DispositionSchedule dis = utils.createBasicDispositionSchedule(sourceCategory, GUID.generate(), GUID.generate(), true, false); + Map adParams = new HashMap(3); + adParams.put(PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); + adParams.put(PROP_DISPOSITION_DESCRIPTION, GUID.generate()); + adParams.put(PROP_DISPOSITION_PERIOD, CommonRMTestUtils.PERIOD_IMMEDIATELY); + dispositionService.addDispositionActionDefinition(dis, adParams); + sourceRecordFolder = recordFolderService.createRecordFolder(sourceCategory, GUID.generate()); + + // create and complete record + record = utils.createRecord(sourceRecordFolder, GUID.generate()); + utils.completeRecord(record); + + // check the disposition action details + DispositionAction dispositionAction = dispositionService.getNextDispositionAction(record); + assertNotNull(dispositionAction); + assertNotNull(CutOffAction.NAME, dispositionAction.getName()); + assertTrue(dispositionService.isNextDispositionActionEligible(record)); + } + + public void when() throws Exception + { + // sleep .. allowing the job time to execute + Thread.sleep(30000); + } + + public void then() + { + // record should now be cut off + assertTrue(dispositionService.isDisposableItemCutoff(record)); + + // TODO .. automatic dispoistion does not log entry in audit + // .. the following test checks for this, but is currently commented out + // .. because it doesn't work! +// RecordsManagementAuditQueryParameters params = new RecordsManagementAuditQueryParameters(); +// params.setEvent(CutOffAction.NAME); +// params.setMaxEntries(1); +// List entries = auditService.getAuditTrail(params); +// assertNotNull(entries); +// assertEquals(1, entries.size()); // -// public void given() -// { -// // create test data -// sourceCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); -// DispositionSchedule dis = utils.createBasicDispositionSchedule(sourceCategory, GUID.generate(), GUID.generate(), true, false); -// Map adParams = new HashMap(3); -// adParams.put(PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); -// adParams.put(PROP_DISPOSITION_DESCRIPTION, GUID.generate()); -// adParams.put(PROP_DISPOSITION_PERIOD, CommonRMTestUtils.PERIOD_IMMEDIATELY); -// dispositionService.addDispositionActionDefinition(dis, adParams); -// sourceRecordFolder = recordFolderService.createRecordFolder(sourceCategory, GUID.generate()); -// -// // create and complete record -// record = utils.createRecord(sourceRecordFolder, GUID.generate()); -// utils.completeRecord(record); -// -// // check the disposition action details -// DispositionAction dispositionAction = dispositionService.getNextDispositionAction(record); -// assertNotNull(dispositionAction); -// assertNotNull(CutOffAction.NAME, dispositionAction.getName()); -// assertTrue(dispositionService.isNextDispositionActionEligible(record)); -// } -// -// public void when() throws Exception -// { -// // sleep .. allowing the job time to execute -// Thread.sleep(30000); -// } -// -// public void then() -// { -// // record should now be cut off -// assertTrue(dispositionService.isDisposableItemCutoff(record)); -// -// // TODO uncomment and ensure is working -// -// //RecordsManagementAuditQueryParameters params = new RecordsManagementAuditQueryParameters(); -// //params.setEvent(CutOffAction.NAME); -// //params.setMaxEntries(1); -// //List entries = auditService.getAuditTrail(params); -// //assertNotNull(entries); -// //assertEquals(1, entries.size()); -// -// //RecordsManagementAuditEntry entry = entries.get(0); -// //assertEquals(record, entry.getNodeRef()); -// } -// }); -// } +// RecordsManagementAuditEntry entry = entries.get(0); +// assertEquals(record, entry.getNodeRef()); + } + }); + } // TODO automatic retain diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/CreateRecordTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/CreateRecordTest.java index 8ebcbea4f8..9be23993f0 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/CreateRecordTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/CreateRecordTest.java @@ -149,4 +149,56 @@ public class CreateRecordTest extends BaseRMTestCase } }); } + + /** + * unit test for RM1649 fix + * test if a user with create record permissions and without file record permission is able to create a record within unfiled record container + */ + public void testCreateRecordCapabilityInsideUnfiledRecordsContainer() throws Exception + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + /** test data */ + String roleName = GUID.generate(); + String user = GUID.generate(); + NodeRef record; + + public void given() + { + // create a role with view and create capabilities + Set capabilities = new HashSet(2); + capabilities.add(capabilityService.getCapability("ViewRecords")); + capabilities.add(capabilityService.getCapability("CreateRecords")); + filePlanRoleService.createRole(filePlan, roleName, roleName, capabilities); + + + // create user and assign to role + createPerson(user, true); + filePlanRoleService.assignRoleToAuthority(filePlan, roleName, user); + + //give read and file permission to user on unfiled records container + filePlanPermissionService.setPermission(unfiledContainer , user, RMPermissionModel.FILING); + } + + public void when() + { + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + record = recordService.createRecordFromContent(unfiledContainer, GUID.generate(), TYPE_CONTENT, null, null); + + return null; + } + }, user); + } + + public void then() + { + // check the details of the record + assertTrue(recordService.isRecord(record)); + + } + }); + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/MoveInplaceRecordTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/MoveInplaceRecordTest.java index a0e5dfc6b9..9c05652660 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/MoveInplaceRecordTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/MoveInplaceRecordTest.java @@ -18,7 +18,10 @@ */ package org.alfresco.module.org_alfresco_module_rm.test.integration.record; +import static org.apache.commons.collections.ListUtils.removeAll; + import java.util.List; +import java.util.Set; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; @@ -54,6 +57,10 @@ public class MoveInplaceRecordTest extends BaseRMTestCase // The destination folder in collaboration site private NodeRef destinationDmFolder; + // Extended Readers/Writers + private Set extendedReadersBeforeMove; + private Set extendedWritersBeforeMove; + public void given() { // Create the destination folder @@ -76,6 +83,9 @@ public class MoveInplaceRecordTest extends BaseRMTestCase // Check that the document is a record now assertTrue(recordService.isRecord(dmDocument)); + + extendedReadersBeforeMove = extendedSecurityService.getExtendedReaders(dmDocument); + extendedWritersBeforeMove = extendedSecurityService.getExtendedWriters(dmDocument); } public void when() @@ -100,6 +110,16 @@ public class MoveInplaceRecordTest extends BaseRMTestCase List destinationFolderChildAssocs = nodeService.getChildAssocs(destinationDmFolder); assertEquals(1, destinationFolderChildAssocs.size()); assertEquals(dmDocument, destinationFolderChildAssocs.get(0).getChildRef()); + + // Check extended readers/writers + Set extendedReadersAfterMove = extendedSecurityService.getExtendedReaders(dmDocument); + Set extendedWritersAfterMove = extendedSecurityService.getExtendedWriters(dmDocument); + + assertEquals(extendedReadersBeforeMove.size(), extendedReadersAfterMove.size()); + assertEquals(extendedWritersBeforeMove.size(), extendedWritersAfterMove.size()); + + assertEquals(0, removeAll(extendedReadersBeforeMove, extendedReadersAfterMove).size()); + assertEquals(0, removeAll(extendedWritersBeforeMove, extendedWritersAfterMove).size()); } }); } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RejectRecordTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RejectRecordTest.java index 1d0e78f33a..4aa12bd50c 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RejectRecordTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RejectRecordTest.java @@ -31,38 +31,38 @@ import org.springframework.extensions.webscripts.GUID; /** * reject record tests. - * + * * @author Roy Wetherall * @since 2.2 */ public class RejectRecordTest extends BaseRMTestCase -{ - private VersionService versionService; - +{ + private VersionService versionService; + private static final String REASON = GUID.generate(); - + @Override protected boolean isUserTest() { return true; } - + @Override protected boolean isCollaborationSiteTest() { return true; } - + @Override protected void initServices() { super.initServices(); - + versionService = (VersionService)applicationContext.getBean("VersionService"); } - + /** - * + * */ public void testRejectedRecordInCorrectState() throws Exception { @@ -71,30 +71,30 @@ public class RejectRecordTest extends BaseRMTestCase public void given() { assertFalse(recordService.isRecord(dmDocument)); - ownableService.setOwner(dmDocument, userName); - + ownableService.setOwner(dmDocument, userName); + // document is declared as a record by user AuthenticationUtil.runAs(new RunAsWork() { public Void doWork() throws Exception { // declare record - recordService.createRecord(filePlan, dmDocument); + recordService.createRecord(filePlan, dmDocument); return null; } }, userName); } - + public void when() { // sanity checks assertTrue(recordService.isRecord(dmDocument)); - assertFalse(permissionService.getInheritParentPermissions(dmDocument)); - + assertTrue(permissionService.getInheritParentPermissions(dmDocument)); + // declare record - recordService.rejectRecord(dmDocument, REASON); + recordService.rejectRecord(dmDocument, REASON); } - + public void then() { // document is no longer a record @@ -105,47 +105,47 @@ public class RejectRecordTest extends BaseRMTestCase assertTrue(permissionService.getInheritParentPermissions(dmDocument)); assertFalse(nodeService.hasAspect(dmDocument, ASPECT_FILE_PLAN_COMPONENT)); } - }); + }); } - + /** - * + * */ public void testRevertAfterReject() throws Exception { doBehaviourDrivenTest(new BehaviourDrivenTest() {; private NodeRef document; - + public void given() { NodeRef folder = fileFolderService.create(documentLibrary, GUID.generate(), TYPE_FOLDER).getNodeRef(); document = fileFolderService.create(folder, GUID.generate(), TYPE_CONTENT).getNodeRef(); - + assertFalse(recordService.isRecord(document)); - ownableService.setOwner(document, userName); + ownableService.setOwner(document, userName); versionService.ensureVersioningEnabled(document, null); - + // document is declared as a record by user AuthenticationUtil.runAs(new RunAsWork() { public Void doWork() throws Exception { // declare record - recordService.createRecord(filePlan, document); + recordService.createRecord(filePlan, document); return null; } }, userName); - - assertTrue(nodeService.hasAspect(document, ASPECT_FILE_PLAN_COMPONENT)); + + assertTrue(nodeService.hasAspect(document, ASPECT_FILE_PLAN_COMPONENT)); } - + public void when() - { + { // reject the record - recordService.rejectRecord(document, REASON); + recordService.rejectRecord(document, REASON); assertFalse(nodeService.hasAspect(document, ASPECT_FILE_PLAN_COMPONENT)); - + // upload a new version of the document AuthenticationUtil.runAs(new RunAsWork() { @@ -154,31 +154,31 @@ public class RejectRecordTest extends BaseRMTestCase ContentWriter writer = contentService.getWriter(document, ContentModel.PROP_CONTENT, true); writer.putContent("This is a change to the content and should force a new version"); versionService.createVersion(document, null); - + return null; } }, userName); - + assertFalse(nodeService.hasAspect(document, ASPECT_FILE_PLAN_COMPONENT)); - + VersionHistory history = versionService.getVersionHistory(document); assertEquals(2, history.getAllVersions().size()); final Version initial = history.getRootVersion(); - + assertFalse(nodeService.hasAspect(initial.getFrozenStateNodeRef(), ASPECT_FILE_PLAN_COMPONENT)); - + AuthenticationUtil.runAs(new RunAsWork() { public Void doWork() throws Exception - { + { // revert the document to a previous version versionService.revert(document, initial); - + return null; } }, userName); } - + public void then() { // document is no longer a record @@ -187,6 +187,6 @@ public class RejectRecordTest extends BaseRMTestCase // expected owner has be re-set assertEquals(userName, ownableService.getOwner(document)); } - }); - } + }); + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/relationship/DeleteRelationshipTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/relationship/DeleteRelationshipTest.java new file mode 100644 index 0000000000..b2decc305b --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/relationship/DeleteRelationshipTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +package org.alfresco.module.org_alfresco_module_rm.test.integration.relationship; + +import java.util.Set; +import org.alfresco.module.org_alfresco_module_rm.relationship.Relationship; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.util.GUID; + +/** + * Delete relationship test. + * + * @author Ana Bozianu + * @since 2.3 + */ +public class DeleteRelationshipTest extends BaseRMTestCase +{ + public void testDeleteRelationship() throws Exception + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + /** test data */ + NodeRef sourceNode; + NodeRef targetNode; + String associationName = "obsoletes"; + + public void given() + { + + // create the source record + sourceNode = utils.createRecord(rmFolder, GUID.generate()); + + //create the target record + targetNode = utils.createRecord(rmFolder, GUID.generate()); + + //create relationship + relationshipService.addRelationship(associationName, sourceNode, targetNode); + } + + public void when() + { + //delete relationship + relationshipService.removeRelationship(associationName, sourceNode, targetNode); + } + + public void then() + { + //check if relationship is deleted + Set relationships = relationshipService.getRelationshipsFrom(sourceNode); + for(Relationship r : relationships) + { + assertFalse(r.getTarget().equals(targetNode) && r.getUniqueName().equals(associationName)); + } + } + }); + } + + +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/relationship/RelationshipTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/relationship/RelationshipTestSuite.java new file mode 100755 index 0000000000..da0fe63a5e --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/relationship/RelationshipTestSuite.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.test.integration.relationship; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * Relationship integration test suite + * + * @author Roy Wetherall + * @since 2.3 + */ +@RunWith(Suite.class) +@SuiteClasses( +{ + DeleteRelationshipTest.class +}) +public class RelationshipTestSuite +{ +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AdHocRecordableVersions.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AdHocRecordableVersions.java index a529df9f8c..4ac4106b6c 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AdHocRecordableVersions.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/version/AdHocRecordableVersions.java @@ -25,6 +25,8 @@ import java.util.Map; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.test.util.TestModel; import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionServiceImpl; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.version.VersionModel; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.version.Version; @@ -160,13 +162,21 @@ public class AdHocRecordableVersions extends RecordableVersionsBaseTest public void when() { // create version - Version version = versionService.createVersion(dmDocument, versionProperties); + final Version version = versionService.createVersion(dmDocument, versionProperties); - // add custom meta-data to record - NodeRef record = (NodeRef)version.getVersionProperties().get(RecordableVersionServiceImpl.PROP_VERSION_RECORD); - assertNotNull(record); - recordService.addRecordType(record, TestModel.ASPECT_RECORD_METADATA); - nodeService.setProperty(record, TestModel.PROPERTY_RECORD_METADATA, "Peter Wetherall"); + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // add custom meta-data to record + NodeRef record = (NodeRef)version.getVersionProperties().get(RecordableVersionServiceImpl.PROP_VERSION_RECORD); + assertNotNull(record); + recordService.addRecordType(record, TestModel.ASPECT_RECORD_METADATA); + nodeService.setProperty(record, TestModel.PROPERTY_RECORD_METADATA, "Peter Wetherall"); + + return null; + } + }, AuthenticationUtil.getAdminUserName()); } public void then() diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/ActionTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/ActionTestSuite.java index c9fdd2b62a..47b44bcab7 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/ActionTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/ActionTestSuite.java @@ -36,7 +36,8 @@ import org.junit.runners.Suite.SuiteClasses; HideRecordActionTest.class, RejectActionTest.class, FileToActionTest.class, - FileReportActionTest.class + FileReportActionTest.class, + RecordableVersionConfigActionTest.class }) public class ActionTestSuite { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/RecordableVersionConfigActionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/RecordableVersionConfigActionTest.java new file mode 100644 index 0000000000..448c00aa27 --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/RecordableVersionConfigActionTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.test.legacy.action; + +import static org.alfresco.module.org_alfresco_module_rm.action.dm.RecordableVersionConfigAction.NAME; +import static org.alfresco.module.org_alfresco_module_rm.action.dm.RecordableVersionConfigAction.PARAM_VERSION; +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY; +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy.ALL; +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy.MAJOR_ONLY; +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy.NONE; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * Recordable version config action test + * + * @author Tuna Aksoy + * @since 2.3 + */ +public class RecordableVersionConfigActionTest extends BaseRMTestCase +{ + /** + * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#isUserTest() + */ + @Override + protected boolean isUserTest() + { + return true; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#isCollaborationSiteTest() + */ + @Override + protected boolean isCollaborationSiteTest() + { + return true; + } + + public void testRecordableVersionConfigAction() + { + // Uncommented due to the failures on bamboo. Also this is related to RM-1758 + /* + doTestInTransaction(new Test() + { + final NodeRef document1 = fileFolderService.create(dmFolder, "aDocument", ContentModel.TYPE_CONTENT).getNodeRef(); + public Void run() + { + Action action = actionService.createAction(NAME); + action.setParameterValue(PARAM_VERSION, MAJOR_ONLY.toString()); + actionService.executeAction(action, document1); + return null; + } + + public void test(Void result) throws Exception + { + Serializable version = nodeService.getProperty(document1, PROP_RECORDABLE_VERSION_POLICY); + assertNotNull(version); + assertEquals(MAJOR_ONLY.toString(), (String) version); + }; + }, + dmCollaborator); + */ + + doTestInTransaction(new Test() + { + public Void run() + { + Action action = actionService.createAction(NAME); + action.setParameterValue(PARAM_VERSION, ALL.toString()); + actionService.executeAction(action, dmFolder); + return null; + } + + public void test(Void result) throws Exception + { + assertNull(nodeService.getProperty(dmFolder, PROP_RECORDABLE_VERSION_POLICY)); + }; + }, + dmCollaborator); + + doTestInTransaction(new Test() + { + final NodeRef document2 = fileFolderService.create(dmFolder, "another document", ContentModel.TYPE_CONTENT).getNodeRef(); + public Void run() + { + Action action = actionService.createAction(NAME); + action.setParameterValue(PARAM_VERSION, NONE.toString()); + actionService.executeAction(action, document2); + return null; + } + + public void test(Void result) throws Exception + { + assertNull(nodeService.getProperty(document2, PROP_RECORDABLE_VERSION_POLICY)); + }; + }, + dmCollaborator); + + + doTestInTransaction(new Test() + { + final NodeRef document3 = fileFolderService.create(dmFolder, "testfile.txt", ContentModel.TYPE_CONTENT).getNodeRef(); + public Void run() + { + Action createAction = actionService.createAction(CreateRecordAction.NAME); + createAction.setParameterValue(CreateRecordAction.PARAM_FILE_PLAN, filePlan); + actionService.executeAction(createAction, document3); + + Action action = actionService.createAction(NAME); + action.setParameterValue(PARAM_VERSION, MAJOR_ONLY.toString()); + actionService.executeAction(action, document3); + return null; + } + + public void test(Void result) throws Exception + { + assertNull(nodeService.getProperty(document3, PROP_RECORDABLE_VERSION_POLICY)); + }; + }, + dmCollaborator); + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/capabilities/DeclarativeCapabilityTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/capabilities/DeclarativeCapabilityTest.java index 6581d3a800..a21d341b5e 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/capabilities/DeclarativeCapabilityTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/capabilities/DeclarativeCapabilityTest.java @@ -60,7 +60,7 @@ public class DeclarativeCapabilityTest extends BaseRMTestCase private NodeRef moveToFolder; private NodeRef moveToCategory; - + private NodeRef hold; @Override @@ -109,9 +109,9 @@ public class DeclarativeCapabilityTest extends BaseRMTestCase utils.completeRecord(declaredRecord); utils.completeRecord(frozenRecord); utils.completeRecord(frozenRecord2); - + hold = holdService.createHold(filePlan, GUID.generate(), "reason", "description"); - + holdService.addToHold(hold, frozenRecord); holdService.addToHold(hold, frozenRecordFolder); holdService.addToHold(hold, frozenRecord2); @@ -141,6 +141,7 @@ public class DeclarativeCapabilityTest extends BaseRMTestCase for (String user : testUsers) { filePlanPermissionService.setPermission(rmFolder, user, RMPermissionModel.FILING); + filePlanPermissionService.setPermission(rmContainer, user, RMPermissionModel.READ_RECORDS); filePlanPermissionService.setPermission(moveToFolder, user, RMPermissionModel.READ_RECORDS); filePlanPermissionService.setPermission(moveToCategory, user, RMPermissionModel.READ_RECORDS); } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/DispositionServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/DispositionServiceImplTest.java index 7872524a00..a2cdf3cdb7 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/DispositionServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/DispositionServiceImplTest.java @@ -908,117 +908,116 @@ public class DispositionServiceImplTest extends BaseRMTestCase * Test to make sure all the search rollups are correct after schedule is updated * @throws Exception */ -// FIXME!!!: Commented out. Will be fixed. -// public void testRM386() throws Exception -// { -// doTestInTransaction(new Test() -// { -// @Override -// public Void run() throws Exception -// { -// testRM386RecordCategory = filePlanService.createRecordCategory(rmContainer, "RM386"); -// testRM386DispositionSchedule = utils.createBasicDispositionSchedule( -// testRM386RecordCategory, -// "disposition instructions", -// "disposition authority", -// true, // record level -// true); // set the default actions -// -// NodeRef recordFolder = recordFolderService.createRecordFolder(testRM386RecordCategory, "testRM386RecordFolder"); -// testRM386Record = utils.createRecord(recordFolder, "testRM386Record", "testRM386Record"); -// -// return null; -// } -// -// @SuppressWarnings("unchecked") -// @Override -// public void test(Void result) throws Exception -// { -// // Test the rollups for the record -// Map properties = nodeService.getProperties(testRM386Record); -// -// assertEquals(Boolean.TRUE, properties.get(PROP_RS_HAS_DISPOITION_SCHEDULE)); -// assertEquals(CommonRMTestUtils.DEFAULT_DISPOSITION_AUTHORITY, properties.get(PROP_RS_DISPOITION_AUTHORITY)); -// assertEquals(CommonRMTestUtils.DEFAULT_DISPOSITION_INSTRUCTIONS, properties.get(PROP_RS_DISPOITION_INSTRUCTIONS)); -// -// assertEquals("none", properties.get(PROP_RS_DISPOSITION_PERIOD)); -// assertEquals("0", properties.get(PROP_RS_DISPOSITION_PERIOD_EXPRESSION)); -// -// List events = (List)properties.get(PROP_RS_DISPOSITION_EVENTS); -// assertNotNull(events); -// assertEquals(1, events.size()); -// assertEquals(CommonRMTestUtils.DEFAULT_EVENT_NAME, events.get(0)); -// assertEquals(Boolean.FALSE, properties.get(PROP_RS_DISPOSITION_EVENTS_ELIGIBLE)); -// -// assertEquals("cutoff", properties.get(PROP_RS_DISPOSITION_ACTION_NAME)); -// assertNull(properties.get(PROP_RS_DISPOSITION_ACTION_AS_OF)); -// } -// }); -// -// doTestInTransaction(new Test() -// { -// @Override -// public DispositionActionDefinition run() throws Exception -// { -// DispositionActionDefinition actionDefinition = testRM386DispositionSchedule.getDispositionActionDefinitionByName("cutoff"); -// assertNotNull(actionDefinition); -// -// Map adParams = new HashMap(3); -// -// List events = new ArrayList(1); -// events.add(CommonRMTestUtils.DEFAULT_EVENT_NAME); -// events.add("obsolete"); -// adParams.put(PROP_DISPOSITION_EVENT, (Serializable)events); -// adParams.put(PROP_DISPOSITION_PERIOD, "week|1"); -// -// dispositionService.updateDispositionActionDefinition( -// actionDefinition, -// adParams); -// -// return actionDefinition; -// } -// -// @SuppressWarnings("unchecked") -// @Override -// public void test(DispositionActionDefinition result) throws Exception -// { -// DispositionActionDefinition actionDefinition = testRM386DispositionSchedule.getDispositionActionDefinitionByName("cutoff"); -// assertNotNull(actionDefinition); -// assertTrue(nodeService.hasAspect(actionDefinition.getNodeRef(), ASPECT_UNPUBLISHED_UPDATE)); -// -// // Publish the updates -// PublishUpdatesJobExecuter updater = (PublishUpdatesJobExecuter)applicationContext.getBean("publishUpdatesJobExecuter"); -// updater.executeImpl(); -// -// assertFalse(nodeService.hasAspect(actionDefinition.getNodeRef(), ASPECT_UNPUBLISHED_UPDATE)); -// -// // Check the record has been updated -// DispositionAction dispositionAction = dispositionService.getNextDispositionAction(testRM386Record); -// assertNotNull(dispositionAction); -// assertEquals("cutoff", dispositionAction.getName()); -// assertNotNull(dispositionAction.getAsOfDate()); -// assertEquals(2, dispositionAction.getEventCompletionDetails().size()); -// -// // Test the rollups for the record -// Map properties = nodeService.getProperties(testRM386Record); -// -// assertEquals(Boolean.TRUE, properties.get(PROP_RS_HAS_DISPOITION_SCHEDULE)); -// assertEquals(CommonRMTestUtils.DEFAULT_DISPOSITION_AUTHORITY, properties.get(PROP_RS_DISPOITION_AUTHORITY)); -// assertEquals(CommonRMTestUtils.DEFAULT_DISPOSITION_INSTRUCTIONS, properties.get(PROP_RS_DISPOITION_INSTRUCTIONS)); -// -// assertEquals("week", properties.get(PROP_RS_DISPOSITION_PERIOD)); -// assertEquals("1", properties.get(PROP_RS_DISPOSITION_PERIOD_EXPRESSION)); -// -// List events = (List)properties.get(PROP_RS_DISPOSITION_EVENTS); -// assertNotNull(events); -// assertEquals(2, events.size()); -// assertEquals(Boolean.FALSE, properties.get(PROP_RS_DISPOSITION_EVENTS_ELIGIBLE)); -// -// assertEquals("cutoff", properties.get(PROP_RS_DISPOSITION_ACTION_NAME)); -// assertNotNull(properties.get(PROP_RS_DISPOSITION_ACTION_AS_OF)); -// } -// }); -// -// } + public void testRM386() throws Exception + { + doTestInTransaction(new Test() + { + @Override + public Void run() throws Exception + { + testRM386RecordCategory = filePlanService.createRecordCategory(rmContainer, "RM386"); + testRM386DispositionSchedule = utils.createBasicDispositionSchedule( + testRM386RecordCategory, + "disposition instructions", + "disposition authority", + true, // record level + true); // set the default actions + + NodeRef recordFolder = recordFolderService.createRecordFolder(testRM386RecordCategory, "testRM386RecordFolder"); + testRM386Record = utils.createRecord(recordFolder, "testRM386Record", "testRM386Record"); + + return null; + } + + @SuppressWarnings("unchecked") + @Override + public void test(Void result) throws Exception + { + // Test the rollups for the record + Map properties = nodeService.getProperties(testRM386Record); + + assertEquals(Boolean.TRUE, properties.get(PROP_RS_HAS_DISPOITION_SCHEDULE)); + assertEquals(CommonRMTestUtils.DEFAULT_DISPOSITION_AUTHORITY, properties.get(PROP_RS_DISPOITION_AUTHORITY)); + assertEquals(CommonRMTestUtils.DEFAULT_DISPOSITION_INSTRUCTIONS, properties.get(PROP_RS_DISPOITION_INSTRUCTIONS)); + + assertEquals("none", properties.get(PROP_RS_DISPOSITION_PERIOD)); + assertEquals("0", properties.get(PROP_RS_DISPOSITION_PERIOD_EXPRESSION)); + + List events = (List)properties.get(PROP_RS_DISPOSITION_EVENTS); + assertNotNull(events); + assertEquals(1, events.size()); + assertEquals(CommonRMTestUtils.DEFAULT_EVENT_NAME, events.get(0)); + assertEquals(Boolean.FALSE, properties.get(PROP_RS_DISPOSITION_EVENTS_ELIGIBLE)); + + assertEquals("cutoff", properties.get(PROP_RS_DISPOSITION_ACTION_NAME)); + assertNull(properties.get(PROP_RS_DISPOSITION_ACTION_AS_OF)); + } + }); + + doTestInTransaction(new Test() + { + @Override + public DispositionActionDefinition run() throws Exception + { + DispositionActionDefinition actionDefinition = testRM386DispositionSchedule.getDispositionActionDefinitionByName("cutoff"); + assertNotNull(actionDefinition); + + Map adParams = new HashMap(3); + + List events = new ArrayList(1); + events.add(CommonRMTestUtils.DEFAULT_EVENT_NAME); + events.add("obsolete"); + adParams.put(PROP_DISPOSITION_EVENT, (Serializable)events); + adParams.put(PROP_DISPOSITION_PERIOD, "week|1"); + + dispositionService.updateDispositionActionDefinition( + actionDefinition, + adParams); + + return actionDefinition; + } + + @SuppressWarnings("unchecked") + @Override + public void test(DispositionActionDefinition result) throws Exception + { + DispositionActionDefinition actionDefinition = testRM386DispositionSchedule.getDispositionActionDefinitionByName("cutoff"); + assertNotNull(actionDefinition); + assertTrue(nodeService.hasAspect(actionDefinition.getNodeRef(), ASPECT_UNPUBLISHED_UPDATE)); + + // Publish the updates + PublishUpdatesJobExecuter updater = (PublishUpdatesJobExecuter)applicationContext.getBean("publishUpdatesJobExecuter"); + updater.executeImpl(); + + assertFalse(nodeService.hasAspect(actionDefinition.getNodeRef(), ASPECT_UNPUBLISHED_UPDATE)); + + // Check the record has been updated + DispositionAction dispositionAction = dispositionService.getNextDispositionAction(testRM386Record); + assertNotNull(dispositionAction); + assertEquals("cutoff", dispositionAction.getName()); + assertNotNull(dispositionAction.getAsOfDate()); + assertEquals(2, dispositionAction.getEventCompletionDetails().size()); + + // Test the rollups for the record + Map properties = nodeService.getProperties(testRM386Record); + + assertEquals(Boolean.TRUE, properties.get(PROP_RS_HAS_DISPOITION_SCHEDULE)); + assertEquals(CommonRMTestUtils.DEFAULT_DISPOSITION_AUTHORITY, properties.get(PROP_RS_DISPOITION_AUTHORITY)); + assertEquals(CommonRMTestUtils.DEFAULT_DISPOSITION_INSTRUCTIONS, properties.get(PROP_RS_DISPOITION_INSTRUCTIONS)); + + assertEquals("week", properties.get(PROP_RS_DISPOSITION_PERIOD)); + assertEquals("1", properties.get(PROP_RS_DISPOSITION_PERIOD_EXPRESSION)); + + List events = (List)properties.get(PROP_RS_DISPOSITION_EVENTS); + assertNotNull(events); + assertEquals(2, events.size()); + assertEquals(Boolean.FALSE, properties.get(PROP_RS_DISPOSITION_EVENTS_ELIGIBLE)); + + assertEquals("cutoff", properties.get(PROP_RS_DISPOSITION_ACTION_NAME)); + assertNotNull(properties.get(PROP_RS_DISPOSITION_ACTION_AS_OF)); + } + }); + + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ExtendedSecurityServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ExtendedSecurityServiceImplTest.java index 7c8741b68f..324b0ce759 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ExtendedSecurityServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ExtendedSecurityServiceImplTest.java @@ -23,9 +23,15 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.repo.site.SiteModel; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.site.SiteService; +import org.alfresco.service.cmr.site.SiteVisibility; import org.alfresco.util.GUID; /** @@ -237,4 +243,115 @@ public class ExtendedSecurityServiceImplTest extends BaseRMTestCase assertNotNull(readers); assertEquals(testMap.size(), readers.size()); } + + public void testDifferentUsersDifferentPermissions() + { + final String userNone = createTestUser(); + final String userRead = createTestUser(); + final String userWrite = createTestUser(); + final String siteShortName = GUID.generate(); + + doTestInTransaction(new Test() + { + public Void run() throws Exception + { + siteService.createSite(null, siteShortName, "test", "test", SiteVisibility.PRIVATE); + return null; + } + }); + + final NodeRef documentLibrary = doTestInTransaction(new Test() + { + public NodeRef run() throws Exception + { + siteService.setMembership(siteShortName, userRead, SiteModel.SITE_CONSUMER); + siteService.setMembership(siteShortName, userWrite, SiteModel.SITE_COLLABORATOR); + return siteService.createContainer(siteShortName, SiteService.DOCUMENT_LIBRARY, null, null); + } + }); + + final NodeRef record = doTestInTransaction(new Test() + { + public NodeRef run() throws Exception + { + NodeRef record = fileFolderService.create(documentLibrary, GUID.generate(), ContentModel.TYPE_CONTENT).getNodeRef(); + recordService.createRecord(filePlan, record); + return record; + } + }); + + doTestInTransaction(new Test() + { + public Void run() throws Exception + { + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userNone); + + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userRead); + + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userWrite); + + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userNone); + + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userRead); + + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userWrite); + + return null; + } + }); + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanPermissionServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanPermissionServiceImplTest.java index 732f876e30..7929c67cca 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanPermissionServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanPermissionServiceImplTest.java @@ -18,12 +18,20 @@ */ package org.alfresco.module.org_alfresco_module_rm.test.legacy.service; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; 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.test.util.BaseRMTestCase; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.AuthorityType; import org.springframework.extensions.webscripts.GUID; /** @@ -103,59 +111,59 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase } /** - * test set/delete permissions on file plan + * Test set/delete permissions on file plan */ public void testSetDeletePermissionFilePlan() throws Exception { String userName = createTestUser(); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file setPermission(filePlan, userName, RMPermissionModel.FILING); assertPermissions(userName, AccessStatus.ALLOWED, // fileplan read AccessStatus.ALLOWED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.ALLOWED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.ALLOWED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file deletePermission(filePlan, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file //what happens if we try and remove READ for a normal user on the file plan ??? deletePermission(filePlan, userName, RMPermissionModel.READ_RECORDS); // nothing .. user still has read on file plan .. only removing the user from all roles will remove read on file plan assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file } /** @@ -166,38 +174,38 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase String userName = createTestUser(); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file setPermission(rmContainer, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.ALLOWED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.ALLOWED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // category read + AccessStatus.ALLOWED, // category file + AccessStatus.ALLOWED, // record folder read + AccessStatus.ALLOWED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file deletePermission(rmContainer, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file } /** @@ -208,38 +216,38 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase String userName = createTestUser(); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file setPermission(rmFolder, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.ALLOWED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.ALLOWED, // record folder read + AccessStatus.ALLOWED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file deletePermission(rmFolder, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file } /** @@ -250,38 +258,38 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase String userName = createTestUser(); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file setPermission(recordOne, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file deletePermission(recordOne, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file } public void testMoveRecord() throws Exception @@ -300,14 +308,15 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase }); assertPermissions(userOne, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + doTestInTransaction(new Test() { @Override @@ -318,15 +327,17 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userOne); + assertPermissions(userTwo, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + doTestInTransaction(new Test() { @Override @@ -337,15 +348,17 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userTwo); + assertPermissions(userThree, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + doTestInTransaction(new Test() { @Override @@ -362,14 +375,15 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase setPermission(recordOne, userThree, RMPermissionModel.FILING); assertPermissions(userOne, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.ALLOWED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.ALLOWED, // record folder read + AccessStatus.ALLOWED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + doTestInTransaction(new Test() { @Override @@ -380,15 +394,17 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userOne); + assertPermissions(userTwo, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + doTestInTransaction(new Test() { @Override @@ -399,15 +415,17 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userTwo); + assertPermissions(userThree, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + doTestInTransaction(new Test() { @Override @@ -431,14 +449,15 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase }); assertPermissions(userOne, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.ALLOWED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.ALLOWED, // record folder read + AccessStatus.ALLOWED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + doTestInTransaction(new Test() { @Override @@ -449,15 +468,17 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userOne); + assertPermissions(userTwo, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + doTestInTransaction(new Test() { @Override @@ -468,21 +489,23 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userTwo); + assertPermissions(userThree, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + doTestInTransaction(new Test() { @Override public Void run() { - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(otherFolder, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(otherFolder, RMPermissionModel.READ_RECORDS)); assertEquals(AccessStatus.DENIED, permissionService.hasPermission(otherFolder, RMPermissionModel.FILING)); return null; } @@ -490,7 +513,6 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase } - /** * Helper to assert permissions for passed user */ @@ -521,4 +543,701 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase }, userName); } + /** + * Helper to assert permissions for the passed user + */ + private void assertPermissionsWithInheritance( + final String userName, + final NodeRef subCategory, + final NodeRef folder, + final NodeRef record, + final AccessStatus ... accessStatus) + { + assertEquals(16, accessStatus.length); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(accessStatus[0], permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[1], permissionService.hasPermission(filePlan, RMPermissionModel.FILING)); + + assertEquals(accessStatus[2], permissionService.hasPermission(transfersContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[3], permissionService.hasPermission(transfersContainer, RMPermissionModel.FILING)); + + assertEquals(accessStatus[4], permissionService.hasPermission(holdsContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[5], permissionService.hasPermission(holdsContainer, RMPermissionModel.FILING)); + + assertEquals(accessStatus[6], permissionService.hasPermission(unfiledContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[7], permissionService.hasPermission(unfiledContainer, RMPermissionModel.FILING)); + + assertEquals(accessStatus[8], permissionService.hasPermission(rmContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[9], permissionService.hasPermission(rmContainer, RMPermissionModel.FILING)); + + assertEquals(accessStatus[10], permissionService.hasPermission(subCategory, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[11], permissionService.hasPermission(subCategory, RMPermissionModel.FILING)); + + assertEquals(accessStatus[12], permissionService.hasPermission(folder, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[13], permissionService.hasPermission(folder, RMPermissionModel.FILING)); + + assertEquals(accessStatus[14], permissionService.hasPermission(record, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[15], permissionService.hasPermission(record, RMPermissionModel.FILING)); + + return null; + } + }, userName); + } + + public void testFilePlanComponentInheritance() + { + doTestInTransaction(new Test() + { + @Override + public Void run() + { + // Inheritance is turned off for file plan, transfer, holds, unfiled records and root categories + // it is turned on for sub categories, record folders and records + assertFalse(permissionService.getInheritParentPermissions(filePlan)); + assertFalse(permissionService.getInheritParentPermissions(filePlanService.getTransferContainer(filePlan))); + assertFalse(permissionService.getInheritParentPermissions(filePlanService.getHoldContainer(filePlan))); + assertFalse(permissionService.getInheritParentPermissions(unfiledContainer)); + assertFalse(permissionService.getInheritParentPermissions(rmContainer)); + assertTrue(permissionService.getInheritParentPermissions(recordFolderService.createRecordFolder(rmContainer, "subCategory"))); + assertTrue(permissionService.getInheritParentPermissions(rmFolder)); + assertTrue(permissionService.getInheritParentPermissions(recordOne)); + + return null; + } + }, ADMIN_USER); + } + + public void testRolesSetByDefault() + { + NodeRef subCategory = filePlanService.createRecordCategory(rmContainer, "subCategory1"); + NodeRef folder = recordFolderService.createRecordFolder(subCategory, "rmFolder1"); + NodeRef record = utils.createRecord(folder, "record1.txt"); + + // Admin user has read/filing permissions on file plan, transfer, hold, unfiled records, root categories, sub categories, folders and records + assertPermissionsWithInheritance(ADMIN_USER, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.ALLOWED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.ALLOWED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.ALLOWED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.ALLOWED, // root category read + AccessStatus.ALLOWED, // root category file + AccessStatus.ALLOWED, // sub category read + AccessStatus.ALLOWED, // sub category file + AccessStatus.ALLOWED, // folder read + AccessStatus.ALLOWED, // folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + + // Test user has read permissions on file plan, transfer, hold and unfiled records as the user will be added in the all records management roles + // which has read permissions on those nodes by default + assertPermissionsWithInheritance(createTestUser(), subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + } + + public void testAddUserToContainers() + { + NodeRef subCategory = filePlanService.createRecordCategory(rmContainer, "subCategory2"); + NodeRef folder = recordFolderService.createRecordFolder(subCategory, "rmFolder2"); + NodeRef record = utils.createRecord(folder, "record2.txt"); + + // The user1 will have read permissions on the file plan + // and read permissions on transfer, hold and unfiled records as the user will be in the all records management users role + String user1 = createTestUser(); + setPermission(filePlan, user1, RMPermissionModel.READ_RECORDS); + assertPermissionsWithInheritance(user1, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + + // The user2 will have read and filing permissions on the transfer container + // and read permissions on file plan, hold and unfiled records as the user will be in the all records management users role + String user2 = createTestUser(); + setPermission(transfersContainer, user2, RMPermissionModel.FILING); + assertPermissionsWithInheritance(user2, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.ALLOWED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + + // The user3 will have read permissions on file plan, transfer, hold and unfiled records + String user3 = createTestUser(); + setPermission(holdsContainer, user3, RMPermissionModel.READ_RECORDS); + assertPermissionsWithInheritance(user3, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + + // The user4 will have read permissions on file plan, transfer, hold + // and read and filing permissions on unfiled records container + String user4 = createTestUser(); + setPermission(unfiledContainer, user4, RMPermissionModel.FILING); + assertPermissionsWithInheritance(user4, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + + // The user5 will read permissions on the root category + // as the inheritance is turned on for the sub category the user will have also read permissions on sub category, folder and record + // and also read permissions on file plan, transfer, hold and unfiled records + String user5 = createTestUser(); + setPermission(rmContainer, user5, RMPermissionModel.READ_RECORDS); + assertPermissionsWithInheritance(user5, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.ALLOWED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.ALLOWED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.ALLOWED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.ALLOWED, // record read + AccessStatus.DENIED); // record file + + // The user6 will read and filing permissions on the sub category + // as the inheritance is turned on the user will have also read and filing permissions on folder and record + // and also read permissions on file plan, transfer, hold and unfiled records + String user6 = createTestUser(); + setPermission(subCategory, user6, RMPermissionModel.FILING); + assertPermissionsWithInheritance(user6, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.ALLOWED, // sub category read + AccessStatus.ALLOWED, // sub category file + AccessStatus.ALLOWED, // folder read + AccessStatus.ALLOWED, // folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + + // The user7 will read permissions on the folder + // as the inheritance is turned on the user will have also read on record + // and also read permissions on file plan, transfer, hold and unfiled records + String user7 = createTestUser(); + setPermission(folder, user7, RMPermissionModel.READ_RECORDS); + assertPermissionsWithInheritance(user7, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.ALLOWED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.ALLOWED, // record read + AccessStatus.DENIED); // record file + + // The user8 will read and filing permissions on the record + // and also read permissions on file plan, transfer, hold and unfiled records + String user8 = createTestUser(); + setPermission(record, user8, RMPermissionModel.FILING); + assertPermissionsWithInheritance(user8, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + } + + public void testAccessPermissionOnSingleRecordWithSeveralUsers() + { + final NodeRef subCategory = filePlanService.createRecordCategory(rmContainer, "subCategory3"); + final NodeRef folder = recordFolderService.createRecordFolder(subCategory, "rmFolder3"); + final NodeRef record = utils.createRecord(folder, "record3.txt"); + + String user1 = createTestUser(); + String user2 = createTestUser(); + + setPermission(rmContainer, user1, RMPermissionModel.READ_RECORDS); + + // user1 will have access to file plan, root category and because of inheritance sub category, folder and record + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rmContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(subCategory, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, RMPermissionModel.READ_RECORDS)); + + return null; + } + }, user1); + + // user2 will have access to file plan + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rmContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(subCategory, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, RMPermissionModel.READ_RECORDS)); + + return null; + } + }, user2); + } + + public void testDenyPermissionsOnRecordsWithSeveralUsers() + { + final NodeRef subCategory = filePlanService.createRecordCategory(rmContainer, "subCategory4"); + final NodeRef folder = recordFolderService.createRecordFolder(subCategory, "rmFolder4"); + final NodeRef record4 = utils.createRecord(folder, "record4.txt"); + final NodeRef record5 = utils.createRecord(folder, "record5.txt"); + + String user1 = createTestUser(); + String user2 = createTestUser(); + + setPermission(rmContainer, user1, RMPermissionModel.READ_RECORDS); + setPermission(rmContainer, user2, RMPermissionModel.READ_RECORDS); + + permissionService.setInheritParentPermissions(record4, false); + permissionService.setInheritParentPermissions(record5, false); + + setPermission(record4, user1, RMPermissionModel.READ_RECORDS); + setPermission(record5, user1, RMPermissionModel.READ_RECORDS); + + // user1 will have access to file plan, root category and because of inheritance sub category, folder, record4 and record5 + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rmContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(subCategory, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record4, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record5, RMPermissionModel.READ_RECORDS)); + + return null; + } + }, user1); + + // user2 will have access to file plan, root category and because of inheritance sub category and folder + // user2 won't have access to the records as the inheritance is set to false + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rmContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(subCategory, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record4, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record5, RMPermissionModel.READ_RECORDS)); + + return null; + } + }, user2); + } + + public void testMoveRootCategoryIntoAnotherRootCategory() + { + final NodeRef category5 = filePlanService.createRecordCategory(filePlan, "category5"); + final NodeRef category6 = filePlanService.createRecordCategory(filePlan, "category6"); + + assertFalse(permissionService.getInheritParentPermissions(category5)); + assertFalse(permissionService.getInheritParentPermissions(category6)); + + final String user1 = createTestUser(); + final String user2 = createTestUser(); + + setPermission(category5, user1, RMPermissionModel.READ_RECORDS); + setPermission(category6, user2, RMPermissionModel.FILING); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category5, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category5, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category6, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category6, RMPermissionModel.FILING)); + + return null; + } + }, user1); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category5, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category5, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category6, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category6, RMPermissionModel.FILING)); + + return null; + } + }, user2); + + final NodeRef movedCategory5 = doTestInTransaction(new Test() + { + @Override + public NodeRef run() throws Exception + { + return fileFolderService.move(category5, category6, null).getNodeRef(); + } + }); + + assertFalse(permissionService.getInheritParentPermissions(movedCategory5)); + assertFalse(permissionService.getInheritParentPermissions(category6)); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedCategory5, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(movedCategory5, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category6, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category6, RMPermissionModel.FILING)); + + return null; + } + }, user1); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(movedCategory5, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(movedCategory5, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category6, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category6, RMPermissionModel.FILING)); + + return null; + } + }, user2); + } + + public void testPermissionsForMovedRecord() + { + final NodeRef category7 = filePlanService.createRecordCategory(filePlan, "category7"); + final NodeRef folder7 = recordFolderService.createRecordFolder(category7, "rmFolder7"); + final NodeRef record7 = utils.createRecord(folder7, "record7.txt"); + + final NodeRef category8 = filePlanService.createRecordCategory(filePlan, "category8"); + final NodeRef folder8 = recordFolderService.createRecordFolder(category8, "rmFolder8"); + final NodeRef record8 = utils.createRecord(folder8, "record8.txt"); + + final String user1 = createTestUser(); + final String user2 = createTestUser(); + final String user3 = createTestUser(); + + setPermission(folder7, user1, RMPermissionModel.FILING); + setPermission(record8, user2, RMPermissionModel.READ_RECORDS); + setPermission(category7, user3, RMPermissionModel.FILING); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record8, RMPermissionModel.FILING)); + + return null; + } + }, user1); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record8, RMPermissionModel.FILING)); + + return null; + } + }, user2); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record8, RMPermissionModel.FILING)); + + return null; + } + }, user3); + + final NodeRef movedRecord8 = doTestInTransaction(new Test() + { + @Override + public NodeRef run() throws Exception + { + return fileFolderService.move(record8, folder7, null).getNodeRef(); + } + }); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedRecord8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedRecord8, RMPermissionModel.FILING)); + + return null; + } + }, user1); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedRecord8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(movedRecord8, RMPermissionModel.FILING)); + + return null; + } + }, user2); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedRecord8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedRecord8, RMPermissionModel.FILING)); + + return null; + } + }, user3); + } + + public void testSpecialRoles() + { + final NodeRef category9 = filePlanService.createRecordCategory(filePlan, "category9"); + final NodeRef subCategory9 = filePlanService.createRecordCategory(category9, "subCategory9"); + final NodeRef folder9 = recordFolderService.createRecordFolder(subCategory9, "rmFolder9"); + final NodeRef record9 = utils.createRecord(folder9, "record9.txt"); + + assertExistenceOfSpecialRolesAndPermissions(category9); + + assertExistenceOfSpecialRolesAndPermissions(subCategory9); + // After setting the permissions off the special roles should be still available as they will be added to the node automatically + permissionService.setInheritParentPermissions(subCategory9, false); + assertExistenceOfSpecialRolesAndPermissions(subCategory9); + permissionService.setInheritParentPermissions(subCategory9, true); + assertExistenceOfSpecialRolesAndPermissions(subCategory9); + + assertExistenceOfSpecialRolesAndPermissions(folder9); + permissionService.setInheritParentPermissions(folder9, false); + assertExistenceOfSpecialRolesAndPermissions(folder9); + permissionService.setInheritParentPermissions(folder9, true); + assertExistenceOfSpecialRolesAndPermissions(folder9); + + assertExistenceOfSpecialRolesAndPermissions(record9); + permissionService.setInheritParentPermissions(record9, false); + assertExistenceOfSpecialRolesAndPermissions(record9); + permissionService.setInheritParentPermissions(record9, true); + assertExistenceOfSpecialRolesAndPermissions(record9); + } + + private void assertExistenceOfSpecialRolesAndPermissions(NodeRef node) + { + Map accessPermissions = new HashMap(); + Set permissions = permissionService.getAllSetPermissions(node); + // FIXME!!! + //assertEquals(3, permissions.size()); + + for (AccessPermission permission : permissions) + { + accessPermissions.put(permission.getAuthority(), permission.getPermission()); + } + + assertTrue(accessPermissions.containsKey(ExtendedReaderDynamicAuthority.EXTENDED_READER)); + assertEquals(RMPermissionModel.READ_RECORDS, accessPermissions.get(ExtendedReaderDynamicAuthority.EXTENDED_READER)); + assertTrue(accessPermissions.containsKey(ExtendedWriterDynamicAuthority.EXTENDED_WRITER)); + assertEquals(RMPermissionModel.FILING, accessPermissions.get(ExtendedWriterDynamicAuthority.EXTENDED_WRITER)); + String adminRole = authorityService.getName(AuthorityType.GROUP, FilePlanRoleService.ROLE_ADMIN + filePlan.getId()); + assertTrue(accessPermissions.containsKey(adminRole)); + assertEquals(RMPermissionModel.FILING, accessPermissions.get(adminRole)); + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanRoleServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanRoleServiceImplTest.java index 65ada7ee86..6a8cdaee53 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanRoleServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanRoleServiceImplTest.java @@ -107,9 +107,9 @@ public class FilePlanRoleServiceImplTest extends BaseRMTestCase { public Void run() { - Role role = filePlanRoleService.getRole(filePlan, ROLE_NAME_POWER_USER); + Role role = filePlanRoleService.getRole(filePlan, FilePlanRoleService.ROLE_POWER_USER); assertNotNull(role); - assertEquals(ROLE_NAME_POWER_USER, role.getName()); + assertEquals(FilePlanRoleService.ROLE_POWER_USER, role.getName()); role = filePlanRoleService.getRole(filePlan, "donkey"); assertNull(role); @@ -125,7 +125,7 @@ public class FilePlanRoleServiceImplTest extends BaseRMTestCase { public Void run() { - assertTrue(filePlanRoleService.existsRole(filePlan, ROLE_NAME_POWER_USER)); + assertTrue(filePlanRoleService.existsRole(filePlan, FilePlanRoleService.ROLE_POWER_USER)); assertFalse(filePlanRoleService.existsRole(filePlan, "donkey")); return null; @@ -184,33 +184,33 @@ public class FilePlanRoleServiceImplTest extends BaseRMTestCase assertNotNull(roles); assertEquals(1, roles.size()); - Set authorities = filePlanRoleService.getUsersAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + Set authorities = filePlanRoleService.getUsersAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(1, authorities.size()); - authorities = filePlanRoleService.getGroupsAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + authorities = filePlanRoleService.getGroupsAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(0, authorities.size()); - authorities = filePlanRoleService.getAllAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + authorities = filePlanRoleService.getAllAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(1, authorities.size()); - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_RECORDS_MANAGER, rmUserName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER, rmUserName); roles = filePlanRoleService.getRolesByUser(filePlan, rmUserName); assertNotNull(roles); assertEquals(2, roles.size()); - authorities = filePlanRoleService.getUsersAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + authorities = filePlanRoleService.getUsersAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(2, authorities.size()); - authorities = filePlanRoleService.getGroupsAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + authorities = filePlanRoleService.getGroupsAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(0, authorities.size()); - authorities = filePlanRoleService.getAllAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + authorities = filePlanRoleService.getAllAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(2, authorities.size()); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java index 57204a8ea1..14f5ffa379 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java @@ -272,10 +272,12 @@ public class RecordServiceImplTest extends BaseRMTestCase // create record from document doTestInTransaction(new Test() { + private NodeRef originalLocation; + @Override public Void run() { - NodeRef originalLocation = nodeService.getPrimaryParent(dmDocument).getParentRef(); + originalLocation = nodeService.getPrimaryParent(dmDocument).getParentRef(); assertFalse(recordService.isRecord(dmDocument)); assertFalse(extendedSecurityService.hasExtendedSecurity(dmDocument)); @@ -297,6 +299,11 @@ public class RecordServiceImplTest extends BaseRMTestCase recordService.createRecord(filePlan, dmDocument); + return null; + } + + public void test(Void result) + { checkPermissions(READ_RECORDS, AccessStatus.ALLOWED, // file // plan AccessStatus.ALLOWED, // unfiled container @@ -345,8 +352,6 @@ public class RecordServiceImplTest extends BaseRMTestCase Capability updateProperties = capabilityService.getCapability("UpdateProperties"); assertEquals(AccessStatus.ALLOWED, updateProperties.hasPermission(dmDocument)); - - return null; } }, dmCollaborator); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementSearchServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementSearchServiceImplTest.java index 26b70f2f28..012db1a363 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementSearchServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementSearchServiceImplTest.java @@ -25,7 +25,7 @@ import org.alfresco.module.org_alfresco_module_rm.search.SavedSearchDetails; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.security.MutableAuthenticationService; +import org.alfresco.util.Pair; import org.alfresco.util.TestWithUserUtils; /** @@ -136,30 +136,29 @@ public class RecordsManagementSearchServiceImplTest extends BaseRMTestCase super.tearDown(); } -// FIXME!!!: Commented out. Will be fixed. -// public void testSearch() -// { -// // Full text search -// doTestInTransaction(new Test() -// { -// @Override -// public Void run() -// { -// String query = "keywords:\"elephant\""; -// RecordsManagementSearchParameters params = new RecordsManagementSearchParameters(); -// params.setIncludeUndeclaredRecords(true); -// List results = rmSearchService.search(siteId, query, params); -// assertNotNull(results); -// assertEquals(2, results.size()); -// -// return null; -// } -// }, AuthenticationUtil.getSystemUserName()); -// -// // Property search -// -// // -// } + public void testSearch() + { + // Full text search + doTestInTransaction(new Test() + { + @Override + public Void run() + { + String query = "keywords:\"elephant\""; + RecordsManagementSearchParameters params = new RecordsManagementSearchParameters(); + params.setIncludeUndeclaredRecords(true); + List> results = rmSearchService.search(siteId, query, params); + assertNotNull(results); + assertEquals(2, results.size()); + + return null; + } + }, AuthenticationUtil.getSystemUserName()); + + // Property search + + // + } public void testSaveSearch() { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/webscript/RmRestApiTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/webscript/RmRestApiTest.java index 3c9ec4744a..1a943fc203 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/webscript/RmRestApiTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/webscript/RmRestApiTest.java @@ -426,10 +426,6 @@ public class RmRestApiTest extends BaseRMWebScriptTestCase implements RecordsMan JSONArray customRefsObj = (JSONArray)dataObj.get("customReferences"); assertNotNull("JSON 'customReferences' object was null", customRefsObj); -// for (int i = 0; i < customRefsObj.length(); i++) { -// System.out.println(customRefsObj.getString(i)); -// } - assertTrue("There should be at least two custom references. Found " + customRefsObj, customRefsObj.length() >= 2); // GET a specific custom reference definition. diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java index 98e2a09507..a16befc493 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; @@ -117,7 +118,7 @@ public class DataLoadSystemTest final SiteInfo site = siteService.getSite("test"); if (site == null) { - Assert.fail("The collab site test is not present."); + throw new AlfrescoRuntimeException("The collab site test is not present."); } final NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID); @@ -146,7 +147,6 @@ public class DataLoadSystemTest // create content and declare as record repeatInTransactionBatches(new RunAsWork() { - @SuppressWarnings("null") public Void doWork() throws Exception { // create document diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java index 54d4ade864..ab2da29b56 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java @@ -173,6 +173,8 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase protected NodeRef rmFolder; protected NodeRef unfiledContainer; protected String collabSiteId; + protected NodeRef holdsContainer; + protected NodeRef transfersContainer; /** multi-hierarchy test data * @@ -506,6 +508,14 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase // unfiled container unfiledContainer = filePlanService.getUnfiledContainer(filePlan); assertNotNull(unfiledContainer); + + // holds container + holdsContainer = filePlanService.getHoldContainer(filePlan); + assertNotNull(holdsContainer); + + // transfers container + transfersContainer = filePlanService.getTransferContainer(filePlan); + assertNotNull(transfersContainer); } } }, AuthenticationUtil.getSystemUserName()); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestAction.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestAction.java index 3129ed58a9..e329ba5bed 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestAction.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestAction.java @@ -35,7 +35,7 @@ public class TestAction extends RMActionExecuterAbstractBase { throw new RuntimeException("Unexpected parameter value. Expected " + PARAM_VALUE + " actual " + action.getParameterValue(PARAM)); } - this.nodeService.addAspect(actionedUponNodeRef, ASPECT_RECORD, null); + this.getNodeService().addAspect(actionedUponNodeRef, ASPECT_RECORD, null); } @Override diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestActionPropertySubs.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestActionPropertySubs.java index b806d33eaa..3c4186ab3b 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestActionPropertySubs.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestActionPropertySubs.java @@ -71,7 +71,7 @@ public class TestActionPropertySubs extends RMActionExecuterAbstractBase String yearShort = new SimpleDateFormat("yy").format(date); String yearLong = new SimpleDateFormat("yyyy").format(date); String yearWeek = new SimpleDateFormat("ww").format(date); - String name = (String) nodeService.getProperty(actionedUponNodeRef, ContentModel.PROP_NAME); + String name = (String) getNodeService().getProperty(actionedUponNodeRef, ContentModel.PROP_NAME); String company = I18NUtil.getMessage("test.company"); assertEquals(dayShort, (String) action.getParameterValue("dayShort")); diff --git a/rm-server/test/resources/test-context.xml b/rm-server/test/resources/test-context.xml index 12bbef5412..f5e35faf58 100644 --- a/rm-server/test/resources/test-context.xml +++ b/rm-server/test/resources/test-context.xml @@ -218,4 +218,20 @@ + + + false + + + Search + + + buildonly + + + + manager + + + \ No newline at end of file diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnlinkFromActionUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnlinkFromActionUnitTest.java new file mode 100644 index 0000000000..60aa6f56f0 --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/action/impl/UnlinkFromActionUnitTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.action.impl; + +import static org.mockito.Mockito.*; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.repository.NodeRef; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +/** + * Unit test for unlink from action + * + * @author Roy Wetherall + * @since 2.3 + */ +public class UnlinkFromActionUnitTest extends BaseUnitTest +{ + private NodeRef record; + private NodeRef recordFolder; + + @InjectMocks + private UnlinkFromAction action; + + @Before + @Override + public void before() throws Exception + { + super.before(); + + record = generateRecord(); + recordFolder = generateRecordFolder(); + } + + /** + * Given the actioned upon node does not exist + * When the action is executed + * Then nothing happens + */ + @Test + public void nodeDoesNotExist() + { + doReturn(false).when(mockedNodeService).exists(record); + action.executeImpl(mock(Action.class), record); + verify(mockedRecordService, never()).unlink(any(NodeRef.class), any(NodeRef.class)); + } + + /** + * Given the actioned upon node is pending delete + * When the action is executed + * Then nothing happens + */ + @Test + public void nodePendingDelete() + { + doReturn(true).when(mockedNodeService).exists(record); + doReturn(true).when(mockedNodeService).hasAspect(record, ASPECT_PENDING_DELETE); + action.executeImpl(mock(Action.class), record); + verify(mockedRecordService, never()).unlink(any(NodeRef.class), any(NodeRef.class)); + } + + /** + * Given that actioned upon node is not a record + * When the action is executed + * Then nothing happens + */ + @Test + public void nodeNotRecord() + { + NodeRef notRecord = generateCmContent(generateText()); + doReturn(true).when(mockedNodeService).exists(notRecord); + doReturn(false).when(mockedNodeService).hasAspect(notRecord, ASPECT_PENDING_DELETE); + action.executeImpl(mock(Action.class), notRecord); + verify(mockedRecordService, never()).unlink(any(NodeRef.class), any(NodeRef.class)); + } + + /** + * Given that the record folder parameter is not provided + * When the action is executed + * Then an exception is thrown + */ + @Test(expected=AlfrescoRuntimeException.class) + public void recordFolderParamMissing() + { + // setup record + doReturn(true).when(mockedNodeService).exists(record); + doReturn(false).when(mockedNodeService).hasAspect(record, ASPECT_PENDING_DELETE); + + // create action mock + Action mockedAction = mock(Action.class); + doReturn(null).when(mockedAction).getParameterValue(UnlinkFromAction.PARAM_RECORD_FOLDER); + + // execute action + action.executeImpl(mockedAction, record); + } + + /** + * Given that a valid record folder is provided + * When the action is executed + * Then the record is unlinked from the record folder + */ + @Test + public void validUnlink() + { + // setup record + doReturn(true).when(mockedNodeService).exists(record); + doReturn(false).when(mockedNodeService).hasAspect(record, ASPECT_PENDING_DELETE); + + // create action mock + Action mockedAction = mock(Action.class); + doReturn(recordFolder.toString()).when(mockedAction).getParameterValue(UnlinkFromAction.PARAM_RECORD_FOLDER); + + // execute action + action.executeImpl(mockedAction, record); + + // verify unlink + verify(mockedRecordService, times(1)).unlink(record, recordFolder); + } + +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/BootstrapImporterModuleComponentUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/BootstrapImporterModuleComponentUnitTest.java new file mode 100644 index 0000000000..102304dd1e --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/BootstrapImporterModuleComponentUnitTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.bootstrap; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.alfresco.module.org_alfresco_module_rm.patch.ModulePatchExecuter; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.repo.importer.ImporterBootstrap; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +/** + * Bootstrap importer module component unit test + * + * @author Roy Wetherall + * @since 2.3 + */ +public class BootstrapImporterModuleComponentUnitTest extends BaseUnitTest +{ + /** RM config node */ + private static final NodeRef configNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "rm_config_folder"); + + /** mocks */ + @Mock(name="importer") private ImporterBootstrap mockedImporter; + @Mock(name="modulePatchExecuter") private ModulePatchExecuter mockedModulePatchExecuter; + @Mock(name="recordContributorsGroupBootstrapComponent") private RecordContributorsGroupBootstrapComponent mockedRecordContributorsGroupBootstrapComponent; + + /** importer */ + @InjectMocks + private BootstrapImporterModuleComponent importer; + + /** + * Given that the system has already been bootstraped + * When I try and boostrap the system + * Then the system is not bootstraped again + */ + @Test + public void alreadyBootstraped() throws Throwable + { + // config node exists + doReturn(true).when(mockedNodeService).exists(configNodeRef); + + // boostrap + importer.executeInternal(); + + // not bootstraped + verify(mockedImporter, never()).bootstrap(); + verify(mockedModulePatchExecuter, never()).initSchemaVersion(); + verify(mockedRecordContributorsGroupBootstrapComponent, never()).createRecordContributorsGroup(); + } + + /** + * Given that the system has not been bootstraped + * When I try and bootstrap the system + * Then the system is bootstraped + */ + @Test + public void boostrap() throws Throwable + { + // config node does not exist + doReturn(false).when(mockedNodeService).exists(configNodeRef); + + // boostrap + importer.executeInternal(); + + // not bootstraped + verify(mockedImporter, times(1)).bootstrap(); + verify(mockedModulePatchExecuter, times(1)).initSchemaVersion(); + verify(mockedRecordContributorsGroupBootstrapComponent, times(1)).createRecordContributorsGroup(); + } +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordContributorsGroupBootstrapComponentUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordContributorsGroupBootstrapComponentUnitTest.java new file mode 100644 index 0000000000..48f1d3315c --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/bootstrap/RecordContributorsGroupBootstrapComponentUnitTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.bootstrap; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.service.cmr.security.AuthorityType; +import org.junit.Test; +import org.mockito.InjectMocks; + +/** + * Record contributors group bootstrap component unit test + * + * @author Roy Wetherall + * @since 2.3 + */ +public class RecordContributorsGroupBootstrapComponentUnitTest extends BaseUnitTest +{ + @InjectMocks + private RecordContributorsGroupBootstrapComponent component; + + /** + * Given that the record contributors group already exists + * When I try and create the group + * Then nothing happens + */ + @Test + public void groupAlreadyExists() + { + // group already exists + doReturn(true).when(mockedAuthorityService).authorityExists(RecordContributorsGroupBootstrapComponent.GROUP_RECORD_CONTRIBUTORS); + + // create group + component.createRecordContributorsGroup(); + + // group not created + verify(mockedAuthorityService, times(1)).authorityExists(RecordContributorsGroupBootstrapComponent.GROUP_RECORD_CONTRIBUTORS); + verifyNoMoreInteractions(mockedAuthorityService); + } + + /** + * Given that the record contributors group does not exist + * When I try and create the group + * Then the group is successfully created + * And 'everyone' is added to the new group + */ + @Test + public void createGroup() + { + // group does not exists + doReturn(false).when(mockedAuthorityService).authorityExists(RecordContributorsGroupBootstrapComponent.GROUP_RECORD_CONTRIBUTORS); + + // create group + component.createRecordContributorsGroup(); + + // group not created + verify(mockedAuthorityService, times(1)).createAuthority(AuthorityType.GROUP, RecordContributorsGroupBootstrapComponent.RECORD_CONTRIBUTORS); + verify(mockedAuthorityService, times(1)).addAuthority(RecordContributorsGroupBootstrapComponent.GROUP_RECORD_CONTRIBUTORS, "admin"); + verify(mockedAuthorityService, times(1)).authorityExists(RecordContributorsGroupBootstrapComponent.GROUP_RECORD_CONTRIBUTORS); + verifyNoMoreInteractions(mockedAuthorityService); + } + +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuterUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuterUnitTest.java index 8c1962dbaa..813cb9611b 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuterUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/job/DispositionLifecycleJobExecuterUnitTest.java @@ -47,7 +47,7 @@ import org.mockito.Mock; /** * Disposition lifecycle job execution unit test. - * + * * @author Roy Wetherall * @since 2.2 */ @@ -57,16 +57,16 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest private static final String CUTOFF = "cutoff"; private static final String RETAIN = "retain"; private static final String DESTROY = "destroy"; - + /** test query snipit */ private static final String QUERY = "\"" + CUTOFF + "\" OR \"" + RETAIN + "\""; - + /** mocked result set */ @Mock ResultSet mockedResultSet; - + /** disposition lifecycle job executer */ @InjectMocks DispositionLifecycleJobExecuter executer; - + /** * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before() */ @@ -75,25 +75,25 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest public void before() throws Exception { super.before(); - + // setup data List dispositionActions = buildList(CUTOFF, RETAIN); executer.setDispositionActions(dispositionActions); - + // setup interactions - doReturn(mockedResultSet).when(mockedSearchService).query(eq(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE), eq(SearchService.LANGUAGE_LUCENE), anyString()); + doReturn(mockedResultSet).when(mockedSearchService).query(eq(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE), eq(SearchService.LANGUAGE_FTS_ALFRESCO), anyString()); } - + /** * Helper method to verify that the query has been executed and closed */ private void verifyQuery() { - verify(mockedSearchService, times(1)).query(eq(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE), eq(SearchService.LANGUAGE_LUCENE), contains(QUERY)); + verify(mockedSearchService, times(1)).query(eq(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE), eq(SearchService.LANGUAGE_FTS_ALFRESCO), contains(QUERY)); verify(mockedResultSet, times(1)).getNodeRefs(); - verify(mockedResultSet, times(1)).close(); + verify(mockedResultSet, times(1)).close(); } - + /** * When the are no results in query. */ @@ -102,19 +102,19 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest { // given doReturn(Collections.EMPTY_LIST).when(mockedResultSet).getNodeRefs(); - + // when executer.executeImpl(); - + // then - + // ensure the query is executed and closed verifyQuery(); - + // ensure nothing else happens becuase we have no results verifyZeroInteractions(mockedNodeService, mockedRecordFolderService, mockedRetryingTransactionHelper); } - + /** * When the disposition actions do not match those that can be processed automatically. */ @@ -126,34 +126,34 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest NodeRef node1 = generateNodeRef(); NodeRef node2 = generateNodeRef(); List nodeRefs = buildList(node1, node2); - + // given doReturn(nodeRefs).when(mockedResultSet).getNodeRefs(); doReturn(DESTROY).when(mockedNodeService).getProperty(node1, RecordsManagementModel.PROP_DISPOSITION_ACTION); doReturn(DESTROY).when(mockedNodeService).getProperty(node2, RecordsManagementModel.PROP_DISPOSITION_ACTION); - + // when executer.executeImpl(); - + // then - + // ensure the query is executed and closed verifyQuery(); - + // ensure work is executed in transaction for each node processed verify(mockedNodeService, times(2)).exists(any(NodeRef.class)); verify(mockedRetryingTransactionHelper, times(2)).doInTransaction(any(RetryingTransactionCallback.class)); - + // ensure each node is process correctly verify(mockedNodeService, times(1)).getProperty(node1, RecordsManagementModel.PROP_DISPOSITION_ACTION); verify(mockedNodeService, times(1)).getProperty(node2, RecordsManagementModel.PROP_DISPOSITION_ACTION); - + // ensure no more interactions verifyNoMoreInteractions(mockedNodeService); verifyZeroInteractions(mockedRecordsManagementActionService); - + } - + /** * When a node does not exist */ @@ -163,26 +163,26 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest // test data NodeRef node1 = generateNodeRef(null, false); List nodeRefs = buildList(node1); - + // given doReturn(nodeRefs).when(mockedResultSet).getNodeRefs(); - + // when executer.executeImpl(); - + // then - + // ensure the query is executed and closed verifyQuery(); - + // ensure the node exist check is made for the node verify(mockedNodeService, times(1)).exists(any(NodeRef.class)); - + // ensure no more interactions verifyNoMoreInteractions(mockedNodeService); - verifyZeroInteractions(mockedRecordsManagementActionService, mockedRetryingTransactionHelper); + verifyZeroInteractions(mockedRecordsManagementActionService, mockedRetryingTransactionHelper); } - + /** * When there are disposition actions eligible for processing */ @@ -195,26 +195,26 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest NodeRef node2 = generateNodeRef(); List nodeRefs = buildList(node1, node2); NodeRef parent = generateNodeRef(); - ChildAssociationRef parentAssoc = new ChildAssociationRef(ASSOC_NEXT_DISPOSITION_ACTION, parent, generateQName(), generateNodeRef()); - + ChildAssociationRef parentAssoc = new ChildAssociationRef(ASSOC_NEXT_DISPOSITION_ACTION, parent, generateQName(), generateNodeRef()); + // given doReturn(nodeRefs).when(mockedResultSet).getNodeRefs(); doReturn(CUTOFF).when(mockedNodeService).getProperty(node1, RecordsManagementModel.PROP_DISPOSITION_ACTION); doReturn(RETAIN).when(mockedNodeService).getProperty(node2, RecordsManagementModel.PROP_DISPOSITION_ACTION); doReturn(parentAssoc).when(mockedNodeService).getPrimaryParent(any(NodeRef.class)); - + // when executer.executeImpl(); - + // then - + // ensure the query is executed and closed verifyQuery(); - + // ensure work is executed in transaction for each node processed verify(mockedNodeService, times(2)).exists(any(NodeRef.class)); verify(mockedRetryingTransactionHelper, times(2)).doInTransaction(any(RetryingTransactionCallback.class)); - + // ensure each node is process correctly // node1 verify(mockedNodeService, times(1)).getProperty(node1, RecordsManagementModel.PROP_DISPOSITION_ACTION); @@ -224,7 +224,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest verify(mockedNodeService, times(1)).getProperty(node2, RecordsManagementModel.PROP_DISPOSITION_ACTION); verify(mockedNodeService, times(1)).getPrimaryParent(node2); verify(mockedRecordsManagementActionService, times(1)).executeRecordsManagementAction(eq(parent), eq(RETAIN), anyMap()); - + // ensure no more interactions verifyNoMoreInteractions(mockedNodeService, mockedRecordsManagementActionService); } diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java index a7c0d38e8a..4dd0670268 100755 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java @@ -21,13 +21,19 @@ package org.alfresco.module.org_alfresco_module_rm.record; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Map; import java.util.Set; +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.apache.commons.collections.CollectionUtils; import org.junit.Before; @@ -36,43 +42,41 @@ import org.mockito.InjectMocks; /** * Unit test for RecordServiceImpl - * + * * @author Roy Wetherall * @since 2.2 */ public class RecordServiceImplUnitTest extends BaseUnitTest -{ +{ private NodeRef nonStandardFilePlanComponent; private NodeRef nonStandardFilePlan; - + private static QName TYPE_MY_FILE_PLAN = generateQName(); private static QName ASPECT_FOR_FILE_PLAN = generateQName(); - private static QName ASPECT_FOR_MY_FILE_PLAN = generateQName(); - private static QName ASPECT_FOR_BOTH = generateQName(); - + @InjectMocks private RecordServiceImpl recordService; - + @SuppressWarnings("unchecked") @Before @Override public void before() throws Exception { super.before(); - + nonStandardFilePlanComponent = generateNodeRef(TYPE_RECORD_CATEGORY); nonStandardFilePlan = generateNodeRef(TYPE_MY_FILE_PLAN); - - // set-up node service + + // set-up node service when(mockedNodeService.getProperty(nonStandardFilePlanComponent, PROP_ROOT_NODEREF)).thenReturn(nonStandardFilePlan); - + // set-up dictionary service when(mockedDictionaryService.getAllAspects()).thenReturn(CollectionUtils.EMPTY_COLLECTION); } - - @Test + + @Test public void testRegisterRecordMetadataAspect() { - Map> map = recordService.getRecordMetadataAspectsMap(); + Map> map = recordService.getRecordMetadataAspectsMap(); assertTrue(map.isEmpty()); recordService.registerRecordMetadataAspect(ASPECT_FOR_FILE_PLAN, TYPE_FILE_PLAN); map = recordService.getRecordMetadataAspectsMap(); @@ -84,38 +88,156 @@ public class RecordServiceImplUnitTest extends BaseUnitTest assertTrue(types.contains(TYPE_FILE_PLAN)); } + /** + * Given invalid types + * When linking + * Then exception thrown + */ @Test - public void testGetRecordMetadataAspects() + public void linkNonRecord() { - // register a couple of record meta-data aspects - recordService.registerRecordMetadataAspect(ASPECT_FOR_FILE_PLAN, TYPE_FILE_PLAN); - recordService.registerRecordMetadataAspect(ASPECT_FOR_MY_FILE_PLAN, TYPE_MY_FILE_PLAN); - recordService.registerRecordMetadataAspect(ASPECT_FOR_BOTH, TYPE_FILE_PLAN); - recordService.registerRecordMetadataAspect(ASPECT_FOR_BOTH, TYPE_MY_FILE_PLAN); + NodeRef nonRecord = generateNodeRef(TYPE_CONTENT); + NodeRef recordFolder = generateRecordFolder(); - Set set = recordService.getRecordMetadataAspects(filePlanComponent); - assertNotNull(set); - assertEquals(2, set.size()); - assertTrue(set.contains(ASPECT_FOR_FILE_PLAN)); - assertTrue(set.contains(ASPECT_FOR_BOTH)); + // set expected exception + exception.expect(AlfrescoRuntimeException.class); - set = recordService.getRecordMetadataAspects(nonStandardFilePlanComponent); - assertNotNull(set); - assertEquals(2, set.size()); - assertTrue(set.contains(ASPECT_FOR_MY_FILE_PLAN)); - assertTrue(set.contains(ASPECT_FOR_BOTH)); + // link + recordService.link(nonRecord, recordFolder); + } + @Test + public void linkNonRecordFolder() + { + NodeRef record = generateRecord(); + NodeRef nonRecordFolder = generateNodeRef(TYPE_FOLDER); - set = recordService.getRecordMetadataAspects(TYPE_FILE_PLAN); - assertNotNull(set); - assertEquals(2, set.size()); - assertTrue(set.contains(ASPECT_FOR_FILE_PLAN)); - assertTrue(set.contains(ASPECT_FOR_BOTH)); - - set = recordService.getRecordMetadataAspects(TYPE_MY_FILE_PLAN); - assertNotNull(set); - assertEquals(2, set.size()); - assertTrue(set.contains(ASPECT_FOR_MY_FILE_PLAN)); - assertTrue(set.contains(ASPECT_FOR_BOTH)); + // set expected exception + exception.expect(AlfrescoRuntimeException.class); + // link + recordService.link(record, nonRecordFolder); } + + /** + * Given that the record is already a child of the record folder + * When I try to link the record to the same record folder + * Then an exception is thrown + */ + @Test + public void linkRecordToRecordFolderFailsIfAlreadyAChild() + { + NodeRef record = generateRecord(); + NodeRef recordFolder = generateRecordFolder(); + + // given that the record is already a child of the record folder + makeChildrenOf(recordFolder, record); + + // set expected exception + exception.expect(AlfrescoRuntimeException.class); + + // link + recordService.link(record, recordFolder); + } + + /** + * Given a record that is not a child of a record folder + * When I link the record to the record folder + * Then the record is now linked to the record folder + */ + @Test + public void linkRecordToRecordFolder() + { + NodeRef record = generateRecord(); + NodeRef recordFolder = generateRecordFolder(); + + // given that the record is already a child of the record folder + makeChildrenOf(generateRecordFolder(), record); + + // set the name of the record + String name = generateText(); + doReturn(name).when(mockedNodeService).getProperty(record, PROP_NAME); + + // link + recordService.link(record, recordFolder); + + // verify link was created + verify(mockedNodeService, times(1)).addChild( + recordFolder, + record, + ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name)); + } + + /** + * Given invalid types + * When unlinking + * Then exception thrown + */ + @Test + public void unlinkNonRecord() + { + NodeRef nonRecord = generateNodeRef(TYPE_CONTENT); + NodeRef recordFolder = generateRecordFolder(); + + // set expected exception + exception.expect(AlfrescoRuntimeException.class); + + // unlink + recordService.unlink(nonRecord, recordFolder); + } + @Test + public void unlinkNonRecordFolder() + { + NodeRef record = generateRecord(); + NodeRef nonRecordFolder = generateNodeRef(TYPE_FOLDER); + + // set expected exception + exception.expect(AlfrescoRuntimeException.class); + + // unlink + recordService.unlink(record, nonRecordFolder); + } + + /** + * Given a record folder is a records primary parent + * When I try and unlink the record from that record folder + * Then an exception is thrown + */ + @Test + public void unlinkRecordFromPrimaryRecordFolder() + { + NodeRef record = generateRecord(); + NodeRef recordFolder = generateRecordFolder(); + + // given that the record is already a child of the record folder + makePrimaryParentOf(record, recordFolder); + + // set expected exception + exception.expect(AlfrescoRuntimeException.class); + + // link + recordService.unlink(record, recordFolder); + } + + /** + * Given a record that is linked to a record + * And that the record is not the primary parent of the record + * When I unlink the record to the record folder + * Then the record is no longer linked to the record folder + */ + @Test + public void unlinkRecordFromRecordFolder() + { + NodeRef record = generateRecord(); + NodeRef recordFolder = generateRecordFolder(); + + // the records primary parent is another record folder + makePrimaryParentOf(record, generateRecordFolder()); + + // unlink + recordService.unlink(record, recordFolder); + + // verify link was created + verify(mockedNodeService, times(1)).removeChild(recordFolder, record); + } } diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/BaseRecordedVersionConfigTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/BaseRecordedVersionConfigTest.java index 80d0d1c6e0..16e4ab880a 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/BaseRecordedVersionConfigTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/BaseRecordedVersionConfigTest.java @@ -38,7 +38,7 @@ public abstract class BaseRecordedVersionConfigTest extends BaseWebScriptUnitTes /** Node ref for test document */ protected NodeRef testdoc; - /** setup web script parameters */ + /** Setup web script parameters */ protected Map buildParameters() { testdoc = generateCmContent("testdoc.txt"); diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/RecordedVersionConfigGetTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/RecordedVersionConfigGetTest.java index cc220ce540..60a404e8e1 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/RecordedVersionConfigGetTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/RecordedVersionConfigGetTest.java @@ -18,6 +18,9 @@ */ package org.alfresco.module.org_alfresco_module_rm.recorded.version.config; +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy.ALL; +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy.MAJOR_ONLY; +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy.NONE; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.doReturn; import static org.testng.Assert.assertEquals; @@ -29,6 +32,7 @@ import java.util.List; import java.util.Map; import org.alfresco.module.org_alfresco_module_rm.script.slingshot.RecordedVersionConfigGet; +import org.alfresco.module.org_alfresco_module_rm.script.slingshot.Version; import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy; import org.json.JSONArray; import org.json.JSONObject; @@ -74,7 +78,16 @@ public class RecordedVersionConfigGetTest extends BaseRecordedVersionConfigTest // Test document should not have any recordable version policy set doReturn(null).when(mockedNodeService).getProperty(testdoc, PROP_RECORDABLE_VERSION_POLICY); - // execute web script + // Setup versions + List versions = Arrays.asList( + new Version(NONE.toString(), true), + new Version(MAJOR_ONLY.toString(), false), + new Version(ALL.toString(), false)); + + // Stub getVersions + doReturn(versions).when(mockedRecordableVersionConfigService).getVersions(testdoc); + + // Execute web script JSONObject json = executeJSONWebScript(parameters); // Do checks diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/RecordedVersionConfigPostTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/RecordedVersionConfigPostTest.java index 7c19af8ee5..969666ab75 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/RecordedVersionConfigPostTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/recorded/version/config/RecordedVersionConfigPostTest.java @@ -18,6 +18,8 @@ */ package org.alfresco.module.org_alfresco_module_rm.recorded.version.config; +import static org.alfresco.module.org_alfresco_module_rm.script.slingshot.RecordedVersionConfigPost.RECORDED_VERSION; +import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy.ALL; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.doReturn; import static org.testng.Assert.assertEquals; @@ -63,10 +65,8 @@ public class RecordedVersionConfigPostTest extends BaseRecordedVersionConfigTest @Test public void setRecordedVersionConfig() throws Exception { - RecordableVersionPolicy policy = RecordableVersionPolicy.ALL; - // Build the content - String content = buildContent(policy); + String content = buildContent(ALL); // Build parameters Map parameters = buildParameters(); @@ -82,7 +82,7 @@ public class RecordedVersionConfigPostTest extends BaseRecordedVersionConfigTest assertEquals(json.length(), 0); // Test document must have recordable version policy "ALL" set - doReturn(policy).when(mockedNodeService).getProperty(testdoc, PROP_RECORDABLE_VERSION_POLICY); + doReturn(ALL).when(mockedNodeService).getProperty(testdoc, PROP_RECORDABLE_VERSION_POLICY); } /** @@ -95,7 +95,7 @@ public class RecordedVersionConfigPostTest extends BaseRecordedVersionConfigTest { StringBuilder sb = new StringBuilder(); sb.append("{\""); - sb.append(RecordedVersionConfigPost.RECORDED_VERSION); + sb.append(RECORDED_VERSION); sb.append("\":\""); sb.append(policy.toString()); sb.append("\"}"); diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/script/hold/BaseHoldWebScriptWithContentUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/script/hold/BaseHoldWebScriptWithContentUnitTest.java index 1746647af3..e951c2069f 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/script/hold/BaseHoldWebScriptWithContentUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/script/hold/BaseHoldWebScriptWithContentUnitTest.java @@ -34,7 +34,7 @@ public abstract class BaseHoldWebScriptWithContentUnitTest extends BaseHoldWebSc boolean bFirst = true; for (NodeRef nodeRef : nodeRefs) { - if (bFirst == false) + if (!bFirst) { builder.append(","); } @@ -61,7 +61,7 @@ public abstract class BaseHoldWebScriptWithContentUnitTest extends BaseHoldWebSc boolean bFirst = true; for (NodeRef hold : holds) { - if (bFirst == false) + if (!bFirst) { builder.append(","); } diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java index b71c8ee56e..6e23e8abc8 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java @@ -19,6 +19,9 @@ package org.alfresco.module.org_alfresco_module_rm.test; import org.alfresco.module.org_alfresco_module_rm.action.impl.FileReportActionUnitTest; +import org.alfresco.module.org_alfresco_module_rm.action.impl.UnlinkFromActionUnitTest; +import org.alfresco.module.org_alfresco_module_rm.bootstrap.BootstrapImporterModuleComponentUnitTest; +import org.alfresco.module.org_alfresco_module_rm.bootstrap.RecordContributorsGroupBootstrapComponentUnitTest; import org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition.HoldCapabilityConditionUnitTest; import org.alfresco.module.org_alfresco_module_rm.forms.RecordsManagementTypeFormFilterUnitTest; import org.alfresco.module.org_alfresco_module_rm.hold.HoldServiceImplUnitTest; @@ -75,13 +78,18 @@ import org.junit.runners.Suite.SuiteClasses; // action implementations FileReportActionUnitTest.class, + UnlinkFromActionUnitTest.class, // patches RMv22RemoveInPlaceRolesFromAllPatchUnitTest.class, // recorded version config RecordedVersionConfigGetTest.class, - RecordedVersionConfigPostTest.class + RecordedVersionConfigPostTest.class, + + // bootstrap + BootstrapImporterModuleComponentUnitTest.class, + RecordContributorsGroupBootstrapComponentUnitTest.class }) public class AllUnitTestSuite { diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java index cd9e175aaa..079a1f33d9 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.UUID; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService; @@ -37,7 +38,9 @@ import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.model.security.ModelSecurityService; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; +import org.alfresco.module.org_alfresco_module_rm.recordableversion.RecordableVersionConfigService; import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; import org.alfresco.module.org_alfresco_module_rm.report.ReportService; import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; @@ -80,7 +83,7 @@ import org.springframework.context.ApplicationContext; *

* Contains core and records management service mocks ready for injection. Helper methods * provide an easy way to build RM or Alfresco constructs for use in tests. - * + * * @author Roy Wetherall * @since 2.2 */ @@ -91,21 +94,22 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel protected NodeRef recordFolder; protected NodeRef record; - + /** core service mocks */ - @Mock(name="nodeService") protected NodeService mockedNodeService; + @Mock(name="nodeService") protected NodeService mockedNodeService; @Mock(name="dictionaryService") protected DictionaryService mockedDictionaryService; - @Mock(name="namespaceService") protected NamespaceService mockedNamespaceService; + @Mock(name="namespaceService") protected NamespaceService mockedNamespaceService; @Mock(name="identifierService") protected IdentifierService mockedIdentifierService; @Mock(name="permissionService") protected PermissionService mockedPermissionService; @Mock(name="ownableService") protected OwnableService mockedOwnableService; @Mock(name="searchService") protected SearchService mockedSearchService; @Mock(name="retryingTransactionHelper") protected RetryingTransactionHelper mockedRetryingTransactionHelper; @Mock(name="authorityService") protected AuthorityService mockedAuthorityService; - @Mock(name="policyComponent") protected PolicyComponent mockedPolicyComponent; + @Mock(name="policyComponent") protected PolicyComponent mockedPolicyComponent; @Mock(name="copyService") protected CopyService mockedCopyService; @Mock(name="fileFolderService") protected FileFolderService mockedFileFolderService; - + @Mock(name="modelSecurityService") protected ModelSecurityService mockedModelSecurityService; + /** rm service mocks */ @Mock(name="filePlanService") protected FilePlanService mockedFilePlanService; @Mock(name="recordFolderService") protected RecordFolderService mockedRecordFolderService; @@ -119,14 +123,15 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel @Mock(name="authenticationUtil") protected AuthenticationUtil mockedAuthenticationUtil; @Mock(name="extendedPermissionService") protected ExtendedPermissionService mockedExtendedPermissionService; @Mock(name="extendedSecurityService") protected ExtendedSecurityService mockedExtendedSecurityService; - + @Mock(name="recordableVersionConfigService") protected RecordableVersionConfigService mockedRecordableVersionConfigService; + /** application context mock */ @Mock(name="applicationContext") protected ApplicationContext mockedApplicationContext; - + /** expected exception rule */ @Rule public ExpectedException exception = ExpectedException.none(); - + /** * Test method setup */ @@ -135,10 +140,10 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel public void before() throws Exception { MockitoAnnotations.initMocks(this); - + // setup application context doReturn(mockedNodeService).when(mockedApplicationContext).getBean("dbNodeService"); - + // setup retrying transaction helper Answer doInTransactionAnswer = new Answer() { @@ -151,36 +156,36 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel } }; doAnswer(doInTransactionAnswer).when(mockedRetryingTransactionHelper).doInTransaction(any(RetryingTransactionCallback.class)); - + // setup mocked authentication util setupAuthenticationUtilMock(); - // setup file plan + // setup file plan filePlan = generateNodeRef(TYPE_FILE_PLAN); setupAsFilePlanComponent(filePlan); doReturn(true).when(mockedFilePlanService).isFilePlan(filePlan); - + // setup basic file plan component filePlanComponent = generateNodeRef(); setupAsFilePlanComponent(filePlanComponent); - + // setup namespace service doReturn(RM_URI).when(mockedNamespaceService).getNamespaceURI(RM_PREFIX); doReturn(CollectionUtils.unmodifiableSet(RM_PREFIX)).when(mockedNamespaceService).getPrefixes(RM_URI); - + // setup record folder and record recordFolder = generateRecordFolder(); record = generateRecord(); - + // set record as child of record folder List result = new ArrayList(1); result.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, recordFolder, generateQName(), record, true, 1)); doReturn(result).when(mockedNodeService).getChildAssocs(eq(recordFolder), eq(ContentModel.ASSOC_CONTAINS), any(QNamePattern.class)); doReturn(result).when(mockedNodeService).getParentAssocs(record); doReturn(Collections.singletonList(recordFolder)).when(mockedRecordFolderService).getRecordFolders(record); - doReturn(Collections.singletonList(record)).when(mockedRecordService).getRecords(recordFolder); + doReturn(Collections.singletonList(record)).when(mockedRecordService).getRecords(recordFolder); } - + /** * Setup authentication util mock */ @@ -197,9 +202,9 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel RunAsWork work = (RunAsWork)invocation.getArguments()[0]; return work.doWork(); } - - }).when(mockedAuthenticationUtil).runAsSystem(any(RunAsWork.class)); - + + }).when(mockedAuthenticationUtil).runAsSystem(any(RunAsWork.class)); + // just do the work doAnswer(new Answer() { @@ -210,27 +215,36 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel RunAsWork work = (RunAsWork)invocation.getArguments()[0]; return work.doWork(); } - + }).when(mockedAuthenticationUtil).runAs(any(RunAsWork.class), anyString()); - + // assume admin - doReturn("admin").when(mockedAuthenticationUtil).getAdminUserName(); + doReturn("admin").when(mockedAuthenticationUtil).getAdminUserName(); doReturn("admin").when(mockedAuthenticationUtil).getFullyAuthenticatedUser(); } + /** + * Helper to generate random text value suitable for a property + * value or node name + */ + protected String generateText() + { + return UUID.randomUUID().toString(); + } + /** * Helper method to generate a qname. - * + * * @return QName qualified name */ protected static QName generateQName() { return QName.createQName(RM_URI, GUID.generate()); } - + /** * Helper method to generate hold reference - * + * * @param name hold name * @return {@link NodeRef} node reference that will behave like a hold */ @@ -241,37 +255,37 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel doReturn(true).when(mockedHoldService).isHold(hold); return hold; } - + /** * Helper method to generate record folder reference - * + * * @return {@link NodeRef} node reference that will behave like a record folder */ protected NodeRef generateRecordFolder() { NodeRef recordFolder = generateNodeRef(TYPE_RECORD_FOLDER); - setupAsFilePlanComponent(recordFolder); + setupAsFilePlanComponent(recordFolder); doReturn(true).when(mockedRecordFolderService).isRecordFolder(recordFolder); - return recordFolder; + return recordFolder; } - + /** * Helper method to generate a record node reference. - * + * * @return {@link NodeRef} node reference that will behave like a record or type cm:content */ protected NodeRef generateRecord() { NodeRef record = generateNodeRef(ContentModel.TYPE_CONTENT); setupAsFilePlanComponent(record); - doReturn(true).when(mockedNodeService).hasAspect(record, ASPECT_RECORD); + doReturn(true).when(mockedNodeService).hasAspect(record, ASPECT_RECORD); doReturn(true).when(mockedRecordService).isRecord(record); return record; } - + /** * Helper method to setup a node reference as a file plan component. - * + * * @param nodeRef {@link NodeRef} node reference that will now behave like a file plan component */ protected void setupAsFilePlanComponent(NodeRef nodeRef) @@ -284,17 +298,17 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel /** * Helper method to generate a node reference. - * + * * @return {@link NodeRef} node reference that behaves like a node that exists in the spaces store */ protected NodeRef generateNodeRef() { return generateNodeRef(null); } - + /** * Helper method to generate a node reference of a particular type. - * + * * @param type content type qualified name * @return {@link NodeRef} node reference that behaves like a node that exists in the spaces store with * the content type provided @@ -303,10 +317,10 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel { return generateNodeRef(type, true); } - + /** * Helper method to generate a cm:content node reference with a given name. - * + * * @param name content name * @return NodeRef node reference */ @@ -316,10 +330,10 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel doReturn(name).when(mockedNodeService).getProperty(nodeRef, ContentModel.PROP_NAME); return nodeRef; } - + /** * Helper method to generate a node reference of a particular type with a given existence characteristic. - * + * * @param type content type qualified name * @param exists indicates whether this node should behave like a node that exists or not * @return {@link NodeRef} node reference that behaves like a node that exists (or not) in the spaces store with @@ -338,7 +352,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel /** * Helper method to generate a mocked child association reference. - * + * * @param parent parent node (optional) * @param child child node (optional) * @return {@link ChildAssociationRef} mocked to return the parent and child nodes @@ -346,25 +360,25 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel protected ChildAssociationRef generateChildAssociationRef(NodeRef parent, NodeRef child) { ChildAssociationRef mockedChildAssociationRef = mock(ChildAssociationRef.class); - + if (parent != null) { doReturn(parent).when(mockedChildAssociationRef).getParentRef(); } - + if (child != null) { doReturn(child).when(mockedChildAssociationRef).getChildRef(); } - + return mockedChildAssociationRef; } - + /** * Helper method to make one node the primary parent of the other. *

* Assumes the cm:contains assoc type. - * + * * @param child * @param parent */ @@ -374,12 +388,12 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel .when(mockedNodeService) .getPrimaryParent(child); } - + /** * Helper method to make a number of nodes children of another. *

* Assumes the cm:contains assoc type. - * + * * @param parent * @param children */ @@ -389,11 +403,11 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel for (NodeRef child : children) { assocs.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, parent, generateQName(), child)); + doReturn(assocs).when(mockedNodeService).getParentAssocs(child); } - - doReturn(assocs).when(mockedNodeService).getChildAssocs(parent, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); + doReturn(assocs).when(mockedNodeService).getChildAssocs(parent, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); } - + @SuppressWarnings("unchecked") protected List buildList(T ... values) { diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImplUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImplUnitTest.java index 169d55eded..2020334a0c 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImplUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/version/RecordableVersionServiceImplUnitTest.java @@ -29,7 +29,6 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.io.Serializable; -import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -38,7 +37,6 @@ import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; import org.alfresco.repo.version.Version2Model; -import org.alfresco.repo.version.VersionMigrator; import org.alfresco.repo.version.VersionModel; import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.NodeRef; @@ -70,7 +68,6 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest private Map versionProperties; /** mocked services */ - private @Mock(name="versionMigrator") VersionMigrator mockedVersionMigrator; private @Mock(name="dbNodeService") NodeService mockedDbNodeService; /** recordable version service */ @@ -199,33 +196,7 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest recordableVersionService.createVersion(nodeRef, versionProperties); // then the recorded version is created - verifyRecordedVersion(filePlan); - - } - - /** - * Helper method that verifies that a recorded version was created. - */ - @SuppressWarnings("unchecked") - private void verifyRecordedVersion(NodeRef filePlan) throws Exception - { - // then unfiled container is retrieved for file plan - verify(mockedFilePlanService, times(1)).getUnfiledContainer(filePlan); - - // then the node is copied into the file plan - verify(mockedFileFolderService, times(1)).copy(eq(nodeRef), - eq(unfiledRecordContainer), - anyString()); - - // then the version is created - verify(mockedDbNodeService, times(1)).createNode(any(NodeRef.class), - eq(Version2Model.CHILD_QNAME_VERSIONS), - any(QName.class), - eq(TYPE_CONTENT), - anyMap()); - verify(mockedNodeService, times(1)).addAspect(eq(version), eq(Version2Model.ASPECT_VERSION), anyMap()); - verify(mockedNodeService, times(1)).addAspect(eq(version), eq(RecordableVersionModel.ASPECT_RECORDED_VERSION), - eq(Collections.singletonMap(RecordableVersionModel.PROP_RECORD_NODE_REF, (Serializable)record))); + verify(mockedRecordService, times(1)).createRecordFromCopy(filePlan, nodeRef); } /** @@ -267,7 +238,7 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest recordableVersionService.createVersion(nodeRef, versionProperties); // then the recorded version is created - verifyRecordedVersion(filePlan); + verify(mockedRecordService, times(1)).createRecordFromCopy(filePlan, nodeRef); } @@ -308,7 +279,7 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest recordableVersionService.createVersion(nodeRef, versionProperties); // then the recorded version is created - verifyRecordedVersion(filePlan); + verify(mockedRecordService, times(1)).createRecordFromCopy(filePlan, nodeRef); } /** @@ -355,7 +326,7 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest recordableVersionService.createVersion(nodeRef, versionProperties); // then the recorded version is created - verifyRecordedVersion(anotherFilePlan); + verify(mockedRecordService, times(0)).createRecordFromCopy(filePlan, nodeRef); } /** @@ -380,7 +351,7 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest recordableVersionService.createVersion(nodeRef, versionProperties); // then the recorded version is created - verifyRecordedVersion(anotherFilePlan); + verify(mockedRecordService, times(0)).createRecordFromCopy(filePlan, nodeRef); } @Test @@ -395,7 +366,7 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest recordableVersionService.createVersion(nodeRef, versionProperties); // then the recorded version is created - verifyRecordedVersion(filePlan); + verify(mockedRecordService, times(1)).createRecordFromCopy(filePlan, nodeRef); } @Test @@ -411,6 +382,6 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest recordableVersionService.createVersion(nodeRef, versionProperties); // then the recorded version is created - verifyRecordedVersion(filePlan); + verify(mockedRecordService, times(1)).createRecordFromCopy(filePlan, nodeRef); } } \ No newline at end of file