diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java index 3bfbeea9ad..12cc74de28 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -551,6 +551,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 257c4473b4..f3a78e4543 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java @@ -282,6 +282,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. */ @@ -441,30 +450,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()) @@ -527,7 +513,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); @@ -588,4 +577,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 b969951007..0d1bc6c682 100644 --- a/source/java/org/alfresco/web/forms/FormImpl.java +++ b/source/java/org/alfresco/web/forms/FormImpl.java @@ -28,6 +28,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; @@ -36,6 +37,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; @@ -140,8 +142,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)); @@ -150,9 +152,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); @@ -263,4 +286,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 80a268761a..3fbef7e934 100644 --- a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java +++ b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java @@ -59,6 +59,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 b28702888e..c361915c4d 100644 --- a/source/java/org/alfresco/web/forms/FormProcessor.java +++ b/source/java/org/alfresco/web/forms/FormProcessor.java @@ -39,17 +39,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 { @@ -76,14 +86,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..7015db150c --- /dev/null +++ b/source/java/org/alfresco/web/forms/FreeMarkerUtil.java @@ -0,0 +1,59 @@ +/* + * 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. + */ +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 94667c18b4..6ad744c531 100644 --- a/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java +++ b/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java @@ -18,11 +18,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; @@ -30,7 +36,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; @@ -158,24 +172,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, @@ -362,10 +392,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 f146a992e0..92653bc599 100644 --- a/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java +++ b/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java @@ -1713,7 +1713,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); @@ -2447,29 +2447,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 6dd7e08a76..1b6b2d45e0 100644 --- a/source/java/org/alfresco/web/forms/xforms/XFormsBean.java +++ b/source/java/org/alfresco/web/forms/xforms/XFormsBean.java @@ -98,6 +98,7 @@ public class XFormsBean { private final Document formInstanceData; + private final String formInstanceDataName; private final Form form; private ChibaBean chibaBean; @@ -106,10 +107,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, @@ -148,6 +151,11 @@ public class XFormsBean { return this.formInstanceData; } + + public String getFormInstanceDataName() + { + return this.formInstanceDataName; + } } ///////////////////////////////////////////////////////////////////////////// @@ -260,12 +268,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(); @@ -277,7 +287,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 e02efff564..39d414c592 100644 --- a/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java +++ b/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java @@ -79,6 +79,7 @@ public class XFormsProcessor } public Session process(final Document instanceDataDocument, + final String formInstanceDataName, final Form form, final Writer out) throws FormProcessor.ProcessingException @@ -88,7 +89,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; } @@ -145,6 +146,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 28ad3d43c2..d0b708c3bc 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIFormProcessor.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIFormProcessor.java @@ -39,6 +39,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; @@ -59,8 +60,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) @@ -70,6 +72,7 @@ public class UIFormProcessor // standard component attributes are saved by the super class super.saveState(context), this.formInstanceData, + this.formInstanceDataName, this.form, this.formProcessorSession }; @@ -92,7 +95,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 && @@ -112,6 +115,7 @@ public class UIFormProcessor } LOGGER.debug("creating a new session for " + fid); this.setFormProcessorSession(fp.process(fid, + formInstanceDataName, form, out)); } @@ -151,6 +155,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 3b199a103e..881026a2d0 100644 --- a/source/java/org/alfresco/web/ui/wcm/tag/FormProcessorTag.java +++ b/source/java/org/alfresco/web/ui/wcm/tag/FormProcessorTag.java @@ -30,6 +30,7 @@ public class FormProcessorTag extends BaseComponentTag { private String formInstanceData = null; + private String formInstanceDataName = null; private String form = null; private String formProcessorSession = null; @@ -62,6 +63,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); @@ -83,6 +90,7 @@ public class FormProcessorTag { super.release(); this.formInstanceData = null; + this.formInstanceDataName = null; this.form = null; this.formProcessorSession = null; } @@ -97,6 +105,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 97d711893f..4d4bbd81ee 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 @@ -35,4 +35,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 5d748fd8ec..885218f0ab 100644 --- a/source/web/jsp/wcm/edit-xml-inline.jsp +++ b/source/web/jsp/wcm/edit-xml-inline.jsp @@ -112,6 +112,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 4ba9c9666f..1f6a37137e 100644 --- a/source/web/scripts/ajax/xforms.js +++ b/source/web/scripts/ajax/xforms.js @@ -736,6 +736,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) @@ -2303,6 +2304,11 @@ dojo.declare("alfresco.xforms.ViewRoot", this.focusedRepeat = null; }, { + + ///////////////////////////////////////////////////////////////// + // overridden methods & properties + ///////////////////////////////////////////////////////////////// + render: function(attach_point) { this.domNode.widget = this; @@ -2330,6 +2336,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; } }); @@ -3115,8 +3129,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 = {}; },