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 9dea1037dd..7e86ee5f93 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
@@ -684,7 +684,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 4822dc0072..3ba031ec0c 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
@@ -64,6 +64,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.cache.caveatConfigCache
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.caveatConfigTransactionalCache
+
+
+
+
+
+
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 8540efc651..5381b22235 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
@@ -121,9 +121,10 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin
private static final String MSG_ERROR_SPLIT_ID = "rm.admin.error-split-id";
/** Constants */
- public static final String RMC_CUSTOM_ASSOCS = RecordsManagementCustomModel.RM_CUSTOM_PREFIX + ":customAssocs";
+ 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 NodeRef RM_CUSTOM_MODEL_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "records_management_custom_model");
+ 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";
private static final String PARAM_MATCH_LOGIC = "matchLogic";
@@ -1413,7 +1414,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));
}
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 30dc9fd22f..759a88f2ca 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,17 +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;
@@ -65,7 +70,7 @@ import org.json.JSONObject;
/**
* RM Caveat Config component impl
- *
+ *
* @author janv
*/
public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnContentUpdatePolicy,
@@ -74,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;
@@ -82,81 +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
+ * 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
*/
-
- // TODO - convert to SimpleCache to be cluster-aware (for dynamic changes to caveat config across a cluster)
- private Map>> caveatConfig = new ConcurrentHashMap>>(2);
-
+ 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
*/
@@ -167,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);
@@ -196,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);
@@ -213,44 +227,50 @@ 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.
+ *
+ * @param nodeRef The nodeRef of the config
+ * @param updateCache Set to true
to update the cache
+ */
@SuppressWarnings("unchecked")
protected void validateAndReset(NodeRef nodeRef)
{
@@ -259,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)
{
@@ -268,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);
@@ -288,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");
@@ -311,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;
@@ -330,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);
@@ -361,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)))
{
@@ -393,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)
{
@@ -407,16 +427,30 @@ 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();
-
- caveatConfig.put(conStr, caveatMap);
+ 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))
+ {
+ // update the cache
+ caveatConfig.put(conStr, caveatMap);
+ }
+ }
+ }
+ finally
+ {
+ writeLock.unlock();
}
}
catch (JSONException e)
@@ -426,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();
@@ -480,30 +514,40 @@ 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 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)
public List getRMAllowedValues(String constraintName)
{
List allowedValues = new ArrayList(0);
-
+
String userName = AuthenticationUtil.getRunAsUser();
if (userName != null)
{
@@ -511,21 +555,31 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
{
// note: userName and userGroupNames must not be null
caveatConfig.get(constraintName);
+
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 = caveatConfig.get(constraintName);
-
+ Map> caveatConstraintDef = null;
+ try
+ {
+ readLock.lock();
+ caveatConstraintDef = caveatConfig.get(constraintName);
+ }
+ finally
+ {
+ readLock.unlock();
+ }
+
if (caveatConstraintDef != null)
{
List direct = caveatConstraintDef.get(userName);
@@ -533,7 +587,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
{
allowedValues.addAll(direct);
}
-
+
for (String group : userGroupFullNames)
{
List values = caveatConstraintDef.get(group);
@@ -543,15 +597,15 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
}
}
}
-
+
Listret = new ArrayList();
ret.addAll(allowedValues);
- return ret;
+ 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
*/
@@ -562,7 +616,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
{
return true;
}
-
+
boolean found = false;
for (QName caveatAspectQName : caveatAspectQNames)
{
@@ -572,7 +626,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
break;
}
}
-
+
if (! found)
{
// no caveat aspect
@@ -590,7 +644,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();
@@ -602,7 +656,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;
@@ -611,7 +665,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)
@@ -623,7 +677,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
{
propValues = (List)val;
}
-
+
if (propValues != null && !isAllowed(propValues, allowedValues, matchLogic))
{
if (logger.isDebugEnabled())
@@ -638,11 +692,11 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
}
}
}
-
+
return true;
}
}
-
+
private boolean isAllowed(List propValues, List userGroupValues, MatchLogic matchLogic)
{
if (matchLogic.equals(MatchLogic.AND))
@@ -656,11 +710,11 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
{
logger.trace("Not allowed: "+propValues+", "+userGroupValues+", "+matchLogic);
}
-
+
return false;
}
}
-
+
return true;
}
else if (matchLogic.equals(MatchLogic.OR))
@@ -673,43 +727,73 @@ 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 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));
}
-
+
/**
* Get the member details of the specified list
* @param listName
@@ -717,107 +801,96 @@ 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()
{
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
*/
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);
+ 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));
+ }
+
+ caveatConfig.put(listName, members);
+ updateOrCreateCaveatConfig(convertToJSONString(caveatConfig));
}
- else
+ finally
{
- members.put(authorityName, values);
+ writeLock.unlock();
}
-
- updateOrCreateCaveatConfig(convertToJSONString(caveatConfig));
}
-
+
/**
* Replace the authorities for a value in a list
- *
+ *
* @param listName
* @param valueName
* @param authorities
*/
public void updateRMConstraintListValue(String listName, String valueName, Listauthorities)
{
-
- // members contains member, values[]
+
Map> members = caveatConfig.get(listName);
-
- if(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);
-
- // remove all authorities which have this value
- List existingAuthorities = pivot.get(valueName);
- if(existingAuthorities != null)
- {
- for(String authority : existingAuthorities)
+ writeLock.lock();
+
+ 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);
-
+
// remove all authorities which have this value
List existingAuthorities = pivot.get(valueName);
if(existingAuthorities != null)
@@ -828,52 +901,137 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
vals.remove(valueName);
}
}
-
+ // 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();
+ }
+ }
+
/**
* Remove an authority from a list
- *
+ *
* @param listName the name of the RMConstraintList
* @param authorityName
* @param values
*/
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
+
+ try
{
- Set listNames = config.keySet();
+ 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);
}
}
@@ -883,7 +1041,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
}
return obj.toString();
}
-
+
/**
* Get an RMConstraintInfo
* @param listQName
@@ -898,7 +1056,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());
@@ -909,7 +1067,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;
@@ -920,7 +1078,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
/**
* Get RM Constraint detail.
- *
+ *
* @return the constraintInfo or null
*/
public RMConstraintInfo getRMConstraint(String listName)
@@ -928,17 +1086,33 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
QName listQName = QName.createQName(listName, namespaceService);
return getRMConstraint(listQName);
}
-
+
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();
+ }
}
}
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 915cca99cc..f8495049ca 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/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);
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 fd14cc1597..e84d8fb8a1 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,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);
}