From e5c487db07a012fe59ba982791d066ca4d19003b Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Thu, 4 Jul 2013 01:41:20 +0000 Subject: [PATCH 1/5] RM-732: CLONE - "caveat" functionality of the (dod5015) Records Management Module is not cluster-aware git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.0@52115 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../rm-service-context.xml | 35 ++ .../caveat/RMCaveatConfigComponentImpl.java | 377 +++++++++++++----- 2 files changed, 309 insertions(+), 103 deletions(-) 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 06f21ffa6f..629a9ee404 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 @@ -892,9 +892,44 @@ + + + + + + + + + + + + + + + + org.alfresco.cache.caveatConfigCache + + + + + + + + + + + + + org.alfresco.caveatConfigTransactionalCache + + + + + + diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/caveat/RMCaveatConfigComponentImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/caveat/RMCaveatConfigComponentImpl.java index 09a94de97a..60781a2f83 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/caveat/RMCaveatConfigComponentImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/caveat/RMCaveatConfigComponentImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2011 Alfresco Software Limited. + * Copyright (C) 2005-2013 Alfresco Software Limited. * * This file is part of Alfresco * @@ -22,18 +22,22 @@ import java.io.File; import java.io.InputStream; import java.io.Serializable; import java.util.ArrayList; +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 java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint.MatchLogic; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.content.ContentServicePolicies; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.node.NodeServicePolicies; @@ -97,16 +101,25 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon private static final QName DATATYPE_TEXT = DataTypeDefinition.TEXT; + /** + * Lock objects + */ + private ReadWriteLock lock = new ReentrantReadWriteLock(); + private Lock readLock = lock.readLock(); + private Lock writeLock = lock.writeLock(); /* - * Caveat Config + * Caveat Config (Shared) config * first string is property name * second string is authority name (user or group full name) * third string is list of values of property - */ + */ + private SimpleCache>> caveatConfig; - // TODO - convert to SimpleCache to be cluster-aware (for dynamic changes to caveat config across a cluster) - private Map>> caveatConfig = new ConcurrentHashMap>>(2); + public void setCaveatConfig(SimpleCache>> caveatConfig) + { + this.caveatConfig = caveatConfig; + } public void setPolicyComponent(PolicyComponent policyComponent) { @@ -252,6 +265,12 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon validateAndReset(childAssocRef.getChildRef()); } + /** + * Validate the caveat config and optionally update the cache. + * + * @param nodeRef The nodeRef of the config + * @param updateCache Set to true to update the cache + */ @SuppressWarnings("unchecked") protected void validateAndReset(NodeRef nodeRef) { @@ -409,15 +428,29 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon } } - // Valid, so update - caveatConfig.clear(); - - for (Map.Entry conEntry : caveatConfigMap.entrySet()) + try { - String conStr = conEntry.getKey(); - Map> caveatMap = (Map>)conEntry.getValue(); + writeLock.lock(); + // we can't just clear the cache, as all puts to the cache afterwards in this transaction will be ignored + // first delete all keys that are now not in the config + caveatConfig.getKeys().retainAll(caveatConfigMap.keySet()); - caveatConfig.put(conStr, caveatMap); + for (Map.Entry conEntry : caveatConfigMap.entrySet()) + { + String conStr = conEntry.getKey(); + Map> caveatMap = (Map>)conEntry.getValue(); + + Map> cacheValue = caveatConfig.get(conStr); + if (cacheValue == null || !cacheValue.equals(caveatMap)) + { + // update the cache + caveatConfig.put(conStr, caveatMap); + } + } + } + finally + { + writeLock.unlock(); } } catch (JSONException e) @@ -495,9 +528,19 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon } // Get list of all caveat qualified names - public Set getRMConstraintNames() + public Collection getRMConstraintNames() { - return caveatConfig.keySet(); + Collection rmConstraintNames = Collections.emptySet(); + try + { + readLock.lock(); + rmConstraintNames = caveatConfig.getKeys(); + } + finally + { + readLock.unlock(); + } + return Collections.unmodifiableCollection(rmConstraintNames); } // Get allowed values for given caveat (for current user) @@ -510,8 +553,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { if (! (AuthenticationUtil.isMtEnabled() && AuthenticationUtil.isRunAsUserTheSystemUser())) { - // note: userName and userGroupNames must not be null - Map> caveatConstraintDef = caveatConfig.get(constraintName); + // note: userName and userGroupNames must not be null Set userGroupFullNames = authorityService.getAuthoritiesForUser(userName); allowedValues = getRMAllowedValues(userName, userGroupFullNames, constraintName); } @@ -525,7 +567,16 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon SetallowedValues = new HashSet(); // note: userName and userGroupNames must not be null - Map> caveatConstraintDef = caveatConfig.get(constraintName); + Map> caveatConstraintDef = null; + try + { + readLock.lock(); + caveatConstraintDef = caveatConfig.get(constraintName); + } + finally + { + readLock.unlock(); + } if (caveatConstraintDef != null) { @@ -547,7 +598,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon Listret = new ArrayList(); ret.addAll(allowedValues); - return ret; + return Collections.unmodifiableList(ret); } /** @@ -692,23 +743,53 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon * * @param listName the name of the RMConstraintList * @param authorityName - * @param values + * @param value * @throws AlfrescoRuntimeException if either the list or the authority do not already exist. */ public void addRMConstraintListValue(String listName, String authorityName, String value) { - Map> members = caveatConfig.get(listName); - if(members == null) + Map> members = null; + try { - throw new AlfrescoRuntimeException("unable to add to list, list not defined:"+ listName); + readLock.lock(); + members = caveatConfig.get(listName); + if(members == null) + { + throw new AlfrescoRuntimeException("unable to add to list, list not defined:"+ listName); + } + + try + { + readLock.unlock(); + writeLock.lock(); + // check again + members = caveatConfig.get(listName); + if(members == null) + { + throw new AlfrescoRuntimeException("unable to add to list, list not defined:"+ listName); + } + + List values = members.get(authorityName); + if(values == null) + { + throw new AlfrescoRuntimeException("Unable to add to authority in list. Authority not member listName: "+ listName + " authorityName:" +authorityName); + } + values.add(value); + + caveatConfig.put(listName, members); + updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + } + finally + { + readLock.lock(); + writeLock.unlock(); + } + } - List values = members.get(authorityName); - if(values == null) + finally { - throw new AlfrescoRuntimeException("Unable to add to authority in list. Authority not member listName: "+ listName + " authorityName:" +authorityName); + readLock.unlock(); } - values.add(value); - updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); } /** @@ -718,7 +799,24 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon */ public Map> getListDetails(String listName) { - return caveatConfig.get(listName); + Map> listDetails = null; + try + { + readLock.lock(); + listDetails = caveatConfig.get(listName); + } + finally + { + readLock.unlock(); + } + if (listDetails == null) + { + return Collections.emptyMap(); + } + else + { + return Collections.unmodifiableMap(listDetails); + } } public List getRMCaveatModels() @@ -738,20 +836,30 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon */ public void updateRMConstraintListAuthority(String listName, String authorityName, Listvalues) { - Map> members = caveatConfig.get(listName); - if(members == null) + Map> members = null; + try { - // Create the new list, with the authority name - Map> constraint = new HashMap>(0); - constraint.put(authorityName, values); - caveatConfig.put(listName, constraint); - } - else - { - members.put(authorityName, values); - } + writeLock.lock(); + members = caveatConfig.get(listName); + if(members == null) + { + // Create the new list, with the authority name + Map> constraint = new HashMap>(0); + constraint.put(authorityName, new ArrayList(values)); + members = constraint; + } + else + { + members.put(authorityName, new ArrayList(values)); + } - updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + caveatConfig.put(listName, members); + updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + } + finally + { + writeLock.unlock(); + } } /** @@ -764,57 +872,19 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon public void updateRMConstraintListValue(String listName, String valueName, Listauthorities) { - // members contains member, values[] - Map> members = caveatConfig.get(listName); - - if(members == null) + Map> members = null; + try { - // Members List does not exist - Map> emptyConstraint = new HashMap>(0); - caveatConfig.put(listName, emptyConstraint); - members = emptyConstraint; - - } - // authorities contains authority, values[] - // pivot contains value, members[] - Map> pivot = PivotUtil.getPivot(members); + writeLock.lock(); - // remove all authorities which have this value - List existingAuthorities = pivot.get(valueName); - if(existingAuthorities != null) - { - for(String authority : existingAuthorities) + if(members == null) { - List vals = members.get(authority); - vals.remove(valueName); + // Members List does not exist + Map> emptyConstraint = new HashMap>(0); + caveatConfig.put(listName, emptyConstraint); + members = emptyConstraint; + } - } - // add the new authorities for this value - for(String authority : authorities) - { - List vals = members.get(authority); - if(vals == null) - { - vals= new ArrayList(); - members.put(authority, vals); - } - vals.add(valueName); - } - - updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); - } - - public void removeRMConstraintListValue(String listName, String valueName) - { - // members contains member, values[] - Map> members = caveatConfig.get(listName); - - if(members == null) - { - // list does not exist - } - else - { // authorities contains authority, values[] // pivot contains value, members[] Map> pivot = PivotUtil.getPivot(members); @@ -829,8 +899,82 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon vals.remove(valueName); } } - - updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + // add the new authorities for this value + for(String authority : authorities) + { + List vals = members.get(authority); + if(vals == null) + { + vals= new ArrayList(); + members.put(authority, vals); + } + vals.add(valueName); + } + caveatConfig.put(listName, members); + updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + } + finally + { + writeLock.unlock(); + } + } + + public void removeRMConstraintListValue(String listName, String valueName) + { + Map> members = null; + try + { + readLock.lock(); + + members = caveatConfig.get(listName); + if(members == null) + { + // list does not exist + } + else + { + try + { + readLock.unlock(); + writeLock.lock(); + // check again + members = caveatConfig.get(listName); + if(members == null) + { + // list does not exist + } + else + { + // authorities contains authority, values[] + // pivot contains value, members[] + Map> pivot = PivotUtil.getPivot(members); + + // remove all authorities which have this value + List existingAuthorities = pivot.get(valueName); + if(existingAuthorities != null) + { + for(String authority : existingAuthorities) + { + List vals = members.get(authority); + vals.remove(valueName); + } + caveatConfig.put(listName, members); + } + } + + updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + } + finally + { + readLock.lock(); + writeLock.unlock(); + } + + } + } + finally + { + readLock.unlock(); } } @@ -843,26 +987,37 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon */ public void removeRMConstraintListAuthority(String listName, String authorityName) { - Map> members = caveatConfig.get(listName); - if(members != null) + Map> members = null; + try { - members.remove(listName); + writeLock.lock(); + members = caveatConfig.get(listName); + if(members != null) + { + members.remove(listName); + } + + caveatConfig.put(listName, members); + updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + } - - updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); - } + finally + { + writeLock.unlock(); + } +} /** * @param config the configuration to convert * @return a String containing the JSON representation of the configuration. */ - private String convertToJSONString(Map>> config) + private String convertToJSONString(SimpleCache>> config) { JSONObject obj = new JSONObject(); try { - Set listNames = config.keySet(); + Collection listNames = config.getKeys(); for(String listName : listNames) { Map> members = config.get(listName); @@ -932,14 +1087,30 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon public void deleteRMConstraint(String listName) { - caveatConfig.remove(listName); - updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + try + { + writeLock.lock(); + caveatConfig.remove(listName); + updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + } + finally + { + writeLock.unlock(); + } } public void addRMConstraint(String listName) { - Map> emptyConstraint = new HashMap>(0); - caveatConfig.put(listName, emptyConstraint); - updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + try + { + writeLock.lock(); + Map> emptyConstraint = new HashMap>(0); + caveatConfig.put(listName, emptyConstraint); + updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + } + finally + { + writeLock.unlock(); + } } } From d24300700005c43370b1999f357e2bd87cb910a7 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Mon, 8 Jul 2013 23:54:08 +0000 Subject: [PATCH 2/5] RM-757: Permission confusion after upgrade from 1.0 RM-753: Can't edit former seria untill it's vital git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.0@52262 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../model/recordsModel.xml | 1 - .../rm-patch-context.xml | 2 + .../RecordsManagementTypeFormFilter.java | 11 ++- .../patch/RMv2FilePlanNodeRefPatch.java | 68 +++++++++++++++++-- .../BroadcastVitalRecordDefinitionAction.java | 10 ++- .../vital/VitalRecordDefinitionImpl.java | 4 ++ 6 files changed, 86 insertions(+), 10 deletions(-) diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml index 94c3a75c1a..82097435aa 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/model/recordsModel.xml @@ -677,7 +677,6 @@ Review Period d:period - true none|0 diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml index 0a28801ddc..d030f80f98 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml @@ -46,6 +46,8 @@ + + \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementTypeFormFilter.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementTypeFormFilter.java index 56f3939301..70d7723616 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementTypeFormFilter.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/forms/RecordsManagementTypeFormFilter.java @@ -113,11 +113,20 @@ public class RecordsManagementTypeFormFilter extends RecordsManagementFormFilter for (FieldDefinition fieldDef : fieldDefs) { String prefixName = fieldDef.getName(); - if (prefixName.equals("rma:identifier")) + if (prefixName.equals("rma:identifier") == true) { String defaultId = identifierService.generateIdentifier(typeName, null); fieldDef.setDefaultValue(defaultId); } + // NOTE: we set these defaults in the form for backwards compatibility reasons (RM-753) + else if (prefixName.equals("rma:vitalRecordIndicator") == true) + { + fieldDef.setDefaultValue(Boolean.FALSE.toString()); + } + else if (prefixName.equals("rma:reviewPeriod") == true) + { + fieldDef.setDefaultValue("none|0"); + } } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2FilePlanNodeRefPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2FilePlanNodeRefPatch.java index 526b4756cb..bd8175f8dd 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2FilePlanNodeRefPatch.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2FilePlanNodeRefPatch.java @@ -18,11 +18,16 @@ */ package org.alfresco.module.org_alfresco_module_rm.patch; +import java.io.Serializable; import java.util.List; +import org.alfresco.module.org_alfresco_module_rm.FilePlanComponentKind; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService; +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService; +import org.alfresco.module.org_alfresco_module_rm.security.Role; import org.alfresco.repo.domain.node.NodeDAO; import org.alfresco.repo.domain.patch.PatchDAO; import org.alfresco.repo.domain.qname.QNameDAO; @@ -30,6 +35,8 @@ import org.alfresco.repo.module.AbstractModuleComponent; import org.alfresco.repo.policy.BehaviourFilter; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.Period; +import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; import org.alfresco.util.Pair; import org.apache.commons.logging.Log; @@ -53,6 +60,8 @@ public class RMv2FilePlanNodeRefPatch extends AbstractModuleComponent private PatchDAO patchDAO; private NodeDAO nodeDAO; private QNameDAO qnameDAO; + private PermissionService permissionService; + private RecordsManagementSecurityService recordsManagementSecurityService; public void setNodeService(NodeService nodeService) { @@ -84,6 +93,22 @@ public class RMv2FilePlanNodeRefPatch extends AbstractModuleComponent this.qnameDAO = qnameDAO; } + /** + * @param recordsManagementSecurityService records management security service + */ + public void setRecordsManagementSecurityService(RecordsManagementSecurityService recordsManagementSecurityService) + { + this.recordsManagementSecurityService = recordsManagementSecurityService; + } + + /** + * @param permissionService permission service + */ + public void setPermissionService(PermissionService permissionService) + { + this.permissionService = permissionService; + } + /** * @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal() */ @@ -98,24 +123,53 @@ public class RMv2FilePlanNodeRefPatch extends AbstractModuleComponent Pair aspectPair = qnameDAO.getQName(ASPECT_FILE_PLAN_COMPONENT); if (aspectPair != null) { - List records = patchDAO.getNodesByAspectQNameId(aspectPair.getFirst(), 0L, patchDAO.getMaxAdmNodeID()); + List filePlanComponents = patchDAO.getNodesByAspectQNameId(aspectPair.getFirst(), 0L, patchDAO.getMaxAdmNodeID()); if (logger.isDebugEnabled() == true) { - logger.debug(" ... updating " + records.size() + " items" ); + logger.debug(" ... updating " + filePlanComponents.size() + " items" ); } behaviourFilter.disableBehaviour(); try { - for (Long record : records) + for (Long filePlanComponent : filePlanComponents) { - Pair recordPair = nodeDAO.getNodePair(record); - NodeRef recordNodeRef = recordPair.getSecond(); + Pair recordPair = nodeDAO.getNodePair(filePlanComponent); + NodeRef filePlanComponentNodeRef = recordPair.getSecond(); - if (nodeService.getProperty(recordNodeRef, PROP_ROOT_NODEREF) == null) + NodeRef filePlan = recordsManagementService.getFilePlan(filePlanComponentNodeRef); + + // set the file plan node reference + if (nodeService.getProperty(filePlanComponentNodeRef, PROP_ROOT_NODEREF) == null) { - nodeService.setProperty(recordNodeRef, PROP_ROOT_NODEREF, recordsManagementService.getFilePlan(recordNodeRef)); + nodeService.setProperty(filePlanComponentNodeRef, PROP_ROOT_NODEREF, filePlan); + } + + // only set the rmadmin permissions on record categories, record folders and records + FilePlanComponentKind kind = recordsManagementService.getFilePlanComponentKind(filePlanComponentNodeRef); + if (FilePlanComponentKind.RECORD_CATEGORY.equals(kind) == true || + FilePlanComponentKind.RECORD_FOLDER.equals(kind) == true || + FilePlanComponentKind.RECORD.equals(kind) == true ) + { + // ensure the that the records management role has read and file on the node + Role adminRole = recordsManagementSecurityService.getRole(filePlan, "Administrator"); + if (adminRole != null) + { + permissionService.setPermission(filePlanComponentNodeRef, adminRole.getRoleGroupName(), RMPermissionModel.FILING, true); + } + + // ensure that the default vital record default values have been set (RM-753) + Serializable vitalRecordIndicator = nodeService.getProperty(filePlanComponentNodeRef, PROP_VITAL_RECORD_INDICATOR); + if (vitalRecordIndicator == null) + { + nodeService.setProperty(filePlanComponentNodeRef, PROP_VITAL_RECORD_INDICATOR, false); + } + Serializable reviewPeriod = nodeService.getProperty(filePlanComponentNodeRef, PROP_REVIEW_PERIOD); + if (reviewPeriod == null) + { + nodeService.setProperty(filePlanComponentNodeRef, PROP_REVIEW_PERIOD, new Period("none|0")); + } } } } 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 e7adec62e7..faa03fa17b 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 @@ -68,7 +68,15 @@ public class BroadcastVitalRecordDefinitionAction extends RMActionExecuterAbstra private void propagateChangeToChildrenOf(NodeRef actionedUponNodeRef) { Map parentProps = nodeService.getProperties(actionedUponNodeRef); - boolean parentVri = (Boolean) parentProps.get(PROP_VITAL_RECORD_INDICATOR); + + // parent vital record indicator, default to null if not set + boolean parentVri = false; + Boolean parentVriValue = (Boolean) parentProps.get(PROP_VITAL_RECORD_INDICATOR); + if (parentVriValue != null) + { + parentVri = parentVriValue.booleanValue(); + } + Period parentReviewPeriod = (Period) parentProps.get(PROP_REVIEW_PERIOD); List assocs = this.nodeService.getChildAssocs(actionedUponNodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/VitalRecordDefinitionImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/VitalRecordDefinitionImpl.java index 571992b247..2315ddf2bf 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/VitalRecordDefinitionImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/vital/VitalRecordDefinitionImpl.java @@ -63,6 +63,10 @@ public class VitalRecordDefinitionImpl implements VitalRecordDefinition, Records /* package */ static VitalRecordDefinition create(NodeService nodeService, NodeRef nodeRef) { Boolean enabled = (Boolean)nodeService.getProperty(nodeRef, PROP_VITAL_RECORD_INDICATOR); + if (enabled == null) + { + enabled = Boolean.FALSE; + } Period reviewPeriod = (Period)nodeService.getProperty(nodeRef, PROP_REVIEW_PERIOD); return new VitalRecordDefinitionImpl(enabled, reviewPeriod); } From caf766123fd9c68228f2b8413f4ec96182a10a25 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Tue, 9 Jul 2013 01:20:51 +0000 Subject: [PATCH 3/5] RM: Unable to set list of values after migration from 1.0->2.0.3 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.0@52264 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../RecordsManagementAdminServiceImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementAdminServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementAdminServiceImpl.java index 3b6b7de0ed..8c341b93d1 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementAdminServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/RecordsManagementAdminServiceImpl.java @@ -120,7 +120,8 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin /** Constants */ public static final String RMC_CUSTOM_ASSOCS = RecordsManagementCustomModel.RM_CUSTOM_PREFIX + ":customAssocs"; - private static final String CUSTOM_CONSTRAINT_TYPE = org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint.class.getName(); + private static final String CUSTOM_CONSTRAINT_TYPE = org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint.class.getName(); + private static final String CAPATIBILITY_CUSTOM_CONTRAINT_TYPE = org.alfresco.module.org_alfresco_module_dod5015.caveat.RMListOfValuesConstraint.class.getName(); private static final NodeRef RM_CUSTOM_MODEL_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "records_management_custom_model"); private static final String PARAM_ALLOWED_VALUES = "allowedValues"; private static final String PARAM_CASE_SENSITIVE = "caseSensitive"; @@ -1367,7 +1368,9 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin } String type = customConstraint.getType(); - if ((type == null) || (! type.equals(CUSTOM_CONSTRAINT_TYPE))) + if (type == null || + (type.equals(CUSTOM_CONSTRAINT_TYPE) == false && + type.equals(CAPATIBILITY_CUSTOM_CONTRAINT_TYPE) == false)) { throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_UNEXPECTED_TYPE_CONSTRAINT, type, constraintNameAsPrefixString, CUSTOM_CONSTRAINT_TYPE)); } From 9eb525f63d063914e7316223b06204d439481e96 Mon Sep 17 00:00:00 2001 From: Tuna Aksoy Date: Tue, 9 Jul 2013 15:49:51 +0000 Subject: [PATCH 4/5] RM-769 (Impossible to add access for several values) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.0@52294 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../caveat/RMCaveatConfigComponentImpl.java | 290 +++++++++--------- 1 file changed, 145 insertions(+), 145 deletions(-) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/caveat/RMCaveatConfigComponentImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/caveat/RMCaveatConfigComponentImpl.java index 60781a2f83..d1af5a0ace 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/caveat/RMCaveatConfigComponentImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/caveat/RMCaveatConfigComponentImpl.java @@ -70,7 +70,7 @@ import org.json.JSONObject; /** * RM Caveat Config component impl - * + * * @author janv */ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnContentUpdatePolicy, @@ -79,7 +79,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon RMCaveatConfigComponent { private static Log logger = LogFactory.getLog(RMCaveatConfigComponentImpl.class); - + private PolicyComponent policyComponent; private ContentService contentService; private DictionaryService dictionaryService; @@ -87,90 +87,90 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon private AuthorityService authorityService; private PersonService personService; private NodeService nodeService; - + // Default private StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"); - + private List caveatAspectURINames = new ArrayList(0); private List caveatAspectQNames = new ArrayList(0); - + private List caveatModelURINames = new ArrayList(0); private List caveatModelQNames = new ArrayList(0); - + private static final String CAVEAT_CONFIG_NAME = "caveatConfig.json"; - + private static final QName DATATYPE_TEXT = DataTypeDefinition.TEXT; - + /** * Lock objects */ private ReadWriteLock lock = new ReentrantReadWriteLock(); private Lock readLock = lock.readLock(); private Lock writeLock = lock.writeLock(); - + /* * Caveat Config (Shared) config * first string is property name * second string is authority name (user or group full name) - * third string is list of values of property - */ + * third string is list of values of property + */ private SimpleCache>> caveatConfig; - + public void setCaveatConfig(SimpleCache>> caveatConfig) { this.caveatConfig = caveatConfig; } - + public void setPolicyComponent(PolicyComponent policyComponent) { this.policyComponent = policyComponent; } - + public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } - + public void setContentService(ContentService contentService) { this.contentService = contentService; } - + public void setDictionaryService(DictionaryService dictionaryService) { this.dictionaryService = dictionaryService; } - + public void setNamespaceService(NamespaceService namespaceService) { this.namespaceService = namespaceService; } - + public void setAuthorityService(AuthorityService authorityService) { this.authorityService = authorityService; } - + public void setPersonService(PersonService personService) { this.personService = personService; } - + public void setStoreRef(String storeRef) { this.storeRef = new StoreRef(storeRef); } - + public void setCaveatAspects(List caveatAspectNames) { this.caveatAspectURINames = caveatAspectNames; } - + public void setCaveatModels(List caveatModelNames) { this.caveatModelURINames = caveatModelNames; } - + /** * Initialise behaviours and caveat config cache */ @@ -181,26 +181,26 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon ContentServicePolicies.OnContentUpdatePolicy.QNAME, RecordsManagementModel.TYPE_CAVEAT_CONFIG, new JavaBehaviour(this, "onContentUpdate")); - + // Register interest in the beforeDeleteNode policy policyComponent.bindClassBehaviour( QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"), RecordsManagementModel.TYPE_CAVEAT_CONFIG, new JavaBehaviour(this, "beforeDeleteNode")); - + // Register interest in the onCreateNode policy policyComponent.bindClassBehaviour( QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"), RecordsManagementModel.TYPE_CAVEAT_CONFIG, new JavaBehaviour(this, "onCreateNode")); - + if (caveatAspectURINames.size() > 0) { for (String caveatAspectURIName : caveatAspectURINames) { caveatAspectQNames.add(QName.createQName(caveatAspectURIName)); } - + if (logger.isInfoEnabled()) { logger.info("Caveat aspects configured "+caveatAspectQNames); @@ -210,14 +210,14 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { logger.warn("No caveat aspects configured - caveats will not be applied"); } - + if (caveatModelURINames.size() > 0) { for (String caveatModelURIName : caveatModelURINames) { caveatModelQNames.add(QName.createQName(caveatModelURIName)); } - + if (logger.isInfoEnabled()) { logger.info("Caveat models configured "+caveatModelQNames); @@ -227,44 +227,44 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { logger.info("No caveat models configured - all models will be checked"); } - + NodeRef caveatConfigNodeRef = getCaveatConfigNode(); if (caveatConfigNodeRef != null) { validateAndReset(caveatConfigNodeRef); } } - + public void onContentUpdate(NodeRef nodeRef, boolean newContent) { if (logger.isInfoEnabled()) { logger.info("onContentUpdate: "+nodeRef+", "+newContent); } - + validateAndReset(nodeRef); } - + public void beforeDeleteNode(NodeRef nodeRef) { if (logger.isInfoEnabled()) { logger.info("beforeDeleteNode: "+nodeRef); } - + validateAndReset(nodeRef); } - + public void onCreateNode(ChildAssociationRef childAssocRef) { if (logger.isInfoEnabled()) { logger.info("onCreateNode: "+childAssocRef); } - + validateAndReset(childAssocRef.getChildRef()); } - + /** * Validate the caveat config and optionally update the cache. * @@ -279,7 +279,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { // TODO - check who can change caveat config ! // TODO - locking (or checkout/checkin) - + String caveatConfigData = cr.getContentString(); if (caveatConfigData != null) { @@ -288,18 +288,18 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { throw new AlfrescoRuntimeException("Cannot create more than one caveat config (existing="+existing+", new="+nodeRef+")"); } - + try { if (logger.isTraceEnabled()) { logger.trace(caveatConfigData); } - + Set models = new HashSet(1); Set props = new HashSet(10); Set expectedPrefixes = new HashSet(10); - + if (caveatModelQNames.size() > 0) { models.addAll(caveatModelQNames); @@ -308,18 +308,18 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { models.addAll(dictionaryService.getAllModels()); } - + if (logger.isTraceEnabled()) { logger.trace("validateAndReset: models to check "+models); } - + for (QName model : models) { props.addAll(dictionaryService.getProperties(model, DATATYPE_TEXT)); expectedPrefixes.addAll(namespaceService.getPrefixes(model.getNamespaceURI())); } - + if (props.size() == 0) { logger.warn("validateAndReset: no caveat properties found"); @@ -331,15 +331,15 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon logger.trace("validateAndReset: properties to check "+props); } } - + Map caveatConfigMap = JSONtoFmModel.convertJSONObjectToMap(caveatConfigData); - + for (Map.Entry conEntry : caveatConfigMap.entrySet()) { String conStr = conEntry.getKey(); - + QName conQName = QName.resolveToQName(namespaceService, conStr); - + // check prefix String conPrefix = QName.splitPrefixedQName(conStr)[0]; boolean prefixFound = false; @@ -350,17 +350,17 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon prefixFound = true; } } - + if (! prefixFound) { throw new AlfrescoRuntimeException("Unexpected prefix: "+ conPrefix + " (" + conStr +") expected one of "+expectedPrefixes+")"); } - + Map> caveatMap = (Map>)conEntry.getValue(); - + List allowedValues = null; boolean found = false; - + for (QName propertyName : props) { PropertyDefinition propDef = dictionaryService.getProperty(propertyName); @@ -381,31 +381,31 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon return ((RMListOfValuesConstraint)con).getAllowedValues(); } }, AuthenticationUtil.getSystemUserName()); - + found = true; break; } } } } - + if (! found) { //throw new AlfrescoRuntimeException("Constraint does not exist (or is not used): "+conStr); } - + if (allowedValues != null) { if (logger.isInfoEnabled()) { logger.info("Processing constraint: "+conQName); } - + for (Map.Entry> caveatEntry : caveatMap.entrySet()) { String authorityName = caveatEntry.getKey(); List caveatList = caveatEntry.getValue(); - + // validate authority (user or group) - note: groups are configured with fullname (ie. GROUP_xxx) if ((! authorityService.authorityExists(authorityName) && ! personService.personExists(authorityName))) { @@ -413,7 +413,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon String msg = "User/group does not exist: "+authorityName+" (constraint="+conStr+")"; logger.warn(msg); } - + // validate caveat list for (String value : caveatList) { @@ -427,19 +427,19 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon } } } - + try { writeLock.lock(); // we can't just clear the cache, as all puts to the cache afterwards in this transaction will be ignored // first delete all keys that are now not in the config caveatConfig.getKeys().retainAll(caveatConfigMap.keySet()); - + for (Map.Entry conEntry : caveatConfigMap.entrySet()) { String conStr = conEntry.getKey(); Map> caveatMap = (Map>)conEntry.getValue(); - + Map> cacheValue = caveatConfig.get(conStr); if (cacheValue == null || !cacheValue.equals(caveatMap)) { @@ -460,53 +460,53 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon } } } - + private NodeRef getCaveatConfigNode() { NodeRef rootNode = nodeService.getRootNode(storeRef); return nodeService.getChildByName(rootNode, RecordsManagementModel.ASSOC_CAVEAT_CONFIG, CAVEAT_CONFIG_NAME); } - - + + public NodeRef updateOrCreateCaveatConfig(InputStream is) { NodeRef caveatConfig = getOrCreateCaveatConfig(); - + // Update the content ContentWriter writer = this.contentService.getWriter(caveatConfig, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.setEncoding("UTF-8"); writer.putContent(is); - + return caveatConfig; } - + public NodeRef updateOrCreateCaveatConfig(File jsonFile) { NodeRef caveatConfig = getOrCreateCaveatConfig(); - + // Update the content ContentWriter writer = this.contentService.getWriter(caveatConfig, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.setEncoding("UTF-8"); writer.putContent(jsonFile); - + return caveatConfig; } - + public NodeRef updateOrCreateCaveatConfig(String jsonString) { NodeRef caveatConfig = getOrCreateCaveatConfig(); - + // Update the content ContentWriter writer = this.contentService.getWriter(caveatConfig, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.setEncoding("UTF-8"); writer.putContent(jsonString); - + return caveatConfig; } - + private NodeRef getOrCreateCaveatConfig() { NodeRef caveatConfig = getCaveatConfigNode(); @@ -514,19 +514,19 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { NodeRef rootNode = nodeService.getRootNode(storeRef); nodeService.addAspect(rootNode, VersionModel.ASPECT_VERSION_STORE_ROOT, null); - + // Create caveat config caveatConfig = nodeService.createNode(rootNode, RecordsManagementModel.ASSOC_CAVEAT_CONFIG, QName.createQName(RecordsManagementModel.RM_URI, CAVEAT_CONFIG_NAME), RecordsManagementModel.TYPE_CAVEAT_CONFIG).getChildRef(); - + nodeService.setProperty(caveatConfig, ContentModel.PROP_NAME, CAVEAT_CONFIG_NAME); } - + return caveatConfig; } - + // Get list of all caveat qualified names public Collection getRMConstraintNames() { @@ -542,30 +542,30 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon } return Collections.unmodifiableCollection(rmConstraintNames); } - + // Get allowed values for given caveat (for current user) public List getRMAllowedValues(String constraintName) { List allowedValues = new ArrayList(0); - + String userName = AuthenticationUtil.getRunAsUser(); if (userName != null) { if (! (AuthenticationUtil.isMtEnabled() && AuthenticationUtil.isRunAsUserTheSystemUser())) { - // note: userName and userGroupNames must not be null + // note: userName and userGroupNames must not be null Set userGroupFullNames = authorityService.getAuthoritiesForUser(userName); allowedValues = getRMAllowedValues(userName, userGroupFullNames, constraintName); } } - + return allowedValues; } - + private List getRMAllowedValues(String userName, Set userGroupFullNames, String constraintName) { SetallowedValues = new HashSet(); - + // note: userName and userGroupNames must not be null Map> caveatConstraintDef = null; try @@ -577,7 +577,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { readLock.unlock(); } - + if (caveatConstraintDef != null) { List direct = caveatConstraintDef.get(userName); @@ -585,7 +585,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { allowedValues.addAll(direct); } - + for (String group : userGroupFullNames) { List values = caveatConstraintDef.get(group); @@ -595,15 +595,15 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon } } } - + Listret = new ArrayList(); ret.addAll(allowedValues); return Collections.unmodifiableList(ret); } - + /** * Check whether access to 'record component' node is vetoed for current user due to caveat(s) - * + * * @param nodeRef * @return false, if caveat(s) veto access otherwise return true */ @@ -614,7 +614,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { return true; } - + boolean found = false; for (QName caveatAspectQName : caveatAspectQNames) { @@ -624,7 +624,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon break; } } - + if (! found) { // no caveat aspect @@ -642,7 +642,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { QName propName = entry.getKey(); PropertyDefinition propDef = dictionaryService.getProperty(propName); - + if ((propDef != null) && (propDef.getDataType().getName().equals(DATATYPE_TEXT))) { List conDefs = propDef.getConstraints(); @@ -654,7 +654,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon RMListOfValuesConstraint rmCon = ((RMListOfValuesConstraint)con); String conName = rmCon.getShortName(); MatchLogic matchLogic = rmCon.getMatchLogicEnum(); - Map> caveatConstraintDef = caveatConfig.get(conName); + Map> caveatConstraintDef = caveatConfig.get(conName); if (caveatConstraintDef == null) { continue; @@ -663,7 +663,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { Set userGroupNames = authorityService.getAuthoritiesForUser(userName); List allowedValues = getRMAllowedValues(userName, userGroupNames, conName); - + List propValues = null; Object val = entry.getValue(); if (val instanceof String) @@ -675,7 +675,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { propValues = (List)val; } - + if (propValues != null && !isAllowed(propValues, allowedValues, matchLogic)) { if (logger.isDebugEnabled()) @@ -690,11 +690,11 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon } } } - + return true; } } - + private boolean isAllowed(List propValues, List userGroupValues, MatchLogic matchLogic) { if (matchLogic.equals(MatchLogic.AND)) @@ -708,11 +708,11 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { logger.trace("Not allowed: "+propValues+", "+userGroupValues+", "+matchLogic); } - + return false; } } - + return true; } else if (matchLogic.equals(MatchLogic.OR)) @@ -725,22 +725,22 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon return true; } } - + if (logger.isTraceEnabled()) { logger.trace("Not allowed: "+propValues+", "+userGroupValues+", "+matchLogic); } - + return false; } - + logger.error("Unexpected match logic type: "+matchLogic); return false; } - + /** * Add a single value to an authority in a list. The existing values of the list remain. - * + * * @param listName the name of the RMConstraintList * @param authorityName * @param value @@ -757,7 +757,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { throw new AlfrescoRuntimeException("unable to add to list, list not defined:"+ listName); } - + try { readLock.unlock(); @@ -782,7 +782,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon finally { readLock.lock(); - writeLock.unlock(); + writeLock.unlock(); } } @@ -791,7 +791,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon readLock.unlock(); } } - + /** * Get the member details of the specified list * @param listName @@ -818,18 +818,18 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon return Collections.unmodifiableMap(listDetails); } } - + public List getRMCaveatModels() { return caveatModelQNames; } - + /** - * Replace the values for an authority in a list. + * Replace the values for an authority in a list. * The existing values are removed. - * + * * If the authority does not already exist in the list, it will be added - * + * * @param listName the name of the RMConstraintList * @param authorityName * @param values @@ -841,7 +841,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { writeLock.lock(); members = caveatConfig.get(listName); - if(members == null) + if(members == null) { // Create the new list, with the authority name Map> constraint = new HashMap>(0); @@ -852,43 +852,43 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { members.put(authorityName, new ArrayList(values)); } - + caveatConfig.put(listName, members); - updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); } finally { writeLock.unlock(); } } - + /** * Replace the authorities for a value in a list - * + * * @param listName * @param valueName * @param authorities */ public void updateRMConstraintListValue(String listName, String valueName, Listauthorities) { - - Map> members = null; + + Map> members = caveatConfig.get(listName); try { writeLock.lock(); - + if(members == null) { // Members List does not exist Map> emptyConstraint = new HashMap>(0); caveatConfig.put(listName, emptyConstraint); members = emptyConstraint; - + } // authorities contains authority, values[] // pivot contains value, members[] Map> pivot = PivotUtil.getPivot(members); - + // remove all authorities which have this value List existingAuthorities = pivot.get(valueName); if(existingAuthorities != null) @@ -911,21 +911,21 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon vals.add(valueName); } caveatConfig.put(listName, members); - updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); + updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); } finally { writeLock.unlock(); } } - + public void removeRMConstraintListValue(String listName, String valueName) { Map> members = null; try { readLock.lock(); - + members = caveatConfig.get(listName); if(members == null) { @@ -948,7 +948,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon // authorities contains authority, values[] // pivot contains value, members[] Map> pivot = PivotUtil.getPivot(members); - + // remove all authorities which have this value List existingAuthorities = pivot.get(valueName); if(existingAuthorities != null) @@ -961,7 +961,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon caveatConfig.put(listName, members); } } - + updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); } finally @@ -977,10 +977,10 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon readLock.unlock(); } } - + /** * Remove an authority from a list - * + * * @param listName the name of the RMConstraintList * @param authorityName * @param values @@ -996,7 +996,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon { members.remove(listName); } - + caveatConfig.put(listName, members); updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); @@ -1006,7 +1006,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon writeLock.unlock(); } } - + /** * @param config the configuration to convert * @return a String containing the JSON representation of the configuration. @@ -1014,22 +1014,22 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon private String convertToJSONString(SimpleCache>> config) { JSONObject obj = new JSONObject(); - - try + + try { Collection listNames = config.getKeys(); for(String listName : listNames) { Map> members = config.get(listName); - + Set authorityNames = members.keySet(); JSONObject listMembers = new JSONObject(); - + for(String authorityName : authorityNames) { listMembers.put(authorityName, members.get(authorityName)); } - + obj.put(listName, listMembers); } } @@ -1039,7 +1039,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon } return obj.toString(); } - + /** * Get an RMConstraintInfo * @param listQName @@ -1054,7 +1054,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon if (con instanceof RMListOfValuesConstraint) { final RMListOfValuesConstraint def = (RMListOfValuesConstraint)con; - + RMConstraintInfo info = new RMConstraintInfo(); info.setName(listQName.toPrefixString()); info.setTitle(con.getTitle()); @@ -1065,7 +1065,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon return def.getAllowedValues(); } }, AuthenticationUtil.getSystemUserName()); - + info.setAllowedValues(allowedValues.toArray(new String[allowedValues.size()])); info.setCaseSensitive(def.isCaseSensitive()); return info; @@ -1076,7 +1076,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon /** * Get RM Constraint detail. - * + * * @return the constraintInfo or null */ public RMConstraintInfo getRMConstraint(String listName) @@ -1084,33 +1084,33 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon QName listQName = QName.createQName(listName, namespaceService); return getRMConstraint(listQName); } - + public void deleteRMConstraint(String listName) { try { - writeLock.lock(); + writeLock.lock(); caveatConfig.remove(listName); updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); } finally { - writeLock.unlock(); + writeLock.unlock(); } } - + public void addRMConstraint(String listName) { try { - writeLock.lock(); + writeLock.lock(); Map> emptyConstraint = new HashMap>(0); caveatConfig.put(listName, emptyConstraint); updateOrCreateCaveatConfig(convertToJSONString(caveatConfig)); } finally { - writeLock.unlock(); + writeLock.unlock(); } } } From aa8fa181579af69e3663c36788eeba30ef7c8e7a Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Wed, 10 Jul 2013 06:11:17 +0000 Subject: [PATCH 5/5] RM: Saved searches where not being upgraded correctly * searches resaved on upgrade (to account for updated model) * searches are public by defalut * relates to RM-758 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.0@52340 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../rm-patch-context.xml | 11 +++ .../patch/RMv2SavedSearchPatch.java | 95 +++++++++++++++++++ .../search/SavedSearchDetails.java | 6 +- 3 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2SavedSearchPatch.java diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml index d030f80f98..21905bc79a 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml @@ -49,5 +49,16 @@ + + + + + + + + + \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2SavedSearchPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2SavedSearchPatch.java new file mode 100644 index 0000000000..076ec3860c --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv2SavedSearchPatch.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.patch; + +import java.util.List; + +import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService; +import org.alfresco.module.org_alfresco_module_rm.search.SavedSearchDetails; +import org.alfresco.repo.module.AbstractModuleComponent; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.BeanNameAware; + +/** + * RM v2.0 Saved Search Patch + * + * + * @author Roy Wetherall + */ +public class RMv2SavedSearchPatch extends AbstractModuleComponent + implements BeanNameAware, RecordsManagementModel, DOD5015Model +{ + /** Logger */ + private static Log logger = LogFactory.getLog(RMv2SavedSearchPatch.class); + + /** RM site id */ + private static final String RM_SITE_ID = "rm"; + + /** Records management search service */ + private RecordsManagementSearchService recordsManagementSearchService; + + /** + * @param recordsManagementSearchService records management search service + */ + public void setRecordsManagementSearchService(RecordsManagementSearchService recordsManagementSearchService) + { + this.recordsManagementSearchService = recordsManagementSearchService; + } + + /** + * @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal() + */ + @Override + protected void executeInternal() throws Throwable + { + if (logger.isDebugEnabled() == true) + { + logger.debug("RM Module RMv2SavedSearchPatch ..."); + } + + // get the saved searches + List savedSearches = recordsManagementSearchService.getSavedSearches(RM_SITE_ID); + + if (logger.isDebugEnabled() == true) + { + logger.debug(" ... updating " + savedSearches.size() + " saved searches"); + } + + for (SavedSearchDetails savedSearchDetails : savedSearches) + { + // re-save each search so that the query is regenerated correctly + recordsManagementSearchService.deleteSavedSearch(RM_SITE_ID, savedSearchDetails.getName()); + recordsManagementSearchService.saveSearch(RM_SITE_ID, + savedSearchDetails.getName(), + savedSearchDetails.getDescription(), + savedSearchDetails.getSearch(), + savedSearchDetails.getSearchParameters(), + savedSearchDetails.isPublic()); + } + + if (logger.isDebugEnabled() == true) + { + logger.debug(" ... complete"); + } + + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/SavedSearchDetails.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/SavedSearchDetails.java index 53d6923a03..8be1c3d2a6 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/SavedSearchDetails.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/SavedSearchDetails.java @@ -95,7 +95,7 @@ public class SavedSearchDetails extends ReportDetails private String siteId; /** Indicates whether the saved search is public or not */ - private boolean isPublic; + private boolean isPublic = true; /** Indicates whether the saved search is a report */ private boolean isReport = false; @@ -103,8 +103,10 @@ public class SavedSearchDetails extends ReportDetails /** Namespace service */ NamespaceService namespaceService; + /** Records management search service */ RecordsManagementSearchServiceImpl searchService; + /** Saves search details compatibility */ private SavedSearchDetailsCompatibility compatibility; /** @@ -178,7 +180,7 @@ public class SavedSearchDetails extends ReportDetails } // Determine whether the saved query is public or not - boolean isPublic = false; + boolean isPublic = true; if (search.has(PUBLIC) == true) { isPublic = search.getBoolean(PUBLIC);