Merged BRANCHES/V2.0 to HEAD:

51415: Merged DEV/DODRECERT TO BRANCHES/V2.0:
        * 50932: RM-741: Allow category and folder id to be editable upon creation.
   51418: Merged DEV/DODRECERT TO BRANCHES/V2.0:
        - r50934: RM-742:  Search sort order now works as expected
   51419: Merged DEV/DODRECERT TO BRANCHES/V2.0:
        - r50953: Creating an RM site was not possible (ref RM-742)
   51420: Merged DEV/DODRECERT TO BRANCHES/V2.0:
        - r50970: RM-735 (DOD Recert: Bugs on the "Edit Custom Metadata" page)
   51421: Merged DEV/DODRECERT TO BRANCHES/V2.0:
        - r50975: RM-736 (DOD Recert: Bugs on the "List of Values" page)
   51423: Merged DEV/DODRECERT TO BRANCHES/V2.0:
   51425: Merged DEV/DODRECERT TO BRANCHES/V2.0:
        - r51082: RM Audit
           * improved display so it's easier to see what's going on
           * RM 744: audit user creation
        - r51095: RM-738 (DOD Recert: Add events and properties to the "Audit" page)
        - r51099: Fix upgrade issue
        - r51108: RM-745:  Simple support for event and property filtering on audit
        - r51134: Upgrade issues
           * added patch to fill in missing file plan root node reference
           * default site id set when retrieving saved searches
        - r51212: RM-746: Space in the property name
   51426: Merged DEV/DODRECERT TO BRANCHES/V2.0:
        - r51218: RM-747: Search for undeclared records results in exception
        - r51219: RM-748: Editing a disposition schedule did not work for a non admin user
        - r51220: RM-749: Fixed Accession Report
   51504: RM: Fix build



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@51946 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2013-07-02 04:39:47 +00:00
20 changed files with 693 additions and 378 deletions

View File

@@ -240,6 +240,7 @@ subprojects {
from configDir
exclude "**/${moduleProperties}"
exclude "**/${fileMapping}"
exclude "**/dev-context.xml"
into "${assembleDir}/config"
}

View File

@@ -1,2 +1,3 @@
log4j.logger.org.alfresco.module.org_alfresco_module_rm.caveat=warn
log4j.logger.org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityPostProcessor=warn
log4j.logger.org.alfresco.module.org_alfresco_module_rm.patch=debug

View File

@@ -581,7 +581,6 @@
<!-- rma:filePlanComponent is a marker interface for all things RM -->
<!-- Security uses it as a key to determine which implementation to use -->
<!-- TODO ... this should not be called "filePlan" as it is DOD specific terminology -->
<aspect name="rma:filePlanComponent">
<title>File Plan Component</title>
<archive>false</archive>

View File

@@ -50,6 +50,22 @@
<property name="qnameDAO" ref="qnameDAO"/>
</bean>
<bean id="org_alfresco_module_rm_RMv2FilePlanNodeRefPatch"
parent="module.baseComponent"
class="org.alfresco.module.org_alfresco_module_rm.patch.RMv2FilePlanNodeRefPatch">
<property name="moduleId" value="org_alfresco_module_rm"/>
<property name="name" value="org_alfresco_module_rm_RMv2FilePlanNodeRefPatch"/>
<property name="description" value="Patches the existing RM data with the root file plan values."/>
<property name="sinceVersion" value="2.0"/>
<property name="appliesFromVersion" value="2.0"/>
<property name="patchDAO" ref="patchDAO"/>
<property name="nodeDAO" ref="nodeDAO" />
<property name="qnameDAO" ref="qnameDAO"/>
<property name="nodeService" ref="NodeService"/>
<property name="recordsManagementService" ref="RecordsManagementService" />
<property name="behaviourFilter" ref="policyBehaviourFilter"/>
</bean>
<bean id="org_alfresco_module_rm_RMv21InPlacePatch"
parent="module.baseComponent"
class="org.alfresco.module.org_alfresco_module_rm.patch.RMv21InPlacePatch">

View File

