first pass at summary screen for create web content.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@4368 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ariel Backenroth
2006-11-16 07:28:33 +00:00
parent 67aab090e5
commit 612dd27044
11 changed files with 379 additions and 42 deletions

View File

@@ -652,6 +652,10 @@ create_form_configure_rendering_engine_templates_title=Step Two - Configure Rend
create_form_configure_rendering_engine_templates_desc=Enter information about the rendering engine templates you want to use for this form. create_form_configure_rendering_engine_templates_desc=Enter information about the rendering engine templates you want to use for this form.
create_form_select_default_workflow_title=Stop Three - Select default workflow create_form_select_default_workflow_title=Stop Three - Select default workflow
create_form_select_default_workflow_desc=Select the workflow you want to be used by default for this form. create_form_select_default_workflow_desc=Select the workflow you want to be used by default for this form.
create_form_summary_desc=The wizard has successfully created the content and all renditions.
create_form_summary_content_details=Content Details
create_form_summary_rendition_details=Rendition Details
create_form_summary_submit_message=Submit {0} when wizard finishes.
selected_rendering_engines=Selected Rendering Engines selected_rendering_engines=Selected Rendering Engines
create_form_configure_rendering_engines_title=Configure Rendering Engines create_form_configure_rendering_engines_title=Configure Rendering Engines

View File

@@ -230,9 +230,9 @@
instruction-id="default_instruction" /> instruction-id="default_instruction" />
</step> </step>
<step name="summary" title-id="summary" description-id="summary_step_description"> <step name="summary" title-id="summary" description-id="summary_step_description">
<page path="/jsp/wizard/summary.jsp" <page path="/jsp/wcm/create-web-content-wizard/summary.jsp"
title-id="summary" title-id="summary"
description-id="summary_desc" description-id="create_form_summary_desc"
instruction-id="content_finish_instruction" /> instruction-id="content_finish_instruction" />
</step> </step>
</wizard> </wizard>

View File

@@ -370,15 +370,6 @@ public class CreateFormWizard
*/ */
public void addSelectedRenderingEngineTemplate(final ActionEvent event) public void addSelectedRenderingEngineTemplate(final ActionEvent event)
{ {
for (RenderingEngineTemplateData retd : this.renderingEngineTemplates)
{
if (retd.getOutputPathPatternForRendition().equals(this.outputPathPatternForRendition))
{
throw new AlfrescoRuntimeException("rendering engine template with output path " + this.outputPathPatternForRendition +
" already exists");
}
}
final RenderingEngineTemplateData data = final RenderingEngineTemplateData data =
this.new RenderingEngineTemplateData(this.getRenderingEngineTemplateFileName(), this.new RenderingEngineTemplateData(this.getRenderingEngineTemplateFileName(),
this.getRenderingEngineTemplateFile(), this.getRenderingEngineTemplateFile(),

View File

@@ -46,9 +46,7 @@ import org.alfresco.web.app.Application;
import org.alfresco.web.bean.content.BaseContentWizard; import org.alfresco.web.bean.content.BaseContentWizard;
import org.alfresco.web.data.IDataContainer; import org.alfresco.web.data.IDataContainer;
import org.alfresco.web.data.QuickSort; import org.alfresco.web.data.QuickSort;
import org.alfresco.web.forms.Form; import org.alfresco.web.forms.*;
import org.alfresco.web.forms.FormProcessor;
import org.alfresco.web.forms.FormsService;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document; import org.w3c.dom.Document;
@@ -64,7 +62,9 @@ public class CreateWebContentWizard extends BaseContentWizard
protected String formName; protected String formName;
protected List<SelectItem> createMimeTypes; protected List<SelectItem> createMimeTypes;
protected String createdPath = null; protected String createdPath = null;
protected List<Rendition> renditions = null;
protected FormInstanceData formInstanceData = null;
/** AVM service bean reference */ /** AVM service bean reference */
protected AVMService avmService; protected AVMService avmService;
@@ -88,7 +88,6 @@ public class CreateWebContentWizard extends BaseContentWizard
this.avmBrowseBean = avmBrowseBean; this.avmBrowseBean = avmBrowseBean;
} }
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Wizard implementation // Wizard implementation
@@ -96,19 +95,6 @@ public class CreateWebContentWizard extends BaseContentWizard
protected String finishImpl(FacesContext context, String outcome) protected String finishImpl(FacesContext context, String outcome)
throws Exception throws Exception
{ {
if (logger.isDebugEnabled())
logger.debug("saving file content to " + this.fileName);
saveContent(null, this.content);
if (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.formName != null)
{
final Form form = this.getForm();
final NodeRef formInstanceDataNodeRef =
AVMNodeConverter.ToNodeRef(-1, this.createdPath);
form.registerFormInstanceData(formInstanceDataNodeRef);
FormsService.getInstance().generateRenditions(formInstanceDataNodeRef);
}
// return the default outcome // return the default outcome
return outcome; return outcome;
@@ -125,6 +111,8 @@ public class CreateWebContentWizard extends BaseContentWizard
*/ */
protected void saveContent(File fileContent, String strContent) throws Exception protected void saveContent(File fileContent, String strContent) throws Exception
{ {
if (logger.isDebugEnabled())
logger.debug("saving file content to " + this.fileName);
// get the parent path of the location to save the content // get the parent path of the location to save the content
String path = this.avmBrowseBean.getCurrentPath(); String path = this.avmBrowseBean.getCurrentPath();
if (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.formName != null) if (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.formName != null)
@@ -158,10 +146,18 @@ public class CreateWebContentWizard extends BaseContentWizard
this.createdPath = path + '/' + this.fileName; this.createdPath = path + '/' + this.fileName;
// add titled aspect for the read/edit properties screens // add titled aspect for the read/edit properties screens
NodeRef fileRef = AVMNodeConverter.ToNodeRef(-1, this.createdPath); final NodeRef formInstanceDataNodeRef = AVMNodeConverter.ToNodeRef(-1, this.createdPath);
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(1, 1.0f); Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(1, 1.0f);
titledProps.put(ContentModel.PROP_TITLE, this.fileName); titledProps.put(ContentModel.PROP_TITLE, this.fileName);
this.nodeService.addAspect(fileRef, ContentModel.ASPECT_TITLED, titledProps); this.nodeService.addAspect(formInstanceDataNodeRef, ContentModel.ASPECT_TITLED, titledProps);
this.formInstanceData = new FormInstanceDataImpl(formInstanceDataNodeRef);
if (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.formName != null)
{
final Form form = this.getForm();
form.registerFormInstanceData(formInstanceDataNodeRef);
this.renditions = FormsService.getInstance().generateRenditions(formInstanceDataNodeRef);
}
} }
@Override @Override
@@ -331,21 +327,37 @@ public class CreateWebContentWizard extends BaseContentWizard
} }
}; };
} }
public FormInstanceData getFormInstanceData()
throws Exception
{
if (this.formInstanceData == null)
{
this.saveContent(null, this.content);
}
return this.formInstanceData;
}
public List<Rendition> getRenditions()
{
return this.renditions;
}
/** /**
* @return Returns the summary data for the wizard. * @return Returns the summary data for the wizard.
*/ */
public String getSummary() public String getSummary()
{ {
ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance()); ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance());
// TODO: show first few lines of content here? // TODO: show first few lines of content here?
return buildSummary( return buildSummary(
new String[] {bundle.getString("file_name"), new String[] {bundle.getString("file_name"),
bundle.getString("type"), bundle.getString("content_type"),
bundle.getString("content_type")}, bundle.getString("Location")},
new String[] {this.fileName, getSummaryObjectType(), new String[] {this.fileName, getSummaryObjectType(),
getSummaryMimeType(this.mimeType)}); getSummaryMimeType(this.mimeType)});
} }

View File

@@ -50,7 +50,7 @@ import org.apache.commons.logging.LogFactory;
import org.w3c.dom.*; import org.w3c.dom.*;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
public class FormImpl class FormImpl
implements Form implements Form
{ {
private static final Log LOGGER = LogFactory.getLog(FormImpl.class); private static final Log LOGGER = LogFactory.getLog(FormImpl.class);

View File

@@ -0,0 +1,38 @@
/*
* 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.forms;
import java.io.Serializable;
/**
* Encapsulation of form instance data.
*
* @author Ariel Backenroth
*/
public interface FormInstanceData
extends Serializable
{
/** the form generate this form instance data */
public Form getForm();
/** the name of this instance data */
public String getName();
/** the path relative to the containing webapp */
public String getWebappRelativePath();
}

View File

@@ -0,0 +1,87 @@
/*
* 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.forms;
import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.TemplateNode;
import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.bean.wcm.AVMConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Encapsulation of a rendition.
*
* @author Ariel Backenroth
*/
public class FormInstanceDataImpl
implements FormInstanceData
{
private final NodeRef nodeRef;
public FormInstanceDataImpl(final NodeRef nodeRef)
{
this.nodeRef = nodeRef;
}
/** the name of this rendition */
public String getName()
{
final NodeService nodeService = this.getServiceRegistry().getNodeService();
return (String)
nodeService.getProperty(this.nodeRef, ContentModel.PROP_NAME);
}
/** the path relative to the containing webapp */
public String getWebappRelativePath()
{
return AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond();
}
public Form getForm()
{
final NodeService nodeService = this.getServiceRegistry().getNodeService();
final NodeRef formNodeRef = (NodeRef)
nodeService.getProperty(this.nodeRef,
WCMModel.PROP_PARENT_FORM);
return new FormImpl(formNodeRef);
}
/** the node ref containing the contents of this rendition */
public NodeRef getNodeRef()
{
return this.nodeRef;
}
private ServiceRegistry getServiceRegistry()
{
final FacesContext fc = FacesContext.getCurrentInstance();
return Repository.getServiceRegistry(fc);
}
}

View File

@@ -275,7 +275,7 @@ public final class FormsService
* *
* @param formInstanceDataNodeRef the noderef containing the form instance data * @param formInstanceDataNodeRef the noderef containing the form instance data
*/ */
public void generateRenditions(final NodeRef formInstanceDataNodeRef) public List<Rendition> generateRenditions(final NodeRef formInstanceDataNodeRef)
throws IOException, throws IOException,
SAXException, SAXException,
RenderingEngine.RenderingException RenderingEngine.RenderingException
@@ -291,6 +291,7 @@ public final class FormsService
AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond(); AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond();
LOGGER.debug("generating renditions for " + formInstanceDataAvmPath); LOGGER.debug("generating renditions for " + formInstanceDataAvmPath);
final List<Rendition> result = new LinkedList<Rendition>();
for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates()) for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates())
{ {
// get the node ref of the node that will contain the content // get the node ref of the node that will contain the content
@@ -312,17 +313,17 @@ public final class FormsService
final NodeRef renditionNodeRef = final NodeRef renditionNodeRef =
AVMNodeConverter.ToNodeRef(-1, renditionAvmPath); AVMNodeConverter.ToNodeRef(-1, renditionAvmPath);
form.registerFormInstanceData(renditionNodeRef); form.registerFormInstanceData(renditionNodeRef);
ret.registerRendition(renditionNodeRef, formInstanceDataNodeRef); ret.registerRendition(renditionNodeRef, formInstanceDataNodeRef);
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1, 1.0f); Map<QName, Serializable> props = new HashMap<QName, Serializable>(1, 1.0f);
props.put(ContentModel.PROP_TITLE, AVMNodeConverter.SplitBase(renditionAvmPath)[1]); props.put(ContentModel.PROP_TITLE, AVMNodeConverter.SplitBase(renditionAvmPath)[1]);
nodeService.addAspect(renditionNodeRef, ContentModel.ASPECT_TITLED, props); nodeService.addAspect(renditionNodeRef, ContentModel.ASPECT_TITLED, props);
result.add(new RenditionImpl(renditionNodeRef));
if (LOGGER.isDebugEnabled()) if (LOGGER.isDebugEnabled())
LOGGER.debug("generated " + renditionAvmPath + " using " + ret); LOGGER.debug("generated " + renditionAvmPath + " using " + ret);
} }
return result;
} }
/** /**
@@ -330,7 +331,7 @@ public final class FormsService
* *
* @param formInstanceDataNodeRef the node ref containing the form instance data. * @param formInstanceDataNodeRef the node ref containing the form instance data.
*/ */
public void regenerateRenditions(final NodeRef formInstanceDataNodeRef) public List<Rendition> regenerateRenditions(final NodeRef formInstanceDataNodeRef)
throws IOException, throws IOException,
SAXException, SAXException,
RenderingEngine.RenderingException RenderingEngine.RenderingException
@@ -348,7 +349,7 @@ public final class FormsService
// other parameter values passed to rendering engine // other parameter values passed to rendering engine
final String formInstanceDataAvmPath = AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond(); final String formInstanceDataAvmPath = AVMNodeConverter.ToAVMVersionPath(formInstanceDataNodeRef).getSecond();
LOGGER.debug("regenerating renditions for " + formInstanceDataAvmPath); LOGGER.debug("regenerating renditions for " + formInstanceDataAvmPath);
final List<Rendition> result = new LinkedList<Rendition>();
for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates()) for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates())
{ {
final String renditionAvmPath = final String renditionAvmPath =
@@ -376,9 +377,13 @@ public final class FormsService
ret.getRenderingEngine().render(formInstanceData, ret, parameters, out); ret.getRenderingEngine().render(formInstanceData, ret, parameters, out);
out.close(); out.close();
final NodeRef renditionNodeRef =
AVMNodeConverter.ToNodeRef(-1, renditionAvmPath);
result.add(new RenditionImpl(renditionNodeRef));
if (LOGGER.isDebugEnabled()) if (LOGGER.isDebugEnabled())
LOGGER.debug("generated " + renditionAvmPath + " using " + ret); LOGGER.debug("regenerated " + renditionAvmPath + " using " + ret);
} }
return result;
} }
private static String getOutputAvmPathForRendition(final RenderingEngineTemplate ret, private static String getOutputAvmPathForRendition(final RenderingEngineTemplate ret,

View File

@@ -0,0 +1,44 @@
/*
* 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.forms;
import org.alfresco.service.cmr.repository.NodeRef;
import java.io.Serializable;
/**
* Encapsulation of a rendition.
*
* @author Ariel Backenroth
*/
public interface Rendition
extends Serializable
{
/** the name of this instance data */
public String getName();
/** the path relative to the containing webapp */
public String getWebappRelativePath();
/** the primary form instance data used to generate this rendition */
public FormInstanceData getPrimaryFormInstanceData();
/** the rendering engine template that generated this rendition */
public RenderingEngineTemplate getRenderingEngineTemplate();
/** the node ref containing the contents of this rendition */
public NodeRef getNodeRef();
}

View File

@@ -0,0 +1,101 @@
/*
* 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.forms;
import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.TemplateNode;
import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.bean.wcm.AVMConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Encapsulation of a rendition.
*
* @author Ariel Backenroth
*/
public class RenditionImpl
implements Rendition
{
private final NodeRef nodeRef;
public RenditionImpl(final NodeRef nodeRef)
{
this.nodeRef = nodeRef;
}
/** the name of this rendition */
public String getName()
{
final NodeService nodeService = this.getServiceRegistry().getNodeService();
return (String)
nodeService.getProperty(this.nodeRef, ContentModel.PROP_NAME);
}
/** the path relative to the containing webapp */
public String getWebappRelativePath()
{
return AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond();
}
public FormInstanceData getPrimaryFormInstanceData()
{
final NodeService nodeService = this.getServiceRegistry().getNodeService();
final NodeRef fidNodeRef = (NodeRef)
nodeService.getProperty(this.nodeRef,
WCMModel.PROP_PRIMARY_FORM_INSTANCE_DATA);
return new FormInstanceDataImpl(fidNodeRef);
}
/** the rendering engine template that generated this rendition */
public RenderingEngineTemplate getRenderingEngineTemplate()
{
final NodeService nodeService = this.getServiceRegistry().getNodeService();
final NodeRef retNodeRef = (NodeRef)
nodeService.getProperty(this.nodeRef,
WCMModel.PROP_PARENT_RENDERING_ENGINE_TEMPLATE);
final NodeRef rpNodeRef = (NodeRef)
nodeService.getProperty(this.nodeRef,
WCMModel.PROP_PARENT_RENDITION_PROPERTIES);
return new RenderingEngineTemplateImpl(retNodeRef, rpNodeRef);
}
/** the node ref containing the contents of this rendition */
public NodeRef getNodeRef()
{
return this.nodeRef;
}
private ServiceRegistry getServiceRegistry()
{
final FacesContext fc = FacesContext.getCurrentInstance();
return Repository.getServiceRegistry(fc);
}
}

View File

@@ -0,0 +1,55 @@
<%--
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.
--%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
<%@ page isELIgnored="false" %>
<script type="text/javascript">
window.onload = function() { document.getElementById("wizard:finish-button").focus(); }
</script>
<h:panelGrid columns="1" cellpadding="2" style="padding-top: 4px; padding-bottom: 4px;"
width="100%" rowClasses="wizardSectionHeading">
<h:outputText value="&nbsp;#{msg.create_form_summary_content_details}" escape="false" />
</h:panelGrid>
<h:panelGrid columns="2" cellpadding="3" cellspacing="3" border="0">
<h:outputText value="#{msg.name}:"/>
<h:outputText value="#{WizardManager.bean.formInstanceData.name}"/>
<h:outputText value="#{msg.location}:"/>
<h:outputText value="#{WizardManager.bean.formInstanceData.webappRelativePath}"/>
<h:outputText value="#{msg.form}:"/>
<h:outputText value="#{WizardManager.bean.formInstanceData.form.name}"/>
</h:panelGrid>
<h:panelGrid columns="1" cellpadding="2" style="padding-top: 4px; padding-bottom: 4px;"
width="100%" rowClasses="wizardSectionHeading">
<h:outputText value="&nbsp;#{msg.create_form_summary_rendition_details}" escape="false" />
</h:panelGrid>
<h:panelGrid columns="2" cellpadding="3" cellspacing="3" border="0">
<c:forEach items="${WizardManager.bean.renditions}" var="rendition">
<h:outputText value="#{msg.name}:"/>
<f:verbatim>${rendition.name}</f:verbatim>
<h:outputText value="#{msg.location}:"/>
<f:verbatim>${rendition.webappRelativePath}</f:verbatim>
</c:forEach>
</h:panelGrid>
<h:outputText value="&nbsp;#{msg.create_form_summary_submit_message}" escape="false" />