diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java index 0c44fb1bb4..f35b21b746 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -558,6 +558,10 @@ public class AVMBrowseBean implements IContextListener */ public void setAVMActionNodeDescriptor(AVMNodeDescriptor avmRef) { + if (avmRef == null) + { + throw new NullPointerException(); + } AVMNode avmNode = new AVMNode(avmRef); this.avmNode = avmNode; } diff --git a/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java b/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java index dac755271b..3f6296747e 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java @@ -289,6 +289,15 @@ public class AVMEditBean return this.instanceDataDocument; } + /** + * Returns the name of the form instance data for display purposes. + */ + public String getFormInstanceDataName() + { + final FormInstanceData fid = new FormInstanceDataImpl(-1, this.getAvmNode().getPath()); + return fid.getName().replaceAll("(.+)\\..*", "$1"); + } + /** * Returns the form processor session. */ @@ -448,30 +457,7 @@ public class AVMEditBean // regenerate form content if (this.avmService.hasAspect(-1, avmPath, WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) { - final FormInstanceData fid = new FormInstanceDataImpl(AVMNodeConverter.ToNodeRef(-1, avmPath)) - { - @Override - public Form getForm() { return AVMEditBean.this.getForm(); } - }; - - if (LOGGER.isDebugEnabled()) - LOGGER.debug("regenerating renditions of " + fid); - - for (Rendition rendition : fid.getRenditions()) - { - try - { - rendition.regenerate(fid); - } - catch (Exception e) - { - - Utils.addErrorMessage("error regenerating " + rendition.getName() + - " using " + rendition.getRenderingEngineTemplate().getName() + - ": " + e.getMessage(), - e); - } - } + this.regenerateRenditions(); final NodeRef[] uploadedFiles = this.formProcessorSession.getUploadedFiles(); if (LOGGER.isDebugEnabled()) @@ -534,7 +520,10 @@ public class AVMEditBean // commit the transaction tx.commit(); - + if (this.avmService.hasAspect(-1, node.getPath(), WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) + { + this.regenerateRenditions(); + } // Possibly notify virt server AVMConstants.updateVServerWebapp(node.getPath(), false); @@ -595,4 +584,32 @@ public class AVMEditBean FacesContext ctx = FacesContext.getCurrentInstance(); ctx.getExternalContext().getSessionMap().remove(FileUploadBean.FILE_UPLOAD_BEAN_NAME); } + + private void regenerateRenditions() + { + final String avmPath = this.getAvmNode().getPath(); + final FormInstanceData fid = new FormInstanceDataImpl(AVMNodeConverter.ToNodeRef(-1, avmPath)) + { + @Override + public Form getForm() { return AVMEditBean.this.getForm(); } + }; + + if (LOGGER.isDebugEnabled()) + LOGGER.debug("regenerating renditions of " + fid); + + for (Rendition rendition : fid.getRenditions()) + { + try + { + rendition.regenerate(fid); + } + catch (Exception e) + { + Utils.addErrorMessage("error regenerating " + rendition.getName() + + " using " + rendition.getRenderingEngineTemplate().getName() + + ": " + e.getMessage(), + e); + } + } + } } diff --git a/source/java/org/alfresco/web/forms/FormImpl.java b/source/java/org/alfresco/web/forms/FormImpl.java index 2f4a6d966d..7df6b1e330 100644 --- a/source/java/org/alfresco/web/forms/FormImpl.java +++ b/source/java/org/alfresco/web/forms/FormImpl.java @@ -33,6 +33,7 @@ import java.io.*; import java.net.URI; import java.util.*; import javax.faces.context.FacesContext; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; import org.alfresco.service.ServiceRegistry; @@ -41,6 +42,7 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.TemplateException; import org.alfresco.service.cmr.repository.TemplateService; import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowService; @@ -145,8 +147,8 @@ public class FormImpl final String parentAVMPath, final String webappName) { - final String outputPathPattern = this.getOutputPathPattern(); - + final String outputPathPattern = (FreeMarkerUtil.buildNamespaceDeclaration(formInstanceData) + + this.getOutputPathPattern()); final Map root = new HashMap(); root.put("webapp", webappName); root.put("xml", NodeModel.wrap(formInstanceData)); @@ -155,9 +157,30 @@ public class FormImpl final TemplateService templateService = this.getServiceRegistry().getTemplateService(); - String result = templateService.processTemplateString(null, - outputPathPattern, - new SimpleHash(root)); + String result = null; + try + { + if (LOGGER.isDebugEnabled()) + { + + LOGGER.debug("processing " + outputPathPattern + + " using name " + formInstanceDataName + + " in webapp " + webappName + + " and xml data " + XMLUtil.toString(formInstanceData)); + } + result = templateService.processTemplateString(null, + outputPathPattern, + new SimpleHash(root)); + } + catch (TemplateException te) + { + LOGGER.error(te.getMessage(), te); + throw new AlfrescoRuntimeException("Error processing output path pattern " + outputPathPattern + + " for " + formInstanceDataName + + " in webapp " + webappName + + ":\n" + te.getMessage(), + te); + } result = AVMConstants.buildPath(parentAVMPath, result, AVMConstants.PathRelation.SANDBOX_RELATIVE); @@ -268,4 +291,4 @@ public class FormImpl } return result; } -} \ No newline at end of file +} diff --git a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java index f5c69d58dc..5d7a7e9cef 100644 --- a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java +++ b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java @@ -64,6 +64,11 @@ public class FormInstanceDataImpl this.nodeRef = nodeRef; } + public FormInstanceDataImpl(final int version, final String avmPath) + { + this(AVMNodeConverter.ToNodeRef(version, avmPath)); + } + /** the name of this rendition */ public String getName() { diff --git a/source/java/org/alfresco/web/forms/FormProcessor.java b/source/java/org/alfresco/web/forms/FormProcessor.java index 333b072ea7..4d09e8d90f 100644 --- a/source/java/org/alfresco/web/forms/FormProcessor.java +++ b/source/java/org/alfresco/web/forms/FormProcessor.java @@ -44,17 +44,27 @@ public interface FormProcessor public interface Session { + /** Returns the set of file uploaded during the session. */ public NodeRef[] getUploadedFiles(); + /** Destroys the session and releases all resources used by it */ public void destroy(); + /** Returns the form used by the session. */ public Form getForm(); + /** Returns the current state of the form instance data */ public Document getFormInstanceData(); + + /** Returns the name of the form instance data being modified */ + public String getFormInstanceDataName(); } ///////////////////////////////////////////////////////////////////////////// + /** + * Exception for errors encoutered during form processing. + */ public static class ProcessingException extends Exception { @@ -81,14 +91,23 @@ public interface FormProcessor * Processes a user interface for inputing data into a form. * * @param formInstanceData provides the xml instance data if available. + * @param formInstanceDataName the name of the form instance data being modified. * @param form the form to generate for * @param out the writer to write the output to. */ public Session process(final Document formInstanceData, + final String formInstanceDataName, final Form form, final Writer out) throws ProcessingException; + /** + * Processes a user interface for inputing data into a form. + * + * @param session the session to use. + * @param form the form to generate for + * @param out the writer to write the output to. + */ public void process(final Session session, final Writer out) throws ProcessingException; diff --git a/source/java/org/alfresco/web/forms/FreeMarkerUtil.java b/source/java/org/alfresco/web/forms/FreeMarkerUtil.java new file mode 100644 index 0000000000..68372f8f07 --- /dev/null +++ b/source/java/org/alfresco/web/forms/FreeMarkerUtil.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * 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.web.forms; + +import java.io.*; +import java.util.LinkedList; +import javax.xml.XMLConstants; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.xml.sax.SAXException; + +/** + * FreeMarker utility functions. + * + * @author Ariel Backenroth + */ +public class FreeMarkerUtil +{ + public static String buildNamespaceDeclaration(final Document xml) + { + final Element docEl = xml.getDocumentElement(); + final NamedNodeMap attributes = docEl.getAttributes(); + final StringBuilder result = new StringBuilder(); + for (int i = 0; i < attributes.getLength(); i++) + { + final Node a = attributes.item(i); + if (a.getNodeName().startsWith(XMLConstants.XMLNS_ATTRIBUTE)) + { + final String prefix = a.getNodeName().substring((XMLConstants.XMLNS_ATTRIBUTE + ":").length()); + final String uri = a.getNodeValue(); + if (result.length() != 0) + { + result.append(",\n"); + } + result.append("\"").append(prefix).append("\":\"").append(uri).append("\""); + } + } + return "<#ftl ns_prefixes={\n" + result.toString() + "}>\n"; + } +} \ No newline at end of file diff --git a/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java b/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java index e3ae376363..289e816739 100644 --- a/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java +++ b/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java @@ -23,11 +23,17 @@ package org.alfresco.web.forms; import freemarker.ext.dom.NodeModel; -import freemarker.template.*; +import freemarker.template.SimpleDate; +import freemarker.template.SimpleHash; +import freemarker.template.SimpleScalar; +import freemarker.template.TemplateHashModel; +import freemarker.template.TemplateModel; +import freemarker.template.TemplateModelException; import java.io.*; import java.text.MessageFormat; import java.util.*; import javax.faces.context.FacesContext; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; import org.alfresco.repo.avm.AVMNodeConverter; @@ -35,7 +41,15 @@ import org.alfresco.repo.domain.PropertyValue; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.repository.*; +import org.alfresco.service.cmr.repository.AssociationRef; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.TemplateException; +import org.alfresco.service.cmr.repository.TemplateNode; +import org.alfresco.service.cmr.repository.TemplateService; import org.alfresco.service.namespace.*; import org.alfresco.service.cmr.remote.AVMRemote; import org.alfresco.web.app.Application; @@ -163,24 +177,40 @@ public class RenderingEngineTemplateImpl root.put("name", formInstanceDataName.replaceAll("(.+)\\..*", "$1")); root.put("extension", sr.getMimetypeService().getExtension(this.getMimetypeForRendition())); - + Document formInstanceDataDocument = null; try { - root.put("xml", NodeModel.wrap(formInstanceData.getDocument())); + formInstanceDataDocument = formInstanceData.getDocument(); } catch (Exception e) { LOGGER.error(e); + throw new AlfrescoRuntimeException(e.getMessage(), e); } + root.put("xml", NodeModel.wrap(formInstanceDataDocument)); root.put("node", new TemplateNode(((FormInstanceDataImpl)formInstanceData).getNodeRef(), sr, null)); root.put("date", new SimpleDate(new Date(), SimpleDate.DATETIME)); final TemplateService templateService = sr.getTemplateService(); - final String outputPathPattern = this.getOutputPathPattern(); - String result = templateService.processTemplateString(null, - outputPathPattern, - new SimpleHash(root)); + final String outputPathPattern = (FreeMarkerUtil.buildNamespaceDeclaration(formInstanceDataDocument) + + this.getOutputPathPattern()); + String result = null; + try + { + result = templateService.processTemplateString(null, + outputPathPattern, + new SimpleHash(root)); + } + catch (final TemplateException te) + { + LOGGER.error(te.getMessage(), te); + throw new AlfrescoRuntimeException("Error processing output path pattern " + outputPathPattern + + " for " + formInstanceDataName + + " in webapp " + webappName + + ":\n" + te.getMessage(), + te); + } final String parentAVMPath = AVMNodeConverter.SplitBase(formInstanceDataAVMPath)[0]; result = AVMConstants.buildPath(parentAVMPath, result, @@ -367,10 +397,10 @@ public class RenderingEngineTemplateImpl throws IOException, SAXException { - if (arguments.length > 1) + if (arguments.length > 2) { - throw new IllegalArgumentException("expected zero or one arguments to parseXMLDocuments. got " + - arguments.length); + throw new IllegalArgumentException("expected exactly one or two arguments to " + + "parseXMLDocuments. got " + arguments.length); } if (! (arguments[0] instanceof String)) { diff --git a/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java b/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java index 31d08748cb..d1b60321ba 100644 --- a/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java +++ b/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java @@ -1718,7 +1718,7 @@ public class Schema2XForms // e.g. Please provide a valid value for 'Address'. 'Address' is a mandatory decimal field. // final Element alertElement = xformsDocument.createElementNS(NamespaceConstants.XFORMS_NS, - NamespaceConstants.XFORMS_PREFIX + ":alert"); + NamespaceConstants.XFORMS_PREFIX + ":alert"); formControl.appendChild(alertElement); this.setXFormsId(alertElement); @@ -2452,29 +2452,41 @@ public class Schema2XForms NamespaceConstants.XFORMS_PREFIX + ":required", (o.minimum != 0) + "()"); } + else if (controlType instanceof XSComplexTypeDefinition) + { + // make all complex types not required since it helps with validation - otherwise + // chiba seems to expect a nodevalue for the container element + bindElement.setAttributeNS(NamespaceConstants.XFORMS_NS, + NamespaceConstants.XFORMS_PREFIX + ":required", + "false()"); + + } //no more minOccurs & maxOccurs element: add a constraint if maxOccurs>1: //count(.) <= maxOccurs && count(.) >= minOccurs + final String nodeset = bindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, + "nodeset"); String minConstraint = null; String maxConstraint = null; if (o.minimum > 1) { //if 0 or 1 -> no constraint (managed by "required") - minConstraint = "count(.) >= " + o.minimum; - bindElement.setAttributeNS(NamespaceService.ALFRESCO_URI, - NamespaceService.ALFRESCO_PREFIX + ":minimum", - String.valueOf(o.minimum)); + minConstraint = "count(../" + nodeset + ") >= " + o.minimum; } + bindElement.setAttributeNS(NamespaceConstants.XFORMS_NS, + NamespaceConstants.XFORMS_PREFIX + ":minOccurs", + String.valueOf(o.minimum)); if (o.maximum > 1) { //if 1 or unbounded -> no constraint - maxConstraint = "count(.) <= " + o.maximum; - bindElement.setAttributeNS(NamespaceService.ALFRESCO_URI, - NamespaceService.ALFRESCO_PREFIX + ":maximum", - String.valueOf(o.maximum)); + maxConstraint = "count(../" + nodeset + ") <= " + o.maximum; } + bindElement.setAttributeNS(NamespaceConstants.XFORMS_NS, + NamespaceConstants.XFORMS_PREFIX + ":maxOccurs", + o.isUnbounded() ? "unbounded" : String.valueOf(o.maximum)); + final String constraint = (minConstraint != null && maxConstraint != null ? minConstraint + " and " + maxConstraint : (minConstraint != null diff --git a/source/java/org/alfresco/web/forms/xforms/XFormsBean.java b/source/java/org/alfresco/web/forms/xforms/XFormsBean.java index 7f5dbd3aae..553520fd59 100644 --- a/source/java/org/alfresco/web/forms/xforms/XFormsBean.java +++ b/source/java/org/alfresco/web/forms/xforms/XFormsBean.java @@ -103,6 +103,7 @@ public class XFormsBean { private final Document formInstanceData; + private final String formInstanceDataName; private final Form form; private ChibaBean chibaBean; @@ -111,10 +112,12 @@ public class XFormsBean private final List eventLog = new LinkedList(); public XFormsSession(final Document formInstanceData, + final String formInstanceDataName, final Form form, final String baseUrl) { this.formInstanceData = formInstanceData; + this.formInstanceDataName = formInstanceDataName; this.form = form; this.schema2XForms = new Schema2XForms("/ajax/invoke/XFormsBean.handleAction", Schema2XForms.SubmitMethod.POST, @@ -153,6 +156,11 @@ public class XFormsBean { return this.formInstanceData; } + + public String getFormInstanceDataName() + { + return this.formInstanceDataName; + } } ///////////////////////////////////////////////////////////////////////////// @@ -265,12 +273,14 @@ public class XFormsBean * event listeners. */ public XFormsSession createSession(final Document formInstanceData, + final String formInstanceDataName, final Form form) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("initializing xforms session with form " + form.getName() + - " and instance data " + formInstanceData); + " and instance data " + formInstanceDataName + + " (" + formInstanceData + ")"); } final FacesContext facesContext = FacesContext.getCurrentInstance(); @@ -282,7 +292,7 @@ public class XFormsBean request.getServerName() + ':' + request.getServerPort() + request.getContextPath()); - return this.new XFormsSession(formInstanceData, form, baseUrl); + return this.new XFormsSession(formInstanceData, formInstanceDataName, form, baseUrl); } /** diff --git a/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java b/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java index 09b4164327..93160e01e6 100644 --- a/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java +++ b/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java @@ -84,6 +84,7 @@ public class XFormsProcessor } public Session process(final Document instanceDataDocument, + final String formInstanceDataName, final Form form, final Writer out) throws FormProcessor.ProcessingException @@ -93,7 +94,7 @@ public class XFormsProcessor final XFormsBean xforms = (XFormsBean) FacesHelper.getManagedBean(fc, "XFormsBean"); final Session result = - xforms.createSession(instanceDataDocument, form); + xforms.createSession(instanceDataDocument, formInstanceDataName, form); this.process(result, out); return result; } @@ -150,6 +151,9 @@ public class XFormsProcessor js.append("alfresco_xforms_constants.XFORMS_UI_DIV_ID = '"). append(xformsUIDivId). append("';\n"); + js.append("alfresco_xforms_constants.FORM_INSTANCE_DATA_NAME = '"). + append(session.getFormInstanceDataName()). + append("';\n"); for (String[] ns : JS_NAMESPACES) { js.append("alfresco_xforms_constants."). diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIFormProcessor.java b/source/java/org/alfresco/web/ui/wcm/component/UIFormProcessor.java index 3608aeb05b..5c8e6ec82f 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIFormProcessor.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIFormProcessor.java @@ -45,6 +45,7 @@ public class UIFormProcessor private static final Log LOGGER = LogFactory.getLog(UIFormProcessor.class); private Document formInstanceData = null; + private String formInstanceDataName = null; private Form form = null; private FormProcessor.Session formProcessorSession = null; @@ -65,8 +66,9 @@ public class UIFormProcessor // standard component attributes are restored by the super class super.restoreState(context, values[0]); this.formInstanceData = (Document)values[1]; - this.form = (Form)values[2]; - this.formProcessorSession = (FormProcessor.Session)values[3]; + this.formInstanceDataName = (String)values[2]; + this.form = (Form)values[3]; + this.formProcessorSession = (FormProcessor.Session)values[4]; } public Object saveState(FacesContext context) @@ -76,6 +78,7 @@ public class UIFormProcessor // standard component attributes are saved by the super class super.saveState(context), this.formInstanceData, + this.formInstanceDataName, this.form, this.formProcessorSession }; @@ -98,7 +101,7 @@ public class UIFormProcessor final FormProcessor fp = form.getFormProcessors().get(0); final FormProcessor.Session fps = this.getFormProcessorSession(); final Document fid = this.getFormInstanceData(); - + final String formInstanceDataName = this.getFormInstanceDataName(); try { if (fps != null && @@ -118,6 +121,7 @@ public class UIFormProcessor } LOGGER.debug("creating a new session for " + fid); this.setFormProcessorSession(fp.process(fid, + formInstanceDataName, form, out)); } @@ -157,6 +161,31 @@ public class UIFormProcessor this.formInstanceData = formInstanceData; } + /** + * Returns the form instance data name + * + * @return The form instance data name + */ + public String getFormInstanceDataName() + { + final ValueBinding vb = this.getValueBinding("formInstanceDataName"); + if (vb != null) + { + this.formInstanceDataName = (String)vb.getValue(getFacesContext()); + } + return this.formInstanceDataName; + } + + /** + * Sets the form instance data name + * + * @param formInstanceDataName The form instance data name. + */ + public void setForm(final String formInstanceDataName) + { + this.formInstanceDataName = formInstanceDataName; + } + /** * Returns the form * diff --git a/source/java/org/alfresco/web/ui/wcm/tag/FormProcessorTag.java b/source/java/org/alfresco/web/ui/wcm/tag/FormProcessorTag.java index 702639912c..bf6316ee9c 100644 --- a/source/java/org/alfresco/web/ui/wcm/tag/FormProcessorTag.java +++ b/source/java/org/alfresco/web/ui/wcm/tag/FormProcessorTag.java @@ -36,6 +36,7 @@ public class FormProcessorTag extends BaseComponentTag { private String formInstanceData = null; + private String formInstanceDataName = null; private String form = null; private String formProcessorSession = null; @@ -68,6 +69,12 @@ public class FormProcessorTag final ValueBinding vb = app.createValueBinding(this.formInstanceData); component.setValueBinding("formInstanceData", vb); } + if (this.formInstanceDataName != null) + { + assert isValueReference(this.formInstanceDataName); + final ValueBinding vb = app.createValueBinding(this.formInstanceDataName); + component.setValueBinding("formInstanceDataName", vb); + } if (this.form != null) { assert this.isValueReference(this.form); @@ -89,6 +96,7 @@ public class FormProcessorTag { super.release(); this.formInstanceData = null; + this.formInstanceDataName = null; this.form = null; this.formProcessorSession = null; } @@ -103,6 +111,16 @@ public class FormProcessorTag this.formInstanceData = formInstanceData; } + /** + * Set the form instance data name + * + * @param formInstanceDataName the form instance data name + */ + public void setFormInstanceDataName(final String formInstanceDataName) + { + this.formInstanceDataName = formInstanceDataName; + } + /** * Sets the tempalte type * diff --git a/source/test-resources/xforms/unit-tests/attributes-test/attributes-test.xsd b/source/test-resources/xforms/unit-tests/interesting-schema-test/attributes-test.xsd similarity index 94% rename from source/test-resources/xforms/unit-tests/attributes-test/attributes-test.xsd rename to source/test-resources/xforms/unit-tests/interesting-schema-test/attributes-test.xsd index 46266cefa7..dfd5a6efee 100644 --- a/source/test-resources/xforms/unit-tests/attributes-test/attributes-test.xsd +++ b/source/test-resources/xforms/unit-tests/interesting-schema-test/attributes-test.xsd @@ -43,6 +43,10 @@ type="xs:normalizedString" use="optional" fixed="fixed string value"/> + diff --git a/source/test-resources/xforms/unit-tests/interesting-schema-test/xml-namespaces-test.xsd b/source/test-resources/xforms/unit-tests/interesting-schema-test/xml-namespaces-test.xsd index f5aef3f2d5..0acfc2df46 100644 --- a/source/test-resources/xforms/unit-tests/interesting-schema-test/xml-namespaces-test.xsd +++ b/source/test-resources/xforms/unit-tests/interesting-schema-test/xml-namespaces-test.xsd @@ -1,8 +1,8 @@ + targetNamespace="http://www.alfresco.org/fake/mine"> @@ -14,7 +14,7 @@ - + diff --git a/source/test-resources/xforms/unit-tests/simple-test/range-test.xsd b/source/test-resources/xforms/unit-tests/simple-test/range-test.xsd index 6025f259fb..71066e6d81 100644 --- a/source/test-resources/xforms/unit-tests/simple-test/range-test.xsd +++ b/source/test-resources/xforms/unit-tests/simple-test/range-test.xsd @@ -63,6 +63,17 @@ + + + + + + + + + diff --git a/source/web/WEB-INF/wcm.tld b/source/web/WEB-INF/wcm.tld index adb5067b44..dd432095ba 100644 --- a/source/web/WEB-INF/wcm.tld +++ b/source/web/WEB-INF/wcm.tld @@ -112,6 +112,13 @@ The instance data for the form processor + + formInstanceDataName + true + true + The name of the form instance data being modified + + form true diff --git a/source/web/jsp/wcm/create-web-content-wizard/create-xml.jsp b/source/web/jsp/wcm/create-web-content-wizard/create-xml.jsp index 3d0dcf8e1c..0eb1ca59de 100644 --- a/source/web/jsp/wcm/create-web-content-wizard/create-xml.jsp +++ b/source/web/jsp/wcm/create-web-content-wizard/create-xml.jsp @@ -42,4 +42,5 @@ function _xforms_getSaveDraftButtons() diff --git a/source/web/jsp/wcm/edit-xml-inline.jsp b/source/web/jsp/wcm/edit-xml-inline.jsp index 61ed57ef95..ffbbf8f39c 100644 --- a/source/web/jsp/wcm/edit-xml-inline.jsp +++ b/source/web/jsp/wcm/edit-xml-inline.jsp @@ -119,6 +119,7 @@ function _xforms_getSaveDraftButtons() <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> diff --git a/source/web/scripts/ajax/xforms.js b/source/web/scripts/ajax/xforms.js index dae31ff219..6ba62a17d7 100644 --- a/source/web/scripts/ajax/xforms.js +++ b/source/web/scripts/ajax/xforms.js @@ -742,6 +742,7 @@ dojo.declare("alfresco.xforms.NumericalRange", _hSlider_valueChangedHandler: function(value) { + value = Math.round(value * Math.pow(10, this.fractionDigits)) / Math.pow(10, this.fractionDigits); this.currentValueDiv.replaceChild(document.createTextNode("Value: " + value), this.currentValueDiv.firstChild); if (!this.widget._isDragInProgress) @@ -2309,6 +2310,11 @@ dojo.declare("alfresco.xforms.ViewRoot", this.focusedRepeat = null; }, { + + ///////////////////////////////////////////////////////////////// + // overridden methods & properties + ///////////////////////////////////////////////////////////////// + render: function(attach_point) { this.domNode.widget = this; @@ -2336,6 +2342,14 @@ dojo.declare("alfresco.xforms.ViewRoot", this.domNode.childContainerNode.style.width = "100%"; return this.domNode; + }, + + /** */ + getLabel: function() + { + var result = alfresco.xforms.ViewRoot.superclass.getLabel.call(this); + result += " " + alfresco_xforms_constants.FORM_INSTANCE_DATA_NAME; + return result; } }); @@ -3121,8 +3135,9 @@ dojo.declare("alfresco.xforms.Binding", (_hasAttribute(this.xformsNode, alfresco_xforms_constants.XFORMS_PREFIX + ":constraint") ? this.xformsNode.getAttribute(alfresco_xforms_constants.XFORMS_PREFIX + ":constraint") : null); - this.maximum = parseInt(this.xformsNode.getAttribute(alfresco_xforms_constants.ALFRESCO_PREFIX + ":maximum")); - this.minimum = parseInt(this.xformsNode.getAttribute(alfresco_xforms_constants.ALFRESCO_PREFIX + ":minimum")); + this.maximum = this.xformsNode.getAttribute(alfresco_xforms_constants.XFORMS_PREFIX + ":maxOccurs"); + this.maximum = this.maximum == "unbounded" ? Number.MAX_VALUE : parseInt(this.maximum); + this.minimum = parseInt(this.xformsNode.getAttribute(alfresco_xforms_constants.XFORMS_PREFIX + ":minOccurs")); this.parent = parent; this.widgets = {}; },