@@ -20,7 +20,7 @@
<#list prop.constraints as con>
{
"name": "${con.constraint.shortName!""}",
"title": "${con.title!""}",
"title": "${con.constraint.title!""}",
"type": "${con.constraint.type!""}",
"parameters":
{

View File

@@ -1246,7 +1246,8 @@ public class RecordsManagementAdminServiceImpl implements RecordsManagementAdmin
String compoundID = this.getCompoundIdFor(source, target);
if (existsLabel(compoundID))
{
throw new IllegalArgumentException(I18NUtil.getMessage(MSG_REF_LABEL_IN_USE, compoundID));
return null;
//throw new IllegalArgumentException(I18NUtil.getMessage(MSG_REF_LABEL_IN_USE, compoundID));
}
NodeRef modelRef = getCustomModelRef(""); // defaults to RM_CUSTOM_URI

View File

@@ -528,7 +528,8 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe
// Get the period properties value
QName periodProperty = nextDispositionActionDefinition.getPeriodProperty();
if (periodProperty != null)
if (periodProperty != null &&
RecordsManagementModel.PROP_DISPOSITION_AS_OF.equals(periodProperty) == false)
{
// doesn't matter if the period property isn't set ... the asOfDate will get updated later
// when the value of the period property is set

View File

@@ -322,6 +322,10 @@ public class RecordsManagementAuditServiceImpl
new AuditEvent("unfreeze", MSG_UNFREEZE));
this.auditEvents.put("reject",
new AuditEvent("reject", MSG_REJECT_RECORD));
// Added for DOD compliance
this.auditEvents.put("createPerson",
new AuditEvent("createPerson", "User Created"));
}
@Override
@@ -342,6 +346,10 @@ public class RecordsManagementAuditServiceImpl
BeforeDeleteNodePolicy.QNAME,
RecordsManagementModel.ASPECT_RECORD_COMPONENT_ID,
new JavaBehaviour(this, "beforeDeleteNode"));
policyComponent.bindClassBehaviour(
OnCreateNodePolicy.QNAME,
ContentModel.TYPE_PERSON,
new JavaBehaviour(this, "onCreatePersonNode"));
}
@Override
@@ -474,6 +482,11 @@ public class RecordsManagementAuditServiceImpl
auditRMEvent(childAssocRef.getChildRef(), RM_AUDIT_EVENT_CREATE_RM_OBJECT, null, null);
}
public void onCreatePersonNode(ChildAssociationRef childAssocRef)
{
auditRMEvent(childAssocRef.getChildRef(), "createPerson", null, null);
}
/**
* {@inheritDoc}
* @since 3.2
@@ -505,19 +518,9 @@ public class RecordsManagementAuditServiceImpl
{
// Deleted nodes will not be available at the end of the transaction. The data needs to
// be extracted now and the audit entry needs to be created now.
Map<String, Serializable> auditMap = new HashMap<String, Serializable>(13);
auditMap.put(
AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NAME),
eventName);
// Action node
auditMap.put(
AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NODE),
nodeRef);
Map<String, Serializable> auditMap = buildAuditMap(nodeRef, eventName);
auditMap = auditComponent.recordAuditValues(RecordsManagementAuditService.RM_AUDIT_PATH_ROOT, auditMap);
if (logger.isDebugEnabled())
{
logger.debug("RM Audit: Audited node deletion: \n" + auditMap);
@@ -556,6 +559,31 @@ public class RecordsManagementAuditServiceImpl
}
}
/**
* Helper method to build audit map
*
* @param nodeRef
* @param eventName
* @return
* @since 2.0.3
*/
private Map<String, Serializable> buildAuditMap(NodeRef nodeRef, String eventName)
{
Map<String, Serializable> auditMap = new HashMap<String, Serializable>(13);
auditMap.put(
AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NAME),
eventName);
// Action node
auditMap.put(
AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NODE),
nodeRef);
return auditMap;
}
/**
* A <b>stateless</b> transaction listener for RM auditing. This component picks up the data of
* modified nodes and generates the audit information.
@@ -615,20 +643,13 @@ public class RecordsManagementAuditServiceImpl
RMAuditNode auditedNode = entry.getValue();
Map<String, Serializable> auditMap = new HashMap<String, Serializable>(13);
// Action description
String eventName = auditedNode.getEventName();
auditMap.put(
AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NAME),
eventName);
// Action node
auditMap.put(
AuditApplication.buildPath(
RecordsManagementAuditService.RM_AUDIT_SNIPPET_EVENT,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_NODE),
nodeRef);
Map<String, Serializable> auditMap = buildAuditMap(nodeRef, eventName);
// TODO do we care if the before and after are null??
// Property changes
Map<QName, Serializable> propertiesBefore = auditedNode.getNodePropertiesBefore();
Map<QName, Serializable> propertiesAfter = auditedNode.getNodePropertiesAfter();
@@ -648,6 +669,7 @@ public class RecordsManagementAuditServiceImpl
RecordsManagementAuditService.RM_AUDIT_SNIPPET_CHANGES,
RecordsManagementAuditService.RM_AUDIT_SNIPPET_AFTER),
(Serializable) deltaPair.getSecond());
// Audit it
if (logger.isDebugEnabled())
{
@@ -742,7 +764,7 @@ public class RecordsManagementAuditServiceImpl
* @param reportFormat Format to write the audit trail in, ignored if writer is <code>null</code>
*/
private void getAuditTrailImpl(
RecordsManagementAuditQueryParameters params,
final RecordsManagementAuditQueryParameters params,
final List<RecordsManagementAuditEntry> results,
final Writer writer,
final ReportFormat reportFormat)
@@ -785,6 +807,7 @@ public class RecordsManagementAuditServiceImpl
return false;
}
Date timestamp = new Date(time);
String eventName = null;
String fullName = null;
@@ -846,6 +869,22 @@ public class RecordsManagementAuditServiceImpl
return true;
}
// filter out events if set
if (params.getEvent() != null &&
params.getEvent().endsWith(eventName) == false)
{
// skip it
return true;
}
if (params.getProperty() != null &&
getChangedProperties(beforeProperties, afterProperties).contains(params.getProperty()) == false)
{
// skip it
return false;
}
// TODO: Refactor this to use the builder pattern
RecordsManagementAuditEntry entry = new RecordsManagementAuditEntry(
timestamp,
@@ -878,6 +917,32 @@ public class RecordsManagementAuditServiceImpl
return true;
}
private List<QName> getChangedProperties(Map<QName, Serializable> beforeProperties, Map<QName, Serializable> afterProperties)
{
List<QName> changedProperties = new ArrayList<QName>(21);
if (beforeProperties != null && afterProperties != null)
{
// add all the properties present before the audited action
for (QName valuePropName : beforeProperties.keySet())
{
changedProperties.add(valuePropName);
}
// add all the properties present after the audited action that
// have not already been added
for (QName valuePropName : afterProperties.keySet())
{
if (!beforeProperties.containsKey(valuePropName))
{
changedProperties.add(valuePropName);
}
}
}
return changedProperties;
}
private void writeEntryToFile(RecordsManagementAuditEntry entry)
{
if (writer == null)
@@ -1215,7 +1280,18 @@ public class RecordsManagementAuditServiceImpl
json.put("userRole", entry.getUserRole() == null ? "": entry.getUserRole());
json.put("fullName", entry.getFullName() == null ? "": entry.getFullName());
json.put("nodeRef", entry.getNodeRef() == null ? "": entry.getNodeRef());
if (entry.getEvent().equals("createPerson") == true && entry.getNodeRef() != null)
{
NodeRef nodeRef = entry.getNodeRef();
String userName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME);
json.put("nodeName", userName == null ? "": userName);
}
else
{
json.put("nodeName", entry.getNodeName() == null ? "": entry.getNodeName());
}
json.put("nodeType", entry.getNodeType() == null ? "": entry.getNodeType());
json.put("event", entry.getEvent() == null ? "": getAuditEventLabel(entry.getEvent()));
json.put("identifier", entry.getIdentifier() == null ? "": entry.getIdentifier());

