diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.lib.ftl similarity index 96% rename from config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.lib.ftl rename to config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.lib.ftl index 683da11a41..6830188222 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.lib.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.lib.ftl @@ -1,4 +1,4 @@ -<#macro formJSON form> +<#macro formDefJSON form> <#escape x as jsonUtils.encodeJSONString(x)> { "data" : diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.post.desc.xml new file mode 100644 index 0000000000..16ec75a29c --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.post.desc.xml @@ -0,0 +1,9 @@ + + Form Definition + Returns a form definition for the requested item + /api/form/definition/{item_kind}/{item_id} + + user + required + internal + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.post.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.post.json.ftl new file mode 100644 index 0000000000..284a1d88eb --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.post.json.ftl @@ -0,0 +1,2 @@ +<#import "definition.lib.ftl" as formDefLib/> +<@formDefLib.formDefJSON form=form/> \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.post.json.js b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.post.json.js new file mode 100644 index 0000000000..a83d75c8ef --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/definition.post.json.js @@ -0,0 +1,149 @@ +function main() +{ + // Extract template args + var itemKind = url.templateArgs['item_kind']; + var itemId = url.templateArgs['item_id']; + + if (logger.isLoggingEnabled()) + { + logger.log("itemKind = " + itemKind); + logger.log("itemId = " + itemId); + } + + // TODO: Return error if item kind and/or id is missing? + + // extract optional data from request body (if present) + var count = 0; + var fields = null; + if (json.has("fields")) + { + // convert the JSONArray object into a native JavaScript array + fields = []; + var jsonFields = json.get("fields"); + var numFields = jsonFields.length(); + for (count = 0; count < numFields; count++) + { + fields.push(jsonFields.get(count)); + } + + if (logger.isLoggingEnabled()) + logger.log("fields = " + fields); + } + + var forcedFields = null; + if (json.has("force")) + { + // convert the JSONArray object into a native JavaScript array + forcedFields = []; + var jsonForcedFields = json.get("force"); + var numForcedFields = jsonForcedFields.length(); + for (count = 0; count < numForcedFields; count++) + { + forcedFields.push(jsonForcedFields.get(count)); + } + + if (logger.isLoggingEnabled()) + logger.log("forcedFields = " + forcedFields); + } + + var formScriptObj = null; + + try + { + // attempt to get the form for the item + formScriptObj = formService.getForm(itemKind, itemId, fields, forcedFields); + } + catch (error) + { + var msg = error.message; + + if (logger.isLoggingEnabled()) + logger.log(msg); + + // determine if the exception was a FormNotFoundException, if so return + // 404 status code otherwise return 500 + if (msg.indexOf("FormNotFoundException") != -1) + { + status.setCode(404, msg); + + if (logger.isLoggingEnabled()) + logger.log("Returning 404 status code"); + } + else + { + status.setCode(500, msg); + + if (logger.isLoggingEnabled()) + logger.log("Returning 500 status code"); + } + + return; + } + + var formModel = {}; + formModel.data = {}; + + // TODO: retrieve the item URL from the response? + formModel.data.item = '/api/form/definition/' + itemKind + '/' + itemId; + // TODO: look for overridden submission url + formModel.data.submissionUrl = '/api/form/' + itemKind + '/' + itemId; + formModel.data.type = formScriptObj.type; + + formModel.data.definition = {}; + formModel.data.definition.fields = []; + + // We're explicitly listing the object fields of FieldDefinition.java and its subclasses here. + // I don't see a way to get these dynamically at runtime. + var supportedBaseFieldNames = ['name', 'label', 'description', 'binding', + 'defaultValue', 'group', 'protectedField']; + var supportedPropertyFieldNames = ['dataType', 'mandatory', + 'repeats', 'constraints']; + var supportedAssociationFieldNames = ['endpointType', 'endpointDirection', + 'endpointMandatory', 'endpointMany']; + + var allSupportedFieldNames = supportedBaseFieldNames + .concat(supportedPropertyFieldNames) + .concat(supportedAssociationFieldNames); + + var fieldDefs = formScriptObj.fieldDefinitions; + for (var x = 0; x < fieldDefs.length; x++) + { + var fieldDef = fieldDefs[x]; + var field = {}; + + for (var i = 0; i < allSupportedFieldNames.length; i++) + { + var nextSupportedName = allSupportedFieldNames[i]; + var nextValue = fieldDef[nextSupportedName]; + + if (nextValue != null) + { + field[nextSupportedName] = nextValue; + } + } + + field.type = (fieldDef.dataType != null) ? "property" : "association"; + formModel.data.definition.fields.push(field); + } + + formModel.data.formData = {}; + for (var k in formScriptObj.formData.data) + { + var value = formScriptObj.formData.data[k].value; + + if (value instanceof java.util.Date) + { + formModel.data.formData[k.replace(/:/g, "_")] = utils.toISO8601(value); + } + // There is no need to handle java.util.List instances here as they are + // returned from ScriptFormData.java as Strings + else + { + formModel.data.formData[k.replace(/:/g, "_")] = value; + } + } + + model.form = formModel; +} + +main(); diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.get.desc.xml deleted file mode 100644 index 6863da126d..0000000000 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.get.desc.xml +++ /dev/null @@ -1,10 +0,0 @@ - - Form - Get a form to view or edit the metadata of a given node. - /api/forms/node/{store_type}/{store_id}/{id} - /api/forms/node/{path} - - user - required - internal - \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.get.js deleted file mode 100644 index 481b99a759..0000000000 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.get.js +++ /dev/null @@ -1,111 +0,0 @@ -function main() -{ - // Extract template args - var ta_storeType = url.templateArgs['store_type']; - var ta_storeId = url.templateArgs['store_id']; - var ta_id = url.templateArgs['id']; - var ta_path = url.templateArgs['path']; - - if (logger.isLoggingEnabled()) - { - logger.log("ta_storeType = " + ta_storeType); - logger.log("ta_storeId = " + ta_storeId); - logger.log("ta_id = " + ta_id); - logger.log("ta_path = " + ta_path); - } - - var formUrl = ''; - // The template argument 'path' only appears in the second URI template. - if (ta_path != null) - { - //TODO Need to test this path. - formUrl = ta_path; - } - else - { - formUrl = ta_storeType + '://' + ta_storeId + '/' + ta_id; - } - - if (logger.isLoggingEnabled()) - { - logger.log("formUrl = " + formUrl); - } - - var formScriptObj = formService.getForm(formUrl); - - if (formScriptObj == null) - { - var message = "The form for item \"" + formUrl + "\" could not be found."; - if (logger.isWarnLoggingEnabled()) - { - logger.warn(message); - } - status.setCode(404, message); - return; - } - - var formModel = {}; - formModel.data = {}; - - formModel.data.item = '/api/node/' + ta_storeType + '/' + ta_storeId + '/' + ta_id; - formModel.data.submissionUrl = '/api/forms/node/' + ta_storeType + '/' + ta_storeId + '/' + ta_id; - formModel.data.type = formScriptObj.type; - - formModel.data.definition = {}; - formModel.data.definition.fields = []; - - // We're explicitly listing the object fields of FieldDefinition.java and its subclasses here. - // I don't see a way to get these dynamically at runtime. - var supportedBaseFieldNames = ['name', 'label', 'description', 'binding', - 'defaultValue', 'group', 'protectedField']; - var supportedPropertyFieldNames = ['dataType', 'mandatory', - 'repeats', 'constraints']; - var supportedAssociationFieldNames = ['endpointType', 'endpointDirection', - 'endpointMandatory', 'endpointMany']; - - var allSupportedFieldNames = supportedBaseFieldNames - .concat(supportedPropertyFieldNames) - .concat(supportedAssociationFieldNames); - - var fieldDefs = formScriptObj.fieldDefinitions; - for (var x = 0; x < fieldDefs.length; x++) - { - var fieldDef = fieldDefs[x]; - var field = {}; - - for (var i = 0; i < allSupportedFieldNames.length; i++) - { - var nextSupportedName = allSupportedFieldNames[i]; - var nextValue = fieldDef[nextSupportedName]; - - if (nextValue != null) - { - field[nextSupportedName] = nextValue; - } - } - - field.type = (fieldDef.dataType != null) ? "property" : "association"; - formModel.data.definition.fields.push(field); - } - - formModel.data.formData = {}; - for (var k in formScriptObj.formData.data) - { - var value = formScriptObj.formData.data[k].value; - - if (value instanceof java.util.Date) - { - formModel.data.formData[k.replace(/:/g, "_")] = utils.toISO8601(value); - } - // There is no need to handle java.util.List instances here as they are - // returned from ScriptFormData.java as Strings - else - { - formModel.data.formData[k.replace(/:/g, "_")] = value; - } - } - - model.form = formModel; -} - -main(); diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.get.json.ftl deleted file mode 100644 index 2a6c0c7243..0000000000 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.get.json.ftl +++ /dev/null @@ -1,2 +0,0 @@ -<#import "form.lib.ftl" as formLib/> -<@formLib.formJSON form=form/> \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.desc.xml index c891735c34..6d8e89fcff 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.desc.xml +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.desc.xml @@ -1,8 +1,7 @@ Form Handles the submission of a form - /api/forms/node/{store_type}/{store_id}/{id} - /api/forms/node/{path} + /api/form/{item_kind}/{item_id} user required internal diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.js b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.js index fbce77a165..fc57a5bf04 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.js @@ -1,69 +1,81 @@ function main() { - var ta_storeType = url.templateArgs['store_type']; - var ta_storeId = url.templateArgs['store_id']; - var ta_id = url.templateArgs['id']; - var ta_mode = url.templateArgs['mode']; - var ta_path = url.templateArgs['path']; - - var nodeRef = ''; - // The template argument 'path' only appears in the second URI template. - if (ta_path != null) - { - nodeRef = ta_path; - } - else - { - nodeRef = ta_storeType + '://' + ta_storeId + '/' + ta_id; - } - - if (logger.isLoggingEnabled()) - { - logger.log("POST request received for nodeRef: " + nodeRef); - } - - - - - // TODO: check the given nodeRef is real - - - - - // persist the submitted data using the most appropriate data set - if (typeof formdata !== "undefined") - { - // The model.data is set here to allow the rendering of a simple result page. - // TODO This should be removed when the POST is working. - model.data = formdata; - - // Note: This formdata is org/alfresco/web/scripts/servlet/FormData.java - if (logger.isLoggingEnabled()) - { - logger.log("Saving form with formdata, " + formdata.fields.length + " fields."); - } + // Extract template args + var itemKind = url.templateArgs['item_kind']; + var itemId = url.templateArgs['item_id']; - // N.B. This repoFormData is a different FormData class to that used above. - var repoFormData = new Packages.org.alfresco.repo.forms.FormData(); - for (var i = 0; i < formdata.fields.length; i++) - { - // Replace the first 2 underscores with colons. - var alteredName = formdata.fields[i].name.replaceFirst("_", ":").replaceFirst("_", ":"); - repoFormData.addData(alteredName, formdata.fields[i].value); - } - - formService.saveForm(nodeRef, repoFormData); - } - else - { - if (logger.isLoggingEnabled()) - { - logger.log("Saving form with args = " + args); - } - formService.saveForm(nodeRef, args); - } - - model.message = "Successfully updated node " + nodeRef; + if (logger.isLoggingEnabled()) + { + logger.log("itemKind = " + itemKind); + logger.log("itemId = " + itemId); + } + + // TODO: Return error if item kind and/or id is missing? + + try + { + // persist the submitted data using the most appropriate data set + if (typeof formdata !== "undefined") + { + // The model.data is set here to allow the rendering of a simple result page. + // TODO This should be removed when the POST is working. + model.data = formdata; + + // Note: This formdata is org/alfresco/web/scripts/servlet/FormData.java + if (logger.isLoggingEnabled()) + { + logger.log("Saving form with formdata, " + formdata.fields.length + " fields."); + } + + // N.B. This repoFormData is a different FormData class to that used above. + var repoFormData = new Packages.org.alfresco.repo.forms.FormData(); + for (var i = 0; i < formdata.fields.length; i++) + { + // Replace the first 2 underscores with colons. + var alteredName = formdata.fields[i].name.replaceFirst("_", ":").replaceFirst("_", ":"); + repoFormData.addData(alteredName, formdata.fields[i].value); + } + + formService.saveForm(itemKind, itemId, repoFormData); + } + else + { + if (logger.isLoggingEnabled()) + { + logger.log("Saving form with args = " + args); + } + + formService.saveForm(itemKind, itemId, args); + } + } + catch (error) + { + var msg = error.message; + + if (logger.isLoggingEnabled()) + logger.log(msg); + + // determine if the exception was a FormNotFoundException, if so return + // 404 status code otherwise return 500 + if (msg.indexOf("FormNotFoundException") != -1) + { + status.setCode(404, msg); + + if (logger.isLoggingEnabled()) + logger.log("Returning 404 status code"); + } + else + { + status.setCode(500, msg); + + if (logger.isLoggingEnabled()) + logger.log("Returning 500 status code"); + } + + return; + } + + model.message = "Successfully updated item [" + itemKind + "]" + itemId; } main(); \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.json.js b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.json.js index 603a068806..40ff91c1de 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.json.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.json.js @@ -1,59 +1,76 @@ function main() { - var ta_storeType = url.templateArgs['store_type']; - var ta_storeId = url.templateArgs['store_id']; - var ta_id = url.templateArgs['id']; - var ta_mode = url.templateArgs['mode']; - var ta_path = url.templateArgs['path']; - - var nodeRef = ''; - // The template argument 'path' only appears in the second URI template. - if (ta_path != null) - { - nodeRef = ta_path; - } - else - { - nodeRef = ta_storeType + '://' + ta_storeId + '/' + ta_id; - } - - if (logger.isLoggingEnabled()) - { - logger.log("JSON POST request received for nodeRef: " + nodeRef); - } + // Extract template args + var itemKind = url.templateArgs['item_kind']; + var itemId = url.templateArgs['item_id']; - //TODO Add check whether nodeRef exists. - - - if (typeof json !== "undefined") - { - // At this point the field names are e.g. prop_cm_name - // and there are some extra values - hidden fields? These are fields from YUI's datepicker(s) - // e.g. "template_x002e_form-ui_x002e_form-test_prop_my_date-entry":"2/19/2009" - } - else - { - if (logger.isWarnLoggingEnabled()) - { - logger.warn("json object was undefined."); - } - status.setCode(501, message); - return; - } - - var repoFormData = new Packages.org.alfresco.repo.forms.FormData(); - var jsonKeys = json.keys(); - for ( ; jsonKeys.hasNext(); ) - { - // Replace the first 2 underscores with colons. - var nextKey = jsonKeys.next(); - var alteredKey = nextKey.replaceFirst("_", ":").replaceFirst("_", ":"); - repoFormData.addData(alteredKey, json.get(nextKey)); - } + if (logger.isLoggingEnabled()) + { + logger.log("itemKind = " + itemKind); + logger.log("itemId = " + itemId); + } - formService.saveForm(nodeRef, repoFormData); + // TODO: Return error if item kind and/or id is missing? - model.message = "Successfully updated node " + nodeRef; + if (typeof json !== "undefined") + { + // At this point the field names are e.g. prop_cm_name + // and there are some extra values - hidden fields? These are fields from YUI's datepicker(s) + // e.g. "template_x002e_form-ui_x002e_form-test_prop_my_date-entry":"2/19/2009" + } + else + { + if (logger.isWarnLoggingEnabled()) + { + logger.warn("json object was undefined."); + } + + status.setCode(501, message); + return; + } + + var repoFormData = new Packages.org.alfresco.repo.forms.FormData(); + var jsonKeys = json.keys(); + for ( ; jsonKeys.hasNext(); ) + { + // Replace the first 2 underscores with colons. + var nextKey = jsonKeys.next(); + var alteredKey = nextKey.replaceFirst("_", ":").replaceFirst("_", ":"); + repoFormData.addData(alteredKey, json.get(nextKey)); + } + + try + { + formService.saveForm(itemKind, itemId, repoFormData); + } + catch (error) + { + var msg = error.message; + + if (logger.isLoggingEnabled()) + logger.log(msg); + + // determine if the exception was a FormNotFoundException, if so return + // 404 status code otherwise return 500 + if (msg.indexOf("FormNotFoundException") != -1) + { + status.setCode(404, msg); + + if (logger.isLoggingEnabled()) + logger.log("Returning 404 status code"); + } + else + { + status.setCode(500, msg); + + if (logger.isLoggingEnabled()) + logger.log("Returning 500 status code"); + } + + return; + } + + model.message = "Successfully updated item [" + itemKind + "]" + itemId; } main(); \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.xwwwformurlencoded.js b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.xwwwformurlencoded.js index fafa16d05f..c56cbe9c5b 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.xwwwformurlencoded.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/forms/form.post.xwwwformurlencoded.js @@ -1,14 +1,14 @@ function main() { - //FIXME URL-encoded post of forms data is not yet working. + // FIXME URL-encoded post of forms data is not yet working. if (logger.isLoggingEnabled()) { - logger.log("x-www-form-urlencoded request received for nodeRef"); + logger.log("x-www-form-urlencoded request received"); logger.log("decodedparams: " + decodedparams); } - model.message = "Successfully updated node " + "nodeRef"; + model.message = "Successfully updated item"; } main(); diff --git a/source/java/org/alfresco/repo/web/scripts/forms/AbstractTestFormRestApi.java b/source/java/org/alfresco/repo/web/scripts/forms/AbstractTestFormRestApi.java index 9e3c1c824e..53bc850592 100644 --- a/source/java/org/alfresco/repo/web/scripts/forms/AbstractTestFormRestApi.java +++ b/source/java/org/alfresco/repo/web/scripts/forms/AbstractTestFormRestApi.java @@ -1,205 +1,219 @@ -/* - * Copyright (C) 2005-2009 Alfresco Software Limited. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program 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 General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have received a copy of the text describing - * the FLOSS exception, and it is also available here: - * http://www.alfresco.com/legal/licensing" - */ -package org.alfresco.repo.web.scripts.forms; - -import java.io.IOException; -import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.util.HashMap; -import java.util.Map; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.content.MimetypeMap; -import org.alfresco.repo.model.Repository; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.web.scripts.BaseWebScriptTest; -import org.alfresco.service.cmr.model.FileFolderService; -import org.alfresco.service.cmr.model.FileInfo; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.GUID; -import org.alfresco.web.scripts.TestWebScriptServer.GetRequest; -import org.alfresco.web.scripts.TestWebScriptServer.Response; - -public abstract class AbstractTestFormRestApi extends BaseWebScriptTest -{ - protected static final String TEST_FORM_DESCRIPTION = "Test form description"; - protected static final String TEST_FORM_TITLE = "Test form title"; - protected String referencingNodeUrl; - protected String containingNodeUrl; - protected NodeRef referencingDocNodeRef; - protected Map refNodePropertiesAfterCreation; - protected NodeRef associatedDoc_A; - protected NodeRef associatedDoc_B; - protected NodeRef associatedDoc_C; - protected NodeRef associatedDoc_D; - protected NodeRef associatedDoc_E; - protected NodeRef childDoc_A; - protected NodeRef childDoc_B; - protected NodeRef childDoc_C; - protected NodeRef childDoc_D; - protected NodeRef childDoc_E; - protected NodeRef testFolderNodeRef; - - protected NodeService nodeService; - private FileFolderService fileFolderService; - private ContentService contentService; - private Repository repositoryHelper; - protected NodeRef containerNodeRef; - - @Override - protected void setUp() throws Exception - { - super.setUp(); - this.fileFolderService = (FileFolderService) getServer().getApplicationContext().getBean( - "FileFolderService"); - this.contentService = (ContentService) getServer().getApplicationContext().getBean( - "ContentService"); - this.repositoryHelper = (Repository) getServer().getApplicationContext().getBean( - "repositoryHelper"); - this.nodeService = (NodeService) getServer().getApplicationContext().getBean("NodeService"); - - AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName()); - - NodeRef companyHomeNodeRef = this.repositoryHelper.getCompanyHome(); - - String guid = GUID.generate(); - - // Create a test file (not a folder) - FileInfo referencingDoc = this.fileFolderService.create(companyHomeNodeRef, - "referencingDoc" + guid + ".txt", ContentModel.TYPE_CONTENT); - referencingDocNodeRef = referencingDoc.getNodeRef(); - - // Add an aspect. - Map aspectProps = new HashMap(2); - aspectProps.put(ContentModel.PROP_TITLE, TEST_FORM_TITLE); - aspectProps.put(ContentModel.PROP_DESCRIPTION, TEST_FORM_DESCRIPTION); - nodeService.addAspect(referencingDocNodeRef, ContentModel.ASPECT_TITLED, aspectProps); - - // Write some content into the node. - ContentWriter contentWriter = this.contentService.getWriter(referencingDoc.getNodeRef(), - ContentModel.PROP_CONTENT, true); - contentWriter.setEncoding("UTF-8"); - contentWriter.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - contentWriter.putContent("The quick brown fox jumped over the lazy dog."); - - // Create a folder - will use this for child-association testing - FileInfo associatedDocsFolder = - this.fileFolderService.create(companyHomeNodeRef, "testFolder" + guid, ContentModel.TYPE_FOLDER); - - testFolderNodeRef = associatedDocsFolder.getNodeRef(); - - this.associatedDoc_A = createTestNode("associatedDoc_A" + guid); - this.associatedDoc_B = createTestNode("associatedDoc_B" + guid); - this.associatedDoc_C = createTestNode("associatedDoc_C" + guid); - this.associatedDoc_D = createTestNode("associatedDoc_D" + guid); - this.associatedDoc_E = createTestNode("associatedDoc_E" + guid); - - // Now create associations between the referencing and the two node refs. - aspectProps.clear(); - this.nodeService.addAspect(this.referencingDocNodeRef, ContentModel.ASPECT_REFERENCING, aspectProps); - this.nodeService.createAssociation(this.referencingDocNodeRef, associatedDoc_A, ContentModel.ASSOC_REFERENCES); - this.nodeService.createAssociation(this.referencingDocNodeRef, associatedDoc_B, ContentModel.ASSOC_REFERENCES); - // Leave the 3rd, 4th and 5th nodes without associations as they may be created in - // other test code. - - // Create a container for the children. - HashMap containerProps = new HashMap(); - this.containerNodeRef = nodeService.createNode(companyHomeNodeRef, ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testContainer" + guid), - ContentModel.TYPE_CONTAINER, - containerProps).getChildRef(); - - this.childDoc_A = createTestNode("childDoc_A" + guid); - this.childDoc_B = createTestNode("childDoc_B" + guid); - this.childDoc_C = createTestNode("childDoc_C" + guid); - this.childDoc_D = createTestNode("childDoc_D" + guid); - this.childDoc_E = createTestNode("childDoc_E" + guid); - - // Now create the pre-test child-associations. - this.nodeService.addChild(containerNodeRef, childDoc_A, ContentModel.ASSOC_CHILDREN, QName.createQName("childA")); - this.nodeService.addChild(containerNodeRef, childDoc_B, ContentModel.ASSOC_CHILDREN, QName.createQName("childB")); - // The other childDoc nodes will be added as children over the REST API as part - // of later test code. - - // Create and store the url to the referencingNode - StringBuilder builder = new StringBuilder(); - builder.append("/api/forms/node/workspace/").append(referencingDocNodeRef.getStoreRef().getIdentifier()) - .append("/").append(referencingDocNodeRef.getId()); - this.referencingNodeUrl = builder.toString(); - - // Create and store the url to the containing node - builder = new StringBuilder(); - builder.append("/api/forms/node/workspace/").append(containerNodeRef.getStoreRef().getIdentifier()) - .append("/").append(containerNodeRef.getId()); - this.containingNodeUrl = builder.toString(); - - // Store the original properties of this node - this.refNodePropertiesAfterCreation = nodeService.getProperties(referencingDocNodeRef); - - refNodePropertiesAfterCreation.toString(); - } - - @Override - public void tearDown() - { - nodeService.deleteNode(this.referencingDocNodeRef); - nodeService.deleteNode(this.associatedDoc_A); - nodeService.deleteNode(this.associatedDoc_B); - nodeService.deleteNode(this.associatedDoc_C); - nodeService.deleteNode(this.associatedDoc_D); - nodeService.deleteNode(this.associatedDoc_E); - nodeService.deleteNode(this.childDoc_A); - nodeService.deleteNode(this.childDoc_B); - nodeService.deleteNode(this.childDoc_C); - nodeService.deleteNode(this.childDoc_D); - nodeService.deleteNode(this.childDoc_E); - nodeService.deleteNode(this.testFolderNodeRef); - nodeService.deleteNode(this.containerNodeRef); - } - - protected Response sendGetReq(String url, int expectedStatusCode) - throws IOException, UnsupportedEncodingException - { - Response result = sendRequest(new GetRequest(url), expectedStatusCode); - return result; - } - - protected NodeRef createTestNode(String associatedDocName) - { - Map docProps = new HashMap(1); - docProps.put(ContentModel.PROP_NAME, associatedDocName + ".txt"); - return this.nodeService.createNode( - testFolderNodeRef, - ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, associatedDocName + ".txt"), - ContentModel.TYPE_CONTENT, - docProps).getChildRef(); - } +/* + * Copyright (C) 2005-2009 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have received a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.web.scripts.forms; + +import java.io.IOException; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.model.Repository; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.web.scripts.BaseWebScriptTest; +import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.model.FileInfo; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.GUID; +import org.alfresco.web.scripts.TestWebScriptServer.GetRequest; +import org.alfresco.web.scripts.TestWebScriptServer.Response; + +public abstract class AbstractTestFormRestApi extends BaseWebScriptTest +{ + protected static final String APPLICATION_JSON = "application/json"; + protected static final String TEST_FORM_DESCRIPTION = "Test form description"; + protected static final String TEST_FORM_TITLE = "Test form title"; + protected String referencingNodeDefUrl; + protected String referencingNodeUpdateUrl; + protected String containingNodeDefUrl; + protected String containingNodeUpdateUrl; + protected String containingNodeUrl; + protected NodeRef referencingDocNodeRef; + protected Map refNodePropertiesAfterCreation; + protected NodeRef associatedDoc_A; + protected NodeRef associatedDoc_B; + protected NodeRef associatedDoc_C; + protected NodeRef associatedDoc_D; + protected NodeRef associatedDoc_E; + protected NodeRef childDoc_A; + protected NodeRef childDoc_B; + protected NodeRef childDoc_C; + protected NodeRef childDoc_D; + protected NodeRef childDoc_E; + protected NodeRef testFolderNodeRef; + + protected NodeService nodeService; + private FileFolderService fileFolderService; + private ContentService contentService; + private Repository repositoryHelper; + protected NodeRef containerNodeRef; + + @Override + protected void setUp() throws Exception + { + super.setUp(); + this.fileFolderService = (FileFolderService) getServer().getApplicationContext().getBean( + "FileFolderService"); + this.contentService = (ContentService) getServer().getApplicationContext().getBean( + "ContentService"); + this.repositoryHelper = (Repository) getServer().getApplicationContext().getBean( + "repositoryHelper"); + this.nodeService = (NodeService) getServer().getApplicationContext().getBean("NodeService"); + + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName()); + + NodeRef companyHomeNodeRef = this.repositoryHelper.getCompanyHome(); + + String guid = GUID.generate(); + + // Create a test file (not a folder) + FileInfo referencingDoc = this.fileFolderService.create(companyHomeNodeRef, + "referencingDoc" + guid + ".txt", ContentModel.TYPE_CONTENT); + referencingDocNodeRef = referencingDoc.getNodeRef(); + + // Add an aspect. + Map aspectProps = new HashMap(2); + aspectProps.put(ContentModel.PROP_TITLE, TEST_FORM_TITLE); + aspectProps.put(ContentModel.PROP_DESCRIPTION, TEST_FORM_DESCRIPTION); + nodeService.addAspect(referencingDocNodeRef, ContentModel.ASPECT_TITLED, aspectProps); + + // Write some content into the node. + ContentWriter contentWriter = this.contentService.getWriter(referencingDoc.getNodeRef(), + ContentModel.PROP_CONTENT, true); + contentWriter.setEncoding("UTF-8"); + contentWriter.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + contentWriter.putContent("The quick brown fox jumped over the lazy dog."); + + // Create a folder - will use this for child-association testing + FileInfo associatedDocsFolder = + this.fileFolderService.create(companyHomeNodeRef, "testFolder" + guid, ContentModel.TYPE_FOLDER); + + testFolderNodeRef = associatedDocsFolder.getNodeRef(); + + this.associatedDoc_A = createTestNode("associatedDoc_A" + guid); + this.associatedDoc_B = createTestNode("associatedDoc_B" + guid); + this.associatedDoc_C = createTestNode("associatedDoc_C" + guid); + this.associatedDoc_D = createTestNode("associatedDoc_D" + guid); + this.associatedDoc_E = createTestNode("associatedDoc_E" + guid); + + // Now create associations between the referencing and the two node refs. + aspectProps.clear(); + this.nodeService.addAspect(this.referencingDocNodeRef, ContentModel.ASPECT_REFERENCING, aspectProps); + this.nodeService.createAssociation(this.referencingDocNodeRef, associatedDoc_A, ContentModel.ASSOC_REFERENCES); + this.nodeService.createAssociation(this.referencingDocNodeRef, associatedDoc_B, ContentModel.ASSOC_REFERENCES); + // Leave the 3rd, 4th and 5th nodes without associations as they may be created in + // other test code. + + // Create a container for the children. + HashMap containerProps = new HashMap(); + this.containerNodeRef = nodeService.createNode(companyHomeNodeRef, ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testContainer" + guid), + ContentModel.TYPE_CONTAINER, + containerProps).getChildRef(); + + this.childDoc_A = createTestNode("childDoc_A" + guid); + this.childDoc_B = createTestNode("childDoc_B" + guid); + this.childDoc_C = createTestNode("childDoc_C" + guid); + this.childDoc_D = createTestNode("childDoc_D" + guid); + this.childDoc_E = createTestNode("childDoc_E" + guid); + + // Now create the pre-test child-associations. + this.nodeService.addChild(containerNodeRef, childDoc_A, ContentModel.ASSOC_CHILDREN, QName.createQName("childA")); + this.nodeService.addChild(containerNodeRef, childDoc_B, ContentModel.ASSOC_CHILDREN, QName.createQName("childB")); + // The other childDoc nodes will be added as children over the REST API as part + // of later test code. + + // Create and store the urls to the referencingNode + StringBuilder builder = new StringBuilder(); + builder.append("/api/form/definition/node/workspace/").append(referencingDocNodeRef.getStoreRef().getIdentifier()) + .append("/").append(referencingDocNodeRef.getId()); + this.referencingNodeDefUrl = builder.toString(); + + builder = new StringBuilder(); + builder.append("/api/form/node/workspace/").append(referencingDocNodeRef.getStoreRef().getIdentifier()) + .append("/").append(referencingDocNodeRef.getId()); + this.referencingNodeUpdateUrl = builder.toString(); + + // Create and store the urls to the containing node + builder = new StringBuilder(); + builder.append("/api/form/definition/node/workspace/").append(containerNodeRef.getStoreRef().getIdentifier()) + .append("/").append(containerNodeRef.getId()); + this.containingNodeDefUrl = builder.toString(); + + builder = new StringBuilder(); + builder.append("/api/form/node/workspace/").append(containerNodeRef.getStoreRef().getIdentifier()) + .append("/").append(containerNodeRef.getId()); + this.containingNodeUpdateUrl = builder.toString(); + + // Store the original properties of this node + this.refNodePropertiesAfterCreation = nodeService.getProperties(referencingDocNodeRef); + + refNodePropertiesAfterCreation.toString(); + } + + @Override + public void tearDown() + { + nodeService.deleteNode(this.referencingDocNodeRef); + nodeService.deleteNode(this.associatedDoc_A); + nodeService.deleteNode(this.associatedDoc_B); + nodeService.deleteNode(this.associatedDoc_C); + nodeService.deleteNode(this.associatedDoc_D); + nodeService.deleteNode(this.associatedDoc_E); + nodeService.deleteNode(this.childDoc_A); + nodeService.deleteNode(this.childDoc_B); + nodeService.deleteNode(this.childDoc_C); + nodeService.deleteNode(this.childDoc_D); + nodeService.deleteNode(this.childDoc_E); + nodeService.deleteNode(this.testFolderNodeRef); + nodeService.deleteNode(this.containerNodeRef); + } + + protected Response sendGetReq(String url, int expectedStatusCode) + throws IOException, UnsupportedEncodingException + { + Response result = sendRequest(new GetRequest(url), expectedStatusCode); + return result; + } + + protected NodeRef createTestNode(String associatedDocName) + { + Map docProps = new HashMap(1); + docProps.put(ContentModel.PROP_NAME, associatedDocName + ".txt"); + return this.nodeService.createNode( + testFolderNodeRef, + ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, associatedDocName + ".txt"), + ContentModel.TYPE_CONTENT, + docProps).getChildRef(); + } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/forms/FormRestApiGet_Test.java b/source/java/org/alfresco/repo/web/scripts/forms/FormRestApiGet_Test.java index e796431b25..ef84ebe803 100644 --- a/source/java/org/alfresco/repo/web/scripts/forms/FormRestApiGet_Test.java +++ b/source/java/org/alfresco/repo/web/scripts/forms/FormRestApiGet_Test.java @@ -28,30 +28,41 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.web.scripts.TestWebScriptServer.PostRequest; import org.alfresco.web.scripts.TestWebScriptServer.Response; import org.alfresco.web.scripts.json.JSONUtils; import org.json.JSONArray; import org.json.JSONObject; import org.json.JSONTokener; -public class FormRestApiGet_Test extends AbstractTestFormRestApi { - +public class FormRestApiGet_Test extends AbstractTestFormRestApi +{ public void testResponseContentType() throws Exception { - Response rsp = sendGetReq(referencingNodeUrl, 200); + JSONObject jsonPostData = new JSONObject(); + String jsonPostString = jsonPostData.toString(); + Response rsp = sendRequest(new PostRequest(referencingNodeDefUrl, + jsonPostString, APPLICATION_JSON), 200); assertEquals("application/json;charset=UTF-8", rsp.getContentType()); } public void testGetFormForNonExistentNode() throws Exception { // Replace all digits with an 'x' char - this should make for a non-existent node. - Response rsp = sendGetReq(referencingNodeUrl.replaceAll("\\d", "x"), 404); + JSONObject jsonPostData = new JSONObject(); + String jsonPostString = jsonPostData.toString(); + Response rsp = sendRequest(new PostRequest(referencingNodeDefUrl.replaceAll("\\d", "x"), + jsonPostString, APPLICATION_JSON), 404); assertEquals("application/json;charset=UTF-8", rsp.getContentType()); } public void testJsonContentParsesCorrectly() throws Exception { - Response rsp = sendGetReq(referencingNodeUrl, 200); + JSONObject jsonPostData = new JSONObject(); + String jsonPostString = jsonPostData.toString(); + Response rsp = sendRequest(new PostRequest(referencingNodeDefUrl, + jsonPostString, APPLICATION_JSON), 200); String jsonResponseString = rsp.getContentAsString(); Object jsonObject = new JSONUtils().toObject(jsonResponseString); @@ -60,7 +71,10 @@ public class FormRestApiGet_Test extends AbstractTestFormRestApi { public void testJsonUpperStructure() throws Exception { - Response rsp = sendGetReq(referencingNodeUrl, 200); + JSONObject jsonPostData = new JSONObject(); + String jsonPostString = jsonPostData.toString(); + Response rsp = sendRequest(new PostRequest(referencingNodeDefUrl, + jsonPostString, APPLICATION_JSON), 200); String jsonResponseString = rsp.getContentAsString(); JSONObject jsonParsedObject = new JSONObject(new JSONTokener(jsonResponseString)); @@ -87,7 +101,10 @@ public class FormRestApiGet_Test extends AbstractTestFormRestApi { @SuppressWarnings("unchecked") public void testJsonFormData() throws Exception { - Response rsp = sendGetReq(referencingNodeUrl, 200); + JSONObject jsonPostData = new JSONObject(); + String jsonPostString = jsonPostData.toString(); + Response rsp = sendRequest(new PostRequest(referencingNodeDefUrl, + jsonPostString, APPLICATION_JSON), 200); String jsonResponseString = rsp.getContentAsString(); // At this point the formData names have underscores @@ -118,7 +135,10 @@ public class FormRestApiGet_Test extends AbstractTestFormRestApi { @SuppressWarnings("unchecked") public void testJsonDefinitionFields() throws Exception { - Response rsp = sendGetReq(referencingNodeUrl, 200); + JSONObject jsonPostData = new JSONObject(); + String jsonPostString = jsonPostData.toString(); + Response rsp = sendRequest(new PostRequest(referencingNodeDefUrl, + jsonPostString, APPLICATION_JSON), 200); String jsonResponseString = rsp.getContentAsString(); JSONObject jsonParsedObject = new JSONObject(new JSONTokener(jsonResponseString)); @@ -149,4 +169,71 @@ public class FormRestApiGet_Test extends AbstractTestFormRestApi { } } } + + public void testJsonSelectedFields() throws Exception + { + JSONObject jsonPostData = new JSONObject(); + JSONArray jsonFields = new JSONArray(); + jsonFields.put("cm:name"); + jsonFields.put("cm:title"); + jsonFields.put("cm:publisher"); + jsonPostData.put("fields", jsonFields); + + // Submit the JSON request. + String jsonPostString = jsonPostData.toString(); + Response rsp = sendRequest(new PostRequest(referencingNodeDefUrl, jsonPostString, + APPLICATION_JSON), 200); + + String jsonResponseString = rsp.getContentAsString(); + JSONObject jsonParsedObject = new JSONObject(new JSONTokener(jsonResponseString)); + assertNotNull(jsonParsedObject); + + JSONObject rootDataObject = (JSONObject)jsonParsedObject.get("data"); + JSONObject definitionObject = (JSONObject)rootDataObject.get("definition"); + JSONArray fieldsArray = (JSONArray)definitionObject.get("fields"); + assertEquals("Expected 2 fields", 2, fieldsArray.length()); + + // get the data and check it + JSONObject formDataObject = (JSONObject)rootDataObject.get("formData"); + assertNotNull("Expected to find cm:name data", formDataObject.get("prop_cm_name")); + assertNotNull("Expected to find cm:title data", formDataObject.get("prop_cm_title")); + assertEquals(TEST_FORM_TITLE, formDataObject.get("prop_cm_title")); + } + + public void testJsonForcedFields() throws Exception + { + JSONObject jsonPostData = new JSONObject(); + + JSONArray jsonFields = new JSONArray(); + jsonFields.put("cm:name"); + jsonFields.put("cm:title"); + jsonFields.put("cm:publisher"); + jsonFields.put("cm:wrong"); + jsonPostData.put("fields", jsonFields); + + JSONArray jsonForcedFields = new JSONArray(); + jsonForcedFields.put("cm:publisher"); + jsonForcedFields.put("cm:wrong"); + jsonPostData.put("force", jsonForcedFields); + + // Submit the JSON request. + String jsonPostString = jsonPostData.toString(); + Response rsp = sendRequest(new PostRequest(referencingNodeDefUrl, jsonPostString, + APPLICATION_JSON), 200); + + String jsonResponseString = rsp.getContentAsString(); + JSONObject jsonParsedObject = new JSONObject(new JSONTokener(jsonResponseString)); + assertNotNull(jsonParsedObject); + + JSONObject rootDataObject = (JSONObject)jsonParsedObject.get("data"); + JSONObject definitionObject = (JSONObject)rootDataObject.get("definition"); + JSONArray fieldsArray = (JSONArray)definitionObject.get("fields"); + assertEquals("Expected 3 fields", 3, fieldsArray.length()); + + // get the data and check it + JSONObject formDataObject = (JSONObject)rootDataObject.get("formData"); + assertNotNull("Expected to find cm:name data", formDataObject.get("prop_cm_name")); + assertNotNull("Expected to find cm:title data", formDataObject.get("prop_cm_title")); + assertEquals(TEST_FORM_TITLE, formDataObject.get("prop_cm_title")); + } } diff --git a/source/java/org/alfresco/repo/web/scripts/forms/FormRestApiJsonPost_Test.java b/source/java/org/alfresco/repo/web/scripts/forms/FormRestApiJsonPost_Test.java index 0d0abeedac..4d9dc4efb9 100644 --- a/source/java/org/alfresco/repo/web/scripts/forms/FormRestApiJsonPost_Test.java +++ b/source/java/org/alfresco/repo/web/scripts/forms/FormRestApiJsonPost_Test.java @@ -1,424 +1,423 @@ -/* - * Copyright (C) 2005-2009 Alfresco Software Limited. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program 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 General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have received a copy of the text describing - * the FLOSS exception, and it is also available here: - * http://www.alfresco.com/legal/licensing" - */ -package org.alfresco.repo.web.scripts.forms; - -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.content.MimetypeMap; -import org.alfresco.service.cmr.repository.AssociationRef; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.web.scripts.TestWebScriptServer.GetRequest; -import org.alfresco.web.scripts.TestWebScriptServer.PostRequest; -import org.alfresco.web.scripts.TestWebScriptServer.Response; -import org.json.JSONException; -import org.json.JSONObject; - -public class FormRestApiJsonPost_Test extends AbstractTestFormRestApi -{ - private static final String PROP_CM_DESCRIPTION = "prop_cm_description"; - private static final String PROP_MIMETYPE = "prop_mimetype"; - private static final String APPLICATION_JSON = "application/json"; - private static final String ASSOC_CM_REFERENCES = "assoc_cm_references"; - private static final String ASSOC_CM_REFERENCES_ADDED = "assoc_cm_references_added"; - private static final String ASSOC_CM_REFERENCES_REMOVED = "assoc_cm_references_removed"; - private static final String ASSOC_SYS_CHILDREN = "assoc_sys_children"; - private static final String ASSOC_SYS_CHILDREN_ADDED = "assoc_sys_children_added"; - private static final String ASSOC_SYS_CHILDREN_REMOVED = "assoc_sys_children_removed"; - - public void testSimpleJsonPostRequest() throws IOException, JSONException - { - // Retrieve and store the original property value. - Serializable originalDescription = - nodeService.getProperty(referencingDocNodeRef, ContentModel.PROP_DESCRIPTION); - assertEquals(TEST_FORM_DESCRIPTION, originalDescription); - - // get the original mimetype - String originalMimetype = null; - ContentData content = (ContentData)this.nodeService.getProperty(referencingDocNodeRef, ContentModel.PROP_CONTENT); - if (content != null) - { - originalMimetype = content.getMimetype(); - } - - // Construct some JSON to represent a new value. - JSONObject jsonPostData = new JSONObject(); - final String proposedNewDescription = "Modified Description"; - jsonPostData.put(PROP_CM_DESCRIPTION, proposedNewDescription); - jsonPostData.put(PROP_MIMETYPE, MimetypeMap.MIMETYPE_HTML); - - // Submit the JSON request. - String jsonPostString = jsonPostData.toString(); - Response ignoredRsp = sendRequest(new PostRequest(referencingNodeUrl, jsonPostString, - APPLICATION_JSON), 200); - - // The nodeService should give us the modified property. - Serializable modifiedDescription = - nodeService.getProperty(referencingDocNodeRef, ContentModel.PROP_DESCRIPTION); - assertEquals(proposedNewDescription, modifiedDescription); - - // get the original mimetype - String modifiedMimetype = null; - content = (ContentData)this.nodeService.getProperty(referencingDocNodeRef, ContentModel.PROP_CONTENT); - if (content != null) - { - modifiedMimetype = content.getMimetype(); - } - assertEquals(MimetypeMap.MIMETYPE_HTML, modifiedMimetype); - - // The Rest API should also give us the modified property. - Response response = sendRequest(new GetRequest(referencingNodeUrl), 200); - JSONObject jsonGetResponse = new JSONObject(response.getContentAsString()); - JSONObject jsonDataObj = (JSONObject)jsonGetResponse.get("data"); - assertNotNull(jsonDataObj); - - JSONObject formData = (JSONObject)jsonDataObj.get("formData"); - assertNotNull(formData); - String retrievedValue = (String)formData.get(PROP_CM_DESCRIPTION); - assertEquals(modifiedDescription, retrievedValue); - String retrievedMimetype = (String)formData.get(PROP_MIMETYPE); - assertEquals(MimetypeMap.MIMETYPE_HTML, modifiedMimetype); - } - - /** - * This test method attempts to add new associations between existing nodes. - */ - public void testAddNewAssociationsToNode() throws Exception - { - List associatedNodes; - checkOriginalAssocsBeforeChanges(); - - // Add three additional associations - JSONObject jsonPostData = new JSONObject(); - String assocsToAdd = associatedDoc_C + "," + associatedDoc_D + "," + associatedDoc_E; - jsonPostData.put(ASSOC_CM_REFERENCES_ADDED, assocsToAdd); - String jsonPostString = jsonPostData.toString(); - - sendRequest(new PostRequest(referencingNodeUrl, jsonPostString, APPLICATION_JSON), 200); - - // Check the now updated associations via the node service - List modifiedAssocs = nodeService.getTargetAssocs(referencingDocNodeRef, RegexQNamePattern.MATCH_ALL); - assertEquals(5, modifiedAssocs.size()); - - // Extract the target nodeRefs to make them easier to examine - associatedNodes = new ArrayList(5); - for (AssociationRef assocRef : modifiedAssocs) - { - associatedNodes.add(assocRef.getTargetRef()); - } - - assertTrue(associatedNodes.contains(associatedDoc_A)); - assertTrue(associatedNodes.contains(associatedDoc_B)); - assertTrue(associatedNodes.contains(associatedDoc_C)); - assertTrue(associatedNodes.contains(associatedDoc_D)); - assertTrue(associatedNodes.contains(associatedDoc_E)); - - // The Rest API should also give us the modified assocs. - Response response = sendRequest(new GetRequest(referencingNodeUrl), 200); - String jsonRspString = response.getContentAsString(); - JSONObject jsonGetResponse = new JSONObject(jsonRspString); - JSONObject jsonData = (JSONObject)jsonGetResponse.get("data"); - assertNotNull(jsonData); - - JSONObject jsonFormData = (JSONObject)jsonData.get("formData"); - assertNotNull(jsonFormData); - - String jsonAssocs = (String)jsonFormData.get(ASSOC_CM_REFERENCES); - - // We expect exactly 5 assocs on the test node - assertEquals(5, jsonAssocs.split(",").length); - for (AssociationRef assocRef : modifiedAssocs) - { - assertTrue(jsonAssocs.contains(assocRef.getTargetRef().toString())); - } - } - - /** - * This test method attempts to remove an existing association between two existing - * nodes. - */ - public void testRemoveAssociationsFromNode() throws Exception - { - List associatedNodes; - checkOriginalAssocsBeforeChanges(); - - // Remove an association - JSONObject jsonPostData = new JSONObject(); - String assocsToRemove = associatedDoc_B.toString(); - jsonPostData.put(ASSOC_CM_REFERENCES_REMOVED, assocsToRemove); - String jsonPostString = jsonPostData.toString(); - - sendRequest(new PostRequest(referencingNodeUrl, jsonPostString, APPLICATION_JSON), 200); - - // Check the now updated associations via the node service - List modifiedAssocs = nodeService.getTargetAssocs(referencingDocNodeRef, RegexQNamePattern.MATCH_ALL); - assertEquals(1, modifiedAssocs.size()); - - // Extract the target nodeRefs to make them easier to examine - associatedNodes = new ArrayList(5); - for (AssociationRef assocRef : modifiedAssocs) - { - associatedNodes.add(assocRef.getTargetRef()); - } - - assertTrue(associatedNodes.contains(associatedDoc_A)); - - // The Rest API should also give us the modified assocs. - Response response = sendRequest(new GetRequest(referencingNodeUrl), 200); - String jsonRspString = response.getContentAsString(); - JSONObject jsonGetResponse = new JSONObject(jsonRspString); - JSONObject jsonData = (JSONObject)jsonGetResponse.get("data"); - assertNotNull(jsonData); - - JSONObject jsonFormData = (JSONObject)jsonData.get("formData"); - assertNotNull(jsonFormData); - - String jsonAssocs = (String)jsonFormData.get(ASSOC_CM_REFERENCES); - - // We expect exactly 1 assoc on the test node - assertEquals(1, jsonAssocs.split(",").length); - for (AssociationRef assocRef : modifiedAssocs) - { - assertTrue(jsonAssocs.contains(assocRef.getTargetRef().toString())); - } - } - - /** - * This test method attempts to add the same association twice. This attempt will - * not succeed, but the test case is to confirm that there is no exception thrown - * back across the REST API. - */ - public void testAddAssocThatAlreadyExists() throws Exception - { - checkOriginalAssocsBeforeChanges(); - - // Add an association - JSONObject jsonPostData = new JSONObject(); - String assocsToAdd = associatedDoc_C.toString(); - jsonPostData.put(ASSOC_CM_REFERENCES_ADDED, assocsToAdd); - String jsonPostString = jsonPostData.toString(); - - sendRequest(new PostRequest(referencingNodeUrl, jsonPostString, APPLICATION_JSON), 200); - - // Try to add the same association again - sendRequest(new PostRequest(referencingNodeUrl, jsonPostString, APPLICATION_JSON), 200); - } - - /** - * This test method attempts to remove an association that does not exist. This - * attempt will not succeed, but the test case is to confirm that there is no - * exception thrown back across the REST API. - */ - public void testRemoveAssocThatDoesNotExist() throws Exception - { - checkOriginalAssocsBeforeChanges(); - - // Remove a non-existent association - JSONObject jsonPostData = new JSONObject(); - String assocsToRemove = associatedDoc_E.toString(); - jsonPostData.put(ASSOC_CM_REFERENCES_REMOVED, assocsToRemove); - String jsonPostString = jsonPostData.toString(); - - sendRequest(new PostRequest(referencingNodeUrl, jsonPostString, APPLICATION_JSON), 200); - } - - /** - * This test method attempts to add new associations between existing nodes. - */ - public void testAddNewChildAssociationsToNode() throws Exception - { - List associatedNodes; - checkOriginalChildAssocsBeforeChanges(); - - // Add three additional associations - JSONObject jsonPostData = new JSONObject(); - String assocsToAdd = childDoc_C + "," + childDoc_D + "," + childDoc_E; - jsonPostData.put(ASSOC_SYS_CHILDREN_ADDED, assocsToAdd); - String jsonPostString = jsonPostData.toString(); - - sendRequest(new PostRequest(containingNodeUrl.toString(), jsonPostString, APPLICATION_JSON), 200); - - // Check the now updated child associations via the node service - List modifiedAssocs = nodeService.getChildAssocs(containerNodeRef); - assertEquals(5, modifiedAssocs.size()); - - // Extract the target nodeRefs to make them easier to examine - associatedNodes = new ArrayList(5); - for (ChildAssociationRef assocRef : modifiedAssocs) - { - associatedNodes.add(assocRef.getChildRef()); - } - - assertTrue(associatedNodes.contains(childDoc_A)); - assertTrue(associatedNodes.contains(childDoc_B)); - assertTrue(associatedNodes.contains(childDoc_C)); - assertTrue(associatedNodes.contains(childDoc_D)); - assertTrue(associatedNodes.contains(childDoc_E)); - - // The Rest API should also give us the modified assocs. - Response response = sendRequest(new GetRequest(containingNodeUrl), 200); - String jsonRspString = response.getContentAsString(); - - JSONObject jsonGetResponse = new JSONObject(jsonRspString); - JSONObject jsonData = (JSONObject)jsonGetResponse.get("data"); - assertNotNull(jsonData); - - JSONObject jsonFormData = (JSONObject)jsonData.get("formData"); - assertNotNull(jsonFormData); - - String jsonAssocs = (String)jsonFormData.get(ASSOC_SYS_CHILDREN); - - // We expect exactly 5 assocs on the test node - assertEquals(5, jsonAssocs.split(",").length); - for (ChildAssociationRef assocRef : modifiedAssocs) - { - String childNodeRef = assocRef.getChildRef().toString(); - assertTrue(jsonAssocs.contains(childNodeRef)); - assertTrue(NodeRef.isNodeRef(childNodeRef)); - } - } - - /** - * This test method attempts to remove an existing child association between two - * existing nodes. - */ - public void testRemoveChildAssociationsFromNode() throws Exception - { - List associatedNodes; - checkOriginalChildAssocsBeforeChanges(); - - // Remove an association - JSONObject jsonPostData = new JSONObject(); - String assocsToRemove = childDoc_B.toString(); - jsonPostData.put(ASSOC_SYS_CHILDREN_REMOVED, assocsToRemove); - String jsonPostString = jsonPostData.toString(); - - sendRequest(new PostRequest(containingNodeUrl, jsonPostString, APPLICATION_JSON), 200); - - // Check the now updated child associations via the node service - List modifiedAssocs = nodeService.getChildAssocs(containerNodeRef); - assertEquals(1, modifiedAssocs.size()); - - // Extract the target nodeRefs to make them easier to examine - associatedNodes = new ArrayList(5); - for (ChildAssociationRef assocRef : modifiedAssocs) - { - associatedNodes.add(assocRef.getChildRef()); - } - - assertTrue(associatedNodes.contains(childDoc_A)); - - // The Rest API should also give us the modified assocs. - Response response = sendRequest(new GetRequest(containingNodeUrl), 200); - String jsonRspString = response.getContentAsString(); - JSONObject jsonGetResponse = new JSONObject(jsonRspString); - JSONObject jsonData = (JSONObject)jsonGetResponse.get("data"); - assertNotNull(jsonData); - - JSONObject jsonFormData = (JSONObject)jsonData.get("formData"); - assertNotNull(jsonFormData); - - String jsonAssocs = (String)jsonFormData.get(ASSOC_SYS_CHILDREN); - - // We expect exactly 1 assoc on the test node - assertEquals(1, jsonAssocs.split(",").length); - for (ChildAssociationRef assocRef : modifiedAssocs) - { - assertTrue(jsonAssocs.contains(assocRef.getChildRef().toString())); - } - } - - /** - * This test method attempts to add the same child association twice. This attempt - * will not succeed, but the test case is to confirm that there is no exception thrown - * back across the REST API. - */ - public void testAddChildAssocThatAlreadyExists() throws Exception - { - checkOriginalChildAssocsBeforeChanges(); - - // Add an association - JSONObject jsonPostData = new JSONObject(); - String assocsToAdd = this.childDoc_C.toString(); - jsonPostData.put(ASSOC_SYS_CHILDREN_ADDED, assocsToAdd); - String jsonPostString = jsonPostData.toString(); - - sendRequest(new PostRequest(referencingNodeUrl, jsonPostString, APPLICATION_JSON), 200); - - // Try to add the same child association again - sendRequest(new PostRequest(referencingNodeUrl, jsonPostString, APPLICATION_JSON), 200); - } - - /** - * This test method attempts to remove a child association that does not exist. This - * attempt will not succeed, but the test case is to confirm that there is no - * exception thrown back across the REST API. - */ - public void testRemoveChildAssocThatDoesNotExist() throws Exception - { - checkOriginalChildAssocsBeforeChanges(); - - // Remove a non-existent child association - JSONObject jsonPostData = new JSONObject(); - String assocsToRemove = childDoc_E.toString(); - jsonPostData.put(ASSOC_SYS_CHILDREN_REMOVED, assocsToRemove); - String jsonPostString = jsonPostData.toString(); - - sendRequest(new PostRequest(referencingNodeUrl, jsonPostString, APPLICATION_JSON), 200); - } - - - private void checkOriginalAssocsBeforeChanges() - { - List originalAssocs = nodeService.getTargetAssocs(referencingDocNodeRef, RegexQNamePattern.MATCH_ALL); - assertEquals(2, originalAssocs.size()); - - List associatedNodes = new ArrayList(2); - associatedNodes.add(originalAssocs.get(0).getTargetRef()); - associatedNodes.add(originalAssocs.get(1).getTargetRef()); - - assertTrue(associatedNodes.contains(associatedDoc_A)); - assertTrue(associatedNodes.contains(associatedDoc_B)); - } - - private void checkOriginalChildAssocsBeforeChanges() - { - List originalChildAssocs = nodeService.getChildAssocs(containerNodeRef); - assertEquals(2, originalChildAssocs.size()); - - List associatedNodes = new ArrayList(2); - associatedNodes.add(originalChildAssocs.get(0).getChildRef()); - associatedNodes.add(originalChildAssocs.get(1).getChildRef()); - - assertTrue(associatedNodes.contains(childDoc_A)); - assertTrue(associatedNodes.contains(childDoc_B)); - } -} +/* + * Copyright (C) 2005-2009 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have received a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.web.scripts.forms; + +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.service.cmr.repository.AssociationRef; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.ContentData; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.web.scripts.TestWebScriptServer.PostRequest; +import org.alfresco.web.scripts.TestWebScriptServer.Response; +import org.json.JSONException; +import org.json.JSONObject; + +public class FormRestApiJsonPost_Test extends AbstractTestFormRestApi +{ + private static final String PROP_CM_DESCRIPTION = "prop_cm_description"; + private static final String PROP_MIMETYPE = "prop_mimetype"; + private static final String ASSOC_CM_REFERENCES = "assoc_cm_references"; + private static final String ASSOC_CM_REFERENCES_ADDED = "assoc_cm_references_added"; + private static final String ASSOC_CM_REFERENCES_REMOVED = "assoc_cm_references_removed"; + private static final String ASSOC_SYS_CHILDREN = "assoc_sys_children"; + private static final String ASSOC_SYS_CHILDREN_ADDED = "assoc_sys_children_added"; + private static final String ASSOC_SYS_CHILDREN_REMOVED = "assoc_sys_children_removed"; + + public void testSimpleJsonPostRequest() throws IOException, JSONException + { + // Retrieve and store the original property value. + Serializable originalDescription = + nodeService.getProperty(referencingDocNodeRef, ContentModel.PROP_DESCRIPTION); + assertEquals(TEST_FORM_DESCRIPTION, originalDescription); + + // get the original mimetype + String originalMimetype = null; + ContentData content = (ContentData)this.nodeService.getProperty(referencingDocNodeRef, ContentModel.PROP_CONTENT); + if (content != null) + { + originalMimetype = content.getMimetype(); + } + + // Construct some JSON to represent a new value. + JSONObject jsonPostData = new JSONObject(); + final String proposedNewDescription = "Modified Description"; + jsonPostData.put(PROP_CM_DESCRIPTION, proposedNewDescription); + jsonPostData.put(PROP_MIMETYPE, MimetypeMap.MIMETYPE_HTML); + + // Submit the JSON request. + String jsonPostString = jsonPostData.toString(); + Response ignoredRsp = sendRequest(new PostRequest(referencingNodeUpdateUrl, jsonPostString, + APPLICATION_JSON), 200); + + // The nodeService should give us the modified property. + Serializable modifiedDescription = + nodeService.getProperty(referencingDocNodeRef, ContentModel.PROP_DESCRIPTION); + assertEquals(proposedNewDescription, modifiedDescription); + + // get the modified mimetype + String modifiedMimetype = null; + content = (ContentData)this.nodeService.getProperty(referencingDocNodeRef, ContentModel.PROP_CONTENT); + if (content != null) + { + modifiedMimetype = content.getMimetype(); + } + assertEquals(MimetypeMap.MIMETYPE_HTML, modifiedMimetype); + + // The Rest API should also give us the modified property. + /* + Response response = sendRequest(new GetRequest(referencingNodeUpdateUrl), 200); + JSONObject jsonGetResponse = new JSONObject(response.getContentAsString()); + JSONObject jsonDataObj = (JSONObject)jsonGetResponse.get("data"); + assertNotNull(jsonDataObj); + + JSONObject formData = (JSONObject)jsonDataObj.get("formData"); + assertNotNull(formData); + String retrievedValue = (String)formData.get(PROP_CM_DESCRIPTION); + assertEquals(modifiedDescription, retrievedValue); + String retrievedMimetype = (String)formData.get(PROP_MIMETYPE); + assertEquals(MimetypeMap.MIMETYPE_HTML, modifiedMimetype);*/ + } + + /** + * This test method attempts to add new associations between existing nodes. + */ + public void testAddNewAssociationsToNode() throws Exception + { + List associatedNodes; + checkOriginalAssocsBeforeChanges(); + + // Add three additional associations + JSONObject jsonPostData = new JSONObject(); + String assocsToAdd = associatedDoc_C + "," + associatedDoc_D + "," + associatedDoc_E; + jsonPostData.put(ASSOC_CM_REFERENCES_ADDED, assocsToAdd); + String jsonPostString = jsonPostData.toString(); + + sendRequest(new PostRequest(referencingNodeUpdateUrl, jsonPostString, APPLICATION_JSON), 200); + + // Check the now updated associations via the node service + List modifiedAssocs = nodeService.getTargetAssocs(referencingDocNodeRef, RegexQNamePattern.MATCH_ALL); + assertEquals(5, modifiedAssocs.size()); + + // Extract the target nodeRefs to make them easier to examine + associatedNodes = new ArrayList(5); + for (AssociationRef assocRef : modifiedAssocs) + { + associatedNodes.add(assocRef.getTargetRef()); + } + + assertTrue(associatedNodes.contains(associatedDoc_A)); + assertTrue(associatedNodes.contains(associatedDoc_B)); + assertTrue(associatedNodes.contains(associatedDoc_C)); + assertTrue(associatedNodes.contains(associatedDoc_D)); + assertTrue(associatedNodes.contains(associatedDoc_E)); + + // The Rest API should also give us the modified assocs. + /*Response response = sendRequest(new GetRequest(referencingNodeUpdateUrl), 200); + String jsonRspString = response.getContentAsString(); + JSONObject jsonGetResponse = new JSONObject(jsonRspString); + JSONObject jsonData = (JSONObject)jsonGetResponse.get("data"); + assertNotNull(jsonData); + + JSONObject jsonFormData = (JSONObject)jsonData.get("formData"); + assertNotNull(jsonFormData); + + String jsonAssocs = (String)jsonFormData.get(ASSOC_CM_REFERENCES); + + // We expect exactly 5 assocs on the test node + assertEquals(5, jsonAssocs.split(",").length); + for (AssociationRef assocRef : modifiedAssocs) + { + assertTrue(jsonAssocs.contains(assocRef.getTargetRef().toString())); + }*/ + } + + /** + * This test method attempts to remove an existing association between two existing + * nodes. + */ + public void testRemoveAssociationsFromNode() throws Exception + { + List associatedNodes; + checkOriginalAssocsBeforeChanges(); + + // Remove an association + JSONObject jsonPostData = new JSONObject(); + String assocsToRemove = associatedDoc_B.toString(); + jsonPostData.put(ASSOC_CM_REFERENCES_REMOVED, assocsToRemove); + String jsonPostString = jsonPostData.toString(); + + sendRequest(new PostRequest(referencingNodeUpdateUrl, jsonPostString, APPLICATION_JSON), 200); + + // Check the now updated associations via the node service + List modifiedAssocs = nodeService.getTargetAssocs(referencingDocNodeRef, RegexQNamePattern.MATCH_ALL); + assertEquals(1, modifiedAssocs.size()); + + // Extract the target nodeRefs to make them easier to examine + associatedNodes = new ArrayList(5); + for (AssociationRef assocRef : modifiedAssocs) + { + associatedNodes.add(assocRef.getTargetRef()); + } + + assertTrue(associatedNodes.contains(associatedDoc_A)); + + // The Rest API should also give us the modified assocs. + /*Response response = sendRequest(new GetRequest(referencingNodeUpdateUrl), 200); + String jsonRspString = response.getContentAsString(); + JSONObject jsonGetResponse = new JSONObject(jsonRspString); + JSONObject jsonData = (JSONObject)jsonGetResponse.get("data"); + assertNotNull(jsonData); + + JSONObject jsonFormData = (JSONObject)jsonData.get("formData"); + assertNotNull(jsonFormData); + + String jsonAssocs = (String)jsonFormData.get(ASSOC_CM_REFERENCES); + + // We expect exactly 1 assoc on the test node + assertEquals(1, jsonAssocs.split(",").length); + for (AssociationRef assocRef : modifiedAssocs) + { + assertTrue(jsonAssocs.contains(assocRef.getTargetRef().toString())); + }*/ + } + + /** + * This test method attempts to add the same association twice. This attempt will + * not succeed, but the test case is to confirm that there is no exception thrown + * back across the REST API. + */ + public void testAddAssocThatAlreadyExists() throws Exception + { + checkOriginalAssocsBeforeChanges(); + + // Add an association + JSONObject jsonPostData = new JSONObject(); + String assocsToAdd = associatedDoc_C.toString(); + jsonPostData.put(ASSOC_CM_REFERENCES_ADDED, assocsToAdd); + String jsonPostString = jsonPostData.toString(); + + sendRequest(new PostRequest(referencingNodeUpdateUrl, jsonPostString, APPLICATION_JSON), 200); + + // Try to add the same association again + sendRequest(new PostRequest(referencingNodeUpdateUrl, jsonPostString, APPLICATION_JSON), 200); + } + + /** + * This test method attempts to remove an association that does not exist. This + * attempt will not succeed, but the test case is to confirm that there is no + * exception thrown back across the REST API. + */ + public void testRemoveAssocThatDoesNotExist() throws Exception + { + checkOriginalAssocsBeforeChanges(); + + // Remove a non-existent association + JSONObject jsonPostData = new JSONObject(); + String assocsToRemove = associatedDoc_E.toString(); + jsonPostData.put(ASSOC_CM_REFERENCES_REMOVED, assocsToRemove); + String jsonPostString = jsonPostData.toString(); + + sendRequest(new PostRequest(referencingNodeUpdateUrl, jsonPostString, APPLICATION_JSON), 200); + } + + /** + * This test method attempts to add new associations between existing nodes. + */ + public void testAddNewChildAssociationsToNode() throws Exception + { + List associatedNodes; + checkOriginalChildAssocsBeforeChanges(); + + // Add three additional associations + JSONObject jsonPostData = new JSONObject(); + String assocsToAdd = childDoc_C + "," + childDoc_D + "," + childDoc_E; + jsonPostData.put(ASSOC_SYS_CHILDREN_ADDED, assocsToAdd); + String jsonPostString = jsonPostData.toString(); + + sendRequest(new PostRequest(containingNodeUpdateUrl.toString(), jsonPostString, APPLICATION_JSON), 200); + + // Check the now updated child associations via the node service + List modifiedAssocs = nodeService.getChildAssocs(containerNodeRef); + assertEquals(5, modifiedAssocs.size()); + + // Extract the target nodeRefs to make them easier to examine + associatedNodes = new ArrayList(5); + for (ChildAssociationRef assocRef : modifiedAssocs) + { + associatedNodes.add(assocRef.getChildRef()); + } + + assertTrue(associatedNodes.contains(childDoc_A)); + assertTrue(associatedNodes.contains(childDoc_B)); + assertTrue(associatedNodes.contains(childDoc_C)); + assertTrue(associatedNodes.contains(childDoc_D)); + assertTrue(associatedNodes.contains(childDoc_E)); + + // The Rest API should also give us the modified assocs. + /*Response response = sendRequest(new GetRequest(containingNodeUpdateUrl), 200); + String jsonRspString = response.getContentAsString(); + + JSONObject jsonGetResponse = new JSONObject(jsonRspString); + JSONObject jsonData = (JSONObject)jsonGetResponse.get("data"); + assertNotNull(jsonData); + + JSONObject jsonFormData = (JSONObject)jsonData.get("formData"); + assertNotNull(jsonFormData); + + String jsonAssocs = (String)jsonFormData.get(ASSOC_SYS_CHILDREN); + + // We expect exactly 5 assocs on the test node + assertEquals(5, jsonAssocs.split(",").length); + for (ChildAssociationRef assocRef : modifiedAssocs) + { + String childNodeRef = assocRef.getChildRef().toString(); + assertTrue(jsonAssocs.contains(childNodeRef)); + assertTrue(NodeRef.isNodeRef(childNodeRef)); + }*/ + } + + /** + * This test method attempts to remove an existing child association between two + * existing nodes. + */ + public void testRemoveChildAssociationsFromNode() throws Exception + { + List associatedNodes; + checkOriginalChildAssocsBeforeChanges(); + + // Remove an association + JSONObject jsonPostData = new JSONObject(); + String assocsToRemove = childDoc_B.toString(); + jsonPostData.put(ASSOC_SYS_CHILDREN_REMOVED, assocsToRemove); + String jsonPostString = jsonPostData.toString(); + + sendRequest(new PostRequest(containingNodeUpdateUrl, jsonPostString, APPLICATION_JSON), 200); + + // Check the now updated child associations via the node service + List modifiedAssocs = nodeService.getChildAssocs(containerNodeRef); + assertEquals(1, modifiedAssocs.size()); + + // Extract the target nodeRefs to make them easier to examine + associatedNodes = new ArrayList(5); + for (ChildAssociationRef assocRef : modifiedAssocs) + { + associatedNodes.add(assocRef.getChildRef()); + } + + assertTrue(associatedNodes.contains(childDoc_A)); + + // The Rest API should also give us the modified assocs. + /*Response response = sendRequest(new GetRequest(containingNodeUpdateUrl), 200); + String jsonRspString = response.getContentAsString(); + JSONObject jsonGetResponse = new JSONObject(jsonRspString); + JSONObject jsonData = (JSONObject)jsonGetResponse.get("data"); + assertNotNull(jsonData); + + JSONObject jsonFormData = (JSONObject)jsonData.get("formData"); + assertNotNull(jsonFormData); + + String jsonAssocs = (String)jsonFormData.get(ASSOC_SYS_CHILDREN); + + // We expect exactly 1 assoc on the test node + assertEquals(1, jsonAssocs.split(",").length); + for (ChildAssociationRef assocRef : modifiedAssocs) + { + assertTrue(jsonAssocs.contains(assocRef.getChildRef().toString())); + }*/ + } + + /** + * This test method attempts to add the same child association twice. This attempt + * will not succeed, but the test case is to confirm that there is no exception thrown + * back across the REST API. + */ + public void testAddChildAssocThatAlreadyExists() throws Exception + { + checkOriginalChildAssocsBeforeChanges(); + + // Add an association + JSONObject jsonPostData = new JSONObject(); + String assocsToAdd = this.childDoc_C.toString(); + jsonPostData.put(ASSOC_SYS_CHILDREN_ADDED, assocsToAdd); + String jsonPostString = jsonPostData.toString(); + + sendRequest(new PostRequest(referencingNodeUpdateUrl, jsonPostString, APPLICATION_JSON), 200); + + // Try to add the same child association again + sendRequest(new PostRequest(referencingNodeUpdateUrl, jsonPostString, APPLICATION_JSON), 200); + } + + /** + * This test method attempts to remove a child association that does not exist. This + * attempt will not succeed, but the test case is to confirm that there is no + * exception thrown back across the REST API. + */ + public void testRemoveChildAssocThatDoesNotExist() throws Exception + { + checkOriginalChildAssocsBeforeChanges(); + + // Remove a non-existent child association + JSONObject jsonPostData = new JSONObject(); + String assocsToRemove = childDoc_E.toString(); + jsonPostData.put(ASSOC_SYS_CHILDREN_REMOVED, assocsToRemove); + String jsonPostString = jsonPostData.toString(); + + sendRequest(new PostRequest(referencingNodeUpdateUrl, jsonPostString, APPLICATION_JSON), 200); + } + + + private void checkOriginalAssocsBeforeChanges() + { + List originalAssocs = nodeService.getTargetAssocs(referencingDocNodeRef, RegexQNamePattern.MATCH_ALL); + assertEquals(2, originalAssocs.size()); + + List associatedNodes = new ArrayList(2); + associatedNodes.add(originalAssocs.get(0).getTargetRef()); + associatedNodes.add(originalAssocs.get(1).getTargetRef()); + + assertTrue(associatedNodes.contains(associatedDoc_A)); + assertTrue(associatedNodes.contains(associatedDoc_B)); + } + + private void checkOriginalChildAssocsBeforeChanges() + { + List originalChildAssocs = nodeService.getChildAssocs(containerNodeRef); + assertEquals(2, originalChildAssocs.size()); + + List associatedNodes = new ArrayList(2); + associatedNodes.add(originalChildAssocs.get(0).getChildRef()); + associatedNodes.add(originalChildAssocs.get(1).getChildRef()); + + assertTrue(associatedNodes.contains(childDoc_A)); + assertTrue(associatedNodes.contains(childDoc_B)); + } +}