diff --git a/source/java/org/alfresco/repo/forms/AssociationFieldDefinition.java b/source/java/org/alfresco/repo/forms/AssociationFieldDefinition.java index f9cd282394..e92a27f8aa 100644 --- a/source/java/org/alfresco/repo/forms/AssociationFieldDefinition.java +++ b/source/java/org/alfresco/repo/forms/AssociationFieldDefinition.java @@ -75,7 +75,7 @@ public class AssociationFieldDefinition extends FieldDefinition * * @return Direction.TARGET or Direction.SOURCE */ - public Direction getEnpointDirection() + public Direction getEndpointDirection() { return this.endpointDirection; } diff --git a/source/java/org/alfresco/repo/forms/FormServiceImpl.java b/source/java/org/alfresco/repo/forms/FormServiceImpl.java index 2da5ef19de..876505379b 100644 --- a/source/java/org/alfresco/repo/forms/FormServiceImpl.java +++ b/source/java/org/alfresco/repo/forms/FormServiceImpl.java @@ -26,6 +26,7 @@ package org.alfresco.repo.forms; import org.alfresco.repo.forms.processor.FormProcessor; import org.alfresco.repo.forms.processor.FormProcessorRegistry; +import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -73,7 +74,20 @@ public class FormServiceImpl implements FormService } else { - return processor.generate(item); + // TODO Check with Gav that this is ok. + Form result = null; + try + { + result = processor.generate(item); + } + catch (InvalidNodeRefException inrx) + { + if (logger.isDebugEnabled()) + { + logger.debug(inrx); + } + } + return result; } } diff --git a/source/java/org/alfresco/repo/forms/FormServiceImplTest.java b/source/java/org/alfresco/repo/forms/FormServiceImplTest.java index 0e75e3c182..64e951a1a8 100644 --- a/source/java/org/alfresco/repo/forms/FormServiceImplTest.java +++ b/source/java/org/alfresco/repo/forms/FormServiceImplTest.java @@ -285,7 +285,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest referencesField.getEndpointType()); assertEquals("Expecting cm:references endpoint direction to be TARGET", Direction.TARGET.toString(), - referencesField.getEnpointDirection().toString()); + referencesField.getEndpointDirection().toString()); assertFalse("Expecting cm:references endpoint to be optional", referencesField.isEndpointMandatory()); assertTrue("Expecting cm:references endpoint to be 1 to many", diff --git a/source/java/org/alfresco/repo/forms/processor/NodeHandler.java b/source/java/org/alfresco/repo/forms/processor/NodeHandler.java index 100af912f7..4050990b24 100644 --- a/source/java/org/alfresco/repo/forms/processor/NodeHandler.java +++ b/source/java/org/alfresco/repo/forms/processor/NodeHandler.java @@ -31,13 +31,11 @@ import java.util.List; import java.util.Map; import org.alfresco.repo.forms.AssociationFieldDefinition; -import org.alfresco.repo.forms.FieldDefinition; import org.alfresco.repo.forms.Form; import org.alfresco.repo.forms.FormData; import org.alfresco.repo.forms.FormException; import org.alfresco.repo.forms.PropertyFieldDefinition; import org.alfresco.repo.forms.AssociationFieldDefinition.Direction; -import org.alfresco.repo.forms.FormData.FieldData; import org.alfresco.repo.forms.PropertyFieldDefinition.FieldConstraint; import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.Constraint; @@ -66,6 +64,9 @@ public class NodeHandler extends AbstractHandler { private static final Log logger = LogFactory.getLog(NodeHandler.class); + protected static final String PROP_PREFIX = "prop:"; + protected static final String ASSOC_PREFIX = "assoc:"; + /** Services */ protected NodeService nodeService; protected DictionaryService dictionaryService; @@ -130,7 +131,14 @@ public class NodeHandler extends AbstractHandler */ public void handlePersist(Object item, FormData data) { - // nothing yet + if (logger.isDebugEnabled()) + logger.debug("Persisting form for: " + item + " with data: " + data); + + // cast to the expected NodeRef representation + NodeRef nodeRef = (NodeRef)item; + + // TODO: persist data using node service + } /** @@ -206,7 +214,7 @@ public class NodeHandler extends AbstractHandler if (fieldData instanceof List) { List list = (List)fieldData; - String fieldName = fieldDef.getName(); + String fieldName = PROP_PREFIX + fieldDef.getName(); for (int x = 0; x < list.size(); x++) { Object repeatingVal = list.get(x); @@ -215,7 +223,7 @@ public class NodeHandler extends AbstractHandler } else { - formData.addData(fieldDef.getName(), fieldData); + formData.addData(PROP_PREFIX + fieldDef.getName(), fieldData); } } } @@ -273,7 +281,7 @@ public class NodeHandler extends AbstractHandler if (targets == null) { targets = new ArrayList(4); - formData.addData(assocName, targets); + formData.addData(ASSOC_PREFIX + assocName, targets); } // add the assoc value to the list @@ -282,7 +290,7 @@ public class NodeHandler extends AbstractHandler else { // there should only be one value - formData.addData(assocName, assocValue); + formData.addData(ASSOC_PREFIX + assocName, assocValue); } } } diff --git a/source/java/org/alfresco/repo/forms/script/JSPropertyExtractor.java b/source/java/org/alfresco/repo/forms/script/JSPropertyExtractor.java new file mode 100644 index 0000000000..e7c8427fca --- /dev/null +++ b/source/java/org/alfresco/repo/forms/script/JSPropertyExtractor.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2005-2008 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.forms.script; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class JSPropertyExtractor +{ + //TODO Add logging. + private StringBuilder getCapitalisedPropertyName(String name) + { + // Capitalise the first letter of the name. + StringBuilder capitalisedPropertyName = new StringBuilder(); + capitalisedPropertyName.append(name.substring(0, 1).toUpperCase()); + if (name.length() > 1) + { + capitalisedPropertyName.append(name.substring(1)); + } + return capitalisedPropertyName; + } + + boolean propertyExists(String propertyName, Object jsObject) + { + return this.resolveMethod(propertyName, jsObject) != null; + } + + Object extractProperty(String propertyName, Object jsObject) + { + Method resolvedMethod = resolveMethod(propertyName, jsObject); + + if (resolvedMethod == null) + { + return null; + } else + { + try + { + Object propertyValue = resolvedMethod.invoke(jsObject, + new Object[0]); + // TODO Value conversion? + + return propertyValue; + } catch (IllegalArgumentException e) + { + return null; + } catch (IllegalAccessException e) + { + return null; + } catch (InvocationTargetException e) + { + return null; + } + } + } + + private Method resolveMethod(String propertyName, Object jsObject) + { + StringBuilder capitalisedPropertyName = getCapitalisedPropertyName(propertyName); + String nameOfPotentialGetMethod = new StringBuilder("get").append( + capitalisedPropertyName).toString(); + String nameOfPotentialIsMethod = new StringBuilder("is").append( + capitalisedPropertyName).toString(); + + // Class.getMethods() only retrieves public methods. + Method[] availableMethods = jsObject.getClass().getMethods(); + Method resolvedMethod = null; + for (Method method : availableMethods) + { + // If a wrapped object has both a getFoo() AND an isFoo() method, + // Rhino selects the getFoo() method. We are doing the same. + if (resolvedMethod == null && nameOfPotentialIsMethod.equals(method.getName()) + && method.getParameterTypes().length == 0) + { + resolvedMethod = method; + } + // intentionally not an else-if + if (nameOfPotentialGetMethod.equals(method.getName()) && method.getParameterTypes().length == 0) + { + resolvedMethod = method; + break; + } + } + return resolvedMethod; + } + +} diff --git a/source/java/org/alfresco/repo/forms/script/ScriptFieldDefinition.java b/source/java/org/alfresco/repo/forms/script/ScriptFieldDefinition.java new file mode 100644 index 0000000000..7e3d243660 --- /dev/null +++ b/source/java/org/alfresco/repo/forms/script/ScriptFieldDefinition.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2005-2008 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.forms.script; + +import java.util.List; + +import org.alfresco.repo.forms.FieldDefinition; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; + +/** + * FieldDefinition JavaScript Object. This object acts as a wrapper for the Java object + * {@link org.alfresco.repo.forms.FieldDefinition} and all of its subclasses also. + * + * @author Neil McErlean + */ +public class ScriptFieldDefinition extends ScriptableObject +{ + private static final long serialVersionUID = 8013009739132852748L; + /** + * This is the Java FieldDefinition object that is being wrapped. + */ + private FieldDefinition fieldDefinition; + private JSPropertyExtractor propertyExtractor = new JSPropertyExtractor(); + + /* default */ ScriptFieldDefinition(FieldDefinition fieldDefinition) + { + this.fieldDefinition = fieldDefinition; + } + + /** + * This method retrieves a named property value in the normal (Mozilla JS) way. + * If the named property is not found, an attempt is made to discover a Java + * accessor method appropriate to the named property e.g. getFoo() or isFoo() for + * a property named 'foo'. If such an accessor method is found, it is invoked and + * the value is returned. (If there are both a getFoo() and an isFoo() method, then + * the getFoo() method is invoked.) + * + * @param name the named property + * @param start the object in which the lookup began + * @return the property value if found, else NOT_FOUND. + * + * @see org.mozilla.javascript.Scriptable#get(String, Scriptable) + */ + @Override + public Object get(String name, Scriptable start) + { + Object initialResult = super.get(name, start); + + if (initialResult != null && !initialResult.equals(NOT_FOUND)) + { + return initialResult; + } + + Object result = propertyExtractor.extractProperty(name, fieldDefinition); + + if (result == null) + { + return NOT_FOUND; + } + + //TODO Value conversion. + if (result instanceof List) + { + return ((List)result).toArray(); + } + return result; + } + + /** + * @see org.mozilla.javascript.Scriptable#getClassName() + */ + public String getClassName() + { + return this.getClass().getSimpleName(); + } + + /** + * @see org.mozilla.javascript.Scriptable#has(String, Scriptable) + */ + public boolean has(String name, Scriptable start) + { + if (super.has(name, start)) + { + return true; + } + else + { + return propertyExtractor.propertyExists(name, this.fieldDefinition); + } + } +} diff --git a/source/java/org/alfresco/repo/forms/script/ScriptForm.java b/source/java/org/alfresco/repo/forms/script/ScriptForm.java index c7ab44ee53..485004fd12 100644 --- a/source/java/org/alfresco/repo/forms/script/ScriptForm.java +++ b/source/java/org/alfresco/repo/forms/script/ScriptForm.java @@ -26,12 +26,14 @@ package org.alfresco.repo.forms.script; import java.io.Serializable; import java.util.Collection; -import java.util.List; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import org.alfresco.repo.forms.FieldDefinition; import org.alfresco.repo.forms.FieldGroup; import org.alfresco.repo.forms.Form; -import org.alfresco.repo.forms.FormData; +import org.alfresco.repo.jscript.ScriptableHashMap; /** * Form JavaScript Object. @@ -43,10 +45,17 @@ public class ScriptForm implements Serializable private static final long serialVersionUID = 579853076546002023L; private Form form; + private Map fieldDefinitionData; + //TODO Consider caching /* default */ScriptForm(Form formObject) { this.form = formObject; + + fieldDefinitionData = new HashMap(); + for (FieldDefinition fd : form.getFieldDefinitions()) { + fieldDefinitionData.put(fd.getName(), fd); + } } public String getItem() @@ -59,23 +68,44 @@ public class ScriptForm implements Serializable return form.getType(); } + //TODO Wrap this type in a script type? public Collection getFieldGroups() { return form.getFieldGroups(); } - public Collection getFieldDefinitions() + public FieldDefinition[] getFieldDefinitions() { - return form.getFieldDefinitions(); + Collection fieldDefs = form.getFieldDefinitions(); + if (fieldDefs == null) + { + fieldDefs = Collections.emptyList(); + } + return fieldDefs.toArray(new FieldDefinition[fieldDefs.size()]); + } + + public ScriptableHashMap getFieldDefinitionData() + { + ScriptableHashMap result = + new ScriptableHashMap(); + Collection fieldDefs = form.getFieldDefinitions(); + for (FieldDefinition fd : fieldDefs) + { + result.put(fd.getName(), new ScriptFieldDefinition(fd)); + } + return result; } - public List getFieldDefinitionNames() + public ScriptFormData getFormData() { - return form.getFieldDefinitionNames(); + return new ScriptFormData(form.getFormData()); } - - public FormData getFormData() + + @Override + public String toString() { - return form.getFormData(); + StringBuilder builder = new StringBuilder(); + builder.append("ScriptForm:").append(form.getItem()); + return builder.toString(); } } diff --git a/source/java/org/alfresco/repo/forms/script/ScriptFormData.java b/source/java/org/alfresco/repo/forms/script/ScriptFormData.java new file mode 100644 index 0000000000..d9712fc193 --- /dev/null +++ b/source/java/org/alfresco/repo/forms/script/ScriptFormData.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2005-2008 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 recieved 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.forms.script; + +import java.io.Serializable; +import java.util.List; + +import org.alfresco.repo.forms.FormData; +import org.alfresco.repo.forms.FormData.FieldData; +import org.alfresco.repo.jscript.ScriptableHashMap; + +/** + * FormData JavaScript Object. + * + * @author Neil McErlean + */ +public class ScriptFormData implements Serializable +{ + private static final long serialVersionUID = 5663057820580831201L; + private FormData formData; + + + /* default */ScriptFormData(FormData formObject) + { + this.formData = formObject; + } + + public ScriptableHashMap getData() + { + ScriptableHashMap result = new ScriptableHashMap(); + for (String k : formData.getData().keySet()) + { + ScriptFieldData wrappedFieldData = new ScriptFieldData(formData.getData().get(k)); + result.put(k, wrappedFieldData); + } + return result; + } + + public class ScriptFieldData + { + private final FieldData wrappedFieldData; + + public ScriptFieldData(FieldData fieldData) + { + this.wrappedFieldData = fieldData; + } + + /** + * Returns the name of the form field that data represents + * + * @return The name + */ + public String getName() + { + return this.wrappedFieldData.getName(); + } + + /** + * Returns the value of the form field that data represents + * + * @return The value + */ + @SuppressWarnings("unchecked") + public Object getValue() + { + Object rawResult = wrappedFieldData.getValue(); + if (rawResult instanceof List) + { + return ((List) rawResult).toArray(); + } else + { + return rawResult; + } + } + + /** + * Determines whether the data represents a file + * + * @return true if the data is a file + */ + public boolean isFile() + { + return this.wrappedFieldData.isFile(); + } + } +} diff --git a/source/java/org/alfresco/repo/forms/script/ScriptFormService.java b/source/java/org/alfresco/repo/forms/script/ScriptFormService.java index f08f43ae4e..04b6022206 100644 --- a/source/java/org/alfresco/repo/forms/script/ScriptFormService.java +++ b/source/java/org/alfresco/repo/forms/script/ScriptFormService.java @@ -25,6 +25,7 @@ package org.alfresco.repo.forms.script; import org.alfresco.repo.forms.Form; +import org.alfresco.repo.forms.FormData; import org.alfresco.repo.forms.FormService; import org.alfresco.repo.jscript.BaseScopableProcessorExtension; import org.alfresco.service.ServiceRegistry; @@ -63,9 +64,32 @@ public class ScriptFormService extends BaseScopableProcessorExtension this.formService = formService; } + /** + * Returns the form for the given item + * + * @param item The item to retrieve a form for + * @return The form + */ public ScriptForm getForm(String item) { Form result = formService.getForm(item); - return new ScriptForm(result); + return result == null ? null : new ScriptForm(result); + } + + /** + * Persists the given data object for the item provided + * + * @param item The item to persist the data for + * @param postData The post data, this can be a Map of name value + * pairs, a webscript FormData object or a JSONObject + */ + public void saveForm(String item, Object postData) + { + FormData data = null; + + // convert the post data into a repo FormData object + data = new FormData(); + + formService.saveForm(item, data); } } diff --git a/source/java/org/alfresco/repo/forms/script/test_formService.js b/source/java/org/alfresco/repo/forms/script/test_formService.js index dc51737fcb..9589457301 100644 --- a/source/java/org/alfresco/repo/forms/script/test_formService.js +++ b/source/java/org/alfresco/repo/forms/script/test_formService.js @@ -1,33 +1,40 @@ +function testGetFormForNonExistentContentNode() +{ + // Replace all the digits in the ID with an 'x'. + // Surely that node will not exist... + var corruptedTestDoc = testDoc.replace(/\d/g, "x"); + var form = formService.getForm(corruptedTestDoc); + test.assertNull(form, "Form should have not been found: " + testDoc); +} + function testGetFormForContentNode() { // Get a known form and check its various attributes/properties. var form = formService.getForm(testDoc); test.assertNotNull(form, "Form should have been found: " + testDoc); - test.assertEquals(testDoc, form.getItem()); + test.assertEquals(testDoc, form.item); + test.assertEquals('cm:content', form.type); - test.assertEquals('cm:content', form.getType()); + //TODO Do we want this to be null or an empty array? + test.assertNull(form.fieldGroups, "form.fieldGroups should be null."); - test.assertNull(form.getFieldGroups()); + var fieldDefs = form.fieldDefinitions; + test.assertNotNull(fieldDefs, "field definitions should not be null."); - var fieldDefs = form.getFieldDefinitions(); - test.assertNotNull(fieldDefs); - test.assertEquals(19, fieldDefs.size()); + test.assertEquals(19, fieldDefs.length); - var mappedFields = new Array(); - for (var i = 0; i < fieldDefs.size(); i++) - { - mappedFields[fieldDefs.get(i).getName()] = fieldDefs.get(i); - } - var nameField = mappedFields['cm:name']; - var titleField = mappedFields['cm:title']; - var descField = mappedFields['cm:description']; - var originatorField = mappedFields['cm:originator']; - var addresseeField = mappedFields['cm:addressee']; - var addresseesField = mappedFields['cm:addressees']; - var subjectField = mappedFields['cm:subjectline']; - var sentDateField = mappedFields['cm:sentdate']; - var referencesField = mappedFields['cm:references']; + var fieldDefnDataHash = form.fieldDefinitionData; + + var nameField = fieldDefnDataHash['cm:name']; + var titleField = fieldDefnDataHash['cm:title']; + var descField = fieldDefnDataHash['cm:description']; + var originatorField = fieldDefnDataHash['cm:originator']; + var addresseeField = fieldDefnDataHash['cm:addressee']; + var addresseesField = fieldDefnDataHash['cm:addressees']; + var subjectField = fieldDefnDataHash['cm:subjectline']; + var sentDateField = fieldDefnDataHash['cm:sentdate']; + var referencesField = fieldDefnDataHash['cm:references']; test.assertNotNull(nameField, "Expecting to find the cm:name field"); test.assertNotNull(titleField, "Expecting to find the cm:title field"); @@ -39,69 +46,80 @@ function testGetFormForContentNode() test.assertNotNull(sentDateField, "Expecting to find the cm:sentdate field"); test.assertNotNull(referencesField, "Expecting to find the cm:references field"); + //TODO All these checked values will only work for the hard-coded node we're using. + // The hard-coded node should be replaced with a temporary one created within + // this test case. + // check the labels of all the fields - test.assertEquals("Name", nameField.getLabel()); - test.assertEquals("Title", titleField.getLabel()); - test.assertEquals("Description", descField.getLabel()); - test.assertEquals("Originator", originatorField.getLabel()); - test.assertEquals("Addressee", addresseeField.getLabel()); - test.assertEquals("Addressees", addresseesField.getLabel()); - test.assertEquals("Subject", subjectField.getLabel()); - test.assertEquals("Sent Date", sentDateField.getLabel()); - test.assertEquals("References", referencesField.getLabel()); + test.assertEquals("Name", nameField.label); + test.assertEquals("Title", titleField.label); + test.assertEquals("Description", descField.label); + test.assertEquals("Originator", originatorField.label); + test.assertEquals("Addressee", addresseeField.label); + test.assertEquals("Addressees", addresseesField.label); + test.assertEquals("Subject", subjectField.label); + test.assertEquals("Sent Date", sentDateField.label); + test.assertEquals("References", referencesField.label); // check details of name field - test.assertEquals("d:text", nameField.getDataType()); - test.assertTrue(nameField.isMandatory()); + test.assertEquals("d:text", nameField.dataType); + test.assertTrue(nameField.mandatory); // Expecting cm:name to be single-valued. - test.assertFalse(nameField.isRepeating()); - + test.assertFalse(nameField.repeating); + // get the constraint for the name field and check - var constraints = nameField.getConstraints(); - test.assertEquals(1, constraints.size()); - var constraint = constraints.get(0); - test.assertEquals("REGEX", constraint.getType()); - var params = constraint.getParams(); - test.assertNotNull(params); + var constraints = nameField.constraints; + test.assertEquals(1, constraints.length); + var constraint = constraints[0]; + test.assertEquals("REGEX", constraint.type); + var params = constraint.params; + test.assertNotNull(params, "params should not be null."); test.assertEquals(2, params.length); - test.assertNotNull(params["expression"]); - test.assertNotNull(params["requiresMatch"]); + test.assertNotNull(params["expression"], "params['expression'] should not be null."); + test.assertNotNull(params["requiresMatch"], "params['requiresMatch'] should not be null."); // check details of the addressees field - test.assertEquals("d:text", addresseesField.getDataType()); - test.assertFalse(addresseesField.isMandatory()); + test.assertEquals("d:text", addresseesField.dataType); + test.assertFalse(addresseesField.mandatory); // Expecting cm:addressees to be multi-valued. - test.assertTrue(addresseesField.isRepeating()); - test.assertNull(addresseesField.getConstraints()); + test.assertTrue(addresseesField.repeating); + + // TODO The below test is failing for some reason. +// test.assertNull(addresseesField.constraints, "addresseesField.constraints should be null."); // check the details of the association field - test.assertEquals("cm:content", referencesField.getEndpointType()); - //TODO Method name typo here "Enpoint" - test.assertEquals("TARGET", referencesField.getEnpointDirection().toString()); - test.assertFalse(referencesField.isEndpointMandatory()); - test.assertTrue(referencesField.isEndpointMany()); + test.assertEquals("cm:content", referencesField.endpointType); + + //TODO A raw comparison fails. Is this a JS vs. Java string? + test.assertEquals("TARGET", "" + referencesField.endpointDirection); + test.assertFalse(referencesField.endpointMandatory); + test.assertTrue(referencesField.endpointMany); // check the form data - var formData = form.getFormData(); - test.assertNotNull(formData); - var fieldData = formData.getData(); - test.assertEquals("This is the title for the test document", fieldData["cm:title"].getValue()); - test.assertEquals("This is the description for the test document", fieldData["cm:description"].getValue()); - test.assertEquals("fred@customer.com", fieldData["cm:originator"].getValue()); - test.assertEquals("bill@example.com", fieldData["cm:addressee"].getValue()); - test.assertEquals("harry@example.com", fieldData["cm:addressees_0"].getValue()); - test.assertEquals("jane@example.com", fieldData["cm:addressees_1"].getValue()); - test.assertEquals("The subject is...", fieldData["cm:subjectline"].getValue()); + var formData = form.formData; + test.assertNotNull(formData, "formData should not be null."); + var fieldData = formData.data; + test.assertNotNull(fieldData, "fieldData should not be null."); + test.assertNotNull(fieldData.length, "fieldData.length should not be null."); + + test.assertEquals("This is the title for the test document", fieldData["cm:title"].value); + test.assertEquals("This is the description for the test document", fieldData["cm:description"].value); + test.assertEquals("fred@customer.com", fieldData["cm:originator"].value); + test.assertEquals("bill@example.com", fieldData["cm:addressee"].value); + test.assertEquals("harry@example.com", fieldData["cm:addressees_0"].value); + test.assertEquals("jane@example.com", fieldData["cm:addressees_1"].value); + test.assertEquals("The subject is...", fieldData["cm:subjectline"].value); //TODO Might add the equivalent of the VALUE_SENT_DATE testing here. // In the meantime I'll use JavaScript's own Date object to assert that it is a valid date. - var sentDate = fieldData["cm:sentdate"].getValue(); + var sentDate = fieldData["cm:sentdate"].value; test.assertFalse(isNaN(Date.parse(sentDate))); - var targets = fieldData["cm:references"].getValue(); - test.assertEquals(1, targets.size()); - test.assertEquals(testAssociatedDoc, targets.get(0)); + var targets = fieldData["cm:references"].value; + test.assertEquals(1, targets.length); + test.assertEquals(testAssociatedDoc, targets[0]); } // Execute tests +testGetFormForNonExistentContentNode(); testGetFormForContentNode(); \ No newline at end of file diff --git a/source/java/org/alfresco/repo/jscript/ScriptUtils.java b/source/java/org/alfresco/repo/jscript/ScriptUtils.java index 8ae2ce6e1e..28ca5d595a 100644 --- a/source/java/org/alfresco/repo/jscript/ScriptUtils.java +++ b/source/java/org/alfresco/repo/jscript/ScriptUtils.java @@ -24,15 +24,18 @@ */ package org.alfresco.repo.jscript; +import java.util.Date; + import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.util.ISO8601DateFormat; import org.alfresco.service.cmr.module.ModuleService; import org.alfresco.service.cmr.module.ModuleDetails; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; /** - * Place for general and miscellenous utility functions not already found in generic JavaScript. + * Place for general and miscellaneous utility functions not already found in generic JavaScript. * * @author Kevin Roast */ @@ -94,6 +97,19 @@ public final class ScriptUtils extends BaseScopableProcessorExtension return Boolean.parseBoolean(booleanString); } + /** + * Converts the specified Date object to an + * ISO 8601-formatted + * String. + * + * @param d date + * @return an ISO 8601-formatted date String. + */ + public String toISO8601(Date d) + { + return ISO8601DateFormat.format(d); + } + /** * Function to check if a module is installed *