View File

@@ -28,6 +28,7 @@ import java.util.List;
import java.util.Set;
import org.alfresco.service.cmr.security.AuthorityService;
import org.apache.commons.lang.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
@@ -226,7 +227,7 @@ public class ScriptConstraint implements Serializable
a.setAuthorityName(authority);
String displayName = authorityService.getAuthorityDisplayName(authority);
if(displayName != null)
if(StringUtils.isNotBlank(displayName))
{
a.setAuthorityTitle(displayName);
}

View File

@@ -26,6 +26,7 @@ import java.util.Set;
import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.forms.Field;
import org.alfresco.repo.forms.FieldDefinition;
import org.alfresco.repo.forms.FieldGroup;
import org.alfresco.repo.forms.Form;
import org.alfresco.repo.forms.FormData;
@@ -84,7 +85,11 @@ public class RecordsManagementTypeFormFilter extends RecordsManagementFormFilter
* java.util.List, java.util.List, org.alfresco.repo.forms.Form,
* java.util.Map)
*/
public void afterGenerate(TypeDefinition type, List<String> fields, List<String> forcedFields, Form form,
public void afterGenerate(
TypeDefinition type,
List<String> fields,
List<String> forcedFields,
Form form,
Map<String, Object> context)
{
QName typeName = type.getName();
@@ -102,6 +107,18 @@ public class RecordsManagementTypeFormFilter extends RecordsManagementFormFilter
addCustomRMProperties(aspect, form);
}
}
// set the id
List<FieldDefinition> fieldDefs = form.getFieldDefinitions();
for (FieldDefinition fieldDef : fieldDefs)
{
String prefixName = fieldDef.getName();
if (prefixName.equals("rma:identifier"))
{
String defaultId = identifierService.generateIdentifier(typeName, null);
fieldDef.setDefaultValue(defaultId);
}
}
}
/**
@@ -140,5 +157,4 @@ public class RecordsManagementTypeFormFilter extends RecordsManagementFormFilter
public void afterPersist(TypeDefinition item, FormData data, final NodeRef nodeRef)
{
}
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.module.org_alfresco_module_rm.patch;
import java.util.List;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.domain.patch.PatchDAO;
import org.alfresco.repo.domain.qname.QNameDAO;
import org.alfresco.repo.module.AbstractModuleComponent;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanNameAware;
/**
* RM v2.0 File Plan Node Ref Patch
*
* @author Roy Wetherall
*/
public class RMv2FilePlanNodeRefPatch extends AbstractModuleComponent
implements BeanNameAware, RecordsManagementModel, DOD5015Model
{
/** Logger */
private static Log logger = LogFactory.getLog(RMv2FilePlanNodeRefPatch.class);
private NodeService nodeService;
private RecordsManagementService recordsManagementService;
private BehaviourFilter behaviourFilter;
private PatchDAO patchDAO;
private NodeDAO nodeDAO;
private QNameDAO qnameDAO;
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setRecordsManagementService(RecordsManagementService recordsManagementService)
{
this.recordsManagementService = recordsManagementService;
}
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
{
this.behaviourFilter = behaviourFilter;
}
public void setPatchDAO(PatchDAO patchDAO)
{
this.patchDAO = patchDAO;
}
public void setNodeDAO(NodeDAO nodeDAO)
{
this.nodeDAO = nodeDAO;
}
public void setQnameDAO(QNameDAO qnameDAO)
{
this.qnameDAO = qnameDAO;
}
/**
* @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal()
*/
@Override
protected void executeInternal() throws Throwable
{
if (logger.isDebugEnabled() == true)
{
logger.debug("RM Module RMv2FilePlanNodeRef Patch ...");
}
Pair<Long, QName> aspectPair = qnameDAO.getQName(ASPECT_FILE_PLAN_COMPONENT);
if (aspectPair != null)
{
List<Long> records = patchDAO.getNodesByAspectQNameId(aspectPair.getFirst(), 0L, patchDAO.getMaxAdmNodeID());
if (logger.isDebugEnabled() == true)
{
logger.debug(" ... updating " + records.size() + " items" );
}
behaviourFilter.disableBehaviour();
try
{
for (Long record : records)
{
Pair<Long, NodeRef> recordPair = nodeDAO.getNodePair(record);
NodeRef recordNodeRef = recordPair.getSecond();
if (nodeService.getProperty(recordNodeRef, PROP_ROOT_NODEREF) == null)
{
nodeService.setProperty(recordNodeRef, PROP_ROOT_NODEREF, recordsManagementService.getFilePlan(recordNodeRef));
}
}
}
finally
{
behaviourFilter.enableBehaviour();
}
}
if (logger.isDebugEnabled() == true)
{
logger.debug(" ... complete RM Module RMv2FilePlanNodeRef Patch");
}
}
}

View File

@@ -80,7 +80,7 @@ public class RMv2ModelPatch extends AbstractModuleComponent
{
if (logger.isDebugEnabled() == true)
{
logger.debug("RM Module NotificationTemplatePatch ...");
logger.debug("RM Module RMv2ModelPatch ...");
}
updateQName(QName.createQName(DOD_URI, "filePlan"), TYPE_FILE_PLAN, "TYPE");

View File

@@ -22,19 +22,22 @@ import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.CustomMetadataException;
import org.alfresco.module.org_alfresco_module_rm.PropertyAlreadyExistsMetadataException;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementAdminService;
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
import org.alfresco.service.namespace.QName;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.springframework.extensions.surf.util.ParameterCheck;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
/**
* Implementation for Java backed webscript to update RM custom property definitions
@@ -125,6 +128,7 @@ public class CustomPropertyDefinitionPut extends BaseCustomPropertyWebScript
protected QName updatePropertyDefinition(Map<String, Serializable> params) throws CustomMetadataException
{
QName result = null;
boolean updated = false;
String propId = (String)params.get(PROP_ID);
ParameterCheck.mandatoryString("propId", propId);
@@ -139,28 +143,54 @@ public class CustomPropertyDefinitionPut extends BaseCustomPropertyWebScript
if (params.containsKey(PARAM_CONSTRAINT_REF))
{
String constraintRef = (String)params.get(PARAM_CONSTRAINT_REF);
List<ConstraintDefinition> constraints = rmAdminService.getCustomPropertyDefinitions().get(propQName).getConstraints();
if (constraintRef == null)
{
result = rmAdminService.removeCustomPropertyDefinitionConstraints(propQName);
updated = constraints.isEmpty() ? false : true;
}
else
{
boolean exists = false;
for (ConstraintDefinition constraintDefinition : constraints)
{
if (constraintDefinition.getConstraint().getShortName().equalsIgnoreCase(constraintRef))
{
exists = true;
break;
}
}
if (exists == false)
{
QName constraintRefQName = QName.createQName(constraintRef, namespaceService);
result = rmAdminService.setCustomPropertyDefinitionConstraint(propQName, constraintRefQName);
updated = true;
}
}
}
if (params.containsKey(PARAM_LABEL))
{
String label = (String)params.get(PARAM_LABEL);
try
{
result = rmAdminService.updateCustomPropertyDefinitionName(propQName, label);
}
catch (PropertyAlreadyExistsMetadataException ex)
{
if (updated == false)
{
String propIdAsString = rmAdminService.getQNameForClientId(label).toPrefixString(namespaceService);
throw new PropertyAlreadyExistsMetadataException(propIdAsString);
}
}
}
return result;
}
@SuppressWarnings("unchecked")
@SuppressWarnings("rawtypes")
protected Map<String, Serializable> getParamsFromUrlAndJson(WebScriptRequest req, JSONObject json)
throws JSONException
{

View File

@@ -248,7 +248,15 @@ public class TransferReportPost extends BaseTransferWebScript
// write the HTML header
writer.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
writer.write("<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n");
Boolean isAccession = (Boolean)this.nodeService.getProperty(transferNode, PROP_TRANSFER_ACCESSION_INDICATOR);
if (isAccession == true)
{
writer.write("<title>Accession Report</title></head>\n");
}
else
{
writer.write("<title>Transfer Report</title></head>\n");
}
writer.write("<style>\n");
writer.write("body { font-family: arial,verdana; font-size: 81%; color: #333; }\n");
writer.write(".records { margin-left: 20px; margin-top: 10px; }\n");
@@ -257,7 +265,14 @@ public class TransferReportPost extends BaseTransferWebScript
writer.write(".nodeName { font-weight: bold; }\n");
writer.write(".transferred-item { background-color: #eee; padding: 10px; margin-bottom: 15px; }\n");
writer.write("</style>\n");
if (isAccession == true)
{
writer.write("<body>\n<h1>Accession Report</h1>\n");
}
else
{
writer.write("<body>\n<h1>Transfer Report</h1>\n");
}
writer.write("<table cellpadding=\"3\" cellspacing=\"3\">");
writer.write("<tr><td class=\"label\">Transfer Date:</td><td>");
@@ -265,8 +280,15 @@ public class TransferReportPost extends BaseTransferWebScript
writer.write(StringEscapeUtils.escapeHtml(transferDate.toString()));
writer.write("</td></tr>");
writer.write("<tr><td class=\"label\">Transfer Location:</td><td>");
if (isAccession == true)
{
writer.write("NARA");
}
else
{
writer.write(StringEscapeUtils.escapeHtml((String)this.nodeService.getProperty(transferNode,
RecordsManagementModel.PROP_TRANSFER_LOCATION)));
}
writer.write("</td></tr>");
writer.write("<tr><td class=\"label\">Performed By:</td><td>");
writer.write(StringEscapeUtils.escapeHtml((String)this.nodeService.getProperty(transferNode,

View File

@@ -21,6 +21,7 @@ package org.alfresco.module.org_alfresco_module_rm.script.slingshot;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -201,12 +202,17 @@ public class RMSearchGet extends DeclarativeWebScript
personDataCache = new HashMap<String, String>(57);
// Process the result items
Item[] items = new Item[results.size()];
int index = 0;
List<Item> items = new ArrayList<Item>(results.size());
for (NodeRef nodeRef : results)
{
items[index] = new Item(nodeRef);
index++;
// FIXME: This is a workaround for DOD Recert
// TC 3-3 Create User Groups
try
{
Item item = new Item(nodeRef);
items.add(item);
}
catch(Exception e) {}
}
// Return model

View File

@@ -39,10 +39,10 @@ import org.json.JSONObject;
public class RecordsManagementSearchParameters
{
/** Default sort order */
private static final Map<QName, Boolean> DEFAULT_SORT_ORDER = new HashMap<QName, Boolean>()
private static final List<SortItem> DEFAULT_SORT_ORDER = new ArrayList<SortItem>()
{
{
put(ContentModel.PROP_NAME, Boolean.TRUE);
add(new SortItem(ContentModel.PROP_NAME, Boolean.TRUE));
}
};
@@ -87,7 +87,7 @@ public class RecordsManagementSearchParameters
private boolean includeCutoff = false;
private List<QName> includedContainerTypes = DEFAULT_INCLUDED_CONTAINER_TYPES;
private Map<QName, Boolean> sortOrder = DEFAULT_SORT_ORDER;
private List<SortItem> sortOrder = DEFAULT_SORT_ORDER;
private Map<String, String> templates = DEFAULT_TEMPLATES;
private static final String JSON_MAXITEMS = "maxitems";
@@ -196,16 +196,16 @@ public class RecordsManagementSearchParameters
if (jsonObject.has(JSON_SORT) == true)
{
JSONArray jsonArray = jsonObject.getJSONArray(JSON_SORT);
Map<QName, Boolean> sortOrder = new HashMap<QName, Boolean>(jsonArray.length());
List<SortItem> sortOrder = new ArrayList<SortItem>(jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject sortJSONObject = jsonArray.getJSONObject(i);
if (sortJSONObject.has(JSON_FIELD) == true &&
sortJSONObject.has(JSON_ASCENDING) == true)
{
sortOrder.put(
sortOrder.add(new SortItem(
QName.createQName(sortJSONObject.getString(JSON_FIELD), namespaceService),
Boolean.valueOf(sortJSONObject.getBoolean(JSON_ASCENDING)));
sortJSONObject.getBoolean(JSON_ASCENDING)));
}
}
searchParameters.setSortOrder(sortOrder);
@@ -251,11 +251,11 @@ public class RecordsManagementSearchParameters
// Sort
JSONArray jsonSortArray = new JSONArray();
for (Map.Entry<QName, Boolean> entry : sortOrder.entrySet())
for (SortItem entry : sortOrder)
{
JSONObject jsonEntry = new JSONObject();
jsonEntry.put(JSON_FIELD, entry.getKey().toPrefixString(namespaceService));
jsonEntry.put(JSON_ASCENDING, entry.getValue().booleanValue());
jsonEntry.put(JSON_FIELD, entry.property.toPrefixString(namespaceService));
jsonEntry.put(JSON_ASCENDING, entry.assc);
jsonSortArray.put(jsonEntry);
}
jsonObject.put(JSON_SORT, jsonSortArray);
@@ -278,12 +278,12 @@ public class RecordsManagementSearchParameters
return maxItems;
}
public void setSortOrder(Map<QName, Boolean> sortOrder)
public void setSortOrder(List<SortItem> sortOrder)
{
this.sortOrder = sortOrder;
}
public Map<QName, Boolean> getSortOrder()
public List<SortItem> getSortOrder()
{
return sortOrder;
}

View File

@@ -182,9 +182,9 @@ public class RecordsManagementSearchServiceImpl implements RecordsManagementSear
searchParameters.setNamespace(RecordsManagementModel.RM_URI);
// set sort
for(Entry<QName, Boolean> entry : rmSearchParameters.getSortOrder().entrySet())
for(SortItem entry : rmSearchParameters.getSortOrder())
{
searchParameters.addSort(entry.getKey().toPrefixString(namespaceService), entry.getValue().booleanValue());
searchParameters.addSort(entry.property.toPrefixString(namespaceService), entry.assc);
}
// set templates

View File

@@ -89,6 +89,8 @@ public class SavedSearchDetails extends ReportDetails
public static final String SORT = "sort";
public static final String PARAMS = "params";
private static final String DEFAULT_SITE_ID = "rm";
/** Site id */
private String siteId;
@@ -117,11 +119,11 @@ public class SavedSearchDetails extends ReportDetails
JSONObject search = new JSONObject(jsonString);
// Get the site id
if (search.has(SITE_ID) == false)
String siteId = DEFAULT_SITE_ID;
if (search.has(SITE_ID) == true)
{
throw new AlfrescoRuntimeException("Can not create saved search details from json, because required siteid is not present. " + jsonString);
siteId = search.getString(SITE_ID);
}
String siteId = search.getString(SITE_ID);
// Get the name
if (search.has(NAME) == false)

View File

@@ -21,9 +21,7 @@ package org.alfresco.module.org_alfresco_module_rm.search;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.service.namespace.NamespaceService;
@@ -128,10 +126,6 @@ public class SavedSearchDetailsCompatibility implements RecordsManagementModel
{
includedContainerTypes.add(TYPE_RECORD_CATEGORY);
}
// else if ("series".equals(paramName) == true && Boolean.parseBoolean(paramValue) == true)
// {
// includedContainerTypes.add(DOD5015Model.TYPE_RECORD_SERIES);
// }
}
result.setIncludedContainerTypes(includedContainerTypes);
@@ -139,7 +133,7 @@ public class SavedSearchDetailsCompatibility implements RecordsManagementModel
{
// Map the sort string into the search details
String[] sortPairs = sort.split(",");
Map<QName, Boolean> sortOrder = new HashMap<QName, Boolean>(sortPairs.length);
List<SortItem> sortOrder = new ArrayList<SortItem>(sortPairs.length);
for (String sortPairString : sortPairs)
{
String[] sortPair = sortPairString.split("/");
@@ -149,7 +143,7 @@ public class SavedSearchDetailsCompatibility implements RecordsManagementModel
{
isAcsending = Boolean.TRUE;
}
sortOrder.put(field, isAcsending);
sortOrder.add(new SortItem(field, isAcsending));
}
result.setSortOrder(sortOrder);
}
@@ -178,7 +172,7 @@ public class SavedSearchDetailsCompatibility implements RecordsManagementModel
{
StringBuilder builder = new StringBuilder(64);
for (Map.Entry<QName, Boolean> entry : this.savedSearchDetails.getSearchParameters().getSortOrder().entrySet())
for (SortItem entry : this.savedSearchDetails.getSearchParameters().getSortOrder())
{
if (builder.length() !=0)
{
@@ -186,11 +180,11 @@ public class SavedSearchDetailsCompatibility implements RecordsManagementModel
}
String order = "desc";
if (Boolean.TRUE.equals(entry.getValue()) == true)
if (entry.assc == true)
{
order = "asc";
}
builder.append(entry.getKey().toPrefixString(this.namespaceService))
builder.append(entry.property.toPrefixString(this.namespaceService))
.append("/")
.append(order);
}

View File

@@ -0,0 +1,15 @@
package org.alfresco.module.org_alfresco_module_rm.search;
import org.alfresco.service.namespace.QName;
/*package*/ class SortItem
{
public QName property = null;
public boolean assc = true;
public SortItem(QName property, boolean assc)
{
this.property = property;
this.assc = assc;
}
}