mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Initial impl of Forms config <form> work.
(Refactoring and API improvements continue.) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12068 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
489
source/java/org/alfresco/web/config/FormConfigElement.java
Normal file
489
source/java/org/alfresco/web/config/FormConfigElement.java
Normal file
@@ -0,0 +1,489 @@
|
|||||||
|
/*
|
||||||
|
* 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.web.config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
import org.alfresco.config.ConfigElement;
|
||||||
|
import org.alfresco.config.ConfigException;
|
||||||
|
import org.alfresco.config.element.ConfigElementAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom config element that represents form values for the client.
|
||||||
|
*
|
||||||
|
* @author Neil McErlean.
|
||||||
|
*/
|
||||||
|
public class FormConfigElement extends ConfigElementAdapter
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -7008510360503886308L;
|
||||||
|
|
||||||
|
public enum Mode
|
||||||
|
{
|
||||||
|
VIEW, EDIT, CREATE;
|
||||||
|
public static Mode fromString(String modeString)
|
||||||
|
{
|
||||||
|
if (modeString.equalsIgnoreCase("create")) {
|
||||||
|
return Mode.CREATE;
|
||||||
|
}
|
||||||
|
else if (modeString.equalsIgnoreCase("edit"))
|
||||||
|
{
|
||||||
|
return Mode.EDIT;
|
||||||
|
}
|
||||||
|
else if (modeString.equalsIgnoreCase("view"))
|
||||||
|
{
|
||||||
|
return Mode.VIEW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String FORM_ID = "form";
|
||||||
|
private String submissionURL;
|
||||||
|
private List<StringPair> modelOverrides = new ArrayList<StringPair>();
|
||||||
|
|
||||||
|
// We need to maintain the order of templates - per mode.
|
||||||
|
private List<String> createTemplates = new ArrayList<String>();
|
||||||
|
private List<String> editTemplates = new ArrayList<String>();
|
||||||
|
private List<String> viewTemplates = new ArrayList<String>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of the required roles for create-form templates.
|
||||||
|
* Key = the template String. Value = the requires-role String.
|
||||||
|
*/
|
||||||
|
private Map<String, String> rolesForCreateTemplates = new HashMap<String, String>();
|
||||||
|
private Map<String, String> rolesForEditTemplates = new HashMap<String, String>();
|
||||||
|
private Map<String, String> rolesForViewTemplates = new HashMap<String, String>();
|
||||||
|
|
||||||
|
private List<FieldVisibilityInstruction> visibilityInstructions = new ArrayList<FieldVisibilityInstruction>();
|
||||||
|
|
||||||
|
private List<String> setIdentifiers = new ArrayList<String>();
|
||||||
|
private Map<String, FormSet> sets = new HashMap<String, FormSet>();
|
||||||
|
|
||||||
|
private List<String> fieldIdentifiers = new ArrayList<String>();
|
||||||
|
private Map<String, FormField> fields = new HashMap<String, FormField>();
|
||||||
|
|
||||||
|
public FormConfigElement()
|
||||||
|
{
|
||||||
|
super(FORM_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FormConfigElement(String name)
|
||||||
|
{
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.config.ConfigElement#getChildren()
|
||||||
|
*/
|
||||||
|
public List<ConfigElement> getChildren()
|
||||||
|
{
|
||||||
|
throw new ConfigException(
|
||||||
|
"Reading the default-controls config via the generic interfaces is not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.config.ConfigElement#combine(org.alfresco.config.ConfigElement)
|
||||||
|
*/
|
||||||
|
public ConfigElement combine(ConfigElement configElement)
|
||||||
|
{
|
||||||
|
// TODO Impl this.
|
||||||
|
throw new UnsupportedOperationException("This method not yet impl'd.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubmissionURL()
|
||||||
|
{
|
||||||
|
return this.submissionURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
* @param roles a list of roles, can be an empty list or null.
|
||||||
|
* @return <code>null</code> if there is no template available for the specified role(s).
|
||||||
|
*/
|
||||||
|
public String getFormTemplate(Mode m, List<String> roles)
|
||||||
|
{
|
||||||
|
switch (m)
|
||||||
|
{
|
||||||
|
case CREATE: return findFirstMatchingTemplate(createTemplates, rolesForCreateTemplates, roles);
|
||||||
|
case EDIT: return findFirstMatchingTemplate(editTemplates, rolesForEditTemplates, roles);
|
||||||
|
case VIEW: return findFirstMatchingTemplate(viewTemplates, rolesForViewTemplates, roles);
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method checks whether the specified field is visible in the specified mode.
|
||||||
|
* The algorithm for determining visibility works as follows
|
||||||
|
* <ul>
|
||||||
|
* <li>If there is no field-visibility configuration (show or hide tags) then
|
||||||
|
* all fields are visible in all modes.</li>
|
||||||
|
* <li>If there are one or more hide tags then the specified fields will be hidden
|
||||||
|
* in the specified modes. All other fields remain visible as before.</li>
|
||||||
|
* <li>However, as soon as a single show tag appears in the config xml, this is
|
||||||
|
* taken as a signal that all field visibility is to be manually configured.
|
||||||
|
* At that point, all fields default to hidden and only those explicitly
|
||||||
|
* configured to be shown (with a show tag) will actually be shown.</li>
|
||||||
|
* <li>Show and hide rules will be applied in sequence with later rules
|
||||||
|
* invalidating previous rules.</li>
|
||||||
|
* <li>Show or hide rules which only apply for specified modes have an implicit
|
||||||
|
* element. e.g. <show id="name" for-mode="view"/> would show the name field
|
||||||
|
* in view mode and by implication, hide it in other modes.</li>
|
||||||
|
* </ul>
|
||||||
|
* @param fieldId
|
||||||
|
* @param m
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isFieldVisible(String fieldId, Mode m)
|
||||||
|
{
|
||||||
|
if (visibilityInstructions.isEmpty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boolean listContainsAtLeastOneShow = false;
|
||||||
|
// true means show, false means hide, null means 'no answer'.
|
||||||
|
Boolean latestInstructionToShow = null;
|
||||||
|
for (FieldVisibilityInstruction instruc : visibilityInstructions)
|
||||||
|
{
|
||||||
|
if (instruc.isShow())
|
||||||
|
{
|
||||||
|
listContainsAtLeastOneShow = true;
|
||||||
|
}
|
||||||
|
if (instruc.getFieldId().equals(fieldId))
|
||||||
|
{
|
||||||
|
// This matters
|
||||||
|
if (instruc.getModes().contains(m))
|
||||||
|
{
|
||||||
|
latestInstructionToShow = instruc.isShow() ?
|
||||||
|
Boolean.TRUE : Boolean.FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
latestInstructionToShow = instruc.isShow() ?
|
||||||
|
Boolean.FALSE : Boolean.TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (latestInstructionToShow == null)
|
||||||
|
{
|
||||||
|
// We really on the 'default' behaviour
|
||||||
|
return !listContainsAtLeastOneShow;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return latestInstructionToShow.booleanValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSetIDs()
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableList(setIdentifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, FormSet> getSets()
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableMap(this.sets);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO This is all fields. need getVisFields(Role)
|
||||||
|
public Map<String, FormField> getFields()
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableMap(this.fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String findFirstMatchingTemplate(List<String> templates,
|
||||||
|
Map<String, String> templatesToRoles, List<String> currentRoles)
|
||||||
|
{
|
||||||
|
// If there is no current role, we can only return templates that require no role.
|
||||||
|
if (currentRoles == null || currentRoles.isEmpty())
|
||||||
|
{
|
||||||
|
for (String template : templates)
|
||||||
|
{
|
||||||
|
String requiredRolesForThisTemplate = templatesToRoles.get(template);
|
||||||
|
if (requiredRolesForThisTemplate.trim().length() == 0)
|
||||||
|
{
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here there is at least one current role.
|
||||||
|
for (String template : templates)
|
||||||
|
{
|
||||||
|
String requiredRolesForThisTemplate = templatesToRoles.get(template);
|
||||||
|
for (String role : currentRoles)
|
||||||
|
{
|
||||||
|
if (requiredRolesForThisTemplate.contains(role))
|
||||||
|
{
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<StringPair> getModelOverrideProperties()
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableList(modelOverrides);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */void setSubmissionURL(String newURL)
|
||||||
|
{
|
||||||
|
this.submissionURL = newURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */void addFormTemplate(String nodeName, String template,
|
||||||
|
String requiredRole)
|
||||||
|
{
|
||||||
|
if (requiredRole == null)
|
||||||
|
{
|
||||||
|
requiredRole = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeName.equals("create-form"))
|
||||||
|
{
|
||||||
|
createTemplates.add(template);
|
||||||
|
rolesForCreateTemplates.put(template, requiredRole);
|
||||||
|
}
|
||||||
|
else if (nodeName.equals("edit-form"))
|
||||||
|
{
|
||||||
|
editTemplates.add(template);
|
||||||
|
rolesForEditTemplates.put(template, requiredRole);
|
||||||
|
}
|
||||||
|
else if (nodeName.equals("view-form"))
|
||||||
|
{
|
||||||
|
viewTemplates.add(template);
|
||||||
|
rolesForViewTemplates.put(template, requiredRole);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ignore it. We don't recognise the mode.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */void addFieldVisibility(String showOrHide, String fieldId,
|
||||||
|
String mode)
|
||||||
|
{
|
||||||
|
FieldVisibilityInstruction instruc = new FieldVisibilityInstruction(showOrHide, fieldId, mode);
|
||||||
|
this.visibilityInstructions.add(instruc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */void addSet(String setId, String parentSetId, String appearance)
|
||||||
|
{
|
||||||
|
setIdentifiers.add(setId);
|
||||||
|
sets.put(setId, new FormSet(setId, parentSetId, appearance));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */void addField(String fieldId, List<String> attributeNames,
|
||||||
|
List<String> attributeValues)
|
||||||
|
{
|
||||||
|
Map<String, String> attrs = new HashMap<String, String>();
|
||||||
|
for (int i = 0; i < attributeNames.size(); i++)
|
||||||
|
{
|
||||||
|
attrs.put(attributeNames.get(i), attributeValues.get(i));
|
||||||
|
}
|
||||||
|
fields.put(fieldId, new FormField(attrs));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */void addControlForField(String fieldId, String template,
|
||||||
|
List<String> controlParamNames, List<String> controlParamValues)
|
||||||
|
{
|
||||||
|
FormField field = fields.get(fieldId);
|
||||||
|
field.setTemplate(template);
|
||||||
|
for (int i = 0; i < controlParamNames.size(); i++)
|
||||||
|
{
|
||||||
|
field.addControlParam(new StringPair(controlParamNames.get(i),
|
||||||
|
controlParamValues.get(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */void addConstraintForField(String fieldId, String type,
|
||||||
|
String message, String messageId)
|
||||||
|
{
|
||||||
|
FormField field = fields.get(fieldId);
|
||||||
|
field.setConstraintType(type);
|
||||||
|
field.setConstraintMessage(message);
|
||||||
|
field.setConstraintMessageId(messageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */void addModelOverrides(String name, String value)
|
||||||
|
{
|
||||||
|
modelOverrides.add(new StringPair(name, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FormSet
|
||||||
|
{
|
||||||
|
private final String setId;
|
||||||
|
private final String parentId;
|
||||||
|
private final String appearance;
|
||||||
|
public FormSet(String setId, String parentId, String appearance)
|
||||||
|
{
|
||||||
|
this.setId = setId;
|
||||||
|
this.parentId = parentId;
|
||||||
|
this.appearance = appearance;
|
||||||
|
}
|
||||||
|
public String getSetId()
|
||||||
|
{
|
||||||
|
return setId;
|
||||||
|
}
|
||||||
|
public String getParentId()
|
||||||
|
{
|
||||||
|
return parentId;
|
||||||
|
}
|
||||||
|
public String getAppearance()
|
||||||
|
{
|
||||||
|
return appearance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FormField
|
||||||
|
{
|
||||||
|
private final Map<String, String> attributes;
|
||||||
|
private String template;
|
||||||
|
private final List<StringPair> controlParams = new ArrayList<StringPair>();
|
||||||
|
private String constraintType;
|
||||||
|
private String constraintMessage;
|
||||||
|
private String constraintMessageId;
|
||||||
|
public FormField(Map<String, String> attributes)
|
||||||
|
{
|
||||||
|
this.attributes = attributes;
|
||||||
|
}
|
||||||
|
public void setTemplate(String template)
|
||||||
|
{
|
||||||
|
this.template = template;
|
||||||
|
}
|
||||||
|
public void setConstraintType(String constraintType)
|
||||||
|
{
|
||||||
|
this.constraintType = constraintType;
|
||||||
|
}
|
||||||
|
public void setConstraintMessage(String constraintMessage)
|
||||||
|
{
|
||||||
|
this.constraintMessage = constraintMessage;
|
||||||
|
}
|
||||||
|
public void setConstraintMessageId(String constraintMessageId)
|
||||||
|
{
|
||||||
|
this.constraintMessageId = constraintMessageId;
|
||||||
|
}
|
||||||
|
public void addControlParam(StringPair nameValue)
|
||||||
|
{
|
||||||
|
this.controlParams.add(nameValue);
|
||||||
|
}
|
||||||
|
public Map<String, String> getAttributes()
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableMap(attributes);
|
||||||
|
}
|
||||||
|
public String getTemplate()
|
||||||
|
{
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
public List<StringPair> getControlParams()
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableList(controlParams);
|
||||||
|
}
|
||||||
|
public String getConstraintType()
|
||||||
|
{
|
||||||
|
return constraintType;
|
||||||
|
}
|
||||||
|
public String getConstraintMessage()
|
||||||
|
{
|
||||||
|
return constraintMessage;
|
||||||
|
}
|
||||||
|
public String getConstraintMessageId()
|
||||||
|
{
|
||||||
|
return constraintMessageId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FieldVisibilityInstruction
|
||||||
|
{
|
||||||
|
private final boolean show;
|
||||||
|
private final String fieldId;
|
||||||
|
private final List<Mode> forModes;
|
||||||
|
public FieldVisibilityInstruction(String showOrHide, String fieldId, String modesString)
|
||||||
|
{
|
||||||
|
if (showOrHide.equals("show"))
|
||||||
|
{
|
||||||
|
this.show = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.show = false;
|
||||||
|
}
|
||||||
|
this.fieldId = fieldId;
|
||||||
|
this.forModes = new ArrayList<Mode>();
|
||||||
|
if (modesString == null)
|
||||||
|
{
|
||||||
|
forModes.addAll(Arrays.asList(Mode.values()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StringTokenizer st = new StringTokenizer(modesString, ",");
|
||||||
|
while (st.hasMoreTokens())
|
||||||
|
{
|
||||||
|
String nextToken = st.nextToken().trim();
|
||||||
|
Mode nextMode = Mode.fromString(nextToken);
|
||||||
|
forModes.add(nextMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShow()
|
||||||
|
{
|
||||||
|
return show;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFieldId()
|
||||||
|
{
|
||||||
|
return fieldId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Mode> getModes()
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableList(forModes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
result.append(show ? "show" : "hide");
|
||||||
|
result.append(" ").append(fieldId).append(" ").append(forModes);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
209
source/java/org/alfresco/web/config/FormElementReader.java
Normal file
209
source/java/org/alfresco/web/config/FormElementReader.java
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* 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.web.config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.config.ConfigElement;
|
||||||
|
import org.alfresco.config.ConfigException;
|
||||||
|
import org.alfresco.config.xml.elementreader.ConfigElementReader;
|
||||||
|
import org.dom4j.Attribute;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a custom element reader to parse the config file for
|
||||||
|
* <form> elements.
|
||||||
|
*
|
||||||
|
* @author Neil McErlean.
|
||||||
|
*/
|
||||||
|
public class FormElementReader implements ConfigElementReader
|
||||||
|
{
|
||||||
|
public static final String ATTR_APPEARANCE = "appearance";
|
||||||
|
public static final String ATTR_FOR_MODE = "for-mode";
|
||||||
|
public static final String ATTR_MESSAGE = "message";
|
||||||
|
public static final String ATTR_MESSAGE_ID = "message-id";
|
||||||
|
public static final String ATTR_NAME = "name";
|
||||||
|
public static final String ATTR_NAME_ID = "id";
|
||||||
|
public static final String ATTR_PARENT = "parent";
|
||||||
|
public static final String ATTR_REQUIRES_ROLE = "requires-role";
|
||||||
|
public static final String ATTR_SUBMISSION_URL = "submission-url";
|
||||||
|
public static final String ATTR_TEMPLATE = "template";
|
||||||
|
public static final String ATTR_TYPE = "type";
|
||||||
|
public static final String ELEMENT_FORM = "form";
|
||||||
|
public static final String ELEMENT_HIDE = "hide";
|
||||||
|
public static final String ELEMENT_SHOW = "show";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.alfresco.config.xml.elementreader.ConfigElementReader#parse(org.dom4j.Element)
|
||||||
|
*/
|
||||||
|
public ConfigElement parse(Element formElement)
|
||||||
|
{
|
||||||
|
FormConfigElement result = null;
|
||||||
|
if (formElement == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = formElement.getName();
|
||||||
|
if (!name.equals(ELEMENT_FORM))
|
||||||
|
{
|
||||||
|
throw new ConfigException(this.getClass().getName()
|
||||||
|
+ " can only parse " + ELEMENT_FORM
|
||||||
|
+ " elements, the element passed was '" + name + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
result = new FormConfigElement();
|
||||||
|
|
||||||
|
parseSubmissionURL(formElement, result);
|
||||||
|
|
||||||
|
// Using xpath expressions to select nodes under <form> and their attributes.
|
||||||
|
parseForms(formElement, result);
|
||||||
|
|
||||||
|
parseFieldVisibilities(formElement, result);
|
||||||
|
|
||||||
|
parseSets(formElement, result);
|
||||||
|
|
||||||
|
parseFields(formElement, result);
|
||||||
|
|
||||||
|
parseModelOverrides(formElement, result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseModelOverrides(Element formElement, FormConfigElement result)
|
||||||
|
{
|
||||||
|
for (Object propObj : formElement.selectNodes("./model-override/property")) {
|
||||||
|
Element propertyElem = (Element)propObj;
|
||||||
|
String propName = propertyElem.attributeValue(ATTR_NAME);
|
||||||
|
String propValue = propertyElem.getTextTrim();
|
||||||
|
result.addModelOverrides(propName, propValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void parseFields(Element formElement, FormConfigElement result)
|
||||||
|
{
|
||||||
|
for (Object fieldObj : formElement.selectNodes("./appearance/field")) {
|
||||||
|
Element fieldElem = (Element)fieldObj;
|
||||||
|
List<Attribute> fieldAttributes = fieldElem.selectNodes("./@*");
|
||||||
|
|
||||||
|
List<String> fieldAttributeNames = new ArrayList<String>();
|
||||||
|
List<String> fieldAttributeValues = new ArrayList<String>();
|
||||||
|
|
||||||
|
// With special handling for the mandatory "id" attribute.
|
||||||
|
String fieldIdValue = null;
|
||||||
|
for (Attribute nextAttr : fieldAttributes) {
|
||||||
|
String nextAttributeName = nextAttr.getName();
|
||||||
|
String nextAttributeValue = nextAttr.getValue();
|
||||||
|
|
||||||
|
if (nextAttributeName.equals(ATTR_NAME_ID))
|
||||||
|
{
|
||||||
|
fieldIdValue = nextAttributeValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fieldAttributeNames.add(nextAttributeName);
|
||||||
|
fieldAttributeValues.add(nextAttributeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fieldIdValue == null)
|
||||||
|
{
|
||||||
|
throw new ConfigException("<field> node missing mandatory id attribute.");
|
||||||
|
}
|
||||||
|
result.addField(fieldIdValue, fieldAttributeNames, fieldAttributeValues);
|
||||||
|
|
||||||
|
List<Element> controlObjs = fieldElem.selectNodes("./control");
|
||||||
|
if (!controlObjs.isEmpty())
|
||||||
|
{
|
||||||
|
Element controlElem = controlObjs.get(0);
|
||||||
|
|
||||||
|
String templateValue = controlElem.attributeValue(ATTR_TEMPLATE);
|
||||||
|
List<String> controlParamNames = new ArrayList<String>();
|
||||||
|
List<String> controlParamValues = new ArrayList<String>();
|
||||||
|
for (Object paramObj : controlElem
|
||||||
|
.selectNodes("./control-param"))
|
||||||
|
{
|
||||||
|
Element paramElem = (Element) paramObj;
|
||||||
|
controlParamNames.add(paramElem.attributeValue(ATTR_NAME));
|
||||||
|
controlParamValues.add(paramElem.getTextTrim());
|
||||||
|
}
|
||||||
|
result.addControlForField(fieldIdValue, templateValue, controlParamNames, controlParamValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Object constraintMessageObj : fieldElem.selectNodes("./constraint-message")) {
|
||||||
|
Element constraintMessage = (Element)constraintMessageObj;
|
||||||
|
String type = constraintMessage.attributeValue(ATTR_TYPE);
|
||||||
|
String message = constraintMessage.attributeValue(ATTR_MESSAGE);
|
||||||
|
String messageId = constraintMessage.attributeValue(ATTR_MESSAGE_ID);
|
||||||
|
result.addConstraintForField(fieldIdValue, type, message, messageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseSets(Element formElement, FormConfigElement result)
|
||||||
|
{
|
||||||
|
for (Object setObj : formElement.selectNodes("./appearance/set")) {
|
||||||
|
Element setElem = (Element)setObj;
|
||||||
|
String setId = setElem.attributeValue(ATTR_NAME_ID);
|
||||||
|
String parentSetId = setElem.attributeValue(ATTR_PARENT);
|
||||||
|
String appearance = setElem.attributeValue(ATTR_APPEARANCE);
|
||||||
|
|
||||||
|
result.addSet(setId, parentSetId, appearance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseFieldVisibilities(Element formElement,
|
||||||
|
FormConfigElement result)
|
||||||
|
{
|
||||||
|
for (Object obj : formElement.selectNodes("./field-visibility/show|./field-visibility/hide")) {
|
||||||
|
Element showOrHideElem = (Element)obj;
|
||||||
|
String nodeName = showOrHideElem.getName();
|
||||||
|
String fieldId = showOrHideElem.attributeValue(ATTR_NAME_ID);
|
||||||
|
String mode = showOrHideElem.attributeValue(ATTR_FOR_MODE);
|
||||||
|
|
||||||
|
result.addFieldVisibility(nodeName, fieldId, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseForms(Element formElement, FormConfigElement result)
|
||||||
|
{
|
||||||
|
for (Object obj : formElement.selectNodes("./edit-form|./view-form|./create-form")) {
|
||||||
|
Element editOrViewOrCreateFormElem = (Element)obj;
|
||||||
|
String nodeName = editOrViewOrCreateFormElem.getName();
|
||||||
|
String template = editOrViewOrCreateFormElem.attributeValue(ATTR_TEMPLATE);
|
||||||
|
String requiresRole = editOrViewOrCreateFormElem.attributeValue(ATTR_REQUIRES_ROLE);
|
||||||
|
|
||||||
|
result.addFormTemplate(nodeName, template, requiresRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseSubmissionURL(Element formElement,
|
||||||
|
FormConfigElement result)
|
||||||
|
{
|
||||||
|
String submissionURL = formElement.attributeValue(ATTR_SUBMISSION_URL);
|
||||||
|
result.setSubmissionURL(submissionURL);
|
||||||
|
}
|
||||||
|
}
|
@@ -44,6 +44,9 @@ import org.alfresco.web.config.ActionsConfigElement.ActionGroup;
|
|||||||
import org.alfresco.web.config.AdvancedSearchConfigElement.CustomProperty;
|
import org.alfresco.web.config.AdvancedSearchConfigElement.CustomProperty;
|
||||||
import org.alfresco.web.config.DefaultControlsConfigElement.ControlParam;
|
import org.alfresco.web.config.DefaultControlsConfigElement.ControlParam;
|
||||||
import org.alfresco.web.config.DialogsConfigElement.DialogConfig;
|
import org.alfresco.web.config.DialogsConfigElement.DialogConfig;
|
||||||
|
import org.alfresco.web.config.FormConfigElement.FormField;
|
||||||
|
import org.alfresco.web.config.FormConfigElement.FormSet;
|
||||||
|
import org.alfresco.web.config.FormConfigElement.Mode;
|
||||||
import org.alfresco.web.config.PropertySheetConfigElement.ItemConfig;
|
import org.alfresco.web.config.PropertySheetConfigElement.ItemConfig;
|
||||||
import org.alfresco.web.config.WizardsConfigElement.ConditionalPageConfig;
|
import org.alfresco.web.config.WizardsConfigElement.ConditionalPageConfig;
|
||||||
import org.alfresco.web.config.WizardsConfigElement.PageConfig;
|
import org.alfresco.web.config.WizardsConfigElement.PageConfig;
|
||||||
@@ -1199,6 +1202,111 @@ public class WebClientConfigTest extends BaseTest
|
|||||||
.getMessageFor("NUMERIC"));
|
.getMessageFor("NUMERIC"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testFormConfig()
|
||||||
|
{
|
||||||
|
XMLConfigService svc = initXMLConfigService("test-config-forms.xml");
|
||||||
|
|
||||||
|
Config contentConfig = svc.getConfig("content");
|
||||||
|
ConfigElement confElement = contentConfig.getConfigElement("form");
|
||||||
|
assertNotNull("confElement was null.", confElement);
|
||||||
|
assertTrue("confElement should be instanceof FormConfigElement.", confElement
|
||||||
|
instanceof FormConfigElement);
|
||||||
|
FormConfigElement formConfigElement = (FormConfigElement)confElement;
|
||||||
|
|
||||||
|
assertEquals("Submission URL was incorrect.", "submission/url",
|
||||||
|
formConfigElement.getSubmissionURL());
|
||||||
|
|
||||||
|
List<StringPair> expectedModelOverrideProperties = new ArrayList<StringPair>();
|
||||||
|
expectedModelOverrideProperties.add(new StringPair("fields.title.mandatory", "true"));
|
||||||
|
assertEquals("Expected property missing.", expectedModelOverrideProperties,
|
||||||
|
formConfigElement.getModelOverrideProperties());
|
||||||
|
|
||||||
|
// Get the form templates. Testing the mode and role combinations.
|
||||||
|
// For this config xml, there are no templates available to a user without a role.
|
||||||
|
assertNull("Incorrect template.", formConfigElement.getFormTemplate(Mode.CREATE, null));
|
||||||
|
assertNull("Incorrect template.", formConfigElement.getFormTemplate(Mode.EDIT, null));
|
||||||
|
assertNull("Incorrect template.", formConfigElement.getFormTemplate(Mode.VIEW, null));
|
||||||
|
assertNull("Incorrect template.", formConfigElement.getFormTemplate(Mode.CREATE, Collections.EMPTY_LIST));
|
||||||
|
assertNull("Incorrect template.", formConfigElement.getFormTemplate(Mode.EDIT, Collections.EMPTY_LIST));
|
||||||
|
assertNull("Incorrect template.", formConfigElement.getFormTemplate(Mode.VIEW, Collections.EMPTY_LIST));
|
||||||
|
|
||||||
|
List<String> roles = new ArrayList<String>();
|
||||||
|
roles.add("Consumer");
|
||||||
|
roles.add("Manager");
|
||||||
|
assertEquals("Incorrect template.", "/path/create/template", formConfigElement.getFormTemplate(Mode.CREATE, roles));
|
||||||
|
assertEquals("Incorrect template.", "/path/edit/template/manager", formConfigElement.getFormTemplate(Mode.EDIT, roles));
|
||||||
|
assertEquals("Incorrect template.", "/path/view/template", formConfigElement.getFormTemplate(Mode.VIEW, roles));
|
||||||
|
|
||||||
|
|
||||||
|
// Field visibility checks.
|
||||||
|
assertTrue("Field should be visible.", formConfigElement.isFieldVisible("name", Mode.CREATE));
|
||||||
|
assertTrue("Field should be visible.", formConfigElement.isFieldVisible("title", Mode.CREATE));
|
||||||
|
assertTrue("Field should be visible.", formConfigElement.isFieldVisible("quota", Mode.CREATE));
|
||||||
|
assertFalse("Field should be invisible.", formConfigElement.isFieldVisible("rubbish", Mode.CREATE));
|
||||||
|
|
||||||
|
assertTrue("Field should be visible.", formConfigElement.isFieldVisible("name", Mode.EDIT));
|
||||||
|
assertFalse("Field should be invisible.", formConfigElement.isFieldVisible("title", Mode.EDIT));
|
||||||
|
assertFalse("Field should be invisible.", formConfigElement.isFieldVisible("quota", Mode.EDIT));
|
||||||
|
assertFalse("Field should be invisible.", formConfigElement.isFieldVisible("rubbish", Mode.EDIT));
|
||||||
|
|
||||||
|
assertTrue("Field should be visible.", formConfigElement.isFieldVisible("name", Mode.VIEW));
|
||||||
|
assertTrue("Field should be visible.", formConfigElement.isFieldVisible("title", Mode.VIEW));
|
||||||
|
assertTrue("Field should be visible.", formConfigElement.isFieldVisible("quota", Mode.VIEW));
|
||||||
|
assertFalse("Field should be invisible.", formConfigElement.isFieldVisible("rubbish", Mode.VIEW));
|
||||||
|
|
||||||
|
// Set checks
|
||||||
|
List<String> expectedSetIds = new ArrayList<String>();
|
||||||
|
expectedSetIds.add("details");
|
||||||
|
expectedSetIds.add("user");
|
||||||
|
assertEquals("Set IDs were wrong.", expectedSetIds, formConfigElement.getSetIDs());
|
||||||
|
|
||||||
|
Map<String, FormSet> sets = formConfigElement.getSets();
|
||||||
|
assertEquals("Set parent was wrong.", "details", sets.get("user").getParentId());
|
||||||
|
assertEquals("Set parent was wrong.", null, sets.get("details").getParentId());
|
||||||
|
|
||||||
|
assertEquals("Set parent was wrong.", "fieldset", sets.get("details").getAppearance());
|
||||||
|
assertEquals("Set parent was wrong.", "panel", sets.get("user").getAppearance());
|
||||||
|
|
||||||
|
// Field checks
|
||||||
|
Map<String, FormField> fields = formConfigElement.getFields();
|
||||||
|
assertEquals("Wrong number of Fields.", 4, fields.size());
|
||||||
|
|
||||||
|
FormField usernameField = fields.get("username");
|
||||||
|
assertNotNull("usernameField was null.", usernameField);
|
||||||
|
assertTrue("Missing attribute.", usernameField.getAttributes().containsKey("set"));
|
||||||
|
assertEquals("Incorrect attribute.", "user", usernameField.getAttributes().get("set"));
|
||||||
|
assertNull("username field's template should be null.", usernameField.getTemplate());
|
||||||
|
|
||||||
|
FormField nameField = fields.get("name");
|
||||||
|
String nameTemplate = nameField.getTemplate();
|
||||||
|
assertNotNull("name field had null template", nameTemplate);
|
||||||
|
assertEquals("name field had incorrect template.", "alfresco/extension/formcontrols/my-name.ftl", nameTemplate);
|
||||||
|
|
||||||
|
List<StringPair> controlParams = nameField.getControlParams();
|
||||||
|
assertNotNull("name field should have control params.", controlParams);
|
||||||
|
assertEquals("name field has incorrect number of control params.", 1, controlParams.size());
|
||||||
|
|
||||||
|
assertEquals("Control param has wrong name.", "foo", controlParams.get(0).getName());
|
||||||
|
assertEquals("Control param has wrong value.", "bar", controlParams.get(0).getValue());
|
||||||
|
|
||||||
|
assertEquals("name field had incorrect type.", "REGEX", nameField.getConstraintType());
|
||||||
|
assertEquals("name field had incorrect message.",
|
||||||
|
"The name can not contain the character '{0}'", nameField.getConstraintMessage());
|
||||||
|
assertEquals("name field had incorrect message-id.", "field_error_name",
|
||||||
|
nameField.getConstraintMessageId());
|
||||||
|
|
||||||
|
// test that a call to the generic getChildren call throws an error
|
||||||
|
try
|
||||||
|
{
|
||||||
|
formConfigElement.getChildren();
|
||||||
|
fail("getChildren() did not throw an exception.");
|
||||||
|
} catch (ConfigException expectedException)
|
||||||
|
{
|
||||||
|
// intentionally empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private XMLConfigService initXMLConfigService(String xmlConfigFile)
|
private XMLConfigService initXMLConfigService(String xmlConfigFile)
|
||||||
{
|
{
|
||||||
String fullFileName = getResourcesDir() + xmlConfigFile;
|
String fullFileName = getResourcesDir() + xmlConfigFile;
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
<element-reader element-name="actions" class="org.alfresco.web.config.ActionsElementReader" />
|
<element-reader element-name="actions" class="org.alfresco.web.config.ActionsElementReader" />
|
||||||
<element-reader element-name="default-controls" class="org.alfresco.web.config.DefaultControlsElementReader"/>
|
<element-reader element-name="default-controls" class="org.alfresco.web.config.DefaultControlsElementReader"/>
|
||||||
<element-reader element-name="constraint-handlers" class="org.alfresco.web.config.ConstraintHandlersElementReader"/>
|
<element-reader element-name="constraint-handlers" class="org.alfresco.web.config.ConstraintHandlersElementReader"/>
|
||||||
<!-- <element-reader element-name="form" class="org.alfresco.web.config.FormElementReader"/> -->
|
<element-reader element-name="form" class="org.alfresco.web.config.FormElementReader"/>
|
||||||
</element-readers>
|
</element-readers>
|
||||||
</plug-ins>
|
</plug-ins>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user