mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged DEV/FORMS to HEAD (all activity from branch creation r12855 through r13056)
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13058 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -75,7 +75,7 @@ public class AssociationFieldDefinition extends FieldDefinition
|
|||||||
*
|
*
|
||||||
* @return Direction.TARGET or Direction.SOURCE
|
* @return Direction.TARGET or Direction.SOURCE
|
||||||
*/
|
*/
|
||||||
public Direction getEnpointDirection()
|
public Direction getEndpointDirection()
|
||||||
{
|
{
|
||||||
return this.endpointDirection;
|
return this.endpointDirection;
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ package org.alfresco.repo.forms;
|
|||||||
|
|
||||||
import org.alfresco.repo.forms.processor.FormProcessor;
|
import org.alfresco.repo.forms.processor.FormProcessor;
|
||||||
import org.alfresco.repo.forms.processor.FormProcessorRegistry;
|
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.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
@@ -73,7 +74,20 @@ public class FormServiceImpl implements FormService
|
|||||||
}
|
}
|
||||||
else
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -285,7 +285,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
|
|||||||
referencesField.getEndpointType());
|
referencesField.getEndpointType());
|
||||||
assertEquals("Expecting cm:references endpoint direction to be TARGET",
|
assertEquals("Expecting cm:references endpoint direction to be TARGET",
|
||||||
Direction.TARGET.toString(),
|
Direction.TARGET.toString(),
|
||||||
referencesField.getEnpointDirection().toString());
|
referencesField.getEndpointDirection().toString());
|
||||||
assertFalse("Expecting cm:references endpoint to be optional",
|
assertFalse("Expecting cm:references endpoint to be optional",
|
||||||
referencesField.isEndpointMandatory());
|
referencesField.isEndpointMandatory());
|
||||||
assertTrue("Expecting cm:references endpoint to be 1 to many",
|
assertTrue("Expecting cm:references endpoint to be 1 to many",
|
||||||
|
@@ -31,13 +31,11 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.repo.forms.AssociationFieldDefinition;
|
import org.alfresco.repo.forms.AssociationFieldDefinition;
|
||||||
import org.alfresco.repo.forms.FieldDefinition;
|
|
||||||
import org.alfresco.repo.forms.Form;
|
import org.alfresco.repo.forms.Form;
|
||||||
import org.alfresco.repo.forms.FormData;
|
import org.alfresco.repo.forms.FormData;
|
||||||
import org.alfresco.repo.forms.FormException;
|
import org.alfresco.repo.forms.FormException;
|
||||||
import org.alfresco.repo.forms.PropertyFieldDefinition;
|
import org.alfresco.repo.forms.PropertyFieldDefinition;
|
||||||
import org.alfresco.repo.forms.AssociationFieldDefinition.Direction;
|
import org.alfresco.repo.forms.AssociationFieldDefinition.Direction;
|
||||||
import org.alfresco.repo.forms.FormData.FieldData;
|
|
||||||
import org.alfresco.repo.forms.PropertyFieldDefinition.FieldConstraint;
|
import org.alfresco.repo.forms.PropertyFieldDefinition.FieldConstraint;
|
||||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.Constraint;
|
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);
|
private static final Log logger = LogFactory.getLog(NodeHandler.class);
|
||||||
|
|
||||||
|
protected static final String PROP_PREFIX = "prop:";
|
||||||
|
protected static final String ASSOC_PREFIX = "assoc:";
|
||||||
|
|
||||||
/** Services */
|
/** Services */
|
||||||
protected NodeService nodeService;
|
protected NodeService nodeService;
|
||||||
protected DictionaryService dictionaryService;
|
protected DictionaryService dictionaryService;
|
||||||
@@ -130,7 +131,14 @@ public class NodeHandler extends AbstractHandler
|
|||||||
*/
|
*/
|
||||||
public void handlePersist(Object item, FormData data)
|
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)
|
if (fieldData instanceof List)
|
||||||
{
|
{
|
||||||
List list = (List)fieldData;
|
List list = (List)fieldData;
|
||||||
String fieldName = fieldDef.getName();
|
String fieldName = PROP_PREFIX + fieldDef.getName();
|
||||||
for (int x = 0; x < list.size(); x++)
|
for (int x = 0; x < list.size(); x++)
|
||||||
{
|
{
|
||||||
Object repeatingVal = list.get(x);
|
Object repeatingVal = list.get(x);
|
||||||
@@ -215,7 +223,7 @@ public class NodeHandler extends AbstractHandler
|
|||||||
}
|
}
|
||||||
else
|
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)
|
if (targets == null)
|
||||||
{
|
{
|
||||||
targets = new ArrayList<String>(4);
|
targets = new ArrayList<String>(4);
|
||||||
formData.addData(assocName, targets);
|
formData.addData(ASSOC_PREFIX + assocName, targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the assoc value to the list
|
// add the assoc value to the list
|
||||||
@@ -282,7 +290,7 @@ public class NodeHandler extends AbstractHandler
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// there should only be one value
|
// there should only be one value
|
||||||
formData.addData(assocName, assocValue);
|
formData.addData(ASSOC_PREFIX + assocName, assocValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -26,12 +26,14 @@ package org.alfresco.repo.forms.script;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collection;
|
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.FieldDefinition;
|
||||||
import org.alfresco.repo.forms.FieldGroup;
|
import org.alfresco.repo.forms.FieldGroup;
|
||||||
import org.alfresco.repo.forms.Form;
|
import org.alfresco.repo.forms.Form;
|
||||||
import org.alfresco.repo.forms.FormData;
|
import org.alfresco.repo.jscript.ScriptableHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form JavaScript Object.
|
* Form JavaScript Object.
|
||||||
@@ -43,10 +45,17 @@ public class ScriptForm implements Serializable
|
|||||||
private static final long serialVersionUID = 579853076546002023L;
|
private static final long serialVersionUID = 579853076546002023L;
|
||||||
|
|
||||||
private Form form;
|
private Form form;
|
||||||
|
private Map<String, FieldDefinition> fieldDefinitionData;
|
||||||
|
//TODO Consider caching
|
||||||
|
|
||||||
/* default */ScriptForm(Form formObject)
|
/* default */ScriptForm(Form formObject)
|
||||||
{
|
{
|
||||||
this.form = formObject;
|
this.form = formObject;
|
||||||
|
|
||||||
|
fieldDefinitionData = new HashMap<String, FieldDefinition>();
|
||||||
|
for (FieldDefinition fd : form.getFieldDefinitions()) {
|
||||||
|
fieldDefinitionData.put(fd.getName(), fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getItem()
|
public String getItem()
|
||||||
@@ -59,23 +68,44 @@ public class ScriptForm implements Serializable
|
|||||||
return form.getType();
|
return form.getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO Wrap this type in a script type?
|
||||||
public Collection<FieldGroup> getFieldGroups()
|
public Collection<FieldGroup> getFieldGroups()
|
||||||
{
|
{
|
||||||
return form.getFieldGroups();
|
return form.getFieldGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<FieldDefinition> getFieldDefinitions()
|
public FieldDefinition[] getFieldDefinitions()
|
||||||
{
|
{
|
||||||
return form.getFieldDefinitions();
|
Collection<FieldDefinition> fieldDefs = form.getFieldDefinitions();
|
||||||
|
if (fieldDefs == null)
|
||||||
|
{
|
||||||
|
fieldDefs = Collections.emptyList();
|
||||||
|
}
|
||||||
|
return fieldDefs.toArray(new FieldDefinition[fieldDefs.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScriptableHashMap<String, ScriptFieldDefinition> getFieldDefinitionData()
|
||||||
|
{
|
||||||
|
ScriptableHashMap<String, ScriptFieldDefinition> result =
|
||||||
|
new ScriptableHashMap<String, ScriptFieldDefinition>();
|
||||||
|
Collection<FieldDefinition> fieldDefs = form.getFieldDefinitions();
|
||||||
|
for (FieldDefinition fd : fieldDefs)
|
||||||
|
{
|
||||||
|
result.put(fd.getName(), new ScriptFieldDefinition(fd));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
108
source/java/org/alfresco/repo/forms/script/ScriptFormData.java
Normal file
108
source/java/org/alfresco/repo/forms/script/ScriptFormData.java
Normal file
@@ -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<String, ScriptFieldData> getData()
|
||||||
|
{
|
||||||
|
ScriptableHashMap<String, ScriptFieldData> result = new ScriptableHashMap<String, ScriptFieldData>();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -25,6 +25,7 @@
|
|||||||
package org.alfresco.repo.forms.script;
|
package org.alfresco.repo.forms.script;
|
||||||
|
|
||||||
import org.alfresco.repo.forms.Form;
|
import org.alfresco.repo.forms.Form;
|
||||||
|
import org.alfresco.repo.forms.FormData;
|
||||||
import org.alfresco.repo.forms.FormService;
|
import org.alfresco.repo.forms.FormService;
|
||||||
import org.alfresco.repo.jscript.BaseScopableProcessorExtension;
|
import org.alfresco.repo.jscript.BaseScopableProcessorExtension;
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
@@ -63,9 +64,32 @@ public class ScriptFormService extends BaseScopableProcessorExtension
|
|||||||
this.formService = formService;
|
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)
|
public ScriptForm getForm(String item)
|
||||||
{
|
{
|
||||||
Form result = formService.getForm(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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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()
|
function testGetFormForContentNode()
|
||||||
{
|
{
|
||||||
// Get a known form and check its various attributes/properties.
|
// Get a known form and check its various attributes/properties.
|
||||||
var form = formService.getForm(testDoc);
|
var form = formService.getForm(testDoc);
|
||||||
test.assertNotNull(form, "Form should have been found: " + 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.assertEquals(19, fieldDefs.length);
|
||||||
test.assertNotNull(fieldDefs);
|
|
||||||
test.assertEquals(19, fieldDefs.size());
|
|
||||||
|
|
||||||
var mappedFields = new Array();
|
var fieldDefnDataHash = form.fieldDefinitionData;
|
||||||
for (var i = 0; i < fieldDefs.size(); i++)
|
|
||||||
{
|
var nameField = fieldDefnDataHash['cm:name'];
|
||||||
mappedFields[fieldDefs.get(i).getName()] = fieldDefs.get(i);
|
var titleField = fieldDefnDataHash['cm:title'];
|
||||||
}
|
var descField = fieldDefnDataHash['cm:description'];
|
||||||
var nameField = mappedFields['cm:name'];
|
var originatorField = fieldDefnDataHash['cm:originator'];
|
||||||
var titleField = mappedFields['cm:title'];
|
var addresseeField = fieldDefnDataHash['cm:addressee'];
|
||||||
var descField = mappedFields['cm:description'];
|
var addresseesField = fieldDefnDataHash['cm:addressees'];
|
||||||
var originatorField = mappedFields['cm:originator'];
|
var subjectField = fieldDefnDataHash['cm:subjectline'];
|
||||||
var addresseeField = mappedFields['cm:addressee'];
|
var sentDateField = fieldDefnDataHash['cm:sentdate'];
|
||||||
var addresseesField = mappedFields['cm:addressees'];
|
var referencesField = fieldDefnDataHash['cm:references'];
|
||||||
var subjectField = mappedFields['cm:subjectline'];
|
|
||||||
var sentDateField = mappedFields['cm:sentdate'];
|
|
||||||
var referencesField = mappedFields['cm:references'];
|
|
||||||
|
|
||||||
test.assertNotNull(nameField, "Expecting to find the cm:name field");
|
test.assertNotNull(nameField, "Expecting to find the cm:name field");
|
||||||
test.assertNotNull(titleField, "Expecting to find the cm:title 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(sentDateField, "Expecting to find the cm:sentdate field");
|
||||||
test.assertNotNull(referencesField, "Expecting to find the cm:references 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
|
// check the labels of all the fields
|
||||||
test.assertEquals("Name", nameField.getLabel());
|
test.assertEquals("Name", nameField.label);
|
||||||
test.assertEquals("Title", titleField.getLabel());
|
test.assertEquals("Title", titleField.label);
|
||||||
test.assertEquals("Description", descField.getLabel());
|
test.assertEquals("Description", descField.label);
|
||||||
test.assertEquals("Originator", originatorField.getLabel());
|
test.assertEquals("Originator", originatorField.label);
|
||||||
test.assertEquals("Addressee", addresseeField.getLabel());
|
test.assertEquals("Addressee", addresseeField.label);
|
||||||
test.assertEquals("Addressees", addresseesField.getLabel());
|
test.assertEquals("Addressees", addresseesField.label);
|
||||||
test.assertEquals("Subject", subjectField.getLabel());
|
test.assertEquals("Subject", subjectField.label);
|
||||||
test.assertEquals("Sent Date", sentDateField.getLabel());
|
test.assertEquals("Sent Date", sentDateField.label);
|
||||||
test.assertEquals("References", referencesField.getLabel());
|
test.assertEquals("References", referencesField.label);
|
||||||
|
|
||||||
// check details of name field
|
// check details of name field
|
||||||
test.assertEquals("d:text", nameField.getDataType());
|
test.assertEquals("d:text", nameField.dataType);
|
||||||
test.assertTrue(nameField.isMandatory());
|
test.assertTrue(nameField.mandatory);
|
||||||
// Expecting cm:name to be single-valued.
|
// Expecting cm:name to be single-valued.
|
||||||
test.assertFalse(nameField.isRepeating());
|
test.assertFalse(nameField.repeating);
|
||||||
|
|
||||||
// get the constraint for the name field and check
|
// get the constraint for the name field and check
|
||||||
var constraints = nameField.getConstraints();
|
var constraints = nameField.constraints;
|
||||||
test.assertEquals(1, constraints.size());
|
test.assertEquals(1, constraints.length);
|
||||||
var constraint = constraints.get(0);
|
var constraint = constraints[0];
|
||||||
test.assertEquals("REGEX", constraint.getType());
|
test.assertEquals("REGEX", constraint.type);
|
||||||
var params = constraint.getParams();
|
var params = constraint.params;
|
||||||
test.assertNotNull(params);
|
test.assertNotNull(params, "params should not be null.");
|
||||||
test.assertEquals(2, params.length);
|
test.assertEquals(2, params.length);
|
||||||
test.assertNotNull(params["expression"]);
|
test.assertNotNull(params["expression"], "params['expression'] should not be null.");
|
||||||
test.assertNotNull(params["requiresMatch"]);
|
test.assertNotNull(params["requiresMatch"], "params['requiresMatch'] should not be null.");
|
||||||
|
|
||||||
// check details of the addressees field
|
// check details of the addressees field
|
||||||
test.assertEquals("d:text", addresseesField.getDataType());
|
test.assertEquals("d:text", addresseesField.dataType);
|
||||||
test.assertFalse(addresseesField.isMandatory());
|
test.assertFalse(addresseesField.mandatory);
|
||||||
// Expecting cm:addressees to be multi-valued.
|
// Expecting cm:addressees to be multi-valued.
|
||||||
test.assertTrue(addresseesField.isRepeating());
|
test.assertTrue(addresseesField.repeating);
|
||||||
test.assertNull(addresseesField.getConstraints());
|
|
||||||
|
// 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
|
// check the details of the association field
|
||||||
test.assertEquals("cm:content", referencesField.getEndpointType());
|
test.assertEquals("cm:content", referencesField.endpointType);
|
||||||
//TODO Method name typo here "Enpoint"
|
|
||||||
test.assertEquals("TARGET", referencesField.getEnpointDirection().toString());
|
//TODO A raw comparison fails. Is this a JS vs. Java string?
|
||||||
test.assertFalse(referencesField.isEndpointMandatory());
|
test.assertEquals("TARGET", "" + referencesField.endpointDirection);
|
||||||
test.assertTrue(referencesField.isEndpointMany());
|
test.assertFalse(referencesField.endpointMandatory);
|
||||||
|
test.assertTrue(referencesField.endpointMany);
|
||||||
|
|
||||||
// check the form data
|
// check the form data
|
||||||
var formData = form.getFormData();
|
var formData = form.formData;
|
||||||
test.assertNotNull(formData);
|
test.assertNotNull(formData, "formData should not be null.");
|
||||||
var fieldData = formData.getData();
|
var fieldData = formData.data;
|
||||||
test.assertEquals("This is the title for the test document", fieldData["cm:title"].getValue());
|
test.assertNotNull(fieldData, "fieldData should not be null.");
|
||||||
test.assertEquals("This is the description for the test document", fieldData["cm:description"].getValue());
|
test.assertNotNull(fieldData.length, "fieldData.length should not be null.");
|
||||||
test.assertEquals("fred@customer.com", fieldData["cm:originator"].getValue());
|
|
||||||
test.assertEquals("bill@example.com", fieldData["cm:addressee"].getValue());
|
test.assertEquals("This is the title for the test document", fieldData["cm:title"].value);
|
||||||
test.assertEquals("harry@example.com", fieldData["cm:addressees_0"].getValue());
|
test.assertEquals("This is the description for the test document", fieldData["cm:description"].value);
|
||||||
test.assertEquals("jane@example.com", fieldData["cm:addressees_1"].getValue());
|
test.assertEquals("fred@customer.com", fieldData["cm:originator"].value);
|
||||||
test.assertEquals("The subject is...", fieldData["cm:subjectline"].getValue());
|
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.
|
//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.
|
// 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)));
|
test.assertFalse(isNaN(Date.parse(sentDate)));
|
||||||
|
|
||||||
var targets = fieldData["cm:references"].getValue();
|
var targets = fieldData["cm:references"].value;
|
||||||
test.assertEquals(1, targets.size());
|
test.assertEquals(1, targets.length);
|
||||||
test.assertEquals(testAssociatedDoc, targets.get(0));
|
test.assertEquals(testAssociatedDoc, targets[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute tests
|
// Execute tests
|
||||||
|
testGetFormForNonExistentContentNode();
|
||||||
testGetFormForContentNode();
|
testGetFormForContentNode();
|
@@ -24,15 +24,18 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.jscript;
|
package org.alfresco.repo.jscript;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
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.ModuleService;
|
||||||
import org.alfresco.service.cmr.module.ModuleDetails;
|
import org.alfresco.service.cmr.module.ModuleDetails;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
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
|
* @author Kevin Roast
|
||||||
*/
|
*/
|
||||||
@@ -94,6 +97,19 @@ public final class ScriptUtils extends BaseScopableProcessorExtension
|
|||||||
return Boolean.parseBoolean(booleanString);
|
return Boolean.parseBoolean(booleanString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the specified Date object to an
|
||||||
|
* <a href="http://www.iso.org/iso/date_and_time_format">ISO 8601</a>-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
|
* Function to check if a module is installed
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user