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 372b087f29..cdd73604f3 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 @@ -62,27 +62,26 @@ - - + + + + + - - + parent="rmCustomReferenceDefinitionBase" /> - - + parent="rmCustomReferenceDefinitionBase" /> templateVars = req.getServiceMatch().getTemplateVars(); + Map templateVars = getTemplateVars(req); String storeType = templateVars.get("store_type"); String storeId = templateVars.get("store_id"); String nodeId = templateVars.get("id"); // create the NodeRef and ensure it is valid - StoreRef storeRef = new StoreRef(storeType, storeId); - NodeRef nodeRef = new NodeRef(storeRef, nodeId); + NodeRef nodeRef = new NodeRef(storeType, storeId, nodeId); - if (!this.nodeService.exists(nodeRef)) + if (!nodeService.exists(nodeRef)) { - throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find node: " + - nodeRef.toString()); + throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find node: '" + + nodeRef.toString() + "'."); } return nodeRef; } - /** - * @param dispositionService the disposition serviceS - */ - public void setDispositionService(DispositionService dispositionService) - { - this.dispositionService = dispositionService; - } - - /** - * Sets the NodeService instance - * - * @param nodeService The NodeService instance - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * Sets the NamespaceService instance - * - * @param namespaceService The NamespaceService instance - */ - public void setNamespaceService(NamespaceService namespaceService) - { - this.namespaceService = namespaceService; - } - /** * This method checks if the json object contains an entry with the specified name. * @@ -129,7 +146,123 @@ public abstract class AbstractRmWebScript extends DeclarativeWebScript { for (String name : paramNames) { - this.checkMandatoryJsonParam(json, name); + checkMandatoryJsonParam(json, name); } } + + /** + * Gets the template variable substitutions map + * + * @param req The webscript request + * @return The template variable substitutions + */ + protected Map getTemplateVars(WebScriptRequest req) + { + if (req == null) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "The webscript request is null."); + } + + if (req.getServiceMatch() == null) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "The matching API Service for the request is null."); + } + + Map templateVars = req.getServiceMatch().getTemplateVars(); + if (templateVars == null) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "The template variable substitutions map is null"); + } + + return templateVars; + } + + /** + * Gets the value of a request parameter + * + * @param req The webscript request + * @param parameter The request parameter + * @return The value of the request parameter + */ + protected String getRequestParameterValue(WebScriptRequest req, String parameter) + { + Map templateVars = getTemplateVars(req); + return templateVars.get(parameter); + } + + /** + * Gets the request content as JSON object + * + * @param req The webscript request + * @return The request content as JSON object + */ + protected JSONObject getRequestContentAsJsonObject(WebScriptRequest req) + { + Content reqContent = req.getContent(); + if (reqContent == null) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Missing request body."); + } + + String content; + try + { + content = reqContent.getContent(); + } + catch (IOException error) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not get conent from the request.", error); + } + + if (StringUtils.isBlank(content)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Content does not exist."); + } + + JSONTokener jsonTokener; + try + { + jsonTokener = new JSONTokener(req.getContent().getContent()); + } + catch (IOException error) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not get content.", error); + } + + JSONObject json; + try + { + json = new JSONObject(jsonTokener); + } + catch (JSONException error) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Unable to parse request body.", error); + } + + return json; + } + + /** + * Gets the value of a given key from a json object + * + * @param jsonObject The json object from which the value should be retrieved + * @param key The key for which the value is requested + * @return The value of the given key from the json object + */ + protected Serializable getJSONObjectValue(JSONObject jsonObject, String key) + { + Serializable value; + + try + { + checkMandatoryJsonParam(jsonObject, key); + value = (Serializable) jsonObject.get(key); + } + catch (JSONException error) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not get value for the key '" + key + "'.", error); + } + + return value; + } } \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionBase.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionBase.java new file mode 100644 index 0000000000..1f57ab74e1 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionBase.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.script; + +import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.namespace.QName; +import org.apache.commons.lang.StringUtils; +import org.json.JSONObject; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Base class for custom reference definition classes + * + * @author Tuna Aksoy + * @since 2.3 + */ +public class CustomReferenceDefinitionBase extends AbstractRmWebScript +{ + /** Constants for the custom reference definition classes */ + protected static final String REFERENCE_TYPE = "referenceType"; + protected static final String REF_ID = "refId"; + protected static final String LABEL = "label"; + protected static final String SOURCE = "source"; + protected static final String TARGET = "target"; + protected static final String CUSTOM_REFS = "customRefs"; + protected static final String URL = "url"; + protected static final String SUCCESS = "success"; + + /** Records Management Admin Service */ + private RecordsManagementAdminService rmAdminService; + + /** Dictionary Service */ + private DictionaryService dictionaryService; + + /** + * Sets the records management admin service + * + * @param rmAdminService The records management admin service + */ + public void setRecordsManagementAdminService(RecordsManagementAdminService rmAdminService) + { + this.rmAdminService = rmAdminService; + } + + /** + * Gets the records management admin service instance + * + * @return The records management admin service instance + */ + protected RecordsManagementAdminService getRmAdminService() + { + return this.rmAdminService; + } + + /** + * Sets the dictionary service + * + * @param dictionaryService The dictionary service + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * Gets the dictionary service instance + * + * @return The dictionary service instance + */ + protected DictionaryService getDictionaryService() + { + return this.dictionaryService; + } + + /** + * Gets the QName for the given custom reference id + * + * @param referenceId The reference id + * @return The QName for the given custom reference id + */ + protected QName getCustomReferenceQName(String referenceId) + { + QName customReferenceQName = getRmAdminService().getQNameForClientId(referenceId); + if (customReferenceQName == null) + { + StringBuilder msg = new StringBuilder(); + msg.append("Unable to find QName for the reference: '"); + msg.append(referenceId); + msg.append("'."); + String errorMsg = msg.toString(); + + throw new WebScriptException(Status.STATUS_NOT_FOUND, errorMsg); + } + return customReferenceQName; + } + + /** + * Gets the custom reference type from the json object + * + * @param requestContent The request content as json object + * @return Returns the custom reference type which is either parent/child or bidirectional + */ + protected CustomReferenceType getCustomReferenceType(JSONObject requestContent) + { + String referenceType = (String) getJSONObjectValue(requestContent, REFERENCE_TYPE); + if (StringUtils.isBlank(referenceType)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Reference type is missing."); + } + return CustomReferenceType.getEnumFromString(referenceType); + } + + /** + * Gets the service path from the webscript request + * + * @param req The webscript request + * @return The service path + */ + protected String getServicePath(WebScriptRequest req) + { + return req.getServicePath(); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPost.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPost.java index f973e3da1b..0d063e4471 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPost.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPost.java @@ -18,162 +18,105 @@ */ package org.alfresco.module.org_alfresco_module_rm.script; -import java.io.IOException; -import java.io.Serializable; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; import org.alfresco.service.namespace.QName; -import org.springframework.extensions.surf.util.ParameterCheck; +import org.apache.commons.lang.StringUtils; +import org.json.JSONObject; import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptRequest; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; /** * Implementation for Java backed webscript to add RM custom reference definitions * to the custom model. - * + * * @author Neil McErlean + * @author Tuna Aksoy */ -public class CustomReferenceDefinitionPost extends AbstractRmWebScript +public class CustomReferenceDefinitionPost extends CustomReferenceDefinitionBase { - private static final String URL = "url"; - private static final String REF_ID = "refId"; - private static final String TARGET = "target"; - private static final String SOURCE = "source"; - private static final String LABEL = "label"; - private static final String REFERENCE_TYPE = "referenceType"; - - private static Log logger = LogFactory.getLog(CustomReferenceDefinitionPost.class); - - private RecordsManagementAdminService rmAdminService; - - public void setRecordsManagementAdminService(RecordsManagementAdminService rmAdminService) - { - this.rmAdminService = rmAdminService; - } - - /* - * @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.Status, org.alfresco.web.scripts.Cache) + /** + * @see org.springframework.extensions.webscripts.DeclarativeWebScript#executeImpl(org.springframework.extensions.webscripts.WebScriptRequest, org.springframework.extensions.webscripts.Status, org.springframework.extensions.webscripts.Cache) */ @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { - JSONObject json = null; - Map ftlModel = null; - try - { - json = new JSONObject(new JSONTokener(req.getContent().getContent())); - - ftlModel = addCustomReference(req, json); - } - catch (IOException iox) - { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Could not read content from req.", iox); - } - catch (JSONException je) - { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Could not parse JSON from req.", je); - } - catch (IllegalArgumentException iae) - { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - iae.getMessage(), iae); - } - - return ftlModel; + JSONObject requestContent = getRequestContentAsJsonObject(req); + CustomReferenceType customReferenceType = getCustomReferenceType(requestContent); + QName customReference = addCustomReference(requestContent, customReferenceType); + + Map model = new HashMap(); + String servicePath = getServicePath(req); + Map customReferenceData = getCustomReferenceData(customReferenceType, customReference, servicePath); + model.putAll(customReferenceData); + + return model; } - + /** - * Applies custom properties. + * Adds custom reference to the model + * + * @param requestContent The request content as json object + * @param customReferenceType The custom reference type + * @return Returns the {@link QName} of the new custom reference */ - @SuppressWarnings("rawtypes") - protected Map addCustomReference(WebScriptRequest req, JSONObject json) throws JSONException + private QName addCustomReference(JSONObject requestContent, CustomReferenceType customReferenceType) + { + QName referenceQName; + + if (CustomReferenceType.PARENT_CHILD.equals(customReferenceType)) + { + String source = (String) getJSONObjectValue(requestContent, SOURCE); + if (StringUtils.isBlank(source)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Source is blank."); + } + + String target = (String) getJSONObjectValue(requestContent, TARGET); + if (StringUtils.isBlank(target)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Target is blank."); + } + + referenceQName = getRmAdminService().addCustomChildAssocDefinition(source, target); + } + else if (CustomReferenceType.BIDIRECTIONAL.equals(customReferenceType)) + { + String label = (String) getJSONObjectValue(requestContent, LABEL); + if (StringUtils.isBlank(label)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Label is blank."); + } + + referenceQName = getRmAdminService().addCustomAssocDefinition(label); + } + else + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Unsupported custom reference type."); + } + + return referenceQName; + } + + /** + * Gets the custom reference data + * + * @param customReferenceType The custom reference type + * @param customReference The qualified name of the custom reference + * @param servicePath The service path + * @return The custom reference data + */ + private Map getCustomReferenceData(CustomReferenceType customReferenceType, QName customReference, String servicePath) { Map result = new HashMap(); - Map params = new HashMap(); - - for (Iterator iter = json.keys(); iter.hasNext(); ) - { - String nextKeyString = (String)iter.next(); - Serializable nextValue = (Serializable)json.get(nextKeyString); - - params.put(nextKeyString, nextValue); - } - String refTypeParam = (String)params.get(REFERENCE_TYPE); - ParameterCheck.mandatory(REFERENCE_TYPE, refTypeParam); - CustomReferenceType refTypeEnum = CustomReferenceType.getEnumFromString(refTypeParam); - - boolean isChildAssoc = refTypeEnum.equals(CustomReferenceType.PARENT_CHILD); - - if (logger.isDebugEnabled()) - { - StringBuilder msg = new StringBuilder(); - msg.append("Creating custom "); - if (isChildAssoc) - { - msg.append("child "); - } - msg.append("assoc"); - logger.debug(msg.toString()); - } - - QName generatedQName; - if (isChildAssoc) - { - String source = (String)params.get(SOURCE); - String target = (String)params.get(TARGET); - - generatedQName = rmAdminService.addCustomChildAssocDefinition(source, target); - } - else - { - String label = (String)params.get(LABEL); - - generatedQName = rmAdminService.addCustomAssocDefinition(label); - } - - result.put(REFERENCE_TYPE, refTypeParam); - - String qnameLocalName; - if (refTypeParam.equals(CustomReferenceType.BIDIRECTIONAL.toString())) - { - Serializable labelParam = params.get(LABEL); - // label is mandatory for bidirectional refs only - ParameterCheck.mandatory(LABEL, labelParam); - - qnameLocalName = generatedQName.getLocalName(); - result.put(REF_ID, qnameLocalName); - } - else if (refTypeParam.equals(CustomReferenceType.PARENT_CHILD.toString())) - { - Serializable sourceParam = params.get(SOURCE); - Serializable targetParam = params.get(TARGET); - // source,target mandatory for parent/child refs only - ParameterCheck.mandatory(SOURCE, sourceParam); - ParameterCheck.mandatory(TARGET, targetParam); - - qnameLocalName = generatedQName.getLocalName(); - result.put(REF_ID, qnameLocalName); - } - else - { - throw new WebScriptException("Unsupported reference type: " + refTypeParam); - } - result.put(URL, req.getServicePath() + "/" + qnameLocalName); - - result.put("success", Boolean.TRUE); - + String qnameLocalName = customReference.getLocalName(); + result.put(REFERENCE_TYPE, customReferenceType.toString()); + result.put(REF_ID, qnameLocalName); + result.put(URL, servicePath + PATH_SEPARATOR + qnameLocalName); + result.put(SUCCESS, Boolean.TRUE); return result; } } \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPut.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPut.java index a2402592e2..169c2cfd37 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPut.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionPut.java @@ -18,19 +18,12 @@ */ package org.alfresco.module.org_alfresco_module_rm.script; -import java.io.IOException; -import java.io.Serializable; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; -import org.alfresco.service.cmr.dictionary.AssociationDefinition; -import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition; import org.alfresco.service.namespace.QName; -import org.json.JSONException; +import org.apache.commons.lang.StringUtils; import org.json.JSONObject; -import org.json.JSONTokener; import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; @@ -42,113 +35,100 @@ import org.springframework.extensions.webscripts.WebScriptRequest; * the source/target (for parent/child references). * * @author Neil McErlean + * @author Tuna Aksoy */ -public class CustomReferenceDefinitionPut extends AbstractRmWebScript +public class CustomReferenceDefinitionPut extends CustomReferenceDefinitionBase { - private static final String URL = "url"; - private static final String REF_ID = "refId"; - private static final String TARGET = "target"; - private static final String SOURCE = "source"; - private static final String LABEL = "label"; - - private RecordsManagementAdminService rmAdminService; - - public void setRecordsManagementAdminService(RecordsManagementAdminService rmAdminService) - { - this.rmAdminService = rmAdminService; - } - - /* + /** * @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.Status, org.alfresco.web.scripts.Cache) */ @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { - JSONObject json = null; - Map ftlModel = null; - try - { - json = new JSONObject(new JSONTokener(req.getContent().getContent())); + JSONObject requestContent = getRequestContentAsJsonObject(req); + String referenceId = getReferenceId(req); + updateCustomReference(requestContent, referenceId); - ftlModel = updateCustomReference(req, json); - } - catch (IOException iox) - { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Could not read content from req.", iox); - } - catch (JSONException je) - { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Could not parse JSON from req.", je); - } - catch (IllegalArgumentException iae) - { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - iae.getMessage(), iae); - } + Map model = new HashMap(); + String servicePath = getServicePath(req); + Map customReferenceData = getCustomReferenceData(servicePath, referenceId); + model.putAll(customReferenceData); - return ftlModel; + return model; } /** - * Applies custom properties. + * Gets the reference id from the webscript request + * + * @param req The webscript request + * @return The reference id */ - @SuppressWarnings("rawtypes") - protected Map updateCustomReference(WebScriptRequest req, JSONObject json) throws JSONException + private String getReferenceId(WebScriptRequest req) + { + String referenceId = getRequestParameterValue(req, REF_ID); + if (StringUtils.isBlank(referenceId)) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Reference id is blank."); + } + return referenceId; + } + + /** + * Updates the custom reference + * + * @param requestContent The request content as json object + * @param referenceId The reference id + */ + private void updateCustomReference(JSONObject requestContent, String referenceId) + { + QName referenceQName = getCustomReferenceQName(referenceId); + CustomReferenceType customReferenceType = getCustomReferenceType(requestContent); + + if (CustomReferenceType.PARENT_CHILD.equals(customReferenceType)) + { + String source = (String) getJSONObjectValue(requestContent, SOURCE); + if (StringUtils.isBlank(source)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Source is blank."); + } + + String target = (String) getJSONObjectValue(requestContent, TARGET); + if (StringUtils.isBlank(target)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Target is blank."); + } + + getRmAdminService().updateCustomChildAssocDefinition(referenceQName, source, target); + } + else if (CustomReferenceType.BIDIRECTIONAL.equals(customReferenceType)) + { + String label = (String) getJSONObjectValue(requestContent, LABEL); + if (StringUtils.isBlank(label)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Label is blank."); + } + + getRmAdminService().updateCustomAssocDefinition(referenceQName, label); + } + else + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Unsupported custom reference type."); + } + } + + /** + * Gets the custom reference data + * + * @param servicePath The service path + * @param String The reference id + * @return The custom reference data + */ + private Map getCustomReferenceData(String servicePath, String referenceId) { Map result = new HashMap(); - Map params = new HashMap(); - - for (Iterator iter = json.keys(); iter.hasNext(); ) - { - String nextKeyString = (String)iter.next(); - Serializable nextValue = (Serializable)json.get(nextKeyString); - - params.put(nextKeyString, nextValue); - } - - Map templateVars = req.getServiceMatch().getTemplateVars(); - String refId = templateVars.get(REF_ID); - // refId cannot be null as it is defined within the URL - params.put(REF_ID, (Serializable)refId); - - // Ensure that the reference actually exists. - QName refQName = rmAdminService.getQNameForClientId(refId); - if (refQName == null) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, - "Could not find reference definition for: " + refId); - } - - String newLabel = (String)params.get(LABEL); - String newSource = (String)params.get(SOURCE); - String newTarget = (String)params.get(TARGET); - - // Determine whether it's a bidi or a p/c ref - AssociationDefinition assocDef = rmAdminService.getCustomReferenceDefinitions().get(refQName); - if (assocDef == null) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, - "Could not find reference definition for: " + refId); - } - - if (assocDef instanceof ChildAssociationDefinition) - { - if (newSource != null || newTarget != null) - { - rmAdminService.updateCustomChildAssocDefinition(refQName, newSource, newTarget); - } - } - else if (newLabel != null) - { - rmAdminService.updateCustomAssocDefinition(refQName, newLabel); - } - - result.put(URL, req.getServicePath()); - result.put("refId", refQName.getLocalName()); - result.put("success", Boolean.TRUE); - + result.put(URL, servicePath); + result.put(REF_ID, referenceId); + result.put(SUCCESS, Boolean.TRUE); return result; } } \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionsGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionsGet.java index 72898c62f8..31cd0904d7 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionsGet.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/CustomReferenceDefinitionsGet.java @@ -24,135 +24,169 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import javax.servlet.http.HttpServletResponse; - -import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition; -import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.namespace.QName; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.apache.commons.lang.StringUtils; import org.springframework.extensions.webscripts.Cache; -import org.springframework.extensions.webscripts.DeclarativeWebScript; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptRequest; /** - * This class provides the implementation for the customrefdefinitions.get webscript. + * Implementation for Java backed webscript to get RM custom reference definitions. * * @author Neil McErlean + * @author Tuna Aksoy */ -public class CustomReferenceDefinitionsGet extends DeclarativeWebScript +public class CustomReferenceDefinitionsGet extends CustomReferenceDefinitionBase { - private static final String REFERENCE_TYPE = "referenceType"; - private static final String REF_ID = "refId"; - private static final String LABEL = "label"; - private static final String SOURCE = "source"; - private static final String TARGET = "target"; - private static final String CUSTOM_REFS = "customRefs"; - private static Log logger = LogFactory.getLog(CustomReferenceDefinitionsGet.class); - - private RecordsManagementAdminService rmAdminService; - private DictionaryService dictionaryService; - - public void setRecordsManagementAdminService(RecordsManagementAdminService rmAdminService) - { - this.rmAdminService = rmAdminService; - } - - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - + /** + * @see org.springframework.extensions.webscripts.DeclarativeWebScript#executeImpl(org.springframework.extensions.webscripts.WebScriptRequest, org.springframework.extensions.webscripts.Status, org.springframework.extensions.webscripts.Cache) + */ @Override - public Map executeImpl(WebScriptRequest req, Status status, Cache cache) + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { + String referenceId = getRequestParameterValue(req, REF_ID); + Map customReferenceDefinitions = getCustomReferenceDefinitions(referenceId); + List> customReferenceData = getCustomReferenceData(customReferenceDefinitions); + Map model = new HashMap(); - - Map templateVars = req.getServiceMatch().getTemplateVars(); - String refId = templateVars.get(REF_ID); - - if (logger.isDebugEnabled()) - { - logger.debug("Getting custom reference definitions with refId: " + refId); - } - - Map currentCustomRefs = rmAdminService.getCustomReferenceDefinitions(); - - // If refId has been provided then this is a request for a single custom-ref-defn. - // else it is a request for them all. - if (refId != null) - { - QName qn = rmAdminService.getQNameForClientId(refId); - - AssociationDefinition assDef = currentCustomRefs.get(qn); - if (assDef == null) - { - StringBuilder msg = new StringBuilder(); - msg.append("Unable to find reference: ").append(refId); - if (logger.isDebugEnabled()) - { - logger.debug(msg.toString()); - } - throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, - msg.toString()); - } - - currentCustomRefs = new HashMap(1); - currentCustomRefs.put(qn, assDef); - } - - List> listOfReferenceData = new ArrayList>(); - - for (Entry entry : currentCustomRefs.entrySet()) - { - Map data = new HashMap(); - - AssociationDefinition nextValue = entry.getValue(); - - CustomReferenceType referenceType = nextValue instanceof ChildAssociationDefinition ? - CustomReferenceType.PARENT_CHILD : CustomReferenceType.BIDIRECTIONAL; - - data.put(REFERENCE_TYPE, referenceType.toString()); - - // It is the title which stores either the label, or the source and target. - String nextTitle = nextValue.getTitle(dictionaryService); - if (CustomReferenceType.PARENT_CHILD.equals(referenceType)) - { - if (nextTitle != null) - { - String[] sourceAndTarget = rmAdminService.splitSourceTargetId(nextTitle); - data.put(SOURCE, sourceAndTarget[0]); - data.put(TARGET, sourceAndTarget[1]); - data.put(REF_ID, entry.getKey().getLocalName()); - } - } - else if (CustomReferenceType.BIDIRECTIONAL.equals(referenceType)) - { - if (nextTitle != null) - { - data.put(LABEL, nextTitle); - data.put(REF_ID, entry.getKey().getLocalName()); - } - } - else - { - throw new WebScriptException("Unsupported custom reference type: " + referenceType); - } - - listOfReferenceData.add(data); - } - - if (logger.isDebugEnabled()) - { - logger.debug("Retrieved custom reference definitions: " + listOfReferenceData.size()); - } - - model.put(CUSTOM_REFS, listOfReferenceData); + model.put(CUSTOM_REFS, customReferenceData); return model; } + + /** + * Gets the custom reference definition(s) for the given reference id + * + * @param referenceId The reference id + * @return If the reference id is not blank the custom definition for the given reference id will be returned, + * otherwise all custom definitions will be returned. + */ + private Map getCustomReferenceDefinitions(String referenceId) + { + Map customReferenceDefinitions = new HashMap(); + + if (StringUtils.isNotBlank(referenceId)) + { + QName referenceQName = getCustomReferenceQName(referenceId); + AssociationDefinition associationDefinition = getAssosiationDefinitionForCustomReference(referenceQName); + customReferenceDefinitions.put(referenceQName, associationDefinition); + } + else + { + customReferenceDefinitions.putAll(getRmAdminService().getCustomReferenceDefinitions()); + } + + return customReferenceDefinitions; + } + + /** + * Gets the association definition for the given reference QName + * + * @param referenceQName The reference QName + * @return The association definition for the given reference QName + */ + private AssociationDefinition getAssosiationDefinitionForCustomReference(QName referenceQName) + { + AssociationDefinition associationDefinition = getRmAdminService().getCustomReferenceDefinitions().get(referenceQName); + if (associationDefinition == null) + { + StringBuilder msg = new StringBuilder(); + msg.append("Unable to find association definition for the reference: '"); + msg.append(referenceQName.getLocalName()); + msg.append("'."); + String errorMsg = msg.toString(); + + throw new WebScriptException(Status.STATUS_NOT_FOUND, errorMsg); + } + return associationDefinition; + } + + /** + * Gets the custom reference type from the association definition + * + * @param associationDefinition The association definition + * @return Returns the custom reference type which is either parent/child or bidirectional + */ + private CustomReferenceType getCustomReferenceType(AssociationDefinition associationDefinition) + { + CustomReferenceType referenceType; + + if (associationDefinition instanceof ChildAssociationDefinition) + { + referenceType = CustomReferenceType.PARENT_CHILD; + } + else if (associationDefinition instanceof AssociationDefinition) + { + referenceType = CustomReferenceType.BIDIRECTIONAL; + } + else + { + StringBuilder msg = new StringBuilder(); + msg.append("Unsupported association definition: '"); + msg.append(associationDefinition.getName().getLocalName()); + msg.append("'."); + String errorMsg = msg.toString(); + + throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR, errorMsg); + } + + return referenceType; + } + + /** + * Gets the custom reference data + * + * @param customReferenceDefinitions The custom reference definitions + * @return Custom reference data + */ + private List> getCustomReferenceData(Map customReferenceDefinitions) + { + List> customReferences = new ArrayList>(); + + for (Entry entry : customReferenceDefinitions.entrySet()) + { + Map customReference = new HashMap(); + AssociationDefinition associationDefinition = entry.getValue(); + CustomReferenceType referenceType = getCustomReferenceType(associationDefinition); + String title = getAssociationDefinitionTitle(associationDefinition); + + if (CustomReferenceType.PARENT_CHILD.equals(referenceType)) + { + String[] sourceAndTarget = getRmAdminService().splitSourceTargetId(title); + customReference.put(SOURCE, sourceAndTarget[0]); + customReference.put(TARGET, sourceAndTarget[1]); + } + else if (CustomReferenceType.BIDIRECTIONAL.equals(referenceType)) + { + customReference.put(LABEL, title); + } + + String referenceId = entry.getKey().getLocalName(); + customReference.put(REF_ID, referenceId); + customReference.put(REFERENCE_TYPE, referenceType.toString()); + + customReferences.add(customReference); + } + + return customReferences; + } + + /** + * Gets the association definition title + * + * @param associationDefinition The association definition + * @return The title of the association definition + */ + private String getAssociationDefinitionTitle(AssociationDefinition associationDefinition) + { + String title = associationDefinition.getTitle(getDictionaryService()); + if (StringUtils.isBlank(title)) + { + throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR, "Association definition title is blank."); + } + return title; + } } \ No newline at end of file