first pass at edit form wizard

- modified evaluators to only show Create Form when in the Content Forms directory
- edit form evaluator which only shows the edit form action when inside of a form directory


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4627 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ariel Backenroth
2006-12-17 01:30:11 +00:00
parent d318fea7a9
commit 3175254cb4
12 changed files with 530 additions and 131 deletions

View File

@@ -18,12 +18,16 @@ package org.alfresco.web.action.evaluator;
import javax.faces.context.FacesContext;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.web.action.ActionEvaluator;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.NavigationBean;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.forms.FormsService;
/**
* UI Action Evaluator - Create Web Form in the Forms DataDictionary folder
@@ -37,10 +41,15 @@ public class CreateFormEvaluator implements ActionEvaluator
*/
public boolean evaluate(Node node)
{
PermissionService service =
Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getPermissionService();
return service.hasPermission(
FormsService.getInstance().getContentFormsNodeRef(),
PermissionService.ADD_CHILDREN) == AccessStatus.ALLOWED;
final FacesContext fc = FacesContext.getCurrentInstance();
final ServiceRegistry services = Repository.getServiceRegistry(fc);
final NavigationBean navigator = (NavigationBean)FacesHelper.getManagedBean(fc, NavigationBean.BEAN_NAME);
// get the path to the current name - compare last element with the Website folder assoc name
final Path path = services.getNodeService().getPath(navigator.getCurrentNode().getNodeRef());
final Path.Element element = path.get(path.size() - 1);
final String endPath = element.getPrefixedString(services.getNamespaceService());
// check we have the permission to create nodes in that Website folder
return (Application.getContentFormsFolderName(fc).equals(endPath) &&
navigator.getCurrentNode().hasPermission(PermissionService.ADD_CHILDREN));
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.action.evaluator;
import javax.faces.context.FacesContext;
import org.alfresco.model.WCMAppModel;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.web.action.ActionEvaluator;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.NavigationBean;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
/**
* UI Action Evaluator - Edit Web Form in the Forms DataDictionary folder
*
* @author Ariel Backenroth
*/
public class EditFormEvaluator implements ActionEvaluator
{
/**
* @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node)
*/
public boolean evaluate(Node node)
{
final FacesContext fc = FacesContext.getCurrentInstance();
final ServiceRegistry services = Repository.getServiceRegistry(fc);
final NavigationBean navigator = (NavigationBean)
FacesHelper.getManagedBean(fc, NavigationBean.BEAN_NAME);
// get the path to the current name - compare last element with the Website folder assoc name
final Node currentNode = navigator.getCurrentNode();
return (currentNode.hasAspect(WCMAppModel.ASPECT_FORM) &&
currentNode.hasPermission(PermissionService.ADD_CHILDREN));
}
}

View File

@@ -73,6 +73,7 @@ public class CreateFormWizard
implements Serializable
{
private final String fileName;
private final NodeRef nodeRef;
private final File file;
private final String title;
private final String description;
@@ -80,6 +81,18 @@ public class CreateFormWizard
private final String outputPathPatternForRendition;
private final RenderingEngine renderingEngine;
public RenderingEngineTemplateData(final RenderingEngineTemplate ret)
{
this.file = null;
this.nodeRef = ret.getNodeRef();
this.fileName = ret.getName();
this.title = ret.getTitle();
this.description = ret.getDescription();
this.outputPathPatternForRendition = ret.getOutputPathPattern();
this.mimetypeForRendition = ret.getMimetypeForRendition();
this.renderingEngine = ret.getRenderingEngine();
}
public RenderingEngineTemplateData(final String fileName,
final File file,
final String title,
@@ -88,6 +101,7 @@ public class CreateFormWizard
final String mimetypeForRendition,
final RenderingEngine renderingEngine)
{
this.nodeRef = null;
this.fileName = fileName;
this.file = file;
this.title = title;
@@ -116,6 +130,11 @@ public class CreateFormWizard
{
return this.file;
}
public NodeRef getNodeRef()
{
return this.nodeRef;
}
public String getTitle()
{
@@ -155,20 +174,25 @@ public class CreateFormWizard
private final static Log LOGGER = LogFactory.getLog(CreateFormWizard.class);
protected String defaultWorkflowName = null;
protected List<RenderingEngineTemplateData> renderingEngineTemplates = null;
protected transient XSModel schema;
protected String schemaFileName;
protected ContentService contentService;
protected MimetypeService mimetypeService;
protected WorkflowService workflowService;
private String schemaRootElementName = null;
private String formName = null;
private String formTitle = null;
private String formDescription = null;
private String outputPathPatternForFormInstanceData = null;
private String renderingEngineTemplateTitle = null;
private String renderingEngineTemplateDescription = null;
private String defaultWorkflowName = null;
private RenderingEngine renderingEngine = null;
protected ContentService contentService;
protected MimetypeService mimetypeService;
protected WorkflowService workflowService;
private transient DataModel renderingEngineTemplatesDataModel;
private List<RenderingEngineTemplateData> renderingEngineTemplates = null;
private String outputPathPatternForFormInstanceData = null;
protected transient DataModel renderingEngineTemplatesDataModel;
private String outputPathPatternForRendition = null;
private String mimetypeForRendition = null;
private transient List<SelectItem> mimetypeChoices = null;
@@ -181,7 +205,10 @@ public class CreateFormWizard
protected String finishImpl(final FacesContext context, final String outcome)
throws Exception
{
LOGGER.debug("creating form " + this.getFormName());
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("creating form " + this.getFormName());
}
final FormsService ts = FormsService.getInstance();
// get the node ref of the node that will contain the content
@@ -224,75 +251,82 @@ public class CreateFormWizard
for (RenderingEngineTemplateData retd : this.renderingEngineTemplates)
{
LOGGER.debug("adding rendering engine template " + retd +
" to form " + this.getFormName());
NodeRef renderingEngineTemplateNodeRef =
this.fileFolderService.searchSimple(folderInfo.getNodeRef(), retd.getFileName());
if (renderingEngineTemplateNodeRef == null)
{
try
{
fileInfo = this.fileFolderService.create(folderInfo.getNodeRef(),
retd.getFileName(),
ContentModel.TYPE_CONTENT);
if (LOGGER.isDebugEnabled())
LOGGER.debug("Created file node for file: " + retd.getFileName());
renderingEngineTemplateNodeRef = fileInfo.getNodeRef();
}
catch (final FileExistsException fee)
{
LOGGER.error(fee.getName() + " already exists in " +
fee.getParentNodeRef());
throw fee;
}
// get a writer for the content and put the file
writer = this.contentService.getWriter(renderingEngineTemplateNodeRef,
ContentModel.PROP_CONTENT,
true);
// set the mimetype and encoding
// XXXarielb mime type of template isn't known
// writer.setMimetype("text/xml");
writer.setEncoding("UTF-8");
writer.putContent(retd.getFile());
this.nodeService.createAssociation(folderInfo.getNodeRef(),
renderingEngineTemplateNodeRef,
WCMAppModel.ASSOC_RENDERING_ENGINE_TEMPLATES);
props = new HashMap<QName, Serializable>(2, 1.0f);
props.put(WCMAppModel.PROP_PARENT_RENDERING_ENGINE_NAME,
retd.getRenderingEngine().getName());
props.put(WCMAppModel.PROP_FORM_SOURCE, folderInfo.getNodeRef());
this.nodeService.addAspect(renderingEngineTemplateNodeRef,
WCMAppModel.ASPECT_RENDERING_ENGINE_TEMPLATE,
props);
// apply the titled aspect - title and description
props = new HashMap<QName, Serializable>(2, 1.0f);
props.put(ContentModel.PROP_TITLE, retd.getTitle());
props.put(ContentModel.PROP_DESCRIPTION, retd.getDescription());
this.nodeService.addAspect(renderingEngineTemplateNodeRef,
ContentModel.ASPECT_TITLED,
props);
}
LOGGER.debug("adding rendition properties to " + renderingEngineTemplateNodeRef);
props = new HashMap<QName, Serializable>(2, 1.0f);
props.put(WCMAppModel.PROP_OUTPUT_PATH_PATTERN_RENDITION,
retd.getOutputPathPatternForRendition());
props.put(WCMAppModel.PROP_MIMETYPE_FOR_RENDITION,
retd.getMimetypeForRendition());
this.nodeService.createNode(renderingEngineTemplateNodeRef,
WCMAppModel.ASSOC_RENDITION_PROPERTIES,
WCMAppModel.ASSOC_RENDITION_PROPERTIES,
WCMAppModel.TYPE_RENDITION_PROPERTIES,
props);
this.saveRenderingEngineTemplate(retd, folderInfo.getNodeRef());
}
// return the default outcome
return outcome;
}
protected void saveRenderingEngineTemplate(final RenderingEngineTemplateData retd,
final NodeRef formNodeRef)
{
LOGGER.debug("adding rendering engine template " + retd +
" to form " + this.getFormName());
NodeRef renderingEngineTemplateNodeRef =
this.fileFolderService.searchSimple(formNodeRef, retd.getFileName());
HashMap<QName, Serializable> props;
if (renderingEngineTemplateNodeRef == null)
{
try
{
final FileInfo fileInfo = this.fileFolderService.create(formNodeRef,
retd.getFileName(),
ContentModel.TYPE_CONTENT);
if (LOGGER.isDebugEnabled())
LOGGER.debug("Created file node for file: " + retd.getFileName());
renderingEngineTemplateNodeRef = fileInfo.getNodeRef();
}
catch (final FileExistsException fee)
{
LOGGER.error(fee.getName() + " already exists in " +
fee.getParentNodeRef());
throw fee;
}
// get a writer for the content and put the file
final ContentWriter writer = this.contentService.getWriter(renderingEngineTemplateNodeRef,
ContentModel.PROP_CONTENT,
true);
// set the mimetype and encoding
// XXXarielb mime type of template isn't known
// writer.setMimetype("text/xml");
writer.setEncoding("UTF-8");
writer.putContent(retd.getFile());
this.nodeService.createAssociation(formNodeRef,
renderingEngineTemplateNodeRef,
WCMAppModel.ASSOC_RENDERING_ENGINE_TEMPLATES);
props = new HashMap<QName, Serializable>(2, 1.0f);
props.put(WCMAppModel.PROP_PARENT_RENDERING_ENGINE_NAME,
retd.getRenderingEngine().getName());
props.put(WCMAppModel.PROP_FORM_SOURCE, formNodeRef);
this.nodeService.addAspect(renderingEngineTemplateNodeRef,
WCMAppModel.ASPECT_RENDERING_ENGINE_TEMPLATE,
props);
// apply the titled aspect - title and description
props = new HashMap<QName, Serializable>(2, 1.0f);
props.put(ContentModel.PROP_TITLE, retd.getTitle());
props.put(ContentModel.PROP_DESCRIPTION, retd.getDescription());
this.nodeService.addAspect(renderingEngineTemplateNodeRef,
ContentModel.ASPECT_TITLED,
props);
}
LOGGER.debug("adding rendition properties to " + renderingEngineTemplateNodeRef);
props = new HashMap<QName, Serializable>(2, 1.0f);
props.put(WCMAppModel.PROP_OUTPUT_PATH_PATTERN_RENDITION,
retd.getOutputPathPatternForRendition());
props.put(WCMAppModel.PROP_MIMETYPE_FOR_RENDITION,
retd.getMimetypeForRendition());
this.nodeService.createNode(renderingEngineTemplateNodeRef,
WCMAppModel.ASSOC_RENDITION_PROPERTIES,
WCMAppModel.ASSOC_RENDITION_PROPERTIES,
WCMAppModel.TYPE_RENDITION_PROPERTIES,
props);
}
@Override
public void init(Map<String, String> parameters)
{
@@ -300,6 +334,8 @@ public class CreateFormWizard
this.removeUploadedSchemaFile();
this.removeUploadedRenderingEngineTemplateFile();
this.schema = null;
this.schemaFileName = null;
this.schemaRootElementName = null;
this.schemaRootElementNameChoices = null;
this.formName = null;
@@ -331,7 +367,7 @@ public class CreateFormWizard
// checking step numbers
boolean disabled = false;
int step = Application.getWizardManager().getCurrentStep();
final int step = Application.getWizardManager().getCurrentStep();
switch(step)
{
case 1:
@@ -468,8 +504,10 @@ public class CreateFormWizard
*/
public String removeUploadedSchemaFile()
{
clearUpload(FILE_SCHEMA);
this.clearUpload(FILE_SCHEMA);
this.schemaRootElementNameChoices = null;
this.schema = null;
this.schemaFileName = null;
// refresh the current page
return null;
@@ -491,13 +529,17 @@ public class CreateFormWizard
*/
public String schemaFileValueChanged(final ValueChangeEvent vce)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("schemaFileValueChanged(" + this.getSchemaFile() + ")");
}
if (this.getSchemaFile() != null)
{
final FormsService ts = FormsService.getInstance();
try
{
final Document d = ts.parseXML(this.getSchemaFile());
final XSModel xsm = SchemaUtil.loadSchema(d);
final FormsService formsService = FormsService.getInstance();
final Document d = formsService.parseXML(this.getSchemaFile());
this.schema = SchemaUtil.parseSchema(d);
}
catch (Exception e)
{
@@ -512,6 +554,12 @@ public class CreateFormWizard
// ------------------------------------------------------------------------------
// Bean Getters and Setters
/** Indicates whether or not the wizard is currently in edit mode */
public boolean getEditMode()
{
return false;
}
/**
* Returns the properties for current configured output methods JSF DataModel
*
@@ -644,15 +692,23 @@ public class CreateFormWizard
{
return this.getFile(FILE_SCHEMA);
}
/**
* Sets the schema file name
*/
public void setSchemaFileName(final String schemaFileName)
{
this.schemaFileName = (schemaFileName != null && schemaFileName.length() != 0
? schemaFileName
: null);
}
/**
* @return Returns the schema file or <tt>null</tt>
*/
public String getSchemaFileName()
{
// try and retrieve the file and filename from the file upload bean
// representing the file we previously uploaded.
return this.getFileName(FILE_SCHEMA);
return this.schemaFileName;
}
/**
@@ -693,33 +749,27 @@ public class CreateFormWizard
*/
public List<SelectItem> getSchemaRootElementNameChoices()
{
if (this.getSchemaFile() == null)
List<SelectItem> result = Collections.EMPTY_LIST;
if (this.schema != null)
{
return Collections.EMPTY_LIST;
}
if (this.schemaRootElementNameChoices == null)
{
this.schemaRootElementNameChoices = new LinkedList<SelectItem>();
final FormsService ts = FormsService.getInstance();
try
if (this.schemaRootElementNameChoices == null)
{
final Document d = ts.parseXML(this.getSchemaFile());
final XSModel xsm = SchemaUtil.loadSchema(d);
final XSNamedMap elementsMap = xsm.getComponents(XSConstants.ELEMENT_DECLARATION);
this.schemaRootElementNameChoices = new LinkedList<SelectItem>();
final XSNamedMap elementsMap = this.schema.getComponents(XSConstants.ELEMENT_DECLARATION);
for (int i = 0; i < elementsMap.getLength(); i++)
{
final XSElementDeclaration e = (XSElementDeclaration)elementsMap.item(i);
this.schemaRootElementNameChoices.add(new SelectItem(e.getName(), e.getName()));
}
}
catch (Exception e)
{
final String msg = "unable to parse " + this.getSchemaFileName();
this.removeUploadedSchemaFile();
Utils.addErrorMessage(msg, e);
}
result = this.schemaRootElementNameChoices;
}
return this.schemaRootElementNameChoices;
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("getSchemaRootElementNameChoices(" + this.schema +
") = " + result.size());
}
return result;
}
/**

View File

@@ -0,0 +1,196 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.bean.wcm;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMAppModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.web.app.AlfrescoNavigationHandler;
import org.alfresco.web.forms.xforms.SchemaUtil;
import org.alfresco.web.forms.Form;
import org.alfresco.web.forms.FormsService;
import org.alfresco.web.forms.RenderingEngineTemplate;
import org.alfresco.web.ui.common.Utils;
/**
* Backing bean for the Edit Form wizard.
*
* @author Ariel Backenroth
*/
public class EditFormWizard
extends CreateFormWizard
{
private List<RenderingEngineTemplateData> removedRenderingEngineTemplates;
// ------------------------------------------------------------------------------
// Wizard implementation
/**
* Initialises the wizard
*/
@Override
public void init(final Map<String, String> parameters)
{
super.init(parameters);
// the editMode flag is used to disabled some wizard fields
// this.editMode = true;
final NodeRef formNodeRef = this.browseBean.getActionSpace().getNodeRef();
if (formNodeRef == null)
{
throw new IllegalArgumentException("Edit Form wizard requires action node context.");
}
final Form form = FormsService.getInstance().getForm(formNodeRef);
// simple properties
this.setFormName(form.getName());
this.setFormTitle(form.getTitle());
this.setFormDescription(form.getDescription());
this.setSchemaRootElementName(form.getSchemaRootElementName());
final NodeRef schemaNodeRef = (NodeRef)
this.nodeService.getProperty(formNodeRef, WCMAppModel.PROP_XML_SCHEMA);
this.setSchemaFileName((String)this.nodeService.getProperty(schemaNodeRef,
ContentModel.PROP_NAME));
try
{
this.schema = SchemaUtil.parseSchema(form.getSchema());
}
catch (Throwable t)
{
final String msg = "unable to parse " + form.getName();
Utils.addErrorMessage(msg, t);
}
final WorkflowDefinition wf = form.getDefaultWorkflow();
if (wf != null)
{
this.defaultWorkflowName = wf.getName();
}
this.setOutputPathPatternForFormInstanceData(form.getOutputPathPattern());
for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates())
{
final RenderingEngineTemplateData data =
this.new RenderingEngineTemplateData(ret);
this.renderingEngineTemplates.add(data);
}
}
/**
* @see org.alfresco.web.bean.dialog.BaseDialogBean#finishImpl(javax.faces.context.FacesContext, java.lang.String)
*/
@Override
protected String finishImpl(FacesContext context, String outcome)
throws Exception
{
final NodeRef formNodeRef = this.browseBean.getActionSpace().getNodeRef();
// apply the name, title and description props
this.nodeService.setProperty(formNodeRef, ContentModel.PROP_NAME, this.getFormName());
this.nodeService.setProperty(formNodeRef, ContentModel.PROP_TITLE, this.getFormTitle());
this.nodeService.setProperty(formNodeRef, ContentModel.PROP_DESCRIPTION, this.getFormDescription());
this.nodeService.setProperty(formNodeRef,
WCMAppModel.PROP_OUTPUT_PATH_PATTERN_FORM_INSTANCE_DATA,
this.getOutputPathPatternForFormInstanceData());
this.nodeService.setProperty(formNodeRef,
WCMAppModel.PROP_XML_SCHEMA_ROOT_ELEMENT_NAME,
this.getSchemaRootElementName());
final WorkflowDefinition wd = this.getDefaultWorkflowDefinition();
if (wd != null)
{
this.nodeService.setProperty(formNodeRef,
WCMAppModel.PROP_DEFAULT_WORKFLOW_NAME,
wd.getName());
}
if (this.getSchemaFile() != null)
{
FileInfo fileInfo =
this.fileFolderService.create(formNodeRef,
this.getSchemaFileName(),
ContentModel.TYPE_CONTENT);
// get a writer for the content and put the file
final ContentWriter writer = this.contentService.getWriter(fileInfo.getNodeRef(),
ContentModel.PROP_CONTENT,
true);
// set the mimetype and encoding
writer.setMimetype(MimetypeMap.MIMETYPE_XML);
writer.setEncoding("UTF-8");
writer.putContent(this.getSchemaFile());
this.nodeService.setProperty(formNodeRef,
WCMAppModel.PROP_XML_SCHEMA,
fileInfo.getNodeRef());
}
for (RenderingEngineTemplateData retd : this.removedRenderingEngineTemplates)
{
this.nodeService.removeChild(formNodeRef, retd.getNodeRef());
}
for (RenderingEngineTemplateData retd : this.renderingEngineTemplates)
{
if (retd.getFile() != null)
{
this.saveRenderingEngineTemplate(retd, formNodeRef);
}
}
return AlfrescoNavigationHandler.CLOSE_WIZARD_OUTCOME;
}
/**
* Action handler called when the Remove button is pressed to remove a
* rendering engine
*/
@Override
public void removeSelectedRenderingEngineTemplate(final ActionEvent event)
{
final RenderingEngineTemplateData wrapper = (RenderingEngineTemplateData)
this.renderingEngineTemplatesDataModel.getRowData();
if (wrapper != null)
{
if (this.removedRenderingEngineTemplates == null)
{
this.removedRenderingEngineTemplates = new LinkedList<RenderingEngineTemplateData>();
}
this.removedRenderingEngineTemplates.add(wrapper);
}
super.removeSelectedRenderingEngineTemplate(event);
}
/** Indicates whether or not the wizard is currently in edit mode */
public boolean getEditMode()
{
return true;
}
}

View File

@@ -255,7 +255,7 @@ public class SchemaFormBuilder
final ResourceBundle resourceBundle)
throws FormBuilderException
{
final XSModel schema = SchemaUtil.loadSchema(schemaDocument);
final XSModel schema = SchemaUtil.parseSchema(schemaDocument);
this.typeTree = SchemaUtil.buildTypeTree(schema);
//refCounter = 0;

View File

@@ -202,7 +202,7 @@ public class SchemaUtil
return SchemaUtil.DATA_TYPE_TO_NAME.get(type);
}
public static XSModel loadSchema(final Document schemaDocument)
public static XSModel parseSchema(final Document schemaDocument)
throws FormBuilderException
{
try