Return-Path: Delivered-To: apmail-xml-cocoon-cvs-archive@xml.apache.org Received: (qmail 77663 invoked by uid 500); 3 Dec 2002 12:31:37 -0000 Mailing-List: contact cocoon-cvs-help@xml.apache.org; run by ezmlm Precedence: bulk Reply-To: cocoon-dev@xml.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list cocoon-cvs@xml.apache.org Received: (qmail 77651 invoked by uid 500); 3 Dec 2002 12:31:36 -0000 Delivered-To: apmail-xml-cocoon2-cvs@apache.org Date: 3 Dec 2002 12:31:36 -0000 Message-ID: <20021203123136.43582.qmail@icarus.apache.org> From: cziegeler@apache.org To: xml-cocoon2-cvs@apache.org Subject: cvs commit: xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/acting SessionFormAction.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N cziegeler 2002/12/03 04:31:35 Modified: src/blocks/session-fw/conf session-act.xmap src/blocks/session-fw/java/org/apache/cocoon/webapps/session/transformation SessionPostTransformer.java Added: src/blocks/session-fw/java/org/apache/cocoon/webapps/session/acting SessionFormAction.java Log: Adding simple validation. Submitted by Guido Casper (gcasper@s-und-n.de) Revision Changes Path 1.2 +2 -0 xml-cocoon2/src/blocks/session-fw/conf/session-act.xmap Index: session-act.xmap =================================================================== RCS file: /home/cvs/xml-cocoon2/src/blocks/session-fw/conf/session-act.xmap,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- session-act.xmap 27 Sep 2002 09:05:11 -0000 1.1 +++ session-act.xmap 3 Dec 2002 12:31:35 -0000 1.2 @@ -6,4 +6,6 @@ + 1.3 +119 -10 xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/transformation/SessionPostTransformer.java Index: SessionPostTransformer.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/transformation/SessionPostTransformer.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- SessionPostTransformer.java 8 Oct 2002 14:43:19 -0000 1.2 +++ SessionPostTransformer.java 3 Dec 2002 12:31:35 -0000 1.3 @@ -51,17 +51,28 @@ package org.apache.cocoon.webapps.session.transformation; import java.io.IOException; +import java.io.StringBufferInputStream; import java.util.Map; +import org.apache.excalibur.source.Source; import org.apache.excalibur.source.SourceParameters; +import org.apache.excalibur.source.SourceException; import org.apache.avalon.framework.parameters.Parameters; +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; +import org.apache.avalon.framework.configuration.SAXConfigurationHandler; +import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.cocoon.ProcessingException; +import org.apache.cocoon.xml.XMLUtils; +import org.apache.cocoon.environment.Session; import org.apache.cocoon.webapps.session.SessionConstants; +import org.apache.cocoon.acting.ValidatorActionResult; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import org.w3c.dom.DocumentFragment; +import org.w3c.dom.Node; /** * This is the session post transformer. It does all the setting and @@ -105,6 +116,7 @@ public static final String INPUTXML_PATH_ATTRIBUTE = "path"; public static final String INPUTXML_NAME_ATTRIBUTE = "name"; public static final String INPUTXML_TYPE_ATTRIBUTE = "type"; // optional + public static final String INPUTXML_VALIDATIONRESULT_ATTRIBUTE = "valresult"; /** The form element */ public static final String FORM_ELEMENT = "form"; @@ -115,6 +127,11 @@ /** The form content element */ public static final String FORM_CONTENT_ELEMENT = "content"; + /** The form validation rules */ + public static final String FORM_VALIDATION_ELEMENT = "validate"; + public static final String FORM_VALIDATION_SOURCE_ATTRIBUTE = "src"; + public static final String FORM_VALIDATESET_ELEMENT = "validate-set"; + /** State: no element parsed */ private static final int STATE_OUTSIDE = 0; /** State: form element */ @@ -126,8 +143,8 @@ /** The current form name */ private String formName; - /** The unique form number */ - private static int currentFormNumber = 0; + /** The validation results */ + private Map validationResultMap; public void setupTransforming() throws ProcessingException, SAXException, IOException { @@ -202,6 +219,15 @@ "CDATA", attr.getValue(INPUTXML_TYPE_ATTRIBUTE)); } + ValidatorActionResult validationResult = null; + if (validationResultMap != null && validationResultMap.get(fieldname) != null) { + validationResult = (ValidatorActionResult)validationResultMap.get(fieldname); + newattr.addAttribute("", + INPUTXML_VALIDATIONRESULT_ATTRIBUTE, + INPUTXML_VALIDATIONRESULT_ATTRIBUTE, + "CDATA", validationResult.toString()); + } + super.startTransformingElement("", name, name, newattr); // remove namespace this.startRecording(); @@ -224,7 +250,19 @@ // Element form content } else if (name.equals(FORM_CONTENT_ELEMENT) == true && this.state == STATE_FORM) { - // ignore this + // get validation results to be used for inputxml elements + validationResultMap = (Map)this.getSessionManager().getSession(true). + getAttribute(this.formName + "validation-result"); + + // Element form validation rules + } else if (name.equals(FORM_VALIDATION_ELEMENT) == true + && this.state == STATE_FORM) { + this.startRecording(); + if (attr.getValue(FORM_VALIDATION_SOURCE_ATTRIBUTE) != null) { + stack.push(attr.getValue(FORM_VALIDATION_SOURCE_ATTRIBUTE)); + } else { + stack.push("EMPTY"); + } } else { super.startTransformingElement(uri, name, raw, attr); @@ -310,12 +348,7 @@ && this.state == STATE_FORM) { String action = this.endTextRecording(); AttributesImpl a = (AttributesImpl)this.stack.pop(); - // append a unique number to the form - synchronized (this.getClass()) { - this.formName = a.getValue("name") + '_' + currentFormNumber; - currentFormNumber++; - if (currentFormNumber > 99999) currentFormNumber = 0; - } + this.formName = a.getValue("name"); boolean hasPars = (action.indexOf("?") != -1); action = this.response.encodeURL(action + (hasPars ? '&' : '?') + SessionConstants.SESSION_FORM_PARAMETER+'='+this.formName); a.addAttribute("", "action", "action", "CDATA", action); @@ -328,6 +361,82 @@ } else if (name.equals(FORM_CONTENT_ELEMENT) == true && this.state == STATE_FORM) { // ignore this + + // Element form validation rules + } else if (name.equals(FORM_VALIDATION_ELEMENT) == true + && this.state == STATE_FORM) { + if (this.formName == null) { + throw new ProcessingException("The validate element must be contained inside a form."); + } + DocumentFragment validationDoc = this.endRecording(); + String source = (String)stack.pop(); + if (!source.equals("EMPTY")) { + // get configuration from external file + // referenced by "src" attribute of "validate" element + + Configuration conf = null; + Session session = null; + try { + Source resource = this.resolver.resolveURI(source); + SAXConfigurationHandler saxBuilder = new SAXConfigurationHandler(); + resolver.toSAX(resource, saxBuilder); + + conf = saxBuilder.getConfiguration(); + session = this.getSessionManager().getSession(true); + session.setAttribute(this.formName, conf); + + if (validationDoc != null) { + //validationDoc contains "validate-set" element + validationDoc.normalize(); + Node validationNode = validationDoc.getFirstChild(); + while (validationNode.getNodeType() != Node.ELEMENT_NODE) { + validationNode = validationNode.getNextSibling(); + if (validationNode == null) break; + } + if (validationNode != null && + validationNode.getNodeType() == Node.ELEMENT_NODE && + validationNode.getNodeName().equals(FORM_VALIDATESET_ELEMENT)) { + String validationXML = XMLUtils.serializeNodeToXML(validationNode); + DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); + conf = builder.build(new StringBufferInputStream(validationXML)); + session.setAttribute(this.formName+"validate-set", conf); + } + } + + } catch (SourceException se) { + throw new ProcessingException("Cannot resolve"+source, se); + } catch (ConfigurationException ce) { + throw new ProcessingException("Error building Configuration out of validate-set element", ce); + } + + } else if (validationDoc != null) { + //validationDoc contains the validation rules inline + try { + validationDoc.normalize(); + Node validationNode = validationDoc.getFirstChild(); + while (validationNode.getNodeType() != Node.ELEMENT_NODE) { + validationNode = validationNode.getNextSibling(); + if (validationNode == null) break; + } + if (validationNode != null && + validationNode.getNodeType() == Node.ELEMENT_NODE && + validationNode.getNodeName().equals("root")) { + + String validationXML = XMLUtils.serializeNodeToXML(validationNode); + DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); + Configuration conf = null; + Session session = null; + conf = builder.build(new StringBufferInputStream(validationXML)); + session = this.getSessionManager().getSession(true); + session.setAttribute(this.formName, conf); + //the constraint-set to validate is the first and single one + session.setAttribute(this.formName+"validate-set", conf.getChildren ("constraint-set")[0]); + + } + } catch (ConfigurationException ce) { + throw new ProcessingException("Error building Configuration out of validation XML", ce); + } + } } else { super.endTransformingElement(uri, name, raw); 1.1 xml-cocoon2/src/blocks/session-fw/java/org/apache/cocoon/webapps/session/acting/SessionFormAction.java Index: SessionFormAction.java =================================================================== /* ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache Cocoon" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact apache@apache.org. 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by Stefano Mazzocchi . For more information on the Apache Software Foundation, please see . */ package org.apache.cocoon.webapps.session.acting; import org.apache.cocoon.acting.AbstractValidatorAction; import org.apache.cocoon.acting.ValidatorActionHelper; import org.apache.cocoon.acting.ValidatorActionResult; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.thread.ThreadSafe; import org.apache.cocoon.Constants; import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.environment.Redirector; import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.SourceResolver; import org.apache.cocoon.environment.Session; import org.apache.cocoon.webapps.session.SessionConstants; import org.apache.cocoon.webapps.session.components.SessionManager; import org.apache.cocoon.util.Tokenizer; import java.util.HashMap; import java.util.Map; /** * This is the action used to validate Request parameters. * The validation rules are either embedded within the form * *
   *    <session:form name="info_form">
   *      <session:action>next_page</session:action>
   *      <session:content>
   *        <session:inputxml name="name" type="text" context="trackdemo" path="/user/name"/>
   *      </session:content>
   *      <session:validate>
   *        <root>
   *          <parameter name="name" type="string" nullable="no"/>
   *          <constraint-set name="form_a_set">
   *            <validate name="name"/>
   *          </constraint-set>
   *        </root>
   *      </session:validate>
   *    </session:form>
   * 
* * or described via the external xml file referenced * through the "src" attribute * (the format is defined in AbstractValidatorAction). * Then the constraint-set to be used has to be identified * through the "validate-set" element * *
   *    <session:form name="info_form>
   *      <session:action>next_page</session:action>
   *      <session:content>
   *        <session:inputxml name="name" type="text" context="trackdemo" path="/user/name"/>
   *      </session:content>
   *      <session:validate src="descriptor.xml">
   *        <validate-set name="form_a_set"/>
   *      </session:validate>
   *    </session:form>
   * 
* * Since the validation rules are contained within the form document * they are read and supplied by the SessionTransformer. * So this action has to be used in conjunction with the SessionTransformer. * The "next_page" pipeline might look like this: * *
   *     <map:match pattern="next_page">
   *       <map:act type="session-form">
   *           <map:generate src="next_page.xml"/>
   *           <map:transform type="session"/>
   *           <map:transform src="simple2html.xsl"/>
   *           <map:serialize/>
   *       </map:act>
   *       <map:generate src="first_page.xml"/>
   *       <map:transform type="session"/>
   *       <map:transform src="simple2html.xsl"/>
   *       <map:serialize/>
   *     </map:match>
   * 
* * where "session-form" is configured as SessionFormAction * * @author Guido Casper * @version CVS $Id: SessionFormAction.java,v 1.1 2002/10/09 11:47:33 gcasper Exp $ */ public class SessionFormAction extends AbstractValidatorAction implements ThreadSafe { /** * Main invocation routine. */ public Map act (Redirector redirector, SourceResolver resolver, Map objectModel, String src, Parameters parameters) throws Exception { Request req = ObjectModelHelper.getRequest(objectModel); /* check request validity */ if (req == null) { if (getLogger().isDebugEnabled()) getLogger().debug ("No request object"); return null; } // read global parameter settings boolean reloadable = Constants.DESCRIPTOR_RELOADABLE_DEFAULT; if (this.settings.containsKey("reloadable")) { reloadable = Boolean.valueOf((String) this.settings.get("reloadable")).booleanValue(); } // read local settings try { SessionManager sessionManager = (SessionManager)this.manager.lookup(SessionManager.ROLE); Session session = sessionManager.getSession(true); Configuration conf = (Configuration)session.getAttribute( req.getParameter(SessionConstants.SESSION_FORM_PARAMETER)); String valstr = parameters.getParameter ("validate", (String) settings.get("validate","")); String valsetstr = parameters.getParameter ("validate-set", (String) settings.get("validate-set","")); Configuration valConf = (Configuration)session.getAttribute( req.getParameter(SessionConstants.SESSION_FORM_PARAMETER)+"validate-set"); if (valConf != null) { valsetstr = valConf.getAttribute("name",""); } Configuration[] desc = conf.getChildren ("parameter"); Configuration[] csets = conf.getChildren ("constraint-set"); HashMap actionMap = new HashMap (); HashMap resultMap = new HashMap (); boolean allOK = true; /* * old obsoleted method */ if (!"".equals (valstr.trim ())) { if (getLogger().isDebugEnabled()) getLogger().debug ("Validating parameters " + "as specified via 'validate' parameter"); /* get list of params to be validated */ String[] rparams = null; if (!"*".equals(valstr.trim())) { rparams = Tokenizer.tokenize (valstr, ",", false); } else { // validate _all_ parameters rparams = new String[desc.length]; for (int i=0; i