diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml index 4b6a00922e..f3d3fb87a0 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml @@ -187,6 +187,8 @@ + + diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/AuditLogPost.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/AuditLogPost.java index c5820f8108..2c089c207e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/AuditLogPost.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/AuditLogPost.java @@ -19,24 +19,25 @@ package org.alfresco.module.org_alfresco_module_rm.script; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletResponse; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.service.cmr.repository.NodeRef; -import org.springframework.extensions.webscripts.Cache; -import org.springframework.extensions.webscripts.Status; -import org.springframework.extensions.webscripts.WebScriptRequest; -import org.springframework.extensions.webscripts.WebScriptResponse; +import org.alfresco.util.ParameterCheck; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; +import org.springframework.extensions.webscripts.WebScriptResponse; /** * Implementation for Java backed webscript to file an @@ -49,105 +50,240 @@ public class AuditLogPost extends BaseAuditRetrievalWebScript /** Logger */ private static Log logger = LogFactory.getLog(AuditLogPost.class); + /** Constants */ protected static final String PARAM_DESTINATION = "destination"; protected static final String RESPONSE_SUCCESS = "success"; protected static final String RESPONSE_RECORD = "record"; protected static final String RESPONSE_RECORD_NAME = "recordName"; + /** Record folder service */ + private RecordFolderService recordFolderService; + + /** Disposition service */ + private DispositionService dispositionService; + + /** + * Sets the record folder service + * + * @param recordFolderService Record folder service + */ + public void setRecordFolderService(RecordFolderService recordFolderService) + { + this.recordFolderService = recordFolderService; + } + + /** + * Sets the disposition service + * + * @param dispositionService disposition service + */ + public void setDispositionService(DispositionService dispositionService) + { + this.dispositionService = dispositionService; + } + + /** + * @see org.alfresco.repo.web.scripts.content.StreamContent#execute(org.springframework.extensions.webscripts.WebScriptRequest, org.springframework.extensions.webscripts.WebScriptResponse) + */ @Override public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException { try { - // retrieve requested format - String format = req.getFormat(); + ParameterCheck.mandatory("req", req); + ParameterCheck.mandatory("res", res); - // construct model for template - Status status = new Status(); - Cache cache = new Cache(getDescription().getRequiredCache()); - Map model = new HashMap(); - model.put("status", status); - model.put("cache", cache); + // build the json object from the request + JSONObject json = getJSONObjectFromRequest(req); - // extract the destination parameter, ensure it's present and it is - // a record folder - JSONObject json = new JSONObject(new JSONTokener(req.getContent().getContent())); - if (!json.has(PARAM_DESTINATION)) - { - status.setCode(HttpServletResponse.SC_BAD_REQUEST, - "Mandatory '" + PARAM_DESTINATION + "' parameter has not been supplied"); - Map templateModel = createTemplateParameters(req, res, model); - sendStatus(req, res, status, cache, format, templateModel); - return; - } + // extract the destination parameter, ensure it's present and it is a record folder and not closed or cut off + NodeRef destination = getDestination(json); - String destinationParam = json.getString(PARAM_DESTINATION); - if (StringUtils.isBlank(destinationParam)) - { - status.setCode(HttpServletResponse.SC_BAD_REQUEST, - "Please select a record folder."); - Map templateModel = createTemplateParameters(req, res, model); - sendStatus(req, res, status, cache, format, templateModel); - return; - } + // file audit trail as a record + NodeRef record = fileAuditTrail(destination, req); - NodeRef destination = new NodeRef(destinationParam); - - if (!this.nodeService.exists(destination)) - { - status.setCode(HttpServletResponse.SC_NOT_FOUND, - "Node " + destination.toString() + " does not exist"); - Map templateModel = createTemplateParameters(req, res, model); - sendStatus(req, res, status, cache, format, templateModel); - return; - } - - // ensure the node is a filePlan object - if (!RecordsManagementModel.TYPE_RECORD_FOLDER.equals(this.nodeService.getType(destination))) - { - status.setCode(HttpServletResponse.SC_BAD_REQUEST, - "Node " + destination.toString() + " is not a record folder"); - Map templateModel = createTemplateParameters(req, res, model); - sendStatus(req, res, status, cache, format, templateModel); - return; - } - - if (logger.isDebugEnabled()) - { - logger.debug("Filing audit trail as record in record folder: " + destination); - } - - // parse the other parameters and get a file containing the audit trail - NodeRef record = this.rmAuditService.fileAuditTrailAsRecord(parseQueryParameters(req), - destination, parseReportFormat(req)); - - if (logger.isDebugEnabled()) - { - logger.debug("Filed audit trail as new record: " + record); - } - - // return success flag and record noderef as JSON - JSONObject responseJSON = new JSONObject(); - responseJSON.put(RESPONSE_SUCCESS, (record != null)); - if (record != null) - { - responseJSON.put(RESPONSE_RECORD, record.toString()); - responseJSON.put(RESPONSE_RECORD_NAME, - (String)nodeService.getProperty(record, ContentModel.PROP_NAME)); - } - - // setup response - String jsonString = responseJSON.toString(); - res.setContentType(MimetypeMap.MIMETYPE_JSON); - res.setContentEncoding("UTF-8"); - res.setHeader("Content-Length", Long.toString(jsonString.length())); + // create response + String response = createResponse(record); // write the JSON response - res.getWriter().write(jsonString); + writeResponse(res, response); } - catch (Throwable e) + catch (Exception ex) { - throw createStatusException(e, req, res); + JSONObject json = new JSONObject(); + putToJSONObject(json, "message", ex.getMessage()); + writeResponse(res, json.toString()); } } + + /** + * Helper method to write the response to the web script response + * + * @param res {@link WebScriptResponse} Web script response + * @param reponse {@link String} Response to write + * @throws IOException can throw an exception whilst writing the response + */ + private void writeResponse(WebScriptResponse res, String response) throws IOException + { + // setup response + res.setContentType(MimetypeMap.MIMETYPE_JSON); + res.setContentEncoding("UTF-8"); + res.setHeader("Content-Length", Long.toString(response.length())); + + // write the JSON response + res.getWriter().write(response); + } + + /** + * Helper method to create the response text from the record + * + * @param record {@link NodeRef} The audit trail as record + * @return Response text as {@link String} + */ + @SuppressWarnings("null") + private String createResponse(NodeRef record) + { + JSONObject responseJSON = new JSONObject(); + boolean recordExists = record != null; + + putToJSONObject(responseJSON, RESPONSE_SUCCESS, recordExists); + + if (recordExists) + { + putToJSONObject(responseJSON, RESPONSE_RECORD, record.toString()); + putToJSONObject(responseJSON, RESPONSE_RECORD_NAME, (String) nodeService.getProperty(record, ContentModel.PROP_NAME)); + } + + return responseJSON.toString(); + } + + /** + * Helper method to put a key and a value to a json object. + * It handles the {@link JSONException} so that a try/catch + * block is not need through out the code + * + * @param json The json object the key/value write to + * @param key The key which will be written to the json object + * @param value The value which will be written to the json object + */ + private void putToJSONObject(JSONObject json, String key, Object value) + { + try + { + json.put(key, value); + } + catch (JSONException error) + { + throw new AlfrescoRuntimeException("Error writing the value '" + value + "' of the key '" + key + "' to the json object.", error); + } + } + + /** + * Helper method which will file the audit trail + * + * @param destination The destination where the audit trail will be filed + * @param req {@link WebScriptRequest} from which additional parameters will be retrieved + * @return The {@link NodeRef} of the record + */ + private NodeRef fileAuditTrail(NodeRef destination, WebScriptRequest req) + { + + NodeRef record = rmAuditService.fileAuditTrailAsRecord(parseQueryParameters(req), destination, parseReportFormat(req)); + + if (logger.isDebugEnabled()) + { + logger.debug("Filed audit trail as new record: '" + record + "'."); + } + + return record; + } + + /** + * Helper method to create a json object from the request + * + * @param req {@link WebScriptRequest} from which the json object will be created + * @return Returns a json object containing the request content + * @throws IOException can throw an exception whilst getting the content from the request + */ + private JSONObject getJSONObjectFromRequest(WebScriptRequest req) throws IOException + { + JSONObject json; + + try + { + json = new JSONObject(new JSONTokener(req.getContent().getContent())); + } + catch (JSONException error) + { + throw new AlfrescoRuntimeException("Error creating json object from request content.", error); + } + + return json; + } + + /** + * Helper method to get the destination from the json object + * + * @param json The json object which was created from the request content + * @return {@link NodeRef} The destination of the audit log + */ + private NodeRef getDestination(JSONObject json) + { + if (!json.has(PARAM_DESTINATION)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, + "Mandatory parameter '" + PARAM_DESTINATION + "' has not been supplied."); + } + + String destinationParam; + try + { + destinationParam = json.getString(PARAM_DESTINATION); + } + catch (JSONException error) + { + throw new AlfrescoRuntimeException("Error extracting 'destination' from parameter.", error); + } + + if (StringUtils.isBlank(destinationParam)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, + "Please select a record folder."); + } + + NodeRef destination = new NodeRef(destinationParam); + if (!nodeService.exists(destination)) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, + "Selected node does not exist"); + } + + // ensure the node is a record folder + if (!RecordsManagementModel.TYPE_RECORD_FOLDER.equals(nodeService.getType(destination))) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, + "Selected node is not a record folder"); + } + + // ensure the record folder is not closed + if (recordFolderService.isRecordFolderClosed(destination)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, + "Cannot file into a closed folder."); + } + + // ensure the record folder is not cut off + if (dispositionService.isDisposableItemCutoff(destination)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, + "Cannot file into a cut off folder."); + } + + if (logger.isDebugEnabled()) + { + logger.debug("Filing audit trail as record in record folder: '" + destination + "'."); + } + + return destination; + } } \ No newline at end of file