diff --git a/config/alfresco/web-client-config.xml b/config/alfresco/web-client-config.xml index cc08dbba01..403ad05dc0 100644 --- a/config/alfresco/web-client-config.xml +++ b/config/alfresco/web-client-config.xml @@ -67,7 +67,7 @@ alfresco@alfresco.org - alfresco.dyndns.org + arielbackenroth.dyndns.org 8180 diff --git a/project-build.xml b/project-build.xml index 161727815c..0ba53e7501 100644 --- a/project-build.xml +++ b/project-build.xml @@ -104,6 +104,13 @@ + + + + diff --git a/source/java/org/alfresco/web/bean/wcm/AVMConstants.java b/source/java/org/alfresco/web/bean/wcm/AVMConstants.java index 07ee2e62e1..15e0b485aa 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMConstants.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMConstants.java @@ -67,16 +67,31 @@ public final class AVMConstants public static String buildAVMStoreUrl(String store) { + if (store.indexOf(":") > 0) + store = store.substring(0, store.indexOf(':')); ClientConfigElement config = Application.getClientConfig(FacesContext.getCurrentInstance()); return MessageFormat.format(PREVIEW_SANDBOX_URL, lookupStoreDNS(store), config.getWCMDomain(), config.getWCMPort()); } public static String buildAVMAssetUrl(String store, String assetPath) { + if (assetPath.startsWith('/' + DIR_APPBASE + '/' + DIR_WEBAPPS)) + assetPath = assetPath.substring(('/' + DIR_APPBASE + '/' + DIR_WEBAPPS).length()); + if (assetPath.length() == 0 || assetPath.charAt(0) != '/') + assetPath = '/' + assetPath; + ClientConfigElement config = Application.getClientConfig(FacesContext.getCurrentInstance()); return MessageFormat.format(PREVIEW_ASSET_URL, lookupStoreDNS(store), config.getWCMDomain(), config.getWCMPort(), assetPath); } - + + public static String buildAVMAssetUrl(final String avmPath) + { + final String[] s = avmPath.split(":"); + if (s.length != 2) + throw new IllegalArgumentException("expected exactly one ':' in " + avmPath); + return AVMConstants.buildAVMAssetUrl(s[0], s[1]); + } + public static String lookupStoreDNS(String store) { String dns = null; @@ -113,5 +128,5 @@ public final class AVMConstants // URLs for preview of sandboxes and assets public final static String PREVIEW_SANDBOX_URL = "http://www-{0}.avm.{1}:{2}"; - public final static String PREVIEW_ASSET_URL = "http://www-{0}.avm.{1}:{2}/{3}"; + public final static String PREVIEW_ASSET_URL = "http://www-{0}.avm.{1}:{2}{3}"; } diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java index 2cff791a29..dcd9730219 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java @@ -81,7 +81,6 @@ public class CreateWebContentWizard extends BaseContentWizard this.avmBrowseBean = avmBrowseBean; } - // ------------------------------------------------------------------------------ // Wizard implementation diff --git a/source/java/org/alfresco/web/templating/TemplateType.java b/source/java/org/alfresco/web/templating/TemplateType.java index f308beb31c..4a823f8b73 100644 --- a/source/java/org/alfresco/web/templating/TemplateType.java +++ b/source/java/org/alfresco/web/templating/TemplateType.java @@ -35,7 +35,7 @@ public interface TemplateType /** the xml schema for this template type */ public Document getSchema(); - public String /* URI */ getSchemaURI(); + // public String /* URI */ getSchemaURI(); // public void setSchemaNodeRef(final NodeRef nodeRef); // diff --git a/source/java/org/alfresco/web/templating/xforms/FormBuilderException.java b/source/java/org/alfresco/web/templating/xforms/FormBuilderException.java new file mode 100644 index 0000000000..bbc70cc09f --- /dev/null +++ b/source/java/org/alfresco/web/templating/xforms/FormBuilderException.java @@ -0,0 +1,54 @@ +/* + * 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.templating.xforms; + + +/** + * This exception is thrown when implementations of SchemaFormBuilder + * encounters an error building a form. + * + * @author Brian Dueck + */ +public class FormBuilderException + extends Exception +{ + + /** + * Creates a new instance of FormBuilderException without detail message. + */ + public FormBuilderException() { } + + /** + * Constructs an instance of FormBuilderException with the specified detail message. + * + * @param msg the detail message. + */ + public FormBuilderException(String msg) + { + super(msg); + } + + /** + * Constructs an instance of FormBuilderException with the specified root exception. + * + * @param x The root exception. + */ + public FormBuilderException(Exception x) + { + super(x); + } +} diff --git a/source/java/org/alfresco/web/templating/xforms/schemabuilder/AbstractSchemaFormBuilder.java b/source/java/org/alfresco/web/templating/xforms/SchemaFormBuilder.java similarity index 73% rename from source/java/org/alfresco/web/templating/xforms/schemabuilder/AbstractSchemaFormBuilder.java rename to source/java/org/alfresco/web/templating/xforms/SchemaFormBuilder.java index 793f75974c..6c2b46c0e2 100644 --- a/source/java/org/alfresco/web/templating/xforms/schemabuilder/AbstractSchemaFormBuilder.java +++ b/source/java/org/alfresco/web/templating/xforms/SchemaFormBuilder.java @@ -14,37 +14,28 @@ * language governing permissions and limitations under the * License. */ -package org.alfresco.web.templating.xforms.schemabuilder; +package org.alfresco.web.templating.xforms; -import org.apache.commons.jxpath.JXPathContext; -import org.apache.commons.jxpath.Pointer; -import org.apache.xerces.xs.*; -import org.chiba.xml.util.DOMUtil; -import org.chiba.xml.xforms.NamespaceCtx; -import org.w3c.dom.*; -import org.w3c.dom.ls.*; -import org.w3c.dom.bootstrap.DOMImplementationRegistry; -import org.xml.sax.InputSource; -import org.alfresco.web.templating.*; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.*; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.util.*; - -/* - * Search for TODO for things remaining to-do in this implementation. - * - * TODO: Support configuration mechanism to allow properties to be set without programming. - * TODO: i18n/l10n of messages, hints, captions. Possibly leverage org.chiba.i18n classes. - * TODO: When Chiba supports itemset, use schema keyref and key constraints for validation. - * TODO: Support namespaces in instance documents. Currently can't do this due to Chiba bugs. - * TODO: Place default values for list and enumeration types at the beginning of the item list. - * - */ +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.*; +import org.alfresco.web.templating.*; +import org.apache.commons.jxpath.JXPathContext; +import org.apache.commons.jxpath.Pointer; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.xerces.xs.*; +import org.chiba.xml.util.DOMUtil; +import org.chiba.xml.xforms.NamespaceCtx; +import org.w3c.dom.*; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; +import org.w3c.dom.ls.*; +import org.xml.sax.InputSource; /** * An abstract implementation of the SchemaFormBuilder interface allowing @@ -54,10 +45,9 @@ import java.util.*; * required interface methods (createXXX, startXXX, and endXXX methods). * * @author $Author: unl $ - * @version $Id: AbstractSchemaFormBuilder.java,v 1.25 2005/03/29 14:12:06 unl Exp $ */ -public abstract class AbstractSchemaFormBuilder - implements SchemaFormBuilder { +public class SchemaFormBuilder +{ //////////////////////////////////////////////////////////////////////////// @@ -95,6 +85,160 @@ public abstract class AbstractSchemaFormBuilder } }; + //////////////////////////////////////////////////////////////////////////// + + public static class Occurs + { + public final static int UNBOUNDED = -1; + + public final int minimum; + public final int maximum; + + public Occurs(final XSParticle particle) + { + if (particle == null) + { + this.minimum = 1; + this.maximum = 1; + } + else + { + this.minimum = particle.getMinOccurs(); + this.maximum = (particle.getMaxOccursUnbounded() + ? Occurs.UNBOUNDED + : particle.getMaxOccurs()); + } + } + + public Occurs(final int minimum) + { + this(minimum, UNBOUNDED); + } + + public Occurs(final int minimum, final int maximum) + { + this.minimum = minimum; + this.maximum = maximum; + } + + public boolean isUnbounded() + { + return this.maximum == UNBOUNDED; + } + + public String toString() + { + return "minimum=" + minimum + ", maximum=" + maximum; + } + } + + //////////////////////////////////////////////////////////////////////////// + + public final static Log LOGGER = + LogFactory.getLog(SchemaFormBuilder.class); + + /** + * XMLSchema Namespace declaration + */ + public static final String XMLSCHEMA_NS = + "http://www.w3.org/2001/XMLSchema"; + + /** + * XMLSchema prefix + */ + public static final String XMLSCHEMA_NS_PREFIX = "xs:"; + + /** + * XMLSchema Instance Namespace declaration + */ + public static final String XMLSCHEMA_INSTANCE_NS = + "http://www.w3.org/2001/XMLSchema-instance"; + + /** + * XMLSchema instance prefix + */ + public static final String XMLSCHEMA_INSTANCE_NS_PREFIX = "xsi:"; + + /** + * XMLNS Namespace declaration. + */ + public static final String XMLNS_NAMESPACE_URI = + "http://www.w3.org/2000/xmlns/"; + + /** + * XML Namespace declaration + */ + public static final String XML_NAMESPACE_URI = + "http://www.w3.org/XML/1998/namespace"; + + /** + * XForms namespace declaration. + */ + public static final String XFORMS_NS = + "http://www.w3.org/2002/xforms"; + + /** + * XForms prefix + */ + public static final String XFORMS_NS_PREFIX = "xforms:"; + + /** + * Chiba namespace declaration. + */ + public static final String CHIBA_NS = + "http://chiba.sourceforge.net/xforms"; + + /** + * Chiba prefix + */ + public static final String CHIBA_NS_PREFIX = "chiba:"; + + /** + * XLink namespace declaration. + */ + public static final String XLINK_NS = "http://www.w3.org/1999/xlink"; + + /** + * Xlink prefix + */ + public static final String XLINK_NS_PREFIX = "xlink:"; + + /** + * XML Events namsepace declaration. + */ + public static final String XMLEVENTS_NS = "http://www.w3.org/2001/xml-events"; + + /** + * XML Events prefix + */ + public static final String XMLEVENTS_NS_PREFIX = "ev:"; + + /** + * Prossible values of the "@method" on the "submission" element + */ + public static final String SUBMIT_METHOD_POST = "post"; + + /** + * __UNDOCUMENTED__ + */ + public static final String SUBMIT_METHOD_PUT = "put"; + + /** + * __UNDOCUMENTED__ + */ + public static final String SUBMIT_METHOD_GET = "get"; + + /** + * __UNDOCUMENTED__ + */ + public static final String SUBMIT_METHOD_FORM_DATA_POST = "form-data-post"; + + /** + * __UNDOCUMENTED__ + */ + public static final String SUBMIT_METHOD_URLENCODED_POST = + "urlencoded-post"; + private static final String PROPERTY_PREFIX = "http://www.chiba.org/properties/schemaFormBuilder/"; /** @@ -161,30 +305,10 @@ public abstract class AbstractSchemaFormBuilder "compact"; private static final String DEFAULT_LONG_LIST_MAX_SIZE = "6"; - /** - * __UNDOCUMENTED__ - */ - protected Document _instanceDocument; - - /** - * __UNDOCUMENTED__ - */ - protected String _action; - - /** - * __UNDOCUMENTED__ - */ - protected String _submitMethod; - - /** - * __UNDOCUMENTED__ - */ - protected String _base; - - /** - * __UNDOCUMENTED__ - */ - protected WrapperElementsBuilder _wrapper = new XHTMLWrapperElementsBuilder(); + private final String action; + private final String submitMethod; + private final String base; + protected WrapperElementsBuilder wrapper = new XHTMLWrapperElementsBuilder(); /** * generic counter -> replaced by an hashMap with: @@ -194,7 +318,6 @@ public abstract class AbstractSchemaFormBuilder private HashMap counter; private final Properties properties = new Properties(); private String targetNamespace; - private final Map namespacePrefixes = new HashMap(); // typeTree @@ -209,7 +332,7 @@ public abstract class AbstractSchemaFormBuilder new TreeMap>(); /** - * Creates a new AbstractSchemaFormBuilder object. + * Creates a new SchemaFormBuilder object. * * @param rootElementName __UNDOCUMENTED__ * @param instanceSource __UNDOCUMENTED__ @@ -217,27 +340,23 @@ public abstract class AbstractSchemaFormBuilder * @param submitMethod __UNDOCUMENTED__ * @param wrapper __UNDOCUMENTED__ */ - public AbstractSchemaFormBuilder(final Document instanceDocument, - final String action, - final String submitMethod, - final WrapperElementsBuilder wrapper, - final String base) + public SchemaFormBuilder(final String action, + final String submitMethod, + final WrapperElementsBuilder wrapper, + final String base) { reset(); - this._instanceDocument = instanceDocument; - this._action = action; - this._base = base; - - //control if it is one of the SUBMIT_METHOD attributes? - this._submitMethod = submitMethod; - this._wrapper = wrapper; + this.action = action; + this.submitMethod = submitMethod; + this.wrapper = wrapper; + this.base = base; } /** - * __UNDOCUMENTED__ + * Get the current set of properties used by implementations of SchemaFormBuilder. * - * @return __UNDOCUMENTED__ + * @return The list of properties. */ public Properties getProperties() { @@ -245,10 +364,10 @@ public abstract class AbstractSchemaFormBuilder } /** - * __UNDOCUMENTED__ + * Sets the property to the specified value. If the property exists, its value is overwritten. * - * @param key __UNDOCUMENTED__ - * @param value __UNDOCUMENTED__ + * @param key The implementation defined property key. + * @param value The value for the property. */ public void setProperty(String key, String value) { @@ -256,10 +375,10 @@ public abstract class AbstractSchemaFormBuilder } /** - * __UNDOCUMENTED__ + * Gets the value for the specified property. * - * @param key __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ + * @param key The implementation defined property key. + * @return The property value if found, or null if the property cannot be located. */ public String getProperty(String key) { @@ -267,11 +386,11 @@ public abstract class AbstractSchemaFormBuilder } /** - * __UNDOCUMENTED__ + * Gets the value for the specified property, with a default if the property cannot be located. * - * @param key __UNDOCUMENTED__ - * @param defaultValue __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ + * @param key The implementation defined property key. + * @param defaultValue This value will be returned if the property does not exists. + * @return The property value if found, or defaultValue if the property cannot be located. */ public String getProperty(String key, String defaultValue) { @@ -279,17 +398,19 @@ public abstract class AbstractSchemaFormBuilder } /** - * builds a form from a XML schema. + * Generate the XForm based on a user supplied XML Schema. * - * @param inputURI the URI of the Schema to be used - * @return __UNDOCUMENTED__ - * @throws FormBuilderException __UNDOCUMENTED__ + * @param inputURI The document source for the XML Schema. + * @return The Document containing the XForm. + * @throws org.chiba.tools.schemabuilder.FormBuilderException + * If an error occurs building the XForm. */ - public Document buildForm(final TemplateType tt) + public Document buildForm(final Document instanceDocument, + final Document schemaDocument, + String rootElementName) throws FormBuilderException { - String rootElementName = tt.getName(); - final XSModel schema = this.loadSchema(tt); + final XSModel schema = this.loadSchema(schemaDocument); this.buildTypeTree(schema); //refCounter = 0; @@ -298,8 +419,6 @@ public abstract class AbstractSchemaFormBuilder final Document xForm = createFormTemplate(rootElementName); final Element envelopeElement = xForm.getDocumentElement(); - //Element formSection = (Element) envelopeElement.getElementsByTagNameNS(CHIBA_NS, "form").item(0); - //Element formSection =(Element) envelopeElement.getElementsByTagName("body").item(0); //find form element: last element created final NodeList children = xForm.getDocumentElement().getChildNodes(); @@ -308,20 +427,16 @@ public abstract class AbstractSchemaFormBuilder envelopeElement.getElementsByTagNameNS(XFORMS_NS, "model").item(0); //add XMLSchema if we use schema types - if (modelSection != null) - { - final String schemaURI = this._base + tt.getSchemaURI(); - LOGGER.debug("schema url is " + schemaURI); - modelSection.setAttributeNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "schema", - schemaURI); - } + modelSection.setAttributeNS(XFORMS_NS, "schema", "#schema-1"); + final Element importedSchemaRootElement = (Element) + xForm.importNode(schemaDocument.getDocumentElement(), true); + importedSchemaRootElement.setAttributeNS(SchemaFormBuilder.XFORMS_NS, + "id", + "schema-1"); - //xxx XSDNode node = findXSDNodeByName(rootElementTagName,schemaNode.getElementSet()); + modelSection.appendChild(importedSchemaRootElement); //check if target namespace - //no way to do this with XS API ? load DOM document ? - //TODO: find a better way to find the targetNamespace final StringList targetNamespaces = schema.getNamespaces(); if (targetNamespaces.getLength() != 0) { @@ -374,11 +489,11 @@ public abstract class AbstractSchemaFormBuilder XMLSCHEMA_INSTANCE_NS_PREFIX, XMLSCHEMA_INSTANCE_NS); - if (this._instanceDocument == null) + if (instanceDocument == null) instanceElement.appendChild(defaultInstanceRootElement); else { - Element instanceDocumentElement = this._instanceDocument.getDocumentElement(); + Element instanceDocumentElement = instanceDocument.getDocumentElement(); if (!instanceDocumentElement.getNodeName().equals(rootElementName)) throw new IllegalArgumentException("instance document root tag name invalid. " + "expected " + rootElementName + @@ -393,7 +508,7 @@ public abstract class AbstractSchemaFormBuilder instanceElement.appendChild(importedInstanceRootElement); } - Element formContentWrapper = this._wrapper.createGroupContentWrapper(formSection); + Element formContentWrapper = this.wrapper.createGroupContentWrapper(formSection); this.addElement(xForm, modelSection, defaultInstanceRootElement, @@ -414,20 +529,19 @@ public abstract class AbstractSchemaFormBuilder //action submitInfoElement.setAttributeNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "action", - _action == null ? "" : this._base + _action); + this.action == null ? "" : this.base + this.action); //method submitInfoElement.setAttributeNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "method", - (_submitMethod != null && _submitMethod.length() != 0 - ? _submitMethod - : AbstractSchemaFormBuilder.SUBMIT_METHOD_POST)); + (this.submitMethod != null && this.submitMethod.length() != 0 + ? this.submitMethod + : SchemaFormBuilder.SUBMIT_METHOD_POST)); //Element submitButton = (Element) formSection.appendChild(xForm.createElementNS(XFORMS_NS,SchemaFormBuilder.XFORMS_NS_PREFIX+"submit")); Element submitButton = xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "submit"); - Element submitControlWrapper = - _wrapper.createControlsWrapper(submitButton); + Element submitControlWrapper = this.wrapper.createControlsWrapper(submitButton); formContentWrapper.appendChild(submitControlWrapper); submitButton.setAttributeNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "submission", @@ -443,21 +557,7 @@ public abstract class AbstractSchemaFormBuilder } /** - * This method is invoked after the form builder is finished creating and processing - * a form control. Implementations may choose to use this method to add/inspect/modify - * the controlElement prior to the builder moving onto the next control. - * - * @param controlElement The form control element that was created. - * @param controlType The XML Schema type for which controlElement was created. - */ - public void endFormControl(Element controlElement, - XSTypeDefinition controlType, - Occurs occurs) - { - } - - /** - * __UNDOCUMENTED__ + * Reset the SchemaFormBuilder to default values. */ public void reset() { @@ -702,7 +802,7 @@ public abstract class AbstractSchemaFormBuilder */ protected void addChoicesForSelectControl(final Document xForm, final Element choicesElement, - final List choiceValues) { + final Map choiceValues) { // sort the enums values and then add them as choices // // TODO: Should really put the default value (if any) at the top of the list. @@ -712,7 +812,7 @@ public abstract class AbstractSchemaFormBuilder // Iterator iterator = sortedList.iterator(); - for (String textValue : choiceValues) + for (Map.Entry choice : choiceValues.entrySet()) { Element item = xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "item"); @@ -723,13 +823,14 @@ public abstract class AbstractSchemaFormBuilder SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); this.setXFormsId(captionElement); item.appendChild(captionElement); - captionElement.appendChild(xForm.createTextNode(createCaption(textValue))); + final String label = createCaption(choice.getKey(), choice.getValue()); + captionElement.appendChild(xForm.createTextNode(label)); - Element value = - xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "value"); + Element value = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "value"); this.setXFormsId(value); item.appendChild(value); - value.appendChild(xForm.createTextNode(textValue)); + value.appendChild(xForm.createTextNode(choice.getKey())); } } @@ -820,46 +921,47 @@ public abstract class AbstractSchemaFormBuilder * @param annotation __UNDOCUMENTED__ * @return __UNDOCUMENTED__ */ - protected Element addHintFromDocumentation(Document xForm, - XSAnnotation annotation) { + protected Element addHintFromDocumentation(final Document xForm, + final XSAnnotation annotation) + { if (annotation == null) return null; - Element hintElement = - xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "hint"); + final Text text = this.extractDocumentation(annotation); + if (text == null) + return null; + final Element hintElement = + xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "hint"); this.setXFormsId(hintElement); - - Text hintText = (Text) - hintElement.appendChild(xForm.createTextNode("")); - - //write annotation to empty doc - Document doc = DOMUtil.newDocument(true, false); + hintElement.appendChild(xForm.importNode(text, true)); + return hintElement; + } + + private Text extractDocumentation(final XSAnnotation annotation) + { + if (annotation == null) + return null; + // write annotation to empty doc + final Document doc = DOMUtil.newDocument(true, false); annotation.writeAnnotation(doc, XSAnnotation.W3C_DOM_DOCUMENT); - //get "annotation" element - NodeList annots = doc.getElementsByTagNameNS("http://www.w3.org/2001/XMLSchema", - "annotation"); - if (annots.getLength() > 0) - { - Element annotEl = (Element) annots.item(0); - - //documentation - NodeList docos = - annotEl.getElementsByTagNameNS("http://www.w3.org/2001/XMLSchema", - "documentation"); - for (int j = 0; j < docos.getLength(); j++) - { - Element doco = (Element) docos.item(j); + final NodeList d = doc.getElementsByTagNameNS(SchemaFormBuilder.XMLSCHEMA_NS, + "documentation"); + if (d.getLength() == 0) + return null; - //get text value - String text = DOMUtil.getTextNodeAsString(doco); - hintText.appendData(text); + final Text result = doc.createTextNode(""); + + for (int i = 0; i < d.getLength(); i++) + { + //get text value + final String text = DOMUtil.getTextNodeAsString((Element)d.item(i)); + result.appendData(text); - if (j < docos.getLength() - 1) - hintText.appendData(" "); - } - return hintElement; + if (i < d.getLength() - 1) + result.appendData(" "); } - return null; + return result; } public XSParticle findCorrespondingParticleInComplexType(final XSElementDeclaration elDecl) @@ -1062,7 +1164,7 @@ public abstract class AbstractSchemaFormBuilder Element groupWrapper = groupElement; if (groupElement != modelSection) - groupWrapper = _wrapper.createGroupContentWrapper(groupElement); + groupWrapper = this.wrapper.createGroupContentWrapper(groupElement); final Occurs o = this.getOccurance(owner); final Element repeatSection = this.addRepeatIfNecessary(xForm, @@ -1076,8 +1178,7 @@ public abstract class AbstractSchemaFormBuilder if (repeatSection != groupWrapper) { // we have a repeat - repeatContentWrapper = - _wrapper.createGroupContentWrapper(repeatSection); + repeatContentWrapper = this.wrapper.createGroupContentWrapper(repeatSection); relative = true; } @@ -1470,10 +1571,10 @@ public abstract class AbstractSchemaFormBuilder constraint); } - Element choicesControlWrapper = _wrapper.createControlsWrapper(choices); + Element choicesControlWrapper = this.wrapper.createControlsWrapper(choices); control.appendChild(choicesControlWrapper); - Element controlWrapper = _wrapper.createControlsWrapper(control); + Element controlWrapper = this.wrapper.createControlsWrapper(control); formSection.appendChild(controlWrapper); ///////////////// /////////////// @@ -1515,7 +1616,7 @@ public abstract class AbstractSchemaFormBuilder this.setXFormsId(switchElement); Element switchControlWrapper = - _wrapper.createControlsWrapper(switchElement); + this.wrapper.createControlsWrapper(switchElement); formSection.appendChild(switchControlWrapper); //formSection.appendChild(switchElement); @@ -1932,7 +2033,7 @@ public abstract class AbstractSchemaFormBuilder //this.addSelector(xForm, repeatSection); //group wrapper repeatContentWrapper = - _wrapper.createGroupContentWrapper(repeatSection); + this.wrapper.createGroupContentWrapper(repeatSection); } if (LOGGER.isDebugEnabled()) @@ -2136,7 +2237,7 @@ public abstract class AbstractSchemaFormBuilder bindId); final Element controlWrapper = - _wrapper.createControlsWrapper(repeatSection); + this.wrapper.createControlsWrapper(repeatSection); formSection.appendChild(controlWrapper); //add a group inside the repeat? @@ -2186,7 +2287,7 @@ public abstract class AbstractSchemaFormBuilder //set content Element groupWrapper = groupElement; if (groupElement != modelSection) - groupWrapper = _wrapper.createGroupContentWrapper(groupElement); + groupWrapper = this.wrapper.createGroupContentWrapper(groupElement); formSection = groupWrapper; } @@ -2205,7 +2306,7 @@ public abstract class AbstractSchemaFormBuilder if (repeatSection != formSection) { //content of repeat - contentWrapper = _wrapper.createGroupContentWrapper(repeatSection); + contentWrapper = this.wrapper.createGroupContentWrapper(repeatSection); //if there is a repeat -> create another bind with "." Element bindElement2 = @@ -2228,7 +2329,7 @@ public abstract class AbstractSchemaFormBuilder bindId, bindElement, o); - Element controlWrapper = _wrapper.createControlsWrapper(formControl); + Element controlWrapper = this.wrapper.createControlsWrapper(formControl); contentWrapper.appendChild(controlWrapper); // if this is a repeatable then set ref to point to current element @@ -2424,7 +2525,7 @@ public abstract class AbstractSchemaFormBuilder //add the triggers final Element wrapper_triggers = - _wrapper.createControlsWrapper(trigger_insert_before); + this.wrapper.createControlsWrapper(trigger_insert_before); if (wrapper_triggers == trigger_insert_before) { @@ -2560,8 +2661,7 @@ public abstract class AbstractSchemaFormBuilder if (controlType.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) { - XSSimpleTypeDefinition simpleType = - (XSSimpleTypeDefinition) controlType; + XSSimpleTypeDefinition simpleType = (XSSimpleTypeDefinition)controlType; if (simpleType.getItemType() != null) { //list @@ -2578,10 +2678,10 @@ public abstract class AbstractSchemaFormBuilder // use the selectOne control // if (simpleType.isDefinedFacet(XSSimpleTypeDefinition.FACET_ENUMERATION)) - formControl = createControlForEnumerationType(xForm, - simpleType, - caption, - bindElement); + formControl = this.createControlForEnumerationType(xForm, + simpleType, + caption, + bindElement); } } else if (controlType.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE && @@ -2677,7 +2777,7 @@ public abstract class AbstractSchemaFormBuilder final TemplatingService ts = TemplatingService.getInstance(); final Document xForm = ts.newDocument(); - final Element envelopeElement = _wrapper.createEnvelope(xForm); + final Element envelopeElement = this.wrapper.createEnvelope(xForm); final Map namespaces = new HashMap(); namespaces.put(SchemaFormBuilder.CHIBA_NS_PREFIX, SchemaFormBuilder.CHIBA_NS); @@ -2692,20 +2792,20 @@ public abstract class AbstractSchemaFormBuilder } //base - if (_base != null && _base.length() != 0) - envelopeElement.setAttributeNS(XML_NAMESPACE_URI, "xml:base", _base); + if (this.base != null && this.base.length() != 0) + envelopeElement.setAttributeNS(XML_NAMESPACE_URI, "xml:base", this.base); //model element Element modelElement = xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "model"); this.setXFormsId(modelElement); - Element modelWrapper = _wrapper.createModelWrapper(modelElement); + Element modelWrapper = this.wrapper.createModelWrapper(modelElement); envelopeElement.appendChild(modelWrapper); //form control wrapper -> created by wrapper //Element formWrapper = xForm.createElement("body"); //envelopeElement.appendChild(formWrapper); - Element formWrapper = _wrapper.createFormWrapper(envelopeElement); + Element formWrapper = this.wrapper.createFormWrapper(envelopeElement); return xForm; } @@ -2726,7 +2826,7 @@ public abstract class AbstractSchemaFormBuilder { this.setXFormsId(groupElement); - Element controlsWrapper = _wrapper.createControlsWrapper(groupElement); + Element controlsWrapper = this.wrapper.createControlsWrapper(groupElement); //groupElement = (Element) formSection.appendChild(groupElement); formSection.appendChild(controlsWrapper); @@ -2741,6 +2841,577 @@ public abstract class AbstractSchemaFormBuilder return groupElement; } + public String createCaption(final String text, + final XSAnnotation annotation) + { + final Text t = this.extractDocumentation(annotation); + return (t != null ? t.getNodeValue() : text); + } + + /** + * Creates a caption for the provided text extracted from the XML Schema. + * The implementation is responsible for reformatting the provided string to make it + * suitable to be displayed to users of the XForm. This typically includes translating + * XML tag name style identifiers (e.g. customerStreetAddress) into more reader friendly + * captions (e.g. Customer Street Address). + * + * @param text The string value to be reformatted for use as a caption. + * @return The caption. + */ + public String createCaption(String text) + { + // if the word is all upper case, then set to lower case and continue + if (text.equals(text.toUpperCase())) + text = text.toLowerCase(); + final String[] s = text.split("[-_\\ ]"); + final StringBuffer result = new StringBuffer(); + for (int i = 0; i < s.length; i++) + { + if (i != 0) + result.append(' '); + if (s[i].length() > 1) + result.append(Character.toUpperCase(s[i].charAt(0)) + + s[i].substring(1, s[i].length())); + else + result.append(s[i]); + } + return result.toString(); + } + + /** + * Creates a caption for the provided XML Schema attribute. + * The implementation is responsible for providing an appropriate caption + * suitable to be displayed to users of the XForm. This typically includes translating + * XML tag name style identifiers (e.g. customerStreetAddress) into more reader friendly + * captions (e.g. Customer Street Address). + * + * @param attribute The XML schema attribute for which a caption is required. + * @return The caption. + */ + public String createCaption(XSAttributeDeclaration attribute) + { + // TODO: Improve i18n/l10n of caption - may have to use + // a custom element in the XML Schema to do this. + // + return createCaption(attribute.getName()); + } + + public String createCaption(XSAttributeUse attribute) + { + // TODO: Improve i18n/l10n of caption - may have to use + // a custom element in the XML Schema to do this. + // + return createCaption(attribute.getAttrDeclaration().getName()); + } + + /** + * Creates a caption for the provided XML Schema element. + * The implementation is responsible for providing an appropriate caption + * suitable to be displayed to users of the XForm. This typically includes translating + * XML tag name style identifiers (e.g. customerStreetAddress) into more reader friendly + * captions (e.g. Customer Street Address). + * + * @param element The XML schema element for which a caption is required. + * @return The caption. + */ + public String createCaption(XSElementDeclaration element) + { + // TODO: Improve i18n/l10n of caption - may have to use + // a custom element in the XML Schema to do this. + // + return createCaption(element.getName()); + } + + /** + * __UNDOCUMENTED__ + * + * @param element __UNDOCUMENTED__ + * @return __UNDOCUMENTED__ + */ + public String createCaption(XSObject element) + { + // TODO: Improve i18n/l10n of caption - may have to use + // a custom element in the XML Schema to do this. + // + if (element instanceof XSElementDeclaration) { + return createCaption(((XSElementDeclaration) element).getName()); + } else if (element instanceof XSAttributeDeclaration) { + return createCaption(((XSAttributeDeclaration) element).getName()); + } else if (element instanceof XSAttributeUse) { + return createCaption(((XSAttributeUse) element).getAttrDeclaration().getName()); + } else + LOGGER.warn("WARNING: createCaption: element is not an attribute nor an element: " + + element.getClass().getName()); + + return null; + } + + /** + * Creates a form control for an XML Schema any type. + *
+ * This method is called when the form builder determines a form control is required for + * an any type. + * The implementation of this method is responsible for creating an XML element of the + * appropriate type to receive a value for controlType. The caller is responsible + * for adding the returned element to the form and setting caption, bind, and other + * standard elements and attributes. + * + * @param xForm The XForm document. + * @param controlType The XML Schema type for which the form control is to be created. + * @return The element for the form control. + */ + public Element createControlForAnyType(Document xForm, + String caption, + XSTypeDefinition controlType) + { + Element control = xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "textarea"); + this.setXFormsId(control); + control.setAttributeNS(SchemaFormBuilder.CHIBA_NS, + SchemaFormBuilder.CHIBA_NS_PREFIX + "height", + "3"); + + //label + Element captionElement = xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); + control.appendChild(captionElement); + this.setXFormsId(captionElement); + captionElement.appendChild(xForm.createTextNode(caption)); + + return control; + } + + /** + * Creates a form control for an XML Schema simple atomic type. + *

+ * This method is called when the form builder determines a form control is required for + * an atomic type. + * The implementation of this method is responsible for creating an XML element of the + * appropriate type to receive a value for controlType. The caller is responsible + * for adding the returned element to the form and setting caption, bind, and other + * standard elements and attributes. + * + * @param xForm The XForm document. + * @param controlType The XML Schema type for which the form control is to be created. + * @return The element for the form control. + */ + public Element createControlForAtomicType(Document xForm, + String caption, + XSSimpleTypeDefinition controlType) + { + Element control; + + //remove while select1 do not work correctly in repeats + if ("boolean".equals(controlType.getName())) + { + control = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "select1"); + control.setAttributeNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "appearance", + "full"); + this.setXFormsId(control); + final String[] values = { "true", "false" }; + for (String v : values) + { + Element item = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "item"); + this.setXFormsId(item); + Element e = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); + this.setXFormsId(e); + e.appendChild(xForm.createTextNode(v)); + item.appendChild(e); + + e = xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "value"); + this.setXFormsId(e); + e.appendChild(xForm.createTextNode(v)); + item.appendChild(e); + control.appendChild(item); + } + } + else + { + control = xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "input"); + this.setXFormsId(control); + } + + //label + Element captionElement = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); + control.appendChild(captionElement); + this.setXFormsId(captionElement); + captionElement.appendChild(xForm.createTextNode(caption)); + + return control; + } + + /** + * Creates a form control for an XML Schema simple type restricted by an enumeration. + * This method is called when the form builder determines a form control is required for + * an enumerated type. + * The implementation of this method is responsible for creating an XML element of the + * appropriate type to receive a value for controlType. The caller is responsible + * for adding the returned element to the form and setting caption, bind, and other + * standard elements and attributes. + * + * @param xForm The XForm document. + * @param controlType The XML Schema type for which the form control is to be created. + * @param caption The caption for the form control. The caller The purpose of providing the caption + * is to permit the implementation to add a [Select1 .... ] message that involves the caption. + * @param bindElement The bind element for this control. The purpose of providing the bind element + * is to permit the implementation to add a isValid attribute to the bind element that prevents + * the [Select1 .... ] item from being selected. + * @return The element for the form control. + */ + public Element createControlForEnumerationType(Document xForm, + XSSimpleTypeDefinition controlType, + String caption, + Element bindElement) + { + // TODO: Figure out an intelligent or user determined way to decide between + // selectUI style (listbox, menu, combobox, radio) (radio and listbox best apply) + // Possibly look for special appInfo section in the schema and if not present default to comboBox... + // + // For now, use radio if enumValues < DEFAULT_LONG_LIST_MAX_SIZE otherwise use combobox + // + final StringList enumFacets = controlType.getLexicalEnumeration(); + if (enumFacets.getLength() <= 0) + return null; + + Element control = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "select1"); + this.setXFormsId(control); + + //label + Element captionElement1 = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); + control.appendChild(captionElement1); + this.setXFormsId(captionElement1); + captionElement1.appendChild(xForm.createTextNode(caption)); + + Element choices = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "choices"); + this.setXFormsId(choices); + + final XSObjectList mvFacets = controlType.getMultiValueFacets(); + if (mvFacets.getLength() != 1) + throw new RuntimeException("expected exactly one MultiValueFacet for " + controlType); + + final XSObjectList annotations = + ((XSMultiValueFacet)mvFacets.item(0)).getAnnotations(); + + final Map enumValues = + new HashMap(enumFacets.getLength()); + for (int i = 0; i < enumFacets.getLength(); i++) + { + enumValues.put(enumFacets.item(i), + (annotations.getLength() == enumFacets.getLength() + ? (XSAnnotation)annotations.item(i) + : null)); + } + + control.setAttributeNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "appearance", + (enumFacets.getLength() < Long.parseLong(getProperty(SELECTONE_LONG_LIST_SIZE_PROP)) + ? getProperty(SELECTONE_UI_CONTROL_SHORT_PROP) + : getProperty(SELECTONE_UI_CONTROL_LONG_PROP))); + + if (enumFacets.getLength() >= Long.parseLong(getProperty(SELECTONE_LONG_LIST_SIZE_PROP))) + { + // add the "Please select..." instruction item for the combobox + // and set the isValid attribute on the bind element to check for the "Please select..." + // item to indicate that is not a valid value + // + String pleaseSelect = "[Select1 " + caption + "]"; + Element item = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "item"); + this.setXFormsId(item); + choices.appendChild(item); + + Element captionElement = + xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); + this.setXFormsId(captionElement); + item.appendChild(captionElement); + captionElement.appendChild(xForm.createTextNode(pleaseSelect)); + + Element value = + xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "value"); + this.setXFormsId(value); + item.appendChild(value); + value.appendChild(xForm.createTextNode(pleaseSelect)); + + // not(purchaseOrder/state = '[Choose State]') + //String isValidExpr = "not(" + bindElement.getAttributeNS(XFORMS_NS,"nodeset") + " = '" + pleaseSelect + "')"; + // ->no, not(. = '[Choose State]') + String isValidExpr = "not( . = '" + pleaseSelect + "')"; + + //check if there was a constraint + String constraint = bindElement.getAttributeNS(XFORMS_NS, "constraint"); + + constraint = (constraint != null && constraint.length() != 0 + ? constraint + " and " + isValidExpr + : isValidExpr); + + bindElement.setAttributeNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "constraint", + constraint); + } + + control.appendChild(choices); + + this.addChoicesForSelectControl(xForm, choices, enumValues); + + return control; + } + + /** + * Creates a form control for an XML Schema simple list type. + *

+ * This method is called when the form builder determines a form control is required for + * a list type. + * The implementation of this method is responsible for creating an XML element of the + * appropriate type to receive a value for controlType. The caller is responsible + * for adding the returned element to the form and setting caption, bind, and other + * standard elements and attributes. + * + * @param xForm The XForm document. + * @param listType The XML Schema list type for which the form control is to be created. + * @param caption The caption for the form control. The caller The purpose of providing the caption + * is to permit the implementation to add a [Select1 .... ] message that involves the caption. + * @param bindElement The bind element for this control. The purpose of providing the bind element + * is to permit the implementation to add a isValid attribute to the bind element that prevents + * the [Select1 .... ] item from being selected. + * @return The element for the form control. + */ + public Element createControlForListType(final Document xForm, + final XSSimpleTypeDefinition listType, + final String caption, + final Element bindElement) + { + XSSimpleTypeDefinition controlType = listType.getItemType(); + + final StringList enumFacets = controlType.getLexicalEnumeration(); + if (enumFacets.getLength() <= 0) + return null; + Element control = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "select"); + this.setXFormsId(control); + + //label + Element captionElement = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); + control.appendChild(captionElement); + this.setXFormsId(captionElement); + captionElement.appendChild(xForm.createTextNode(caption)); + + final XSObjectList mvFacets = controlType.getMultiValueFacets(); + if (mvFacets.getLength() != 1) + throw new RuntimeException("expected exactly one MultiValueFacet for " + controlType); + + final XSObjectList annotations = + ((XSMultiValueFacet)mvFacets.item(0)).getAnnotations(); + + final Map enumValues = + new HashMap(enumFacets.getLength()); + for (int i = 0; i < enumFacets.getLength(); i++) + { + enumValues.put(enumFacets.item(i), + (annotations.getLength() == enumFacets.getLength() + ? (XSAnnotation)annotations.item(i) + : null)); + } + + // TODO: Figure out an intelligent or user determined way to decide between + // selectUI style (listbox, menu, combobox, radio) (radio and listbox best apply) + // Possibly look for special appInfo section in the schema and if not present default to checkBox... + // + // For now, use checkbox if there are < DEFAULT_LONG_LIST_MAX_SIZE items, otherwise use long control + // + control.setAttributeNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "appearance", + (enumValues.size() < Long.parseLong(getProperty(SELECTMANY_LONG_LIST_SIZE_PROP)) + ? getProperty(SELECTMANY_UI_CONTROL_SHORT_PROP) + : getProperty(SELECTMANY_UI_CONTROL_LONG_PROP))); + Element choices = xForm.createElementNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "choices"); + this.setXFormsId(choices); + control.appendChild(choices); + + this.addChoicesForSelectControl(xForm, choices, enumValues); + + return control; + } + + /** + * Creates a hint XML Schema annotated node (AttributeDecl or ElementDecl). + * The implementation is responsible for providing an xforms:hint element for the + * specified schemaNode suitable to be dsipalayed to users of the XForm. The caller + * is responsible for adding the returned element to the form. + * This typically includes extracting documentation from the element/attribute's + * annotation/documentation elements and/or extracting the same information from the + * element/attribute's type annotation/documentation. + * + * @param schemaNode The string value to be reformatted for use as a caption. + * @return The xforms:hint element. If a null value is returned a hint is not added. + */ + public Element createHint(Document xForm, XSObject node) + { + XSAnnotation annotation = null; + if (node instanceof XSElementDeclaration) + annotation = ((XSElementDeclaration)node).getAnnotation(); + else if (node instanceof XSAttributeDeclaration) + annotation = ((XSAttributeDeclaration)node).getAnnotation(); + else if (node instanceof XSAttributeUse) + annotation = ((XSAttributeUse)node).getAttrDeclaration().getAnnotation(); + + return (annotation != null + ? addHintFromDocumentation(xForm, annotation) + : null); + } + + /** + * This method is invoked after the form builder is finished creating and processing + * a bind element. Implementations may choose to use this method to add/inspect/modify + * the bindElement prior to the builder moving onto the next bind element. + * + * @param bindElement The bind element being processed. + */ + public void endBindElement(Element bindElement) + { + } + + /** + * This method is invoked after the form builder is finished creating and processing + * a form control. Implementations may choose to use this method to add/inspect/modify + * the controlElement prior to the builder moving onto the next control. + * + * @param controlElement The form control element that was created. + * @param controlType The XML Schema type for which controlElement was created. + */ + public void endFormControl(Element controlElement, + XSTypeDefinition controlType, + Occurs occurs) + { + } + + /** + * __UNDOCUMENTED__ + * + * @param groupElement __UNDOCUMENTED__ + */ + public void endFormGroup(final Element groupElement, + final XSTypeDefinition controlType, + final Occurs o, + final Element modelSection) + { + } + + /** + * This method is invoked after an xforms:bind element is created for the specified SimpleType. + * The implementation is responsible for setting setting any/all bind attributes + * except for id and ref - these have been automatically set + * by the caller (and should not be touched by implementation of startBindElement) + * prior to invoking startBindElement. + * The caller automatically adds the returned element to the model section of + * the form. + * + * @param bindElement The bindElement being processed. + * @param controlType XML Schema type of the element/attribute this bind is for. + * @param minOccurs The minimum number of occurences for this element/attribute. + * @param maxOccurs The maximum number of occurences for this element/attribute. + * @return The bind Element to use in the XForm - bindElement or a replacement. + */ + public Element startBindElement(final Element bindElement, + final XSModel schema, + final XSTypeDefinition controlType, + final Occurs o) + { + // START WORKAROUND + // Due to a Chiba bug, anyType is not a recognized type name. + // so, if this is an anyType, then we'll just skip the type + // setting. + // + // type.getName() may be 'null' for anonymous types, so compare against + // static string (see bug #1172541 on sf.net) + if (!"anyType".equals(controlType.getName())) + { + Element enveloppe = bindElement.getOwnerDocument().getDocumentElement(); + String typeName = this.getXFormsTypeName(enveloppe, schema, controlType); + if (typeName != null && typeName.length() != 0) + bindElement.setAttributeNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "type", + typeName); + } + + bindElement.setAttributeNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "required", + o.minimum == 0 ? "false()" : "true()"); + + + //no more minOccurs & maxOccurs element: add a constraint if maxOccurs>1: + //count(.) <= maxOccurs && count(.) >= minOccurs + String minConstraint = null; + String maxConstraint = null; + + if (o.minimum > 1) + //if 0 or 1 -> no constraint (managed by "required") + minConstraint = "count(.) >= " + o.minimum; + + if (o.maximum > 1) + //if 1 or unbounded -> no constraint + maxConstraint = "count(.) <= " + o.maximum; + + final String constraint = (minConstraint != null && maxConstraint != null + ? minConstraint + " and " + maxConstraint + : (minConstraint != null + ? minConstraint + : maxConstraint)); + if (constraint != null && constraint.length() != 0) + bindElement.setAttributeNS(XFORMS_NS, + SchemaFormBuilder.XFORMS_NS_PREFIX + "constraint", + constraint); + return bindElement; + } + + /** + * This method is invoked after the form builder creates a form control + * via a createControlForXXX() method but prior to decorating the form control + * with common attributes such as a caption, hint, help text elements, + * bind attributes, etc. + * The returned element is used in the XForm in place of controlElement. + * Implementations may choose to use this method to substitute controlElement + * with a different element, or perform any other processing on controlElement + * prior to it being added to the form. + * + * @param controlElement The form control element that was created. + * @param controlType The XML Schema type for which controlElement was created. + * @return The Element to use in the XForm - controlElement or a replacement. + */ + public Element startFormControl(Element controlElement, + XSTypeDefinition controlType) + { + return controlElement; + } + + /** + * This method is invoked after an xforms:group element is created for the specified + * ElementDecl. A group is created whenever an element is encountered in the XML Schema + * that contains other elements and attributes (complex types or mixed content types). + * The caller automatically adds the returned element to the XForm. + * + * @param groupElement The groupElement being processed. + * @param schemaElement The schemaElement for the group. + * @return The group Element to use in the XForm - groupElement or a replacement. If a null + * value is returned, the group is not created. + */ + public Element startFormGroup(Element groupElement, + XSElementDeclaration schemaElement) + { + return groupElement; + } + /** * Get a fully qualified name for this element, and eventually declares a new prefix for the namespace if * it was not declared before @@ -2775,7 +3446,7 @@ public abstract class AbstractSchemaFormBuilder return elementName; } - private XSModel loadSchema(final TemplateType tt) + private XSModel loadSchema(final Document schemaDocument) throws FormBuilderException { try @@ -2791,7 +3462,7 @@ public abstract class AbstractSchemaFormBuilder registry.getDOMImplementation("XML 1.0 LS 3.0"); final TemplatingService ts = TemplatingService.getInstance(); final LSInput in = lsImpl.createLSInput(); - in.setStringData(ts.writeXMLToString(tt.getSchema())); + in.setStringData(ts.writeXMLToString(schemaDocument)); final XSImplementation xsImpl = (XSImplementation) registry.getDOMImplementation("XS-Loader"); diff --git a/source/java/org/alfresco/web/templating/xforms/TemplateTypeImpl.java b/source/java/org/alfresco/web/templating/xforms/TemplateTypeImpl.java index b305fd782c..cd74159f87 100644 --- a/source/java/org/alfresco/web/templating/xforms/TemplateTypeImpl.java +++ b/source/java/org/alfresco/web/templating/xforms/TemplateTypeImpl.java @@ -80,7 +80,8 @@ public class TemplateTypeImpl final TemplatingService ts = TemplatingService.getInstance(); try { - this.schema = ts.parseXML(this.schemaNodeRef); + //XXXarielb maybe cloneNode instead? + return /* this.schema = */ ts.parseXML(this.schemaNodeRef); } catch (Exception e) { diff --git a/source/java/org/alfresco/web/templating/xforms/schemabuilder/WrapperElementsBuilder.java b/source/java/org/alfresco/web/templating/xforms/WrapperElementsBuilder.java similarity index 97% rename from source/java/org/alfresco/web/templating/xforms/schemabuilder/WrapperElementsBuilder.java rename to source/java/org/alfresco/web/templating/xforms/WrapperElementsBuilder.java index be42697229..3b8ca63c91 100644 --- a/source/java/org/alfresco/web/templating/xforms/schemabuilder/WrapperElementsBuilder.java +++ b/source/java/org/alfresco/web/templating/xforms/WrapperElementsBuilder.java @@ -14,7 +14,7 @@ * language governing permissions and limitations under the * License. */ -package org.alfresco.web.templating.xforms.schemabuilder; +package org.alfresco.web.templating.xforms; import org.w3c.dom.Document; import org.w3c.dom.Element; diff --git a/source/java/org/alfresco/web/bean/ajax/XFormsBean.java b/source/java/org/alfresco/web/templating/xforms/XFormsBean.java similarity index 80% rename from source/java/org/alfresco/web/bean/ajax/XFormsBean.java rename to source/java/org/alfresco/web/templating/xforms/XFormsBean.java index 0178e4bdc1..d34c0b406e 100644 --- a/source/java/org/alfresco/web/bean/ajax/XFormsBean.java +++ b/source/java/org/alfresco/web/templating/xforms/XFormsBean.java @@ -14,7 +14,7 @@ * language governing permissions and limitations under the * License. */ -package org.alfresco.web.bean.ajax; +package org.alfresco.web.templating.xforms; import java.io.BufferedReader; import java.io.IOException; @@ -27,14 +27,16 @@ import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.context.ExternalContext; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.alfresco.web.bean.wcm.AVMConstants; import org.alfresco.web.templating.*; import org.alfresco.web.templating.xforms.*; -import org.alfresco.web.templating.xforms.schemabuilder.FormBuilderException; import org.w3c.dom.Document; import org.w3c.dom.Node; +import org.alfresco.web.bean.wcm.AVMBrowseBean; import org.alfresco.web.app.servlet.FacesHelper; import org.chiba.xml.xforms.ChibaBean; import org.chiba.xml.xforms.exception.XFormsException; @@ -42,6 +44,8 @@ import org.chiba.xml.xforms.events.XFormsEvent; import org.chiba.xml.xforms.events.XFormsEventFactory; import org.w3c.dom.*; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; +import org.w3c.dom.ls.*; import org.w3c.dom.events.Event; import org.w3c.dom.events.EventListener; import org.w3c.dom.events.EventTarget; @@ -85,20 +89,26 @@ public class XFormsBean public void init() throws XFormsException { + LOGGER.debug("initializing " + this + " with tt " + tt.getName()); this.chibaBean = new ChibaBean(); final FacesContext facesContext = FacesContext.getCurrentInstance(); final ExternalContext externalContext = facesContext.getExternalContext(); final HttpServletRequest request = (HttpServletRequest) externalContext.getRequest(); + final HttpSession session = (HttpSession) + externalContext.getSession(true); + final AVMBrowseBean browseBean = (AVMBrowseBean) + session.getAttribute("AVMBrowseBean"); + LOGGER.debug("avm cwd is " + browseBean.getCurrentPath()); + XFormsBean.storeCookies(request.getCookies(), this.chibaBean); + try { - LOGGER.debug("initializing " + this + - " with tt " + tt.getName()); - //XXXarielb generalize this - final XFormsInputMethod tim = (XFormsInputMethod) - tt.getInputMethods().get(0); - final Document form = tim.getXForm(instanceData.getContent(), tt); + final Document form = this.buildXForm(instanceData.getContent(), + tt, + browseBean.getCurrentPath(), + request); this.chibaBean.setXMLContainer(form); final EventTarget et = (EventTarget) @@ -244,6 +254,59 @@ public class XFormsBean out.close(); } + + private void rewriteInlineURIs(final Document schemaDocument, + final String cwdAvmPath) + { + final NodeList includes = + schemaDocument.getElementsByTagNameNS(SchemaFormBuilder.XMLSCHEMA_NS, "include"); + LOGGER.debug("rewriting " + includes.getLength() + " includes"); + for (int i = 0; i < includes.getLength(); i++) + { + final Element includeEl = (Element)includes.item(i); + if (includeEl.hasAttribute("schemaLocation")) + { + String uri = includeEl.getAttribute("schemaLocation"); + final String baseURI = (uri.charAt(0) == '/' + ? AVMConstants.buildAVMStoreUrl(cwdAvmPath) + : AVMConstants.buildAVMAssetUrl(cwdAvmPath)); + + LOGGER.debug("rewriting " + uri + " as " + (baseURI + uri)); + includeEl.setAttribute("schemaLocation", baseURI + uri); + } + } + } + + /** + * Generates the xforms based on the schema. + */ + private Document buildXForm(Document xmlContent, + final TemplateType tt, + final String cwdAvmPath, + final HttpServletRequest request) + throws FormBuilderException + { + final Document schemaDocument = tt.getSchema(); + this.rewriteInlineURIs(schemaDocument, cwdAvmPath); + final String baseUrl = (request.getScheme() + "://" + + request.getServerName() + ':' + + request.getServerPort() + + request.getContextPath()); + LOGGER.debug("using baseUrl " + baseUrl + " for schemaformbuilder"); + final SchemaFormBuilder builder = + new SchemaFormBuilder("/ajax/invoke/XFormsBean.handleAction", + SchemaFormBuilder.SUBMIT_METHOD_POST, + new XHTMLWrapperElementsBuilder(), + baseUrl); + LOGGER.debug("building xform for schema " + tt.getName()); + final Document result = builder.buildForm(xmlContent, + schemaDocument, + tt.getName()); + LOGGER.debug("generated xform: " + result); + // LOGGER.debug(ts.writeXMLToString(result)); + return result; + } + private Node getEventLog() { final TemplatingService ts = TemplatingService.getInstance(); diff --git a/source/java/org/alfresco/web/templating/xforms/XFormsInputMethod.java b/source/java/org/alfresco/web/templating/xforms/XFormsInputMethod.java index b3826b3903..e3f78b4094 100644 --- a/source/java/org/alfresco/web/templating/xforms/XFormsInputMethod.java +++ b/source/java/org/alfresco/web/templating/xforms/XFormsInputMethod.java @@ -22,8 +22,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.ServletContext; import org.alfresco.web.templating.*; -import org.alfresco.web.templating.xforms.schemabuilder.*; -import org.alfresco.web.bean.ajax.XFormsBean; import org.chiba.xml.util.DOMUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -101,44 +99,4 @@ public class XFormsInputMethod ts.writeXML(result, out); } - - private static String getDocumentElementNameNoNS(final Document d) - { - final Node n = d.getDocumentElement(); - String name = n.getNodeName(); - return name; -// String prefix = n.getPrefix(); -// String namespace = n.getNamespaceURI(); -// System.out.println("name " + name + " prefix " + prefix + " ns uri " + namespace); -// return name.replaceAll(".+\\:", ""); - } - - /** - * Generates the xforms based on the schema. - */ - public Document getXForm(Document xmlContent, final TemplateType tt) - throws FormBuilderException - { - final TemplatingService ts = TemplatingService.getInstance(); - final FacesContext fc = FacesContext.getCurrentInstance(); - final HttpServletRequest request = (HttpServletRequest) - fc.getExternalContext().getRequest(); - final String baseUrl = (request.getScheme() + "://" + - request.getServerName() + ':' + - request.getServerPort() + - request.getContextPath()); - LOGGER.debug("using baseUrl " + baseUrl + " for schemaformbuilder"); - - final SchemaFormBuilder builder = - new BaseSchemaFormBuilder(xmlContent, - "/ajax/invoke/XFormsBean.handleAction", - SchemaFormBuilder.SUBMIT_METHOD_POST, - new XHTMLWrapperElementsBuilder(), - baseUrl); - LOGGER.debug("building xform for schema " + tt.getName()); - final Document result = builder.buildForm(tt); - LOGGER.debug("generated xform: " + result); - // LOGGER.debug(ts.writeXMLToString(result)); - return result; - } } diff --git a/source/java/org/alfresco/web/templating/xforms/schemabuilder/XHTMLWrapperElementsBuilder.java b/source/java/org/alfresco/web/templating/xforms/XHTMLWrapperElementsBuilder.java similarity index 99% rename from source/java/org/alfresco/web/templating/xforms/schemabuilder/XHTMLWrapperElementsBuilder.java rename to source/java/org/alfresco/web/templating/xforms/XHTMLWrapperElementsBuilder.java index abc6fafd2a..06937ba1e5 100644 --- a/source/java/org/alfresco/web/templating/xforms/schemabuilder/XHTMLWrapperElementsBuilder.java +++ b/source/java/org/alfresco/web/templating/xforms/XHTMLWrapperElementsBuilder.java @@ -14,7 +14,7 @@ * language governing permissions and limitations under the * License. */ -package org.alfresco.web.templating.xforms.schemabuilder; +package org.alfresco.web.templating.xforms; import org.w3c.dom.Document; import org.w3c.dom.Element; diff --git a/source/java/org/alfresco/web/templating/xforms/schemabuilder/BaseSchemaFormBuilder.java b/source/java/org/alfresco/web/templating/xforms/schemabuilder/BaseSchemaFormBuilder.java deleted file mode 100644 index 931a7a9322..0000000000 --- a/source/java/org/alfresco/web/templating/xforms/schemabuilder/BaseSchemaFormBuilder.java +++ /dev/null @@ -1,551 +0,0 @@ -/* - * 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.templating.xforms.schemabuilder; - -import org.apache.xerces.xs.*; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Text; -import java.util.*; - -/* - * Search for TODO for things remaining to-do in this implementation. - * - * TODO: i18n/l10n of messages, hints, captions. Possibly leverage org.chiba.i18n classes. - * TODO: When Chiba supports itemset, use schema keyref and key constraints for validation. - * TODO: Add support for default and fixed values. - * TODO: Add support for use=prohibited. - */ - -/** - * A concrete base implementation of the SchemaFormBuilder interface allowing - * an XForm to be automatically generated for an XML Schema definition. - * - * @author Brian Dueck - * @version $Id: BaseSchemaFormBuilder.java,v 1.19 2005/03/29 14:24:34 unl Exp $ - */ -public class BaseSchemaFormBuilder - extends AbstractSchemaFormBuilder - implements SchemaFormBuilder { - - /** - * Creates a new BaseSchemaFormBuilder object. - * - * @param instanceSource __UNDOCUMENTED__ - * @param action __UNDOCUMENTED__ - * @param submitMethod __UNDOCUMENTED__ - * @param wrapper __UNDOCUMENTED__ - */ - public BaseSchemaFormBuilder(final Document instanceDocument, - final String action, - final String submitMethod, - final WrapperElementsBuilder wrapper, - final String base) - { - super(instanceDocument, - action, - submitMethod, - wrapper, - base); - } - - /** - * __UNDOCUMENTED__ - * - * @param text __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public String createCaption(String text) { - // if the word is all upper case, then set to lower case and continue - if (text.equals(text.toUpperCase())) - text = text.toLowerCase(); - String[] s = text.split("[-_\\ ]"); - StringBuffer result = new StringBuffer(); - for (int i = 0; i < s.length; i++) - { - if (i != 0) - result.append(' '); - if (s[i].length() > 1) - { - result.append(Character.toUpperCase(s[i].charAt(0)) + - s[i].substring(1, s[i].length())); - } - else - { - result.append(s[i]); - } - } - return result.toString(); - } - - /** - * __UNDOCUMENTED__ - * - * @param attribute __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public String createCaption(XSAttributeDeclaration attribute) { - // TODO: Improve i18n/l10n of caption - may have to use - // a custom element in the XML Schema to do this. - // - return createCaption(attribute.getName()); - } - - public String createCaption(XSAttributeUse attribute) { - // TODO: Improve i18n/l10n of caption - may have to use - // a custom element in the XML Schema to do this. - // - return createCaption(attribute.getAttrDeclaration().getName()); - } - - /** - * __UNDOCUMENTED__ - * - * @param element __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public String createCaption(XSElementDeclaration element) { - // TODO: Improve i18n/l10n of caption - may have to use - // a custom element in the XML Schema to do this. - // - return createCaption(element.getName()); - } - - /** - * __UNDOCUMENTED__ - * - * @param element __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public String createCaption(XSObject element) { - // TODO: Improve i18n/l10n of caption - may have to use - // a custom element in the XML Schema to do this. - // - if (element instanceof XSElementDeclaration) { - return createCaption(((XSElementDeclaration) element).getName()); - } else if (element instanceof XSAttributeDeclaration) { - return createCaption(((XSAttributeDeclaration) element).getName()); - } else if (element instanceof XSAttributeUse) { - return createCaption(((XSAttributeUse) element).getAttrDeclaration().getName()); - } else - LOGGER.warn("WARNING: createCaption: element is not an attribute nor an element: " - + element.getClass().getName()); - - return null; - } - - /** - * __UNDOCUMENTED__ - * - * @param xForm __UNDOCUMENTED__ - * @param caption __UNDOCUMENTED__ - * @param controlType __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public Element createControlForAnyType(Document xForm, - String caption, - XSTypeDefinition controlType) { - Element control = xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "textarea"); - this.setXFormsId(control); - control.setAttributeNS(SchemaFormBuilder.CHIBA_NS, - SchemaFormBuilder.CHIBA_NS_PREFIX + "height", - "3"); - - //label - Element captionElement = (Element) - control.appendChild(xForm.createElementNS(SchemaFormBuilder.XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "label")); - this.setXFormsId(captionElement); - captionElement.appendChild(xForm.createTextNode(caption)); - - return control; - } - - /** - * __UNDOCUMENTED__ - * - * @param xForm __UNDOCUMENTED__ - * @param caption __UNDOCUMENTED__ - * @param controlType __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public Element createControlForAtomicType(Document xForm, - String caption, - XSSimpleTypeDefinition controlType) { - Element control; - - //remove while select1 do not work correctly in repeats - if ("boolean".equals(controlType.getName())) - { - control = xForm.createElementNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "select1"); - control.setAttributeNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "appearance", - "full"); - this.setXFormsId(control); - - Element item_true = - xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "item"); - this.setXFormsId(item_true); - Element label_true = - xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); - this.setXFormsId(label_true); - Text label_true_text = xForm.createTextNode("true"); - label_true.appendChild(label_true_text); - item_true.appendChild(label_true); - - Element value_true = - xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "value"); - this.setXFormsId(value_true); - Text value_true_text = xForm.createTextNode("true"); - value_true.appendChild(value_true_text); - item_true.appendChild(value_true); - control.appendChild(item_true); - - Element item_false = - xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "item"); - this.setXFormsId(item_false); - Element label_false = - xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); - this.setXFormsId(label_false); - Text label_false_text = xForm.createTextNode("false"); - label_false.appendChild(label_false_text); - item_false.appendChild(label_false); - - Element value_false = - xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "value"); - this.setXFormsId(value_false); - Text value_false_text = xForm.createTextNode("false"); - value_false.appendChild(value_false_text); - item_false.appendChild(value_false); - control.appendChild(item_false); - } - else - { - control = xForm.createElementNS(XFORMS_NS, SchemaFormBuilder.XFORMS_NS_PREFIX + "input"); - this.setXFormsId(control); - } - - //label - Element captionElement = (Element) - control.appendChild(xForm.createElementNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "label")); - this.setXFormsId(captionElement); - captionElement.appendChild(xForm.createTextNode(caption)); - - return control; - } - - /** - * __UNDOCUMENTED__ - * - * @param xForm __UNDOCUMENTED__ - * @param controlType __UNDOCUMENTED__ - * @param caption __UNDOCUMENTED__ - * @param bindElement __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public Element createControlForEnumerationType(Document xForm, - XSSimpleTypeDefinition controlType, - String caption, - Element bindElement) { - // TODO: Figure out an intelligent or user determined way to decide between - // selectUI style (listbox, menu, combobox, radio) (radio and listbox best apply) - // Possibly look for special appInfo section in the schema and if not present default to comboBox... - // - // For now, use radio if enumValues < DEFAULT_LONG_LIST_MAX_SIZE otherwise use combobox - // - final StringList enumFacets = controlType.getLexicalEnumeration(); - if (enumFacets.getLength() <= 0) - return null; - - Element control = xForm.createElementNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "select1"); - this.setXFormsId(control); - - //label - Element captionElement1 = xForm.createElementNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); - control.appendChild(captionElement1); - this.setXFormsId(captionElement1); - captionElement1.appendChild(xForm.createTextNode(caption)); - - Element choices = xForm.createElementNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "choices"); - this.setXFormsId(choices); - - final List enumValues = new ArrayList(enumFacets.getLength()); - for (int i = 0; i < enumFacets.getLength(); i++) - { - enumValues.add(enumFacets.item(i)); - } - control.setAttributeNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "appearance", - (enumFacets.getLength() < Long.parseLong(getProperty(SELECTONE_LONG_LIST_SIZE_PROP)) - ? getProperty(SELECTONE_UI_CONTROL_SHORT_PROP) - : getProperty(SELECTONE_UI_CONTROL_LONG_PROP))); - - if (enumFacets.getLength() >= Long.parseLong(getProperty(SELECTONE_LONG_LIST_SIZE_PROP))) - { - // add the "Please select..." instruction item for the combobox - // and set the isValid attribute on the bind element to check for the "Please select..." - // item to indicate that is not a valid value - // - String pleaseSelect = "[Select1 " + caption + "]"; - Element item = xForm.createElementNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "item"); - this.setXFormsId(item); - choices.appendChild(item); - - Element captionElement = - xForm.createElementNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); - this.setXFormsId(captionElement); - item.appendChild(captionElement); - captionElement.appendChild(xForm.createTextNode(pleaseSelect)); - - Element value = - xForm.createElementNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "value"); - this.setXFormsId(value); - item.appendChild(value); - value.appendChild(xForm.createTextNode(pleaseSelect)); - - // not(purchaseOrder/state = '[Choose State]') - //String isValidExpr = "not(" + bindElement.getAttributeNS(XFORMS_NS,"nodeset") + " = '" + pleaseSelect + "')"; - // ->no, not(. = '[Choose State]') - String isValidExpr = "not( . = '" + pleaseSelect + "')"; - - //check if there was a constraint - String constraint = bindElement.getAttributeNS(XFORMS_NS, "constraint"); - - constraint = (constraint != null && constraint.length() != 0 - ? constraint + " and " + isValidExpr - : isValidExpr); - - bindElement.setAttributeNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "constraint", - constraint); - } - - control.appendChild(choices); - - this.addChoicesForSelectControl(xForm, choices, enumValues); - - return control; - } - - /** - * __UNDOCUMENTED__ - * - * @param xForm __UNDOCUMENTED__ - * @param listType __UNDOCUMENTED__ - * @param caption __UNDOCUMENTED__ - * @param bindElement __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public Element createControlForListType(final Document xForm, - final XSSimpleTypeDefinition listType, - final String caption, - final Element bindElement) { - XSSimpleTypeDefinition controlType = listType.getItemType(); - - final StringList enumFacets = controlType.getLexicalEnumeration(); - if (enumFacets.getLength() <= 0) - return null; - Element control = xForm.createElementNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "select"); - this.setXFormsId(control); - - //label - Element captionElement = xForm.createElementNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "label"); - control.appendChild(captionElement); - this.setXFormsId(captionElement); - captionElement.appendChild(xForm.createTextNode(caption)); - - List enumValues = new ArrayList(enumFacets.getLength()); - for (int i = 0; i < enumFacets.getLength(); i++) - { - enumValues.add(enumFacets.item(i)); - } - - // TODO: Figure out an intelligent or user determined way to decide between - // selectUI style (listbox, menu, combobox, radio) (radio and listbox best apply) - // Possibly look for special appInfo section in the schema and if not present default to checkBox... - // - // For now, use checkbox if there are < DEFAULT_LONG_LIST_MAX_SIZE items, otherwise use long control - // - control.setAttributeNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "appearance", - (enumValues.size() < Long.parseLong(getProperty(SELECTMANY_LONG_LIST_SIZE_PROP)) - ? getProperty(SELECTMANY_UI_CONTROL_SHORT_PROP) - : getProperty(SELECTMANY_UI_CONTROL_LONG_PROP))); - Element choices = xForm.createElementNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "choices"); - this.setXFormsId(choices); - control.appendChild(choices); - - this.addChoicesForSelectControl(xForm, choices, enumValues); - - return control; - } - - /** - * __UNDOCUMENTED__ - * - * @param xForm __UNDOCUMENTED__ - * @param node __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public Element createHint(Document xForm, XSObject node) - { - XSAnnotation annotation = null; - if (node instanceof XSElementDeclaration) - annotation = ((XSElementDeclaration) node).getAnnotation(); - else if (node instanceof XSAttributeDeclaration) - annotation = ((XSAttributeDeclaration) node).getAnnotation(); - else if (node instanceof XSAttributeUse) - annotation = - ((XSAttributeUse) node).getAttrDeclaration().getAnnotation(); - - return (annotation != null - ? addHintFromDocumentation(xForm, annotation) - : null); - } - - /** - * __UNDOCUMENTED__ - * - * @param bindElement __UNDOCUMENTED__ - */ - public void endBindElement(Element bindElement) - { - } - - /** - * __UNDOCUMENTED__ - * - * @param controlElement __UNDOCUMENTED__ - * @param controlType __UNDOCUMENTED__ - */ - public void endFormControl(final Element controlElement, - final XSTypeDefinition controlType, - final Occurs o) - { - } - - /** - * __UNDOCUMENTED__ - * - * @param groupElement __UNDOCUMENTED__ - */ - public void endFormGroup(final Element groupElement, - final XSTypeDefinition controlType, - final Occurs o, - final Element modelSection) - { - } - - /** - * __UNDOCUMENTED__ - * - * @param bindElement __UNDOCUMENTED__ - * @param controlType __UNDOCUMENTED__ - * @param minOccurs __UNDOCUMENTED__ - * @param maxOccurs __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public Element startBindElement(final Element bindElement, - final XSModel schema, - final XSTypeDefinition controlType, - final Occurs o) - { - // START WORKAROUND - // Due to a Chiba bug, anyType is not a recognized type name. - // so, if this is an anyType, then we'll just skip the type - // setting. - // - // type.getName() may be 'null' for anonymous types, so compare against - // static string (see bug #1172541 on sf.net) - if (!"anyType".equals(controlType.getName())) - { - Element enveloppe = bindElement.getOwnerDocument().getDocumentElement(); - String typeName = this.getXFormsTypeName(enveloppe, schema, controlType); - if (typeName != null && typeName.length() != 0) - bindElement.setAttributeNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "type", - typeName); - } - - bindElement.setAttributeNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "required", - o.minimum == 0 ? "false()" : "true()"); - - - //no more minOccurs & maxOccurs element: add a constraint if maxOccurs>1: - //count(.) <= maxOccurs && count(.) >= minOccurs - String minConstraint = null; - String maxConstraint = null; - - if (o.minimum > 1) - //if 0 or 1 -> no constraint (managed by "required") - minConstraint = "count(.) >= " + o.minimum; - - if (o.maximum > 1) - //if 1 or unbounded -> no constraint - maxConstraint = "count(.) <= " + o.maximum; - - final String constraint = (minConstraint != null && maxConstraint != null - ? minConstraint + " and " + maxConstraint - : (minConstraint != null - ? minConstraint - : maxConstraint)); - if (constraint != null && constraint.length() != 0) - bindElement.setAttributeNS(XFORMS_NS, - SchemaFormBuilder.XFORMS_NS_PREFIX + "constraint", - constraint); - return bindElement; - } - - /** - * __UNDOCUMENTED__ - * - * @param controlElement __UNDOCUMENTED__ - * @param controlType __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public Element startFormControl(Element controlElement, - XSTypeDefinition controlType) - { - return controlElement; - } - - /** - * __UNDOCUMENTED__ - * - * @param groupElement __UNDOCUMENTED__ - * @param schemaElement __UNDOCUMENTED__ - * @return __UNDOCUMENTED__ - */ - public Element startFormGroup(Element groupElement, - XSElementDeclaration schemaElement) - { - return groupElement; - } -} diff --git a/source/java/org/alfresco/web/templating/xforms/schemabuilder/FormBuilderException.java b/source/java/org/alfresco/web/templating/xforms/schemabuilder/FormBuilderException.java deleted file mode 100644 index aa437e5605..0000000000 --- a/source/java/org/alfresco/web/templating/xforms/schemabuilder/FormBuilderException.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.templating.xforms.schemabuilder; - - -/** - * This exception is thrown when implementations of SchemaFormBuilder encounters an - * error building a form. - * - * @author Brian Dueck - * @version $Id: FormBuilderException.java,v 1.4 2005/01/31 22:49:31 joernt Exp $ - */ -public class FormBuilderException extends java.lang.Exception { - private Exception cause = null; - - /** - * Creates a new instance of FormBuilderException without detail message. - */ - public FormBuilderException() { - } - - /** - * Constructs an instance of FormBuilderException with the specified detail message. - * - * @param msg the detail message. - */ - public FormBuilderException(String msg) { - super(msg); - } - - /** - * Constructs an instance of FormBuilderException with the specified root exception. - * - * @param x The root exception. - */ - public FormBuilderException(Exception x) { - //THIS DOES NOT WORK WITH JDK 1.3 CAUSE THIS IS NEW IN JDK 1.4 - //super(x); - super(x.getMessage()); - } -} - - -/* - $Log: FormBuilderException.java,v $ - Revision 1.4 2005/01/31 22:49:31 joernt - added copyright notice - - Revision 1.3 2004/08/15 14:14:07 joernt - preparing release... - -reformatted sources to fix mixture of tabs and spaces - -optimized imports on all files - - Revision 1.2 2003/10/02 15:15:49 joernt - applied chiba jalopy settings to whole src tree - - Revision 1.1 2003/07/12 12:22:48 joernt - package refactoring: moved from xforms.builder - Revision 1.1.1.1 2003/05/23 14:54:08 unl - no message - Revision 1.2 2003/02/19 09:09:15 soframel - print the exception's message - Revision 1.1 2002/12/11 14:50:42 soframel - transferred the Schema2XForms generator from chiba2 to chiba1 - Revision 1.3 2002/06/11 17:13:03 joernt - commented out jdk 1.3 incompatible constructor-impl - Revision 1.2 2002/06/11 14:06:31 joernt - commented out the jdk 1.4 constructor - Revision 1.1 2002/05/22 22:24:34 joernt - Brian's initial version of schema2xforms builder - */ diff --git a/source/java/org/alfresco/web/templating/xforms/schemabuilder/SchemaFormBuilder.java b/source/java/org/alfresco/web/templating/xforms/schemabuilder/SchemaFormBuilder.java deleted file mode 100644 index b9860f2d56..0000000000 --- a/source/java/org/alfresco/web/templating/xforms/schemabuilder/SchemaFormBuilder.java +++ /dev/null @@ -1,445 +0,0 @@ -/* - * 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.templating.xforms.schemabuilder; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.xerces.xs.*; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import javax.xml.transform.Source; -import java.util.Properties; - -import org.alfresco.web.templating.*; - -/** - * An object that implements this interface can build an XForm that conforms to - * the elements and attributes declared in an XML Schema. - * - * @author Brian Dueck - * @version $Id: SchemaFormBuilder.java,v 1.16 2005/02/10 13:24:57 joernt Exp $ - */ -public interface SchemaFormBuilder -{ - - //////////////////////////////////////////////////////////////////////////// - - public static class Occurs - { - public final static int UNBOUNDED = -1; - - public final int minimum; - public final int maximum; - - public Occurs(final XSParticle particle) - { - if (particle == null) - { - this.minimum = 1; - this.maximum = 1; - } - else - { - this.minimum = particle.getMinOccurs(); - this.maximum = (particle.getMaxOccursUnbounded() - ? Occurs.UNBOUNDED - : particle.getMaxOccurs()); - } - } - - public Occurs(final int minimum) - { - this(minimum, UNBOUNDED); - } - - public Occurs(final int minimum, final int maximum) - { - this.minimum = minimum; - this.maximum = maximum; - } - - public boolean isUnbounded() - { - return this.maximum == UNBOUNDED; - } - - public String toString() - { - return "minimum=" + minimum + ", maximum=" + maximum; - } - } - - //////////////////////////////////////////////////////////////////////////// - - public final static Log LOGGER = - LogFactory.getLog(SchemaFormBuilder.class); - - /** - * XMLSchema Instance Namespace declaration - */ - public static final String XMLSCHEMA_INSTANCE_NS = - "http://www.w3.org/2001/XMLSchema-instance"; - - /** - * XMLSchema instance prefix - */ - public static final String XMLSCHEMA_INSTANCE_NS_PREFIX = "xsi:"; - - /** - * XMLNS Namespace declaration. - */ - public static final String XMLNS_NAMESPACE_URI = - "http://www.w3.org/2000/xmlns/"; - - /** - * XML Namespace declaration - */ - public static final String XML_NAMESPACE_URI = - "http://www.w3.org/XML/1998/namespace"; - - /** - * XForms namespace declaration. - */ - public static final String XFORMS_NS = - "http://www.w3.org/2002/xforms"; - - /** - * XForms prefix - */ - public static final String XFORMS_NS_PREFIX = "xforms:"; - - /** - * Chiba namespace declaration. - */ - public static final String CHIBA_NS = - "http://chiba.sourceforge.net/xforms"; - - /** - * Chiba prefix - */ - public static final String CHIBA_NS_PREFIX = "chiba:"; - - /** - * XLink namespace declaration. - */ - public static final String XLINK_NS = "http://www.w3.org/1999/xlink"; - - /** - * Xlink prefix - */ - public static final String XLINK_NS_PREFIX = "xlink:"; - - /** - * XML Events namsepace declaration. - */ - public static final String XMLEVENTS_NS = "http://www.w3.org/2001/xml-events"; - - /** - * XML Events prefix - */ - public static final String XMLEVENTS_NS_PREFIX = "ev:"; - - /** - * Prossible values of the "@method" on the "submission" element - */ - public static final String SUBMIT_METHOD_POST = "post"; - - /** - * __UNDOCUMENTED__ - */ - public static final String SUBMIT_METHOD_PUT = "put"; - - /** - * __UNDOCUMENTED__ - */ - public static final String SUBMIT_METHOD_GET = "get"; - - /** - * __UNDOCUMENTED__ - */ - public static final String SUBMIT_METHOD_FORM_DATA_POST = "form-data-post"; - - /** - * __UNDOCUMENTED__ - */ - public static final String SUBMIT_METHOD_URLENCODED_POST = - "urlencoded-post"; - - /** - * Get the current set of properties used by implementations of SchemaFormBuilder. - * - * @return The list of properties. - */ - public Properties getProperties(); - - /** - * Sets the property to the specified value. If the property exists, its value is overwritten. - * - * @param key The implementation defined property key. - * @param value The value for the property. - */ - public void setProperty(String key, String value); - - /** - * Gets the value for the specified property. - * - * @param key The implementation defined property key. - * @return The property value if found, or null if the property cannot be located. - */ - public String getProperty(String key); - - /** - * Gets the value for the specified property, with a default if the property cannot be located. - * - * @param key The implementation defined property key. - * @param defaultValue This value will be returned if the property does not exists. - * @return The property value if found, or defaultValue if the property cannot be located. - */ - public String getProperty(String key, String defaultValue); - - - /** - * Generate the XForm based on a user supplied XML Schema. - * - * @param inputURI The document source for the XML Schema. - * @return The Document containing the XForm. - * @throws org.chiba.tools.schemabuilder.FormBuilderException - * If an error occurs building the XForm. - */ - public Document buildForm(final TemplateType tt) - throws FormBuilderException; - - /** - * Creates a caption for the provided text extracted from the XML Schema. - * The implementation is responsible for reformatting the provided string to make it - * suitable to be displayed to users of the XForm. This typically includes translating - * XML tag name style identifiers (e.g. customerStreetAddress) into more reader friendly - * captions (e.g. Customer Street Address). - * - * @param text The string value to be reformatted for use as a caption. - * @return The caption. - */ - public String createCaption(String text); - - /** - * Creates a caption for the provided XML Schema attribute. - * The implementation is responsible for providing an appropriate caption - * suitable to be displayed to users of the XForm. This typically includes translating - * XML tag name style identifiers (e.g. customerStreetAddress) into more reader friendly - * captions (e.g. Customer Street Address). - * - * @param attribute The XML schema attribute for which a caption is required. - * @return The caption. - */ - public String createCaption(XSAttributeDeclaration attribute); - - /** - * Creates a caption for the provided XML Schema element. - * The implementation is responsible for providing an appropriate caption - * suitable to be displayed to users of the XForm. This typically includes translating - * XML tag name style identifiers (e.g. customerStreetAddress) into more reader friendly - * captions (e.g. Customer Street Address). - * - * @param element The XML schema element for which a caption is required. - * @return The caption. - */ - public String createCaption(XSElementDeclaration element); - - /** - * Creates a form control for an XML Schema any type. - *

- * This method is called when the form builder determines a form control is required for - * an any type. - * The implementation of this method is responsible for creating an XML element of the - * appropriate type to receive a value for controlType. The caller is responsible - * for adding the returned element to the form and setting caption, bind, and other - * standard elements and attributes. - * - * @param xForm The XForm document. - * @param controlType The XML Schema type for which the form control is to be created. - * @return The element for the form control. - */ - public Element createControlForAnyType(Document xForm, - String caption, - XSTypeDefinition controlType); - - /** - * Creates a form control for an XML Schema simple atomic type. - *

- * This method is called when the form builder determines a form control is required for - * an atomic type. - * The implementation of this method is responsible for creating an XML element of the - * appropriate type to receive a value for controlType. The caller is responsible - * for adding the returned element to the form and setting caption, bind, and other - * standard elements and attributes. - * - * @param xForm The XForm document. - * @param controlType The XML Schema type for which the form control is to be created. - * @return The element for the form control. - */ - public Element createControlForAtomicType(Document xForm, - String caption, - XSSimpleTypeDefinition controlType); - - /** - * Creates a form control for an XML Schema simple type restricted by an enumeration. - * This method is called when the form builder determines a form control is required for - * an enumerated type. - * The implementation of this method is responsible for creating an XML element of the - * appropriate type to receive a value for controlType. The caller is responsible - * for adding the returned element to the form and setting caption, bind, and other - * standard elements and attributes. - * - * @param xForm The XForm document. - * @param controlType The XML Schema type for which the form control is to be created. - * @param caption The caption for the form control. The caller The purpose of providing the caption - * is to permit the implementation to add a [Select1 .... ] message that involves the caption. - * @param bindElement The bind element for this control. The purpose of providing the bind element - * is to permit the implementation to add a isValid attribute to the bind element that prevents - * the [Select1 .... ] item from being selected. - * @return The element for the form control. - */ - public Element createControlForEnumerationType(Document xForm, - XSSimpleTypeDefinition controlType, - String caption, - Element bindElement); - - /** - * Creates a form control for an XML Schema simple list type. - *

- * This method is called when the form builder determines a form control is required for - * a list type. - * The implementation of this method is responsible for creating an XML element of the - * appropriate type to receive a value for controlType. The caller is responsible - * for adding the returned element to the form and setting caption, bind, and other - * standard elements and attributes. - * - * @param xForm The XForm document. - * @param listType The XML Schema list type for which the form control is to be created. - * @param caption The caption for the form control. The caller The purpose of providing the caption - * is to permit the implementation to add a [Select1 .... ] message that involves the caption. - * @param bindElement The bind element for this control. The purpose of providing the bind element - * is to permit the implementation to add a isValid attribute to the bind element that prevents - * the [Select1 .... ] item from being selected. - * @return The element for the form control. - */ - public Element createControlForListType(Document xForm, - XSSimpleTypeDefinition listType, - String caption, - Element bindElement); - - /** - * Creates a hint XML Schema annotated node (AttributeDecl or ElementDecl). - * The implementation is responsible for providing an xforms:hint element for the - * specified schemaNode suitable to be dsipalayed to users of the XForm. The caller - * is responsible for adding the returned element to the form. - * This typically includes extracting documentation from the element/attribute's - * annotation/documentation elements and/or extracting the same information from the - * element/attribute's type annotation/documentation. - * - * @param schemaNode The string value to be reformatted for use as a caption. - * @return The xforms:hint element. If a null value is returned a hint is not added. - */ - public Element createHint(Document xForm, XSObject schemaNode); - - /** - * This method is invoked after the form builder is finished creating and processing - * a bind element. Implementations may choose to use this method to add/inspect/modify - * the bindElement prior to the builder moving onto the next bind element. - * - * @param bindElement The bind element being processed. - */ - public void endBindElement(Element bindElement); - - /** - * This method is invoked after the form builder is finished creating and processing - * a form control. Implementations may choose to use this method to add/inspect/modify - * the controlElement prior to the builder moving onto the next control. - * - * @param controlElement The form control element that was created. - * @param controlType The XML Schema type for which controlElement was created. - */ - public void endFormControl(Element controlElement, - XSTypeDefinition controlType, - Occurs occurs); - /** - * __UNDOCUMENTED__ - * - * @param groupElement __UNDOCUMENTED__ - */ - public void endFormGroup(Element groupElement, - XSTypeDefinition controlType, - Occurs occurs, - Element modelSection); - - /** - * Reset the SchemaFormBuilder to default values. - */ - public void reset(); - - /** - * This method is invoked after an xforms:bind element is created for the specified SimpleType. - * The implementation is responsible for setting setting any/all bind attributes - * except for id and ref - these have been automatically set - * by the caller (and should not be touched by implementation of startBindElement) - * prior to invoking startBindElement. - * The caller automatically adds the returned element to the model section of - * the form. - * - * @param bindElement The bindElement being processed. - * @param controlType XML Schema type of the element/attribute this bind is for. - * @param minOccurs The minimum number of occurences for this element/attribute. - * @param maxOccurs The maximum number of occurences for this element/attribute. - * @return The bind Element to use in the XForm - bindElement or a replacement. - */ - public Element startBindElement(Element bindElement, - XSModel schema, - XSTypeDefinition controlType, - Occurs occurs); - - /** - * This method is invoked after the form builder creates a form control - * via a createControlForXXX() method but prior to decorating the form control - * with common attributes such as a caption, hint, help text elements, - * bind attributes, etc. - * The returned element is used in the XForm in place of controlElement. - * Implementations may choose to use this method to substitute controlElement - * with a different element, or perform any other processing on controlElement - * prior to it being added to the form. - * - * @param controlElement The form control element that was created. - * @param controlType The XML Schema type for which controlElement was created. - * @return The Element to use in the XForm - controlElement or a replacement. - */ - public Element startFormControl(Element controlElement, - XSTypeDefinition controlType); - - /** - * This method is invoked after an xforms:group element is created for the specified - * ElementDecl. A group is created whenever an element is encountered in the XML Schema - * that contains other elements and attributes (complex types or mixed content types). - * The caller automatically adds the returned element to the XForm. - * - * @param groupElement The groupElement being processed. - * @param schemaElement The schemaElement for the group. - * @return The group Element to use in the XForm - groupElement or a replacement. If a null - * value is returned, the group is not created. - */ - public Element startFormGroup(Element groupElement, - XSElementDeclaration schemaElement); -} diff --git a/source/test-resources/websites/alfresco/ROOT/WEB-INF/classes/org/alfresco/web/pr/CompanyFooterBean.java b/source/test-resources/websites/alfresco/ROOT/WEB-INF/classes/org/alfresco/web/pr/CompanyFooterBean.java new file mode 100644 index 0000000000..e12e102d11 --- /dev/null +++ b/source/test-resources/websites/alfresco/ROOT/WEB-INF/classes/org/alfresco/web/pr/CompanyFooterBean.java @@ -0,0 +1,40 @@ +/* + * 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.pr; + +public class CompanyFooterBean +{ + private final String name; + private final String href; + + public CompanyFooterBean(final String name, + final String href) + { + this.name = name; + this.href = href; + } + + public String getName() + { + return this.name; + } + + public String getHref() + { + return this.href; + } +} \ No newline at end of file diff --git a/source/test-resources/websites/alfresco/ROOT/WEB-INF/classes/org/alfresco/web/pr/PressReleaseBean.java b/source/test-resources/websites/alfresco/ROOT/WEB-INF/classes/org/alfresco/web/pr/PressReleaseBean.java new file mode 100644 index 0000000000..150b51839c --- /dev/null +++ b/source/test-resources/websites/alfresco/ROOT/WEB-INF/classes/org/alfresco/web/pr/PressReleaseBean.java @@ -0,0 +1,58 @@ +/* + * 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.pr; + +import java.util.Date; + +public class PressReleaseBean +{ + private final String title; + private final String theAbstract; + private final Date launchDate; + private final String href; + + public PressReleaseBean(final String title, + final String theAbstract, + final Date launchDate, + final String href) + { + this.title = title; + this.theAbstract = theAbstract; + this.launchDate = launchDate; + this.href = href; + } + + public String getTitle() + { + return this.title; + } + + public String getAbstract() + { + return this.theAbstract; + } + + public Date getLaunchDate() + { + return this.launchDate; + } + + public String getHref() + { + return this.href; + } +} \ No newline at end of file diff --git a/source/test-resources/websites/alfresco/ROOT/WEB-INF/classes/org/alfresco/web/pr/Util.java b/source/test-resources/websites/alfresco/ROOT/WEB-INF/classes/org/alfresco/web/pr/Util.java new file mode 100644 index 0000000000..ec0cdec2da --- /dev/null +++ b/source/test-resources/websites/alfresco/ROOT/WEB-INF/classes/org/alfresco/web/pr/Util.java @@ -0,0 +1,133 @@ +/* + * 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.pr; + +import javax.servlet.*; +import javax.servlet.http.*; +import java.io.*; +import java.util.*; +import org.alfresco.jndi.*; +import org.alfresco.repo.avm.AVMRemote; +import org.alfresco.service.cmr.avm.AVMNodeDescriptor; +import org.w3c.dom.*; +import javax.xml.parsers.*; +import java.text.*; + +public class Util +{ + public static List getPressReleases(final HttpServletRequest request, + final ServletContext servletContext) + throws Exception + { + final Map entries = Util.loadXMLDocuments(request, + servletContext, + "/media/releases/content", + "alfresco:press-release"); + final List result = new ArrayList(entries.size()); + for (Map.Entry entry : entries.entrySet() ) + { + String fileName = entry.getKey(); + Document d = entry.getValue(); + Element t = (Element)d.getElementsByTagName("alfresco:title").item(0); + Element a = (Element)d.getElementsByTagName("alfresco:abstract").item(0); + Element dateEl = (Element)d.getElementsByTagName("alfresco:launch_date").item(0); + Date date = new SimpleDateFormat("yyyy-MM-dd").parse(dateEl.getFirstChild().getNodeValue()); + String href = "/media/releases/content/" + fileName; + href = href.replaceAll(".xml$", ".shtml"); + result.add(new PressReleaseBean(t.getFirstChild().getNodeValue(), + a.getFirstChild().getNodeValue(), + date, + href)); + } + return result; + } + + public static List getCompanyFooters(final HttpServletRequest request, + final ServletContext servletContext) + throws Exception + { + final Map entries = Util.loadXMLDocuments(request, + servletContext, + "/media/releases/content/company_footers", + "alfresco:company-footer"); + final List result = new ArrayList(entries.size()); + for (Map.Entry entry : entries.entrySet()) + { + String fileName = entry.getKey(); + Document d = entry.getValue(); + Element n = (Element)d.getElementsByTagName("alfresco:name").item(0); + String href = "/media/releases/content/company_footers/" + fileName; + result.add(new CompanyFooterBean(n.getFirstChild().getNodeValue(), + href)); + } + return result; + } + + private static Map loadXMLDocuments(final HttpServletRequest request, + final ServletContext servletContext, + final String path, + final String documentElementNodeName) + throws Exception + { + final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(false); + final DocumentBuilder db = dbf.newDocumentBuilder(); + + // The real_path will look somethign like this: + // /alfresco.avm/avm.alfresco.localhost/$-1$alfreco-guest-main:/appBase/avm_webapps/my_webapp + // + String real_path = servletContext.getRealPath(path); + + // The avm_path to the root of the context will look something like this: + // alfreco-guest-main:/appBase/avm_webapps/my_webapp + // + String avm_path = real_path.substring(real_path.indexOf('$', real_path.indexOf('$') + 1) + 1); + avm_path = avm_path.replace('\\','/'); + + final AVMRemote avm_remote = AVMFileDirContext.getAVMRemote(); + final Map entries = avm_remote.getDirectoryListing(-1, avm_path); + + Map result = new HashMap(); + for (Map.Entry entry : entries.entrySet() ) + { + final String entry_name = entry.getKey(); + AVMNodeDescriptor entry_node = entry.getValue(); + if (entry_node.isFile()) + { + final InputStream istream = + new AVMRemoteInputStream(avm_remote.getInputHandle(-1, avm_path + '/' + entry_name), + avm_remote ); + try + { + final Document d = db.parse(istream); + if (documentElementNodeName.equals(d.getDocumentElement().getNodeName())) + result.put(entry_name, d); + } + catch (Throwable t) + { + t.printStackTrace(); + } + finally + { + istream.close(); + } + } + } + return result; + } +} \ No newline at end of file diff --git a/source/test-resources/websites/alfresco/ROOT/WEB-INF/web.xml b/source/test-resources/websites/alfresco/ROOT/WEB-INF/web.xml index 405b5dc772..0e866198f8 100644 --- a/source/test-resources/websites/alfresco/ROOT/WEB-INF/web.xml +++ b/source/test-resources/websites/alfresco/ROOT/WEB-INF/web.xml @@ -9,11 +9,7 @@ Alfresco Website - - foor - bar - foo bar - + index.jsp diff --git a/source/test-resources/websites/alfresco/ROOT/media/releases/get_company_footer_simple_type.jsp b/source/test-resources/websites/alfresco/ROOT/media/releases/get_company_footer_simple_type.jsp new file mode 100644 index 0000000000..92a82bc45b --- /dev/null +++ b/source/test-resources/websites/alfresco/ROOT/media/releases/get_company_footer_simple_type.jsp @@ -0,0 +1,25 @@ + + + + + + + + +<% +List companyFooters = Util.getCompanyFooters(request, application); +for (CompanyFooterBean companyFooter : companyFooters) +{ +%> + + + <%= companyFooter.getName() %> + + +<% +} +%> + + + diff --git a/source/test-resources/websites/alfresco/ROOT/media/releases/index.jsp b/source/test-resources/websites/alfresco/ROOT/media/releases/index.jsp index b7da419dc7..ec4ca0fcbf 100644 --- a/source/test-resources/websites/alfresco/ROOT/media/releases/index.jsp +++ b/source/test-resources/websites/alfresco/ROOT/media/releases/index.jsp @@ -1,88 +1,7 @@ - - - - - - - + -<%! -class PressRelease -{ - public final String title; - public final String theAbstract; - public final Date date; - public final String href; - - public PressRelease(String title, String theAbstract, Date d, String href) - { - this.title = title; - this.theAbstract = theAbstract; - this.date = d; - this.href = href; - } -} - -public List getPressReleases(HttpServletRequest request, ServletContext servletContext, JspWriter out) - throws Exception -{ - final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(false); - final DocumentBuilder db = dbf.newDocumentBuilder(); - - // The real_path will look somethign like this: - // /alfresco.avm/avm.alfresco.localhost/$-1$alfreco-guest-main:/appBase/avm_webapps/my_webapp - // - String real_path = servletContext.getRealPath("/media/releases/content"); - - // The avm_path to the root of the context will look something like this: - // alfreco-guest-main:/appBase/avm_webapps/my_webapp - // - String avm_path = real_path.substring( real_path.indexOf('$', real_path.indexOf('$') + 1) + 1 ); - avm_path = avm_path.replace('\\','/'); - - AVMRemote avm_remote = AVMFileDirContext.getAVMRemote(); - Map< String, AVMNodeDescriptor> entries = avm_remote.getDirectoryListing(-1, avm_path); - - List result = new LinkedList(); - for ( Map.Entry entry : entries.entrySet() ) - { - String entry_name = entry.getKey(); - AVMNodeDescriptor entry_node = entry.getValue(); - if (entry_node.isFile()) - { - InputStream istream = new AVMRemoteInputStream( avm_remote.getInputHandle( -1, avm_path + '/' + entry_name ), avm_remote ); - try - { - Document d = db.parse(istream); - if ("alfresco:press-release".equals(d.getDocumentElement().getNodeName())) - { - Element t = (Element)d.getElementsByTagName("alfresco:title").item(0); - Element a = (Element)d.getElementsByTagName("alfresco:abstract").item(0); - Element dateEl = (Element)d.getElementsByTagName("alfresco:launch_date").item(0); - Date date = new SimpleDateFormat("yyyy-MM-dd").parse(dateEl.getFirstChild().getNodeValue()); - String href = "/media/releases/content/" + entry_name; - href = href.replaceAll(".xml$", ".shtml"); - result.add(new PressRelease(t.getFirstChild().getNodeValue(), - a.getFirstChild().getNodeValue(), - date, - href)); - } - } - catch (Throwable t) - { - t.printStackTrace(); - } - finally - { - istream.close(); - } - } - } - return result; -} -%> + + @@ -162,12 +81,12 @@ public List getPressReleases(HttpServletRequest request, ServletCo

Alfresco Press Releases

<% -List pressReleases = getPressReleases(request, application, out); -for (PressRelease pr : pressReleases) +List pressReleases = Util.getPressReleases(request, application); +for (PressReleaseBean pr : pressReleases) { %> -

<%= pr.title %>

-

<%= DateFormat.getDateInstance(DateFormat.LONG).format(pr.date) %>

<%= pr.theAbstract %>

+

<%= pr.getTitle() %>

+

<%= DateFormat.getDateInstance(DateFormat.LONG).format(pr.getLaunchDate()) %>

<%= pr.getAbstract() %>

<% } %> diff --git a/source/test-resources/xforms/demos/press-release/company-footer.xsd b/source/test-resources/xforms/demos/press-release/company-footer.xsd index 7601d0b4a8..0be0ab4d9b 100644 --- a/source/test-resources/xforms/demos/press-release/company-footer.xsd +++ b/source/test-resources/xforms/demos/press-release/company-footer.xsd @@ -1,8 +1,10 @@ + diff --git a/source/test-resources/xforms/demos/press-release/press-release.xsd b/source/test-resources/xforms/demos/press-release/press-release.xsd index cbbdd29216..c106cb9080 100644 --- a/source/test-resources/xforms/demos/press-release/press-release.xsd +++ b/source/test-resources/xforms/demos/press-release/press-release.xsd @@ -3,6 +3,7 @@ xmlns:alfresco="http://www.alfresco.org/alfresco" targetNamespace="http://www.alfresco.org/alfresco" elementFormDefault="qualified"> + @@ -12,22 +13,6 @@ - - - - - - - - - - - - - - - - diff --git a/source/test-resources/xforms/demos/press-release/press-release.xsl b/source/test-resources/xforms/demos/press-release/press-release.xsl index 2738e419c7..240557b3c2 100644 --- a/source/test-resources/xforms/demos/press-release/press-release.xsl +++ b/source/test-resources/xforms/demos/press-release/press-release.xsl @@ -87,9 +87,8 @@ - -

About

- +

About

+

diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index c8bac3e208..3b8b864840 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -2473,15 +2473,15 @@ ChildAssociationGenerator org.alfresco.web.bean.generator.ChildAssociationGenerator request - - - - - Bean that generates a separator component - - SeparatorGenerator - org.alfresco.web.bean.generator.SeparatorGenerator - request + + + + + Bean that generates a separator component + + SeparatorGenerator + org.alfresco.web.bean.generator.SeparatorGenerator + request @@ -2545,8 +2545,7 @@ Bean that returns information on a node XFormsBean - org.alfresco.web.bean.ajax.XFormsBean + org.alfresco.web.templating.xforms.XFormsBean session - 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 13781e81f5..3d0c6aa19e 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 @@ -18,6 +18,7 @@ <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> +<%@ page import="org.alfresco.web.bean.wcm.AVMConstants" %> <%@ page import="org.alfresco.web.app.Application" %> <%@ page import="org.alfresco.web.templating.*" %> <%@ page import="org.alfresco.web.bean.wcm.CreateWebContentWizard" %> @@ -25,7 +26,7 @@ <% final CreateWebContentWizard wiz = (CreateWebContentWizard) - Application.getWizardManager().getBean(); + Application.getWizardManager().getBean(); TemplateType tt = wiz.getTemplateType(); TemplateInputMethod tim = tt.getInputMethods().get(0); final TemplatingService ts = TemplatingService.getInstance(); @@ -57,25 +58,4 @@ dojo.addOnLoad(function() addSubmitHandlerToButton(document.getElementById("wizard:next-button")); addSubmitHandlerToButton(document.getElementById("wizard:finish-button")); }); -// -//var baseOnClick = b.onclick; -//b.onclick = function() -//{ -// if (!document.submitTrigger.done) -// { -// document.submitTrigger.buttonClick(); -// return false; -// } -// else -// { -// return baseOnClick(); -// } -//} -//}); -//function doSubmit() -//{ -//var b = document.getElementById("wizard:next-button"); -//b.click(); -//} -