You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by st...@apache.org on 2003/04/25 10:35:03 UTC

cvs commit: cocoon-2.1/src/webapp/samples/xmlform/wizard Readme.txt confirm.xml deployment.xml end.xml start.xml system.xml userIdentity.xml

stephan     2003/04/25 01:35:02

  Modified:    .        blocks.properties gump.xml
               src/test/org/apache/cocoon/components/validation/test
                        ZValidationTest.java
               src/webapp/WEB-INF cocoon.xconf
               src/webapp/samples samples.xml
  Added:       src/blocks/xmlform README.txt
               src/blocks/xmlform/conf xmlform-transformator.xmap
                        xmlform.xconf xmlform.xsamples
               src/blocks/xmlform/java/org/apache/cocoon/acting
                        AbstractXMLFormAction.java
               src/blocks/xmlform/java/org/apache/cocoon/components/flow/javascript
                        xmlForm.js
               src/blocks/xmlform/java/org/apache/cocoon/components/modules/input
                        XMLFormInput.java
               src/blocks/xmlform/java/org/apache/cocoon/components/xmlform
                        Form.java FormListener.java
               src/blocks/xmlform/java/org/apache/cocoon/samples/xmlform
                        UsageFeedbackAction.java UserBean.java
                        WizardAction.java
               src/blocks/xmlform/java/org/apache/cocoon/transformation
                        XMLFormTransformer.java
               src/blocks/xmlform/lib .cvsignore
               src/blocks/xmlform/samples overview.html sitemap.xmap
               src/blocks/xmlform/samples/flow confirm.xml deployment.xml
                        end.xml feedbackWizard.js start.xml system.xml
                        userIdentity.xml
               src/blocks/xmlform/samples/schematron
                        wizard-xmlform-sch-report.xml
               src/blocks/xmlform/samples/stylesheets wizard2html.xsl
               src/blocks/xmlform/samples/webservice error.xml ok.xml
                        usagefeedback.wsdl
               src/blocks/xmlform/samples/wizard Readme.txt confirm.xml
                        deployment.xml end.xml start.xml system.xml
                        userIdentity.xml
               src/blocks/xmlform/test/org/apache/cocoon/components/xmlform
                        TestBean.java TestXMLFormAction.java
                        XMLFormTestCase.java XMLFormTestCase.xtest
                        testform1.xml testform2.xml testresult1.xml
                        testresult2.xml testschema.xml
  Removed:     src/java/org/apache/cocoon/acting AbstractXMLFormAction.java
               src/java/org/apache/cocoon/components/flow/javascript
                        xmlForm.js
               src/java/org/apache/cocoon/components/modules/input
                        XMLFormInput.java
               src/java/org/apache/cocoon/components/validation Schema.java
                        SchemaFactory.java Validator.java Violation.java
               src/java/org/apache/cocoon/components/validation/schematron
                        ActivePattern.java Assert.java Pattern.java
                        Phase.java Report.java Rule.java
                        SchematronFactory.java SchematronSchema.java
                        SchematronValidator.java ValidationResult.java
               src/java/org/apache/cocoon/components/xmlform Form.java
                        FormListener.java
               src/java/org/apache/cocoon/transformation
                        XMLFormTransformer.java
               src/samples/org/apache/cocoon/samples/xmlform
                        UsageFeedbackAction.java UserBean.java
                        WizardAction.java
               src/test/org/apache/cocoon/components/validation/test
                        ZNestedBean.java ZTestBean.java
                        ZValidationTest.java zxmlform-sch-report-test.xml
               src/test/org/apache/cocoon/components/xmlform TestBean.java
                        TestXMLFormAction.java XMLFormTestCase.java
                        XMLFormTestCase.xtest testform1.xml testform2.xml
                        testresult1.xml testresult2.xml testschema.xml
               src/webapp/samples/xmlform README.txt overview.html
                        sitemap.xmap
               src/webapp/samples/xmlform/flow confirm.xml deployment.xml
                        end.xml feedbackWizard.js start.xml system.xml
                        userIdentity.xml
               src/webapp/samples/xmlform/schematron
                        wizard-xmlform-sch-report.xml
               src/webapp/samples/xmlform/stylesheets wizard2html.xsl
               src/webapp/samples/xmlform/webservice error.xml ok.xml
                        usagefeedback.wsdl
               src/webapp/samples/xmlform/wizard Readme.txt confirm.xml
                        deployment.xml end.xml start.xml system.xml
                        userIdentity.xml
  Log:
  Moved XMLForm stuff into a separate block as discussed.
  
  Revision  Changes    Path
  1.8       +1 -0      cocoon-2.1/blocks.properties
  
  Index: blocks.properties
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/blocks.properties,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- blocks.properties	22 Apr 2003 12:06:37 -0000	1.7
  +++ blocks.properties	25 Apr 2003 08:34:56 -0000	1.8
  @@ -43,6 +43,7 @@
   #exclude.block.taglib=true
   #exclude.block.xmldb=true
   #exclude.block.deli=true
  +#exclude.block.xmlform=true
   
   # Unstable blocks --------------------------------------------------------------
   
  
  
  
  1.50      +19 -1     cocoon-2.1/gump.xml
  
  Index: gump.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/gump.xml,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- gump.xml	24 Apr 2003 10:21:30 -0000	1.49
  +++ gump.xml	25 Apr 2003 08:34:56 -0000	1.50
  @@ -759,6 +759,24 @@
       <nag from="Gump" to="cocoon-dev@xml.apache.org"/>
     </project>
   
  +  <project name="cocoon-block-xmlform">
  +    <package>org.apache.cocoon</package>
  +
  +    <ant target="block">
  +      <property name="block-name" value="xmlform"/>
  +      <property name="version" value="@@DATE@@"/>
  +    </ant>
  +
  +    <depend project="cocoon" inherit="all"/>
  +
  +    <work nested="tools/anttasks"/>
  +    <home nested="build/cocoon-@@DATE@@"/>
  +
  +    <jar name="blocks/xmlform-block.jar"/>
  +
  +    <nag from="Gump" to="cocoon-dev@xml.apache.org"/>
  +  </project>
  +
     <!--
       ********************************************
       ********  COCOON SUPPLIED PROJECTS  ********
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/README.txt
  
  Index: README.txt
  ===================================================================
  ================================================================================
  NOTE: information from this document is being gradually moved into
  xdocs/userdocs/concepts/xmlform.xml
  ================================================================================
  
  <snip moved Ivelin Ivanov Introduction/>
  
  <snip moved Daniel Fagerstrom Background/>
  
  
  --------------------------------------------------------------------------------
  
  Following are copies of the announcement emails send to the Cocoon development
  mailing list.
  cocoon-dev@xml.apache.org <co...@xml.apache.org>
  
  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  ----- Original Message ----- 
  From: "Ivelin Ivanov" <iv...@apache.org>
  To: <co...@xml.apache.org>
  Sent: Tuesday, April 16, 2002 
  Subject: [Announcement] Cocoon Form Handling - XML Form Release 0.8
  
  
  First, I would like to thank everyone who participates in the Form Handling discussion.
  I have learned a lot from this discussion in the last few weeks.
  
  There are plenty of great ideas coming from all directions, and some of them influenced my
  thinking significantly.
  
  As I have already mention more than once, I have a certain fear that this topic may be too large 
  to handle at once and may eventually wind up as it did several times before (Schemox, ExFormular, etc.)
  I would very much like this time Cocoon to end up with a better overall form handling solution, than the one that currently exists. It does not have to be perfect from the start.
  
  With all tha said, I am presenting to anyone interested the new incarnation of the xmlform solution.
  It has gone through major refactoring based on heavy influence from Torsten and Konstantin.
  I will not advertsise what it is this time. I would instead encourage people who are *really* interested
  in bettering Cocoon, to look at the demo and provided feedback.
  This time there is only one demo, which is an extension of the survey wizard, originally offered by Torsten.
  
  Once you build c2 with scratchpad, point to 
  http://localhost:8080/cocoon/mount/xmlform/wizard.html
  
  
  For those who will take the time to peek in,
  
  I would like to request votes on the following:
  
  1) Does this solution prohibit further extensions in directions that you might be interested?
  
  2) Does this solution offer better overall form handling than the existing one for C2?
  
  3) Can this solution be the base for 2.1?
  
  
  Thanks everyone,
  
  Ivelin
  
  
  
  
  
  
  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  ----- Original Message ----- 
  From: "Ivelin Ivanov" <iv...@iname.com>
  To: <co...@xml.apache.org>
  Cc: "Sam Robertson" <xm...@yahoo.com>; "Torsten Curdt" <tc...@dff.st>; "Dmitri Plotnikov" <dm...@plotnix.com>; <st...@apache.org>; <ac...@nc.rr.com>; <KP...@flagship.ru>; <co...@wyona.org>; <M....@devote.nl>
  Sent: Thursday, March 14, 2002 3:31 PM
  Subject: [Announcement] HTML Form binding and validation arrived
  
  ===============================================================
  ! The HTML Form symmetry loop is closed: !
  ===============================================================
  HTML Forms <-> XPath <-> JavaBeans <-> XML -> Schematron -> HTML Forms
  ===============================================================
  
  Just released the next version of the symmetric Form binding and validation
  toolkit ( a CocoonBlock wannabe :).
  In addition to the form-binding it now has integrated Schematron validation
  support.
  
  The zip file can be downloaded from:
  http://prdownloads.sourceforge.net/freebuilder/CocoonForm_0-6.zip
  
  With this in place one can provide form binding with just a few lines of
  code (~5 lines) and Sophisticated form validation with 0! lines of Java
  code.
  
  ...
  
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  
  ----- Original Message ----- 
  From: "Ivelin Ivanov" <iv...@iname.com>
  To: <co...@xml.apache.org>
  Cc: "Oliver Becker" <ob...@informatik.hu-berlin.de>; "Rick Jelliffe" <ri...@allette.com.au>; "Dmitri Plotnikov" <dm...@plotnix.com>
  Sent: Sunday, March 24, 2002 7:03 AM
  Subject: [Announcement] Fast Schematron Validation Here !
  
  We've got the rainbow !
  
  +===========================================+
  +    *Fast* Java API for Schematron Validation *Ready* !      +
  +===========================================+
  +    Validates both JavaBeans and DOM nodes                       +
  +===========================================+
  
  It's been another long and fruitful Saturday here in Austin...
  
  I am grateful to everyone in the Cocoon community as well as Dmitri
  Plotnikov for his help with JXPath, Rick Jelliffe for his guidance with
  Schematron and Oliver Becker for the clarifications on his XSLT based Java
  API for Schematron.
  
  
  As I mentioned already, I've decided to implement Schematron in Java using
  JXPath.
  The result is surprisingly little code (~1K lines) and quite exciting speed
  (~20ms per validation for the demo setup).
  
  What's more:
     - Does not need Castor mapping
     - Does not do XSL transformation
     - Direct access through the JXPath library
  
  * Someone let me know if this can be implemented too much faster *
  
  I hope this answers some outstanding questions like:
  "How do we validate HTML Forms ?"
  "How do we reuse validation rules and code for HTML Forms, Web Services and
  domain validation ?"
  "What language do we use or build to implement validation?"
  
  I am not sure if the credits should all go to Schematron or more to XPath,
  but
  Schematron being so simple and powerful is clearly my choice:
  - Schemas can grow organicly. One can start with a few simple rules and grow
  the document with time.
  - Native support for validation in "phases". Unlike XML Schema, one doesn't
  need to provide a complete document in order to be able to perform
  validation.
  - Pin-points the bad elements and provides user-friendly reporting.
  - Very, very simple to learn if one knows XPath. (I just can stop repeating
  that.)
  
  ...
  
  ~~~~~~~~~~~~~~~~~~~~~
  
  <end-of-file/>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/conf/xmlform-transformator.xmap
  
  Index: xmlform-transformator.xmap
  ===================================================================
  <?xml version="1.0"?>
  <xmap xpath="/sitemap/components/transformers" unless="transformer[@name='xmlform']">
      <map:transformer logger="sitemap.transformer.xmlform" name="xmlform" 
                       src="org.apache.cocoon.transformation.XMLFormTransformer"/>
  </xmap>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/conf/xmlform.xconf
  
  Index: xmlform.xconf
  ===================================================================
  <?xml version="1.0"?>
  <xconf xpath="/cocoon/input-modules" unless="component-instance[@name='xmlform']">
      <component-instance logger="core.modules.input" name="xmlform" class="org.apache.cocoon.components.modules.input.XMLFormInput"/>
  </xconf>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/conf/xmlform.xsamples
  
  Index: xmlform.xsamples
  ===================================================================
  <?xml version="1.0"?>
  <xsamples xpath="/samples" unless="group[@name='XMLForm: Form Handling and Web Services']">
  
    <group name="XMLForm: Form Handling and Web Services">
      <sample name="Documentation" href="xmlform/overview.html">
      Introduction to Cocoon's form handling framework,
      which provides W3C XForms based markup, Schematron instance validation,
      and automated binding to JavaBeans and DOM instances.
      Also shows that XMLForm based applications are readily available as Web Services (REST style).
     </sample>
      <sample name="Example" href="xmlform/wizard">
      Presents a sophisticated form handling demo ...
      multi-page wizard with two-way navigation.
     </sample>
     <sample name="WSDL" href="xmlform/UsageFeedbackService/WSDL">
      Example WSDL descriptor for the same application,
      exposed as a Web Service.
     </sample>
    </group>
  </xsamples>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/java/org/apache/cocoon/acting/AbstractXMLFormAction.java
  
  Index: AbstractXMLFormAction.java
  ===================================================================
  /*
   * $Revision: 1.1 $
   * $Date: 2003/04/25 08:34:56 $
   *
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   *
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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 based on software copyright (c) 2001, Plotnix, Inc,
   * <http://www.plotnix.com/>.
   * For more information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.cocoon.acting;
  
  
  import org.apache.avalon.excalibur.pool.Poolable;
  import org.apache.avalon.excalibur.pool.Recyclable;
  import org.apache.avalon.framework.CascadingRuntimeException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.Constants;
  import org.apache.cocoon.components.source.SourceUtil;
  import org.apache.cocoon.components.validation.Schema;
  import org.apache.cocoon.components.validation.SchemaFactory;
  import org.apache.cocoon.components.validation.Validator;
  import org.apache.cocoon.components.xmlform.Form;
  import org.apache.cocoon.components.xmlform.FormListener;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Session;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.excalibur.source.Source;
  import org.xml.sax.InputSource;
  
  import java.util.Enumeration;
  import java.util.HashMap;
  import java.util.Map;
  
  
  
  /**
   *
   * This is the base action class for
   * xmlform handling
   *
   * This action is Poolable which means that
   * subclasses of this class should not be
   * concerned about thread safety.
   * The framework ensures that only one thread
   * has access to a concrete instance at any time.
   *
   * However once an action is complete, the instance
   * will be recycled and reused for another request.
   *
   *
   * Several ideas are borrowed from the original work of
   * Torsten Curdt.
   *
   * @author Ivelin Ivanov <iv...@apache.org>
   * @version CVS $Id: AbstractXMLFormAction.java,v 1.1 2003/04/25 08:34:56 stephan Exp $
   */
  public abstract class AbstractXMLFormAction
          extends ConfigurableComposerAction
          implements Poolable, Recyclable,
          FormListener
  {
  
      public static final String OBJECT_MAP_NEXT_PAGE = "page";
  
      protected static final Map PREPARE_RESULT_CONTINUE = null;
  
  
      // action state objects
      private Redirector redirector_;
      private SourceResolver resolver_;
      private Map objectModel_;
      private Parameters params_;
      private String src_;
      private String command_;
  
  
      /**
       * The first method which is called
       * when an action is invoked.
       *
       * It is called before population.
       *
       *
       * @return null if the Action is prepared to continue.
       * an objectModel map which will be immediately returned by the action.
       *
       * This method is a good place to handle buttons with Cancel
       * kind of semantics. For example
       * <pre>return page("input")</pre>
       *
       */
      protected Map prepare() {
          // by default, assume that there is
          // no preparation needed
          return PREPARE_RESULT_CONTINUE;
      }
  
      /**
       * FormListener callback
       * called in the beginning of Form.populate()
       * before population starts.
       *
       * This is the place to intialize the model for this request.
       *
       * This method should not handle unchecked check boxes
       * when the form is session scope, which is the most common case.
       * It should only do so, if the form is request scoped.
       */
      public void reset( Form form ) {
          // Do Nothing by default
          return;
      }
  
      /**
       * FormListener callback
       *
       * Invoked during Form.populate();
       *
       * It is invoked before a request parameter is mapped to
       * an attribute of the form model.
       *
       * It is appropriate to use this method for filtering
       * custom request parameters which do not reference
       * the model.
       *
       * Another appropriate use of this method is for graceful filtering of invalid
       * values, in case that knowledge of the system state or
       * other circumstainces make the standard validation
       * insufficient. For example if a registering user choses a username which
       * is already taken - the check requires database transaction, which is
       * beyond the scope of document validating schemas.
       * Of course customized Validators can be implemented to do
       * this kind of domain specific validation
       * instead of using this method.
       *
       * @return false if the request parameter should not be filtered.
       * true otherwise.
       */
      public boolean filterRequestParameter (Form form, String parameterName) {
          // in this example we do not expect "custom" parameters
          return false;
      }
  
      /**
       * Invoked during the form population process
       *
       * Provides default implementation, which
       * can be extended or replaced by subclasses
       *
       * Implementations of this method are responsible
       * for creating and
       * returning the Form object which the action
       * is working on.
       *
       * @return Form the form object this action works with
       */
      protected Form getForm () {
          Form form = Form.lookup( getObjectModel(), getFormId() );
  
          if (form != null) {
              return form;
          } else {
              // create new form
              form = new Form( getFormId(), getFormModel() );
              Validator v = getFormValidator();
              form.setValidator ( v );
              form.save ( getObjectModel(), getFormScope() );
              return form;
          }
      }
  
      public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String src, Parameters params)
              throws Exception
      {
          // populate action state objects
          redirector_ = redirector;
          resolver_ = resolver;
          objectModel_ = objectModel;
          src_ = src;
          params_ = params;
  
          // ensure that there is a form available
          // through the rest of the flow
          Form form = getForm();
          if (form == null) {
              throw new IllegalStateException( "Action could not obtain the Form" );
          }
  
          // find and save the action command
          findCommand();
  
          // call the subclass prepare()
          // give it a chance to get ready for action
          Map prepareResult = prepare();
          if (prepareResult != null) {
              return prepareResult;
          }
  
          // attache callback hooks to the form
          // in case the action subclasses are interested in
          // form events
          getForm().addFormListener( this );
          Map result = null;
  
          try {
              // populate form with request parameters
              // population is automatically followed by validation by default.
              // If this is not the desired behaviour, the Form class can be subclassed
              form.populate( objectModel );
  
              result = perform();
          } finally {
              // since the action may be recycled immediately after
              // the request. It is important that it's callback hooks
              // are removed from the Form.
              getForm().removeFormListener( this );
          }
  
          return result;
      }
  
  
      /**
       * Get the command which was submitted with the form.
       * It is extracted from the standard cocoon-action-* request parameter
       */
      public String getCommand()
      {
          return command_;
      }
  
      protected void findCommand() {
          command_ = null;
          Enumeration enum = getRequest().getParameterNames ();
          while (enum.hasMoreElements ())
          {
              String paramName = (String) enum.nextElement ();
              // search for the command
              if ( paramName.startsWith ( Constants.ACTION_PARAM_PREFIX ) )
              {
                  command_ =
                          paramName.substring ( Constants.ACTION_PARAM_PREFIX.length(), paramName.length() );
              }
          }
      }
  
      /**
       * @return the @view attribute of the xmlform form tag.
       * This attribute is used to identify the part(or view)
       * of the model which is used in the specific xmlform
       * document.
       *
       */
      public String getFormView() {
          return getForm().getFormView( getObjectModel() );
      }
  
  
      /**
       * Called to determine the exit point of an action.
       * The pageName is made available in the objectMap,
       * which can be then referenced in the pipeline
       * @param pageName logical name for a next page
       * @return Map a pipeline objectMap containing the pageName
       *
       */
      protected Map page( String pageName ) {
          Map objectModel = new HashMap();
          objectModel.put( OBJECT_MAP_NEXT_PAGE,  pageName );
          return objectModel;
      }
  
      /**
       * Invoked after form population
       * unless a Cancel button was pressed,
       * in which case population is skipped and this method
       * is invoked immediately
       *
       * Semanticly similar to Struts Action.perform()
       *
       * Take appropriate action based on the command
       *
       */
      public abstract Map perform ();
  
  
      protected SourceResolver getSourceResolver() {
          return resolver_;
      }
  
      protected Redirector getRedirector() {
          return redirector_;
      }
  
      protected Map getObjectModel() {
          return objectModel_;
      }
  
  
      protected Parameters getParameters() {
          return params_;
      }
  
      protected String getSrc() {
          return src_;
      }
  
      protected Request getRequest() {
          return (Request) ( getObjectModel().get(ObjectModelHelper.REQUEST_OBJECT) );
      }
  
      protected Session getSession( boolean shouldCreateNew ) {
          return getRequest().getSession( shouldCreateNew );
      }
  
      protected Session getSession() {
          return getSession( true );
      }
  
  
      /**
       * Extract action parameters and
       * instantiate a new validator based on them.
       *
       * xmlform-validator-schema-ns
       * xmlform-validator-schema
       *
       * Subclasses may override this method
       * to use custom validators
       */
      protected Validator getFormValidator() {
          try {
              // initialize the Validor with a schema file
              String schNS = getParameters().getParameter("xmlform-validator-schema-ns", null);
              String schDoc = getParameters().getParameter("xmlform-validator-schema", null);
  
              // if validator params are not specified, then
              // there is no validation by default
              if (schNS == null || schDoc == null ) return null;
  
              Source schemaSrc = getSourceResolver().resolveURI( schDoc );
              try {
                  InputSource is = SourceUtil.getInputSource(schemaSrc);
                  SchemaFactory schf = SchemaFactory.lookup ( schNS );
                  Schema sch = schf.compileSchema ( is );
  
                  return sch.newValidator();
              } finally {
                  getSourceResolver().release(schemaSrc);
              }
          } catch ( Exception e) {
              // couldn't load the validator
              throw new CascadingRuntimeException( " Failed loading validating schema ", e );
          }
      }
  
  
      /**
       * Extract xmlform-model
       * action parameter and
       * instantiate a new form model it.
       *
       *
       * Subclasses may override this method
       * to use custom model instantiation technique
       */
      protected Object getFormModel() {
          try {
              String modelClassName = getParameters().getParameter("xmlform-model", null);
              Class modelClass = Class.forName ( modelClassName );
              Object o = modelClass.newInstance ();
              return o;
          } catch ( Exception e) {
              throw new CascadingRuntimeException( " Failed instantiating form model ", e );
          }
      }
  
  
      protected String getFormId() {
          String formId = getParameters().getParameter("xmlform-id", null);
          if (formId == null)
              throw new RuntimeException( " xmlform-id not specified " );
          else
              return formId;
      }
  
  
      protected String getFormScope() {
          String formScope = getParameters().getParameter("xmlform-scope", null);
          if ( formScope == null ) {
              // default to request scope
              formScope = Form.SCOPE_REQUEST;
          }
  
          return formScope;
      }
  
  
      /**
       *  Recycle this component.
       */
      public void recycle() {
          redirector_ = null;
          resolver_ = null;
          objectModel_ = null;
          params_ = null;
          src_ = null;
          command_ = null;
      }
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/java/org/apache/cocoon/components/flow/javascript/xmlForm.js
  
  Index: xmlForm.js
  ===================================================================
  //
  // CVS $Id: xmlForm.js,v 1.1 2003/04/25 08:34:57 stephan Exp $
  //
  // XMLForm Support
  //
  
  
  /**
   * Creates a new JavaScript wrapper of a Form object
   * see org.apache.cocoon.components.xmlform.Form
   * @param id [String] unique form id
   * @param validatorNS [String] Namespace of validator
   * @param validatorDoc [String] Validator document
   * @param scope [String] either "request" or "session"
   */
  
  function XForm(id, validatorNS, validatorDoc, scope) {
      if (scope == "session") {
          cocoon.createSession();
      }
      this.cocoon = cocoon; // workaround for Rhino dynamic scope bug
      this.id = id;
      this.lastContinuation = null;
      this.validatorNS = validatorNS;
      this.validatorDoc = validatorDoc;
      this.submitId = undefined;
      this.dead = false;
  }
  
  
  /**
   * Return the model object of this form
   * @return a Java bean, JavaScript, DOM, or JDOM object 
   */
  XForm.prototype.getModel = function() {
      return this.form.getModel();
  }
  
  /**
   * Return the id of the xf:submit element of the current form submission
   * @return [String] id attribute of the button that caused this from to be submitted
   */
  XForm.prototype.getSubmitId = function() {
      return this.submitId;
  }
  
  /**
   * Set the model object of this form
   * @param model [Object] Any Java bean, JavaScript, DOM, or JDOM object 
   */
  XForm.prototype.setModel = function(model) {
      this.form = 
         new Packages.org.apache.cocoon.components.xmlform.Form(this.id, 
                                                                 model);
      this.context = 
         Packages.org.apache.commons.jxpath.JXPathContext.newContext(model);
      this.form.setAutoValidate(false);
      if (this.validatorNS != undefined && this.validatorDoc != undefined) {
          this._setValidator(this.validatorNS, this.validatorDoc);
      }
  }
  
  /**
   * Creates a new web continuation
   * @param lastCont [WebContinuation] previous web continuation
   * @param timeToLive [Number] expiration time for this continuation in milliseconds
   * @return [WebContinuation] a new WebContinuation instance
   */
  XForm.prototype.start = function(lastCont, timeToLive) {
      var result = this._start(lastCont, timeToLive);
      // 
      // _start() will return an Object when it's called
      // the first time. However, when its Continuation is invoked it
      // will return a WebContinuation instead. In the latter case
      // we're going back to the previous page: so
      // clear the current page's violations before showing the previous page
      // Without this, violations from the current page will
      // incorrectly be displayed on the previous page.
      if (result instanceof WebContinuation) {
          this.form.clearViolations();
          return result;
      }
      return result.kont;
  } 
  
  XForm.prototype._start = function(lastCont, timeToLive) {
      var k = new Continuation();
      var kont = new WebContinuation(this.cocoon, k, 
                                     lastCont, timeToLive);
      return {kont: kont};
  } 
  
  /**
   * Adds a violation to this form
   * @param xpath [String] xpath location of field that contains invalid data
   * @param message [String] error message
   */
  XForm.prototype.addViolation = function(xpath, message) {
      var violation = 
         new Packages.org.apache.cocoon.components.validation.Violation();
      violation.path = xpath;
      violation.message = message;
      var list = new java.util.LinkedList();
      list.add(violation);
      try {
          this.form.addViolations(list);
      } catch (e) {
          print(e);
          if (e instanceof java.lang.Throwable) {
              e.printStackTrace();
          }
      }
  }
  
  /**
   * Does this form have violations?
   * @return [Boolean] true if violations have been added to this form
   */
  XForm.prototype.hasViolations = function() {
      var set = this.form.violationsAsSortedSet;
      return set != null && set.size() > 0;
  }
  
  /**
   * Computes the value of an xpath expression against the model of this form
   * @param expr [String] xpath expression
   * @return [Object] result of computing <code>expr</code>
   */
  XForm.prototype.getValue = function(expr) {
      return this.context.getValue(expr);
  }
  
  /**
   * Returns an iterator over a nodeset value of an xpath expression evaluated 
   * against the model of this form
   * @param expr [String] xpath expression
   * @return [java.util.Iterator] representing a nodeset 
   */
  XForm.prototype.iterate = function(expr) {
      return this.context.iterate(expr);
  }
  
  XForm.prototype._sendView = function(uri, lastCont, timeToLive) {
      var k = new Continuation();
      var kont = new WebContinuation(this.cocoon, k, lastCont, timeToLive);
      var bizData = this.form.getModel();
      if (bizData == undefined) {
          bizData = null;
      }
      this.cocoon.forwardTo("cocoon://" + 
                            this.cocoon.environment.getURIPrefix() + uri,
                            bizData, kont);
      this.lastContinuation = kont;
      suicide();
  }
  
  /**
   * Sends view to presentation pipeline and waits for subsequent submission.
   * Automatically resends view if validation fails.
   * Creates two continuations: one immediately before the page is sent 
   * and one immediately after. These are used to implement automated support
   * for back/forward navigation in the form. When you move forward in the
   * form the second continuation is invoked. When you move back from the
   * following page the first continuation is invoked.
   * @param phase [String] phase to validate
   * @param uri [String] presentation pipeline resource identifier of view
   * @param validator [Function] optional function invoked to perform validation
   */
  XForm.prototype.sendView = function(view, uri, validator) {
      var lastCont = this.lastContinuation;
      while (true) {
          // create a continuation, the invocation of which will resend
          // the page: this is used to implement <xf:submit continuation="back">
          var k = this.start(lastCont);
          if (this.cocoon.request == null) {
              // this continuation has been invalidated
              this.dead = true;
              handleInvalidContinuation();
              suicide();
          }
          // reset the view in case this is a re-invocation of a continuation
          this.cocoon.request.setAttribute("view", view);
          this.form.remove(this.cocoon.environment.objectModel, this.id);
          this.form.save(this.cocoon.environment.objectModel, "request");
          this._sendView(uri, k);
          // _sendView creates a continuation, the invocation of which
          // will return right here: it is used to implement 
          // <xf:submit continuation="forward">
          if (this.dead ||  this.cocoon.request == null) {
              // this continuation has been invalidated
              handleInvalidContinuation();
              suicide();
          }
          this.form.populate(this.cocoon.environment.objectModel);
          this.submitId = 
  	  this.cocoon.request.getAttribute("xml-form-submit-id");
          if (validator != undefined) {
  	    validator(this);
          }
          this.form.validate(view);
          if (!this.hasViolations()) {
              break;
          }
      }
  }
  
  XForm.prototype._setValidator = function(schNS, schDoc) {
      // if validator params are not specified, then
      // there is no validation by default
      if (schNS == null || schDoc == null ) return null;
      var resolver =  this.cocoon.environment;
      var schemaSrc = resolver.resolveURI( schDoc );
      try {
          var is = Packages.org.apache.cocoon.components.source.SourceUtil.getInputSource(schemaSrc);
          var schf = Packages.org.apache.cocoon.components.validation.SchemaFactory.lookup ( schNS );
          var sch = schf.compileSchema ( is );
          this.form.setValidator(sch.newValidator());
      } finally {
          resolver.release(schemaSrc);
      }
  }
  
  /**
   * Sends view to presentation pipeline but doesn't wait for submission
   * @param uri [String] presentation pipeline uri
   */
  
  XForm.prototype.finish = function(uri) {
      this.form.remove( this.cocoon.environment.objectModel, this.id);
      this.form.save( this.cocoon.environment.objectModel, "request");
      this.cocoon.forwardTo("cocoon://" + 
  			  this.cocoon.environment.getURIPrefix() + uri,
  			  this.form.getModel(), 
  			  null);
      this.dead = true;
      if (this.lastContinuation != null) {
          this.lastContinuation.invalidate();
          this.lastContinuation = null;
      }
      
  }
  
  /**
   * Entry point to a flow-based XMLForm application. Replaces the functionality
   * of XMLForm actions.
   * @param application Name of a JavaScript function that represents the page flow for a form
   * @param id form id
   * @param validator_ns XML namespace of validator
   * @param validator_doc validator document
   * @param scope 
   */
  
  function xmlForm(application, id, validator_ns, validator_doc, scope) {
      if (cocoon.request == null) {
          handleInvalidContinuation("");
          return;
      }
      function getCommand() {
          var enum_ = cocoon.request.parameterNames;
          var command = undefined;
          while (enum_.hasMoreElements()) {
              var paramName = enum_.nextElement();
              // search for the command
              if (paramName.startsWith(Packages.org.apache.cocoon.Constants.ACTION_PARAM_PREFIX)) {
                  command =
                      paramName.substring(Packages.org.apache.cocoon.Constants.ACTION_PARAM_PREFIX.length(), paramName.length());
                  break;
              }
          }
          // command encodes the continuation id for "back" or "next" actions
          return command;
      }
      var command = getCommand();
      if (command != undefined) {
          // invoke a continuation 
          // command looks like kontId:id
  	var id = "";
  	var kontId = command;
  	var index = command.indexOf(java.lang.String(":").charAt(0));
  	if (index > 0) {
  	    var kontId = command.substring(0, index);
  	    if (index + 1 < command.length()) {
  		id = command.substring(index + 1);
  	    }
  	}
  	cocoon.request.setAttribute("xml-form-submit-id", id);
          cocoon.interpreter.handleContinuation(kontId, 
                                                null,
                                                cocoon.environment);
          return;
      } 
      if (id != null) {
          // Just start a new instance of the application
          var args = new Array(arguments.length - 5 + 1);
          args[0] = new XForm(id, validator_ns, validator_doc, scope);
          for (var i = 5; i < arguments.length; i++) {
              args[i-4] = arguments[i];
          }
          this[application].apply(this, args);
      } else {
          handleInvalidContinuation(command);
      }
  }
  
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/java/org/apache/cocoon/components/modules/input/XMLFormInput.java
  
  Index: XMLFormInput.java
  ===================================================================
  /*
   
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
   
   Copyright (C) 1999-2003 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  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
   
   */
  package org.apache.cocoon.components.modules.input;
  
  import java.util.Map;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.components.xmlform.Form;
  
  /**
   * Accesses the form model of an 
   * {@link org.apache.cocoon.components.xmlform.Form XMLForm Instance}. 
   * The xmlform-id needs to be passed with the configuration. Additionally supports 
   * all configuration options from {@link AbstractJXPathModule AbstractJXPathModule}.
   * This can be used for example to let the 
   * <code>org.apache.cocoon.acting.modular.DatabaseAction</code> access 
   * form data.
   * 
   * <p>Configuration example:</p>
   * <table>
   * <tr><td><code>&lt;xmlform-id&gt;form-feedback&lt;/xmlform-id&gt;</td>
   * <td>XMLForm ID to use.</td> 
   * </tr></table>
   *
   * @author <a href="mailto:haul@apache.org">Christian Haul</a>
   * @version CVS $Id: XMLFormInput.java,v 1.1 2003/04/25 08:34:57 stephan Exp $
   */
  public class XMLFormInput extends AbstractJXPathModule implements ThreadSafe {
      String formId = null;
      
      /**
       * Configure component. Preprocess list of packages and functions
       * to add to JXPath context later.
       *
       * @param config a <code>Configuration</code> value
       * @exception ConfigurationException if an error occurs
       */
      public void configure(Configuration config) throws ConfigurationException {
          this.formId = config.getChild("xmlform-id").getValue(null);
          super.configure(config);
      }
      
      /** Returns the object which should be used as JXPath context.
       * Descendants should override this method to return a specific object
       * that is requried by the implementing class.
       * Examples are: request, session and application context objects.
       *
       */
      protected Object getContextObject(Configuration modeConf, Map objectModel) throws ConfigurationException {
          String id = this.formId;
          if (modeConf != null) {
              id = modeConf.getChild("xmlform-id").getValue(this.formId);
          }
          Form form = Form.lookup(objectModel,id);
          Object tmp = null;
          if (form != null) { 
              tmp = form.getModel();
          }
          return tmp;
      }
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/java/org/apache/cocoon/components/xmlform/Form.java
  
  Index: Form.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 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  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.components.xmlform;
  
  import java.util.*;
  
  import org.apache.cocoon.Constants;
  import org.apache.cocoon.components.validation.Validator;
  import org.apache.cocoon.components.validation.Violation;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Session;
  import org.apache.cocoon.transformation.XMLFormTransformer;
  import org.apache.commons.jxpath.JXPathContext;
  import org.apache.commons.jxpath.JXPathException;
  import org.apache.commons.jxpath.Pointer;
  import org.mozilla.javascript.Context;
  import org.mozilla.javascript.NativeArray;
  import org.mozilla.javascript.ScriptableObject;
  
  /**
   * <p>
   *  Encapsulates a form bean and the validation result
   *  in a single class. It is created automatically by the
   *  FormValidatingAction
   * </p>
   *
   * <b>NOTE: This class is NOT thread safe</b>
   *
   * @author Ivelin Ivanov, ivelin@apache.org
   * @author michael_hampel@sonynetservices.com 
   * @version CVS $Id: Form.java,v 1.1 2003/04/25 08:34:57 stephan Exp $
   */
  public class Form {
  
          public static String SCOPE_REQUEST = "request";
          public static String SCOPE_SESSION = "session";
  
          public static String FORM_VIEW_PARAM = "cocoon-xmlform-view";
  
          public static String VIOLATION_MESSAGE_DATA_FORMAT_ERROR =
                  "Invalid data format";
  
          /**
           * an XMLForm is only usable when it has an id and an underlying model
           */
          public Form(String id, Object model) {
  
                  if ((id == null) || (model == null))
                          throw new java.lang.IllegalStateException(
                                  "Form cannot be created with null id or null model ");
                  setId(id);
                  setModel(model);
          }
  
          public String getId() {
                  return id_;
          }
  
          public void setId(String newId) {
                  id_ = newId;
          }
  
          public Object getModel() {
                  return model_;
          }
  
          public void setModel(Object newModel) {
                  model_ = newModel;
                  jxcontext_ = JXPathContext.newContext(model_);
                  jxcontext_.setLenient(false);
          }
  
          public Validator getValidator() {
                  return validator_;
          }
  
          public void setValidator(Validator newValidator) {
                  validator_ = newValidator;
          }
  
          public List getViolations() {
                  return violations_;
          }
  
          /**
           * 
           * This method allows custom validations to be added
           * after population and after a call to validate
           * (either automatic or explicit).
           * Usually used from within the perform method of 
           * a concrete XMLFormAction.
           * 
           * @param newViolations
           *   
           */
          public void addViolations(List newViolations) {
  
                  if (violations_ != null)
                          violations_.addAll(newViolations);
                  else
                          violations_ = newViolations;
                  updateViolationsAsSortedSet();
  
          }
  
          public SortedSet getViolationsAsSortedSet() {
                  return violationsAsSortedSet_;
          }
  
          public void clearViolations() {
                  violations_ = null;
                  violationsAsSortedSet_ = null;
          }
  
          /**
           * Encapsulates access to the model
           *
           * @param xpath to the model attribute
           * @param value to be set
           */
          public void setValue(String xpath, Object value) {
                  if (model_ == null)
                          throw new IllegalStateException("Form model not set");
                  jxcontext_.setValue(xpath, value);
          }
  
          public void setValue(String xpath, Object[] values) {
  
                  //    // Dmitri Plotnikov's patch
                  //    
                  //    // if there are multiple values to set
                  //    // (like in the selectMany case),
                  //    // iterate over the array and set individual values
                  //    if ( values.length > 1  ) 
                  //    {
                  //      Iterator iter = jxcontext_.iteratePointers(xpath);      
                  //      for (int i = 0; i < values.length; i++ )
                  //      {
                  //        Pointer ptr = (Pointer)iter.next();
                  //        ptr.setValue(values[i]);
                  //      }
                  //    }
                  //    else 
                  //    {
                  //      // This is supposed to do the right thing
                  //      jxcontext_.setValue(xpath, values);
                  //    }    
                  //    
  
                  Pointer pointer = jxcontext_.getPointer(xpath);
                  Object property = pointer.getNode();
                  // if there are multiple values to set
                  // (like in the selectMany case),
                  // iterate over the array and set individual values
  
                  // when the instance property is array
                  if (property != null && property.getClass().isArray()) {
                          Class componentType = property.getClass().getComponentType();
                          property =
                                  java.lang.reflect.Array.newInstance(
                                          componentType,
                                          values.length);
                          java.lang.System.arraycopy(values, 0, property, 0, values.length);
                          pointer.setValue(property);
                  } else if (property instanceof Collection) {
                          Collection cl = (Collection) property;
                          cl.clear();
                          cl.addAll(java.util.Arrays.asList(values));
                  } else if (property instanceof NativeArray) {
                      Context.enter();
                      try {
                          NativeArray arr = (NativeArray)property;
                          ScriptableObject.putProperty(arr, "length", 
                                                       new Integer(0));
                          ScriptableObject.putProperty(arr, "length", 
                                                       new Integer(values.length));
                          for (int i = 0; i < values.length; i++) {
                              Object val = values[i];
                              if (!(val == null
                                    || val instanceof String
                                    || val instanceof Number 
                                    || val instanceof Boolean)) {
                                  val = Context.toObject(val, arr);
                              }
                              ScriptableObject.putProperty(arr, i, val);
                          }
                      } catch (Exception willNotBeThrown) {
                          // shouldn't happen
                          willNotBeThrown.printStackTrace();
                      } finally {
                          Context.exit();
                      }
                  } else {
                      jxcontext_.setValue(xpath, values[0]);
                  }
          }
  
          /**
           * Encapsulates access to the model
           *
           * @param xpath of the model attribute
           *
           * @throws RuntimeException if the xpath value 
           * has invalid XPath syntax or it doesn't point 
           * to an attribute of the model
           *
           */
          public Object getValue(String xpath) {
                  if (model_ == null)
                          throw new IllegalStateException("Form model not set");
                  Object result = jxcontext_.getValue(xpath);
                  if (result instanceof NativeArray) {
                      // Convert JavaScript array to Collection
                      NativeArray arr = (NativeArray)result;
                      int len = (int)arr.jsGet_length();
                      List list = new ArrayList(len);
                      for (int i = 0; i < len; i++) {
                          Object obj = arr.get(i, arr);
                          if (obj == Context.getUndefinedValue()) {
                              obj = null;
                          }
                          list.add(obj);
                      }
                      result = list;
                  }
                  return result;
          }
  
          /**
           * Resolves a nodeset selector
           * into a list of concrete node locations
           * @param xpathSelector the nodeset selector
           *
           * @return a Set of XPath strings pointing to 
           * each nodeset satisfying the nodeset selector
           *
           * <p>
           * TODO: the Collection return type should be replaced with a Set.
           * LinkedHashSet implementation should be used. All resolved 
           * nodes are unique in the resulting set, therefore Set is more appropriate.
           * Since LinkedHashSet is only available in JDK 1.4 or later, it is not
           * appropriate to make the change immediately.
           */
          public Collection locate(String xpathSelector) {
                  if (model_ == null)
                          throw new IllegalStateException("Form model not set");
                  List nodeset = new LinkedList();
                  Iterator iter = jxcontext_.iteratePointers(xpathSelector);
                  while (iter.hasNext()) {
                      Pointer nextPointer = (Pointer) iter.next();
                      String path = nextPointer.asPath();
                      nodeset.add(path);
                  }
                  return nodeset;
          }
  
          /**
           * Performs complete validation
           * of the form model
           */
          public boolean validate() {
                  return validate(null);
          }
  
          /**
           *
           * @param phase the validation phase
           *
           * @return
           * if validation finishes without any violations, 
           * return true otherwise return false and save all violations
           *
           */
          public boolean validate(String phase) {
                  if (validator_ == null)
                          return true;
  
                  validator_.setProperty(Validator.PROPERTY_PHASE, phase);
                  List vs = validator_.validate(model_);
                  if (vs != null) {
                      if (violations_ != null) {
                          violations_.addAll(vs);
                      } else {
                          if (!vs.isEmpty())
                              violations_ = vs;
                      }
                  }
                  if (violations_ == null)
                          return true;
                  else {
                          updateViolationsAsSortedSet();
                          return false;
                  }
          }
  
          /**
           * Populates an HTML Form POST into the XMLForm model (JavaBean or DOM node).
           *
           * <p>
           * Expects that all request parameter names are XPath expressions
           * to attributes of the model.
           * For each request parameter, finds and assigns its value to the
           * JavaBean property corresponding to the parameter's name
           * </p>
           *
           * TODO: provide a more sophisticated examples with checkboxes, multi choice,
           * radio button, text area, file upload, etc.
           */
          public void populate(Map sitemapObjectModel) {
                  // clean violations_ set
                  clearViolations();
  
                  // let listeners know that 
                  // population is about to start
                  reset();
  
                  // data format violations
                  // gathered during population
                  // For example when 
                  // a request parameter value is "saymyname"
                  // while the request parameter name points to an int attribute
                  List pviolations = new ArrayList();
  
                  Map filteredParameters =
                          getFilteredRequestParameters(sitemapObjectModel);
                  Iterator iter = filteredParameters.entrySet().iterator();
                  while (iter.hasNext()) {
                          Map.Entry entry = (Map.Entry) iter.next();
  
                          String path = (String) entry.getKey();
  
                          // filter custom request parameter
                          // not refering to the model
                          if (filterRequestParameter(path))
                                  continue;
  
                          Object[] values = (Object[]) entry.getValue();
  
                          try {
                              setValue(path, values);
                          } catch (JXPathException ex) {
                                  Violation v = new Violation();
                                  v.setPath(path);
                                  v.setMessage(ex.getMessage());
                                  pviolations.add(v);
                          }
                  } // while
  
                  // validate form model
                  autoValidate(sitemapObjectModel);
  
                  // merge violation sets
                  if (violations_ != null) {
                          violations_.addAll(pviolations);
                  } else {
                          if (!pviolations.isEmpty())
                                  violations_ = pviolations;
                  }
                  if (violations_ != null) {
                          updateViolationsAsSortedSet();
                  }
          }
  
          /**
           * 
           * Filters request parameters which are not references to model properties.
           * Sets default values for parameters which were expected in the request, 
           * but did not arrive (e.g. check boxes).
           * 
           * @return filtered request parameters
           * 
           */
          protected Map getFilteredRequestParameters(Map sitemapObjectModel) {
  
                  Request request = getRequest(sitemapObjectModel);
  
                  Map filteredParameters = new HashMap();
  
                  // first filter out request parameters which do not refer to model properties
                  Enumeration enum = request.getParameterNames();
                  while (enum.hasMoreElements()) {
                          String path = (String) enum.nextElement();
  
                          // filter custom request parameter
                          // not refering to the model
                          if (filterRequestParameter(path))
                                  continue;
  
                          Object[] values = request.getParameterValues(path);
  
                          filteredParameters.put(path, values);
                  }
  
                  // now, find expected parameters which did not arrive 
                  // and set default values for them
                  String viewName = getFormView(sitemapObjectModel);
                  Map expectedReferences =
                          getFormViewState(viewName).getModelReferenceMap();
  
                  Iterator iter = expectedReferences.entrySet().iterator();
                  while (iter.hasNext()) {
                          Map.Entry entry = (Map.Entry) iter.next();
                          String propertyReference = (String) entry.getKey();
  
                          // check if the expected parameter actually arrived in the request
                          if (filteredParameters.get(propertyReference) == null) {
                                  // Since it is not there, try to provide a default value
                                  String inputType = (String) entry.getValue();
  
                                  Object defaultValue = null;
                                  if (inputType.equals(XMLFormTransformer.TAG_SELECTBOOLEAN)) {
                                          // false for boolean type (usually, single check-box)
                                          defaultValue = new Object[] { Boolean.FALSE };
                                  } else if (
                                          inputType.equals(XMLFormTransformer.TAG_SELECTMANY)) {
                                          // empty array for select many (usually, multi check-box)
                                          defaultValue = new Object[0];
                                  } else {
                                          // for all the rest, use a blank value and hope for the best
                                          defaultValue = new Object[] { "" };
                                  }
  
                                  filteredParameters.put(propertyReference, defaultValue);
  
                          }
  
                  } // iterate over expectedReferences.entrySet()
  
                  return filteredParameters;
  
          } // getFilteredRequestParameters
  
          /** create a SortedSet view of the violations collection
          * for convenience of processors down the pipeline
          * protected void updateViolationsAsSortedSet()
          */
          protected void updateViolationsAsSortedSet() {
                  violationsAsSortedSet_ = new TreeSet(violations_);
          }
  
          /**
          *
          * Convenience method invoked after populate()
          * By default it performs Form model validation.
          *
          * <br>
          * - If default validation is not necessary
          * setAutoValidate( false ) should be used
          *
          * <br>
          * If the validation
          * criteria needs to be different, subclasses can override
          * this method to change the behaviour.
          *
          */
          protected void autoValidate(Map sitemapObjectModel) {
                  if (!autoValidateEnabled_)
                          return;
                  // perform validation for the phase 
                  // which matches the name of the current form view
                  // if one is available
                  String formView = getFormView(sitemapObjectModel);
                  if (formView != null) {
                          validate(formView);
                  }
          }
  
          /**
          * Filters custom request parameter not refering to the model
          *
      * <p>
          * TODO: implement default filtering
          * for standard Cocoon parameters
          * like cocoon-action[-suffix]
          *
          */
          protected boolean filterRequestParameter(String name) {
                  // filter standard cocoon-* parameters
                  if (filterDefaultRequestParameter(name))
                          return true;
  
                  // then consult with FormListeners
                  Set ls = new HashSet();
                  ls.addAll(Collections.synchronizedSet(formListeners_));
                  Iterator iter = ls.iterator();
                  while (iter.hasNext()) {
                          FormListener fl = (FormListener) iter.next();
                          // if any of the listeners wants this parameter filtered
                          // then filter it (return true)
                          if (fl.filterRequestParameter(this, name))
                                  return true;
                  }
                  // if none of the listeners wants this parameter filtered
                  // then don't filter it
                  return false;
          }
  
          /**
          * Filters the standard cocoon request parameters.
          * If default filtering needs to be different,
          * subclasses can override this method.
          * It is invoked before all listeners are asked to filter the parameter
          */
          protected boolean filterDefaultRequestParameter(String paramName) {
                  if (paramName.startsWith(Constants.ACTION_PARAM_PREFIX)
                          || paramName.startsWith(Constants.VIEW_PARAM))
                          return true;
                  if (paramName.equals(FORM_VIEW_PARAM))
                          return true;
                  else
                          return false;
          }
  
          /**
           * Try to extract from the request
           * and return the current form view
           */
          public String getFormView(Map sitemapObjectModel) {
                  return getRequest(sitemapObjectModel).getParameter(Form.FORM_VIEW_PARAM);
          }
  
          /**
           * This method is called before
           * the form is populated with request parameters.
           *
           * Semantically similar to that of the 
           * ActionForm.reset() in Struts
           *
           * Can be used for clearing checkbox fields,
           * because the browser will not send them when
           * not checked.
           *
           * Calls reset on all FormListeners
           */
          protected void reset() {
                  // notify FormListeners
                  Set ls = new HashSet();
                  ls.addAll(Collections.synchronizedSet(formListeners_));
                  Iterator iter = ls.iterator();
                  while (iter.hasNext()) {
                          FormListener fl = (FormListener) iter.next();
                          fl.reset(this);
                  }
                  return;
          }
  
          /**
           * Loads a form from the request or session
           *
           * @param sitemapObjectModel
           * @param id the form id
           */
          public static Form lookup(Map sitemapObjectModel, String id) {
                  Request request = getRequest(sitemapObjectModel);
                  Form form = (Form) request.getAttribute(id);
                  if (form != null)
                          return form;
                  else {
                          Session session = request.getSession(false);
                          if (session != null)
                                  form = (Form) session.getAttribute(id);
                          return form;
                  }
          }
  
          /**
           * Removes a form from the request and session.
           * This method will remove the attribute bindings
           * correspoding to the form id from both request
           * and session to ensure that a subsequent 
           * Form.lookup will not succeed.
           *
           * @param sitemapObjectModel
           * @param id the form id
           */
          public static void remove(Map sitemapObjectModel, String id) {
                  Request request = getRequest(sitemapObjectModel);
                  request.removeAttribute(id);
  
                  Session session = request.getSession(false);
                  if (session != null)
                          session.removeAttribute(id);
          }
  
          /**
           * Saves the form in the request or session
           *
           * @param sitemapObjectModel
           * @param scope if true the form will be bound in the session, otherwise request
           */
          public void save(Map sitemapObjectModel, String scope) {
                  Request request = getRequest(sitemapObjectModel);
  
                  if (lookup(sitemapObjectModel, id_) != null)
                          throw new java.lang.IllegalStateException(
                                  "Form [id=" + id_ + "] already bound in request or session ");
  
                  if (SCOPE_REQUEST.equals(scope)) {
                          request.setAttribute(id_, this);
                  } else // session scope
                          {
                          Session session = request.getSession(true);
                          session.setAttribute(id_, this);
                  }
  
          }
  
          /**
           * Add another FormListener
           *
           */
          public synchronized void addFormListener(FormListener formListener) {
                  formListeners_.add(formListener);
          }
  
          /**
           * Add another FormListener
           *
           */
          public synchronized void removeFormListener(FormListener formListener) {
                  formListeners_.remove(formListener);
          }
  
          protected final static Request getRequest(Map sitemapObjectModel) {
                  return (Request) sitemapObjectModel.get(
                          ObjectModelHelper.REQUEST_OBJECT);
          }
  
          public void setAutoValidate(boolean newAVFlag) {
                  autoValidateEnabled_ = newAVFlag;
          }
  
          /**
           * <pre>
           * When the transformer renders a form view,
           * it lets the form wrapper know about each referenced model property.
           * This allows a precise tracking and can be used for multiple reasons:
           *   1) Verify that the client does not temper with the input fields as specified by the 
           *      form view author
           *   2) Allow default values to be used for properties which were expected to be send by the client,
           *      but for some reason were not. A typical example is a check box. When unchecked, the browser
           *      does not send any request parameter, leaving it to the server to handle the situation.
           *      This proves to be a very error prone problem when solved on a case by case basis.
           *      By having a list of expected property references, the model populator can detect
           *      a checkbox which was not send and set the property value to false.
           * 
           * NOTE: This added functionality is ONLY useful for SESSION scope forms.
           * Request scope forms are constructed anew for every request and therefore
           * cannot benefit from this extra feature.
           * With the high performance CPUs and cheap memory used in today's servers,
           * session scope forms are a safe choice.
           * 
           * </pre>
           * 
           */
          public void saveExpectedModelReferenceForView(
                  String currentFormView,
                  String ref,
                  String inputType) {
                  // if the form view is null, we are not interested in saving any references
                  if (currentFormView == null)
                          return;
  
                  FormViewState formViewState = getFormViewState(currentFormView);
                  formViewState.addModelReferenceAndInputType(ref, inputType);
          }
  
          /**
           * When the transformer starts rendering a new form element
           * It needs to reset previously saved references for another 
           * transformation of the same view.
           */
          public void clearSavedModelReferences(String currentFormView) {
                  FormViewState formViewState = getFormViewState(currentFormView);
                  formViewState.clear();
          }
  
          /**
           * We keep a map of ViewState objects which store 
           * all references to model properties in a particular form view
           * which were rendered by the 
           * XMLFormTansformer in the most recent transformation.
           */
          protected FormViewState getFormViewState(String viewName) {
                  FormViewState formViewState =
                          (FormViewState) viewStateMap_.get(viewName);
                  if (formViewState == null) {
                          formViewState = new FormViewState();
                          viewStateMap_.put(viewName, formViewState);
                  }
                  return formViewState;
          }
  
          /**
           * Internal class used for keeping state information
           * during the life cycle of a form.
           * 
           * <p>Used only for session scoped forms
           */
          class FormViewState {
          private Map modelReferences_ = new HashMap();
  
                  FormViewState() {
          }
  
                  /**
                   * 
                   * @return Map of (String modelPropertyReference, String inputType) pairs 
                   */
                  Map getModelReferenceMap() {
                          return modelReferences_;
                  }
  
                  void addModelReferenceAndInputType(String modelPropertyReference,
                                             String inputType) {
              modelReferences_.put(modelPropertyReference, inputType);
                  }
  
                  void clear() {
                          modelReferences_.clear();
                  }
          }
  
          /** the set of violations the model commited during validation */
          private List violations_ = null;
  
          /** another view of the violations_ collection */
          private SortedSet violationsAsSortedSet_ = null;
  
          /** flag allowing control over automatic validation on populate() */
          private boolean autoValidateEnabled_ = true;
  
          /** The data model this form encapsulates */
          private Object model_ = null;
  
          /** The list of FormListeners */
          private Set formListeners_ = new HashSet();
  
          /** 
           * The unique identifier for this form. Used when form is stored in request 
           * or session for reference by other components
       *
           * <p>
           * TODO: a centralized form registry would be helpful to prevent from id collision
           */
          private String id_ = null;
  
          /**
           * The JXPath context associated with the model
           * Used to traverse the model with XPath expressions
           */
          private JXPathContext jxcontext_ = null;
  
          /**
           * Used to validate the content of the model
           * at various phases
           *
           */
          private Validator validator_ = null;
  
          /**
           * Keeps a state information for
           * each form view that has been processed
           * 
           */
          private Map viewStateMap_ = new HashMap();
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/java/org/apache/cocoon/components/xmlform/FormListener.java
  
  Index: FormListener.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 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  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.components.xmlform;
  
  /**
   * <p>
   *  Defines events fired by a Form object 
   *  
   * </p>
   *
   *
   * @author Ivelin Ivanov, ivelin@apache.org
   * @version CVS $Id: FormListener.java,v 1.1 2003/04/25 08:34:57 stephan Exp $
   */
  public interface FormListener {
  
      /**
       * This method is called before 
       * the form is populated with request parameters.
       *
       * Semantically similar to that of the 
       * ActionForm.reset() in Struts
       *
       * Can be used for clearing checkbox fields,
       * because the browser will not send them when
       * not checked.
       *
       * This method does nothing by default
       * Subclasses should override it to implement custom logic
       *
       */
      void reset(Form form);
      
      /**
       * filters custom request parameter
       * not refering to the model
       */
      boolean filterRequestParameter(Form form, String parameterName);
  
  }
  
  
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/java/org/apache/cocoon/samples/xmlform/UsageFeedbackAction.java
  
  Index: UsageFeedbackAction.java
  ===================================================================
  /*
   * $Revision: 1.1 $
   * $Date: 2003/04/25 08:34:57 $
   *
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   *
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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 based on software copyright (c) 2001, Plotnix, Inc,
   * <http://www.plotnix.com/>.
   * For more information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.cocoon.samples.xmlform;
  
  import java.util.Map;
  import org.apache.cocoon.acting.AbstractXMLFormAction;
  
  /**
   * This action implements a REST web service
   *
   * @author Ivelin Ivanov <iv...@apache.org>
   * @version CVS $Id: UsageFeedbackAction.java,v 1.1 2003/04/25 08:34:57 stephan Exp $
   */
  public class UsageFeedbackAction
    extends AbstractXMLFormAction
  {
  
    // Web Service Response names
    final String SERVICE_RESPONSE_OK = "ok";
    final String SERVICE_RESPONSE_ERROR = "error";
  
  
    public Map perform ()
    {
  
      // When form-view is not provided,
      // only data format validation is performed during population
      // but not consequetive data content validation (i.e. no Schematron validation)
      // Therefore, we will validate "manually"
      getForm().validate();
      
      if ( getForm().getViolations () != null )
      {
        return page( SERVICE_RESPONSE_ERROR );
      }
      else
      {
        return page( SERVICE_RESPONSE_OK );
      }
  
    }
  
  }
  
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/java/org/apache/cocoon/samples/xmlform/UserBean.java
  
  Index: UserBean.java
  ===================================================================
  package org.apache.cocoon.samples.xmlform;
  
  import org.apache.avalon.framework.CascadingRuntimeException;
  import org.w3c.dom.*;
  
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Set;
  
  /**
   *
   * A sample domain object used as a Form model.
   * Notice that it has mixed content: 
   * JavaBean properties and 
   * DOM Nodes, which are handled correctly by the
   * framework when referenced via XPath.
   *
   * @version CVS $Id: UserBean.java,v 1.1 2003/04/25 08:34:57 stephan Exp $
   */
  public class UserBean
  {
    private String fname = "Donald";
    private String lname = "Duck";
    private String email = "donald_duck@disneyland.com";
    private int age = 5;
    private int count = 1;
    private short numInstalls = 1; 
    private String liveUrl = "http://";
    private boolean publish = true;
    private List favorites = new ArrayList();
    private List roles = new ArrayList();
    private String hobbies[];
    private HashMap allHobbies;
    private String notes = "<your notes here>";
    
    private boolean hidden = false; 
    
    private Node system;
  
    public UserBean ()
    {
      initDomNode();
      initRoles();
      initFavorites();
      initHobbies();
    }
  
    public String getFirstName() {
      return fname;
    }
    
    public void setFirstName(String newName) {
      fname = newName;
    }
  
    public String getLastName() {
      return lname;
    }
    
    public void setLastName(String newName) {
      lname = newName;
    }
  
    public String getEmail() {
      return email;
    }
  
    public void setEmail(String newEmail) {
      email = newEmail;
    }
  
  
    public String getLiveUrl() {
      return liveUrl;
    }
  
    public void setLiveUrl( String newUrl ) {
      liveUrl = newUrl;
    }
  
    public int getAge() 
      {
      return age;
      }
    
    public void setAge( int newAge ) 
      {
      age = newAge;
      }
    
  
    public short getNumber() 
      {
      return numInstalls;
      }
    
    public void setNumber( short num ) 
      {
      numInstalls = num;
      }
    
    public boolean getPublish() 
      {
      return publish;
      }
    
    public void setPublish( boolean newPublish ) 
      {
      publish = newPublish;
      }
    
    
     public Node getSystem() 
        {
        return system;
       }
  
      public void setSystem( Node newSystem ) 
        {
        system = newSystem;
       }
  
     public boolean getHidden() 
        {
        return hidden;
       }
  
      public void setHidden( boolean newHidden ) 
        {
        hidden = newHidden;
       }
  
    public int getCount() {
      return count;
    }
  
    public void incrementCount() {
      count++;
    }
  
    public void initDomNode()
    {
      DOMImplementation impl;
      try
      {
        // Find the implementation
        DocumentBuilderFactory factory 
         = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(false);
        factory.setValidating ( false );
        DocumentBuilder builder = factory.newDocumentBuilder();
        impl = builder.getDOMImplementation();
      }
      catch (Exception ex)
      {
        throw new CascadingRuntimeException("Failed to initialize DOM factory.", ex);
      }
  
      // initialize system as dom node
      Document doc = impl.createDocument( null, "XMLForm_Wizard_System_Node", null);
      Node rootElement = doc.getDocumentElement();
  
      Node os = doc.createElement ( "os" );
      Text text = doc.createTextNode( "Linux" );
      os.appendChild(text);
      rootElement.appendChild( os );
  
      Node processor = doc.createElement ( "processor" );
      text = doc.createTextNode( "p4" );
      processor.appendChild(text);
      rootElement.appendChild( processor );
  
      Attr ram = doc.createAttribute ( "ram" );
      ram.setValue ( "512" );
      NamedNodeMap nmap = rootElement.getAttributes();
      nmap.setNamedItem ( ram );
  
      Node servletEngine = doc.createElement ( "servletEngine" );
      text = doc.createTextNode( "Tomcat" );
      servletEngine.appendChild(text);
      rootElement.appendChild( servletEngine );
  
      Node javaVersion = doc.createElement ( "javaVersion" );
      text = doc.createTextNode( "1.3" );
      javaVersion.appendChild(text);
      rootElement.appendChild( javaVersion );
  
      system = rootElement;
  
    }
    
    public List getRole()
    {
      return roles;
    }
    
    public void setRole( List newRoles )
    {
      roles = newRoles;
    }
    
    public String[] getHobby()
    {
      return hobbies;
    }
    
    public void setHobby( String[] newHobbies )
    {
      hobbies = newHobbies;
    }
  
    public Set getAllHobbies()
    {
      return allHobbies.entrySet();
    }
    
    public List getFavorite()
    {
      return favorites;
    }
    
    public void setFavorite( List newFavorites )
    {
      favorites = newFavorites;
    }
    
    public String getNotes()
    {
      return notes;
    }
    
    public void setNotes( String newNotes )
    {
      notes = newNotes;
    }
    
    public void initRoles()
    {
      roles = new ArrayList();
    }
    
    
    public void initHobbies()
    {
      hobbies = new String[] {"swim", "movies", "ski", "gym", "soccer"};
      
      // initialize the reference list of all hobbies
      allHobbies = new HashMap();
      allHobbies.put( "swim", "Swimming" );
      allHobbies.put( "gym", "Body Building" );
      allHobbies.put( "ski", "Skiing" );
      allHobbies.put( "run", "Running" );
      allHobbies.put( "football", "Football" );
      allHobbies.put( "read", "Reading" );
      allHobbies.put( "write", "Writing" );
      allHobbies.put( "soccer", "Soccer" );
      allHobbies.put( "blog", "Blogging" );
    }
    
    
    public void initFavorites()
    {
      favorites.add( "http://cocoon.apache.org" );
      favorites.add( "http://jakarta.apache.org" );
      favorites.add( "http://www.google.com" );
      favorites.add( "http://www.slashdot.org" );
      favorites.add( "http://www.yahoo.com" );
    }
    
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/java/org/apache/cocoon/samples/xmlform/WizardAction.java
  
  Index: WizardAction.java
  ===================================================================
  /* 
   * $Revision: 1.1 $
   * $Date: 2003/04/25 08:34:57 $
   *
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   *
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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 based on software copyright (c) 2001, Plotnix, Inc,
   * <http://www.plotnix.com/>.
   * For more information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.cocoon.samples.xmlform;
  
  import org.apache.cocoon.acting.AbstractXMLFormAction;
  import org.apache.cocoon.components.xmlform.Form;
  import org.apache.cocoon.components.xmlform.FormListener;
  
  import java.util.Map;
  
  /**
   * This action demonstrates
   * a relatively complex form handling scenario.
   *
   * @author Ivelin Ivanov <iv...@apache.org>
   * @version CVS $Id: WizardAction.java,v 1.1 2003/04/25 08:34:57 stephan Exp $
   */
  public class WizardAction
    extends AbstractXMLFormAction
    implements FormListener
  {
  
    // different form views
    // participating in the wizard
    final String VIEW_START = "start";
    final String VIEW_USERID = "userIdentity";
    final String VIEW_DEPLOYMENT = "deployment";
    final String VIEW_SYSTEM = "system";
    final String VIEW_CONFIRM = "confirm";
    final String VIEW_END = "end";
  
    // action commands used in the wizard
    final String CMD_START = "start";
    final String CMD_NEXT = "next";
    final String CMD_PREV = "prev";
  
    /**
     * The first callback method which is called
     * when an action is invoked.
     *
     * It is called before population and validation. 
     *
     *
     * @return null if the Action is prepared to continue - the normal case.
     * an objectModel map which will be immediately returned by the action.
     *
     * This method is a good place to handle buttons with Cancel
     * kind of semantics. For example
     * <pre>if getCommand().equals("Cancel") return page("input");</pre>
     *
     */
    protected Map prepare()
    { 
  
      // following is navigation logic for the GUI version
      if ( getCommand() == null )
        {
          // initial link
          return page( VIEW_START );
        }
      else if ( getCommand().equals( CMD_START ) )
      {
        // reset workflow state if necessary
      
        // remove old form      
        Form.remove( getObjectModel(), getFormId() );
        
        // create new form
        getForm();
  
        return page( VIEW_USERID );
      }
      // safe lookup, side effects free
      else if ( Form.lookup ( getObjectModel(), getFormId() ) == null)
        {
          // session expired
          return page( VIEW_START );
        }
  
  
      // nothing special
      // continue with form population;
      return super.PREPARE_RESULT_CONTINUE;
    }
  
  
    /**
     * Invoked after form population
     * 
     * Responsible for implementing the state machine 
     * of the flow control processing 
     * a single form page or a form wizard.
     *
     * Semanticly similar to Struts Action.perform()
     *
     * Take appropriate action based on the command
     *
     */
    public Map perform ()
    {
  
      // get the actual model which this Form encapsulates
      // and apply additional buziness logic to the model
      UserBean  jBean = (UserBean) getForm().getModel();
      jBean.incrementCount();
  
      // set the page flow control parameter
      // according to the validation result
      if ( getCommand().equals( CMD_NEXT ) &&
        getForm().getViolations () != null )
      {
        // errors, back to the same page
        return page( getFormView() );
      }
      else
      {
        // validation passed
        // continue with flow control
  
        // clear validation left overs in case the user
        // did not press the Next button
        getForm().clearViolations();
  
        // get the user submitted command (through a submit button)
        String command = getCommand();
        // get the form view which was submitted
        String formView = getFormView();
  
        // apply state machine (flow control) rules
        if ( formView.equals ( VIEW_USERID ) )
        {
          if ( command.equals( CMD_NEXT ) )
          {
            return page( VIEW_DEPLOYMENT );
          }
        }
        else if ( formView.equals ( VIEW_DEPLOYMENT ) )
        {
          if ( command.equals( CMD_NEXT ) )
          {
            return page( VIEW_SYSTEM );
          }
          else if( command.equals( CMD_PREV ) )
            return page( VIEW_USERID );
        }
        else if ( formView.equals ( VIEW_SYSTEM ) )
        {
          if ( command.equals( CMD_NEXT ) )
          {
            return page(  VIEW_CONFIRM );
          }
          else if( command.equals( CMD_PREV ) )
            return page( VIEW_DEPLOYMENT );
        }
        else if ( formView.equals ( VIEW_CONFIRM ) )
        {
          if ( command.equals( CMD_NEXT ) )
          {
            Form.remove( getObjectModel(), getFormId() );
            return page( VIEW_END );
          }
          else if( command.equals( CMD_PREV ) )
            return page( VIEW_SYSTEM );
        }
      }
  
      // should never reach this statement
      return page( VIEW_START );
  
    }
  
  
  
  
  
    /**
     *
     * FormListener callback
     * called in the beginning of Form.populate()
     * before population starts.
     *
     * This is the place to intialize the model for this request.
     * 
     * This method should not handle unchecked check boxes
     * when the form is session scope, which is the most common case.
     * It should only do so, if the form is request scoped.
     *
     */
    public void reset( Form form )
    {
      // nothing to do in this case
      // unchecked check boxes are handled by the framework !
      return;
    }
  
  
    /**
     * FormListener callback
     *
     * Invoked during Form.populate();
     *
     * It is invoked before a request parameter is mapped to
     * an attribute of the form model.
     *
     * It is appropriate to use this method for filtering
     * custom request parameters which do not reference
     * the model.
     *
     * Another appropriate use of this method is for graceful filtering of invalid
     * values, in case that knowledge of the system state or
     * other circumstainces make the standard validation
     * insufficient. For example if a registering user choses a username which
     * is already taken - the check requires database transaction, which is
     * beyond the scope of document validating schemas.
     * Of course customized Validators can be implemented to do
     * this kind of domain specific validation
     * instead of using this method.
     *
     *
     * @return false if the request parameter should not be filtered.
     * true otherwise.
     */
    public boolean filterRequestParameter (Form form, String parameterName)
    {
      // in this example we do not expect "custom" parameters
      return false;
    }
  
  
  
  }
  
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/java/org/apache/cocoon/transformation/XMLFormTransformer.java
  
  Index: XMLFormTransformer.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 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  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.cocoon.transformation;
  
  import java.io.IOException;
  import java.lang.reflect.Array;
  import java.util.Collection;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.SortedSet;
  import java.util.Stack;
  
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.components.validation.Violation;
  import org.apache.cocoon.components.xmlform.Form;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.xml.dom.DOMStreamer;
  import org.w3c.dom.DocumentFragment;
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.AttributesImpl;
  import org.apache.cocoon.components.flow.WebContinuation;
  import org.apache.cocoon.environment.Environment;
  
  /**
   * Transforms a document with XMLForm
   * elements into a document in the same namespace,
   * but with populated values for the XPath references
   * to the form's model attributes
   *
   * @author Ivelin Ivanov <iv...@apache.org>, June 2002
   * @author Andrew Timberlake <an...@timberlake.co.za>, June 2002
   * @author Michael Ratliff, mratliff@collegenet.com <mr...@collegenet.com>, May 2002
   * @author Torsten Curdt <tc...@dff.st>, March 2002
   * @author Simon Price <pr...@bristol.ac.uk>, September 2002
   * @version CVS $Id: XMLFormTransformer.java,v 1.1 2003/04/25 08:34:58 stephan Exp $
   */
  public class XMLFormTransformer extends AbstractSAXTransformer
  {
  
    // TODO: implements CacheableProcessingComponent {
  
    public final static String NS = "http://xml.apache.org/cocoon/xmlform/2002";
    private final static String NS_PREFIX = "xf";
    public final static Attributes NOATTR = new AttributesImpl();
    private final static String XMLNS_PREFIX = "xmlns";
  
    /**
     * The main tag in the XMLForm namespace
     * almost all other tags have to appear within the form tag
     * The id attribute refers to a xmlform.Form object
     * available in the current Request or Session
     *
     * &lt;form id="form-feedback">
     *  &lt;output ref="user/age"/>
     *  &lt;textbox ref="user/name"/>
     * &lt;/form>
     */
    public final static String TAG_FORM = "form";
    public final static String TAG_FORM_ATTR_ID = "id";
    public final static String TAG_FORM_ATTR_VIEW = "view";
  
    /**
     * the only tag which can be used outside of the form tag
     * with reference to the form id,
     * &lt;output ref="user/age" id="form-feedback"/>
     */
    public final static String TAG_OUTPUT = "output";
    public final static String TAG_OUTPUT_ATTR_FORM = TAG_FORM;
  
    /**
     * can be used directly under the form tag
     * to enlist all field violations or
     * within a field tag to enlist only the violations for the field.
     * <br>
     * <pre>
     * &lt;form id="form-feedback">
     *  &lt;violations/>
     *  &lt;textbox ref="user/name">
     *    &lt;violations/>
     *  &lt;/textbox>
     * &lt;/form>
     * </pre>
     *
     * When used under the forms tag it is transformed to a set of:
     * <br>
     * &lt;violation ref="user/age">Age must be a positive number &lt;/violation>
     * <br>
     * and when used within a field it is transformed to a set of:
     * <br>
     * &lt;violation>Age must be a positive number &lt;/violation>
     * <br>
     * The only difference is that the ref tag is used in the first case,
     * while in the second it is omited.
     *
     */
    public final static String TAG_INSERTVIOLATIONS = "violations";
  
    /** the name of the elements which replace the violations tag */
    public final static String TAG_VIOLATION = "violation";
  
    /** action buttons */
    public final static String TAG_SUBMIT = "submit";
    public final static String TAG_CANCEL = "cancel";
    public final static String TAG_RESET = "reset";
  
    public final static String TAG_CAPTION = "caption";
    public final static String TAG_HINT = "hint";
    public final static String TAG_HELP = "help";
    public final static String TAG_TEXTBOX = "textbox";
    public final static String TAG_TEXTAREA = "textarea";
    public final static String TAG_PASSWORD = "password";
    public final static String TAG_SELECTBOOLEAN = "selectBoolean";
    public final static String TAG_SELECTONE = "selectOne";
    public final static String TAG_SELECTMANY = "selectMany";
    public final static String TAG_ITEMSET = "itemset";
    public final static String TAG_ITEM = "item";
    public final static String TAG_VALUE = "value";
    public final static String TAG_HIDDEN = "hidden";
     
    /**
     * grouping tag
     *
     * <pre>
     *  <group ref="address">
     *   <caption>Shipping Address</caption>
     *     <input ref="line_1">
     *       <caption>Address line 1</caption>
     *     </input>
     *     <input ref="line_2">
     *       <caption>Address line 2</caption>
     *     </input>
     *     <input ref="postcode">
     *       <caption>Postcode</caption>
     *     </input>
     * </group>
     * </pre>
     *
     *
     */
    public final static String TAG_GROUP = "group";
  
    /**
     *  repeat tag
     *
     *  <repeat nodeset="/cart/items/item">
     *    <input ref="." .../><html:br/>
     *  </repeat>
     *
     *
     */
  
    public final static String TAG_REPEAT = "repeat";
  
  
    /**
     * this attribute is used within the
     * <code>repeat</code> tag
     * to represent an XPath node set selector from
     * the underlying xmlform model.
     */
    public final static String TAG_REPEAT_ATTR_NODESET = "nodeset";
  
    /**
     * The current fully expanded reference
     * in the form model.
     *
     */
    private String cannonicalRef = null;
  
    /**
     * Tracks the current repeat tag depth,
     * when there is one in scope
     */
    private int repeatTagDepth = -1;
  
    /**
     * The nodeset selector string of the
     * currently processed repeat tag (if any)
     */
    private String nodeset = null;
  
  
    /**
     * The flag annotating if the transformer is
     * working on a repeat tag
     */
    private boolean isRecording = false;
  
  
    /**
     * Flag to let us know if the transformer is working
     * on a hidden tag
     */
    private boolean isHiddenTag = false;
  
    /**
     * Flag to let us know that the hidden element contains
     * a value child element.
     */
    private boolean hasHiddenTagValue = false;
  
    
    /**
     * the ref value of the current field
     * used by the violations tag
     */
    private Stack refStack = null;
  
    /**
     * Tracks the current depth of the XML tree
     */
    private int currentTagDepth = 0;
  
  
    /**
     * this attribute is used within all field tags
     * to represent an XPath reference to the attribute of
     * the underlying model.
     */
    public final static String TAG_COMMON_ATTR_REF = "ref";
  
  
    /** the stack of nested forms. 
     * Although nested form tags are not allowed, it is possible 
     * that an output tag (with reference to another form) might be nested within a form tag.
     * In this case elements under the output tag (like caption) can reference properties
     * of the form of the enclosing output tag.
     */
  
    private Stack formStack = null;
    
    
    /**
     * Since form elements cannot be nested,
     * at most one possible value for the current form view is available.
     */
    private String currentFormView = null;
  
  
    private Object value_;
  
  
  
      /**
       * Setup the next round.
       * The instance variables are initialised.
       * @param resolver The current SourceResolver
       * @param objectModel The objectModel of the environment.
       * @param src The value of the src attribute in the sitemap.
       * @param par The parameters from the sitemap.
       */
    public void setup(
                        SourceResolver resolver,
                        Map                   objectModel,
                        String                 src,
                        Parameters        par)
      throws ProcessingException,
             SAXException,
             IOException
      {
        super.setup( resolver, objectModel, src, par );
        if (request == null)
        {
          getLogger().debug("no request object");
          throw new ProcessingException("no request object");
        }
  
        // set the XMLForm namespace as the one
        // this transformer is interested to work on
        namespaceURI = NS;
  
        // init tracking parameters
        formStack = new Stack();
        cannonicalRef = "";
        refStack = new Stack();
        currentTagDepth = 0;
        repeatTagDepth = -1;
        isRecording = false;
        nodeset = null;
    }
  
  
      /**
       *  Recycle this component.
       */
      public void recycle() 
      {
        // init tracking parameters
        formStack = null;
        cannonicalRef = null;
        refStack = null;
        currentTagDepth = 0;
        repeatTagDepth = -1;
        isRecording = false;
        nodeset = null;
  
        super.recycle();
      }
  
  
      /**
       * Start processing elements of our namespace.
       * This hook is invoked for each sax event with our namespace.
       * @param uri The namespace of the element.
       * @param name The local name of the element.
       * @param raw The qualified name of the element.
       * @param attr The attributes of the element.
       */
      public void startTransformingElement(String uri,
                                           String name,
                                           String raw,
                                           Attributes attributes )
      throws ProcessingException, IOException, SAXException
      {
        try
        {
          // avoid endless loop for elements in our namespace
          // when outputting the elements themselves
          this.ignoreHooksCount = 1;
  
          if (this.getLogger().isDebugEnabled() == true)
          {
              this.getLogger().debug("BEGIN startTransformingElement uri=" + uri + ", name=" + name + ", raw=" + raw + ", attr=" + attributes + ")");
          }
  
        // top level element in our namespace
        // set an xmlns:xf="XMLForm namespace..." attribute
        // to explicitely define the prefix to namespace binding
        if (currentTagDepth == 0)
        {
          AttributesImpl atts;
          if (attributes == null || attributes.getLength() == 0) {
              atts = new AttributesImpl();
          } else {
              atts = new AttributesImpl(attributes);
          }
          //atts.addAttribute( null, NS_PREFIX, XMLNS_PREFIX + ":" + NS_PREFIX, "CDATA", NS);
          attributes = atts;
        }
  
        // track the tree depth
        ++currentTagDepth;
  
        // if within a repeat tag, keep recording
        // when recording, nothing is actively processed
        if (isRecording)
        {
          // just record the SAX event
          super.startElement( uri, name, raw, attributes);
        }
       // when a new repeat tag is discovered
       // start recording
       // the repeat will be unrolled after the repeat tag ends
       else if (TAG_REPEAT.equals( name ))
       {
         repeatTagDepth = currentTagDepth;
         isRecording = true;
  
        // get the nodeset selector string
        nodeset = attributes.getValue(TAG_REPEAT_ATTR_NODESET);
  
        if (nodeset == null)
        {
           throw new SAXException( name + " element should provide a '" + TAG_REPEAT_ATTR_NODESET + "' attribute" );
        }
  
         // open the repeat tag in the output document
         super.startElement( uri, name, raw, attributes);
         // and start recording its content
         startRecording();
       }
       // when a new itemset tag (used within select) is discovered
       // start recording
       // the itemset will be unrolled after the tag ends
       // The difference with the repeat tag is that itemset is
       // unrolled in multiple item tags.
       else if ( TAG_ITEMSET.equals( name ) )
       {
         repeatTagDepth = currentTagDepth;
         isRecording = true;
  
        // get the nodeset selector string
        nodeset = attributes.getValue(TAG_REPEAT_ATTR_NODESET);
  
        if (nodeset == null)
        {
           throw new SAXException( name + " element should provide a '" + TAG_REPEAT_ATTR_NODESET + "' attribute" );
        }
  
         // start recording its content
         startRecording();
       }
      else // if not a repeat tag
      {
          // if this tag has a "ref" attribute, then
          // add its value to the refStack
          String aref = attributes.getValue( TAG_COMMON_ATTR_REF );
          if ( aref != null )
          {
            // put on top of the ref stack the full ref
            // append the new ref to the last stack top if not referencing the root
            if ( !refStack.isEmpty() )
            {
            	// this is a nested reference 
    		      cannonicalRef = aref.startsWith ("/") ? aref : ( ((Entry) refStack.peek()).getValue() + "/" + aref );
            }
            else 
            {
              // top level reference
              cannonicalRef = aref;
            }
            Entry entry = new Entry( new Integer(currentTagDepth), cannonicalRef);
            refStack.push( entry );
  
            // replace the ref attribute's value(path) with its full cannonical form
            AttributesImpl atts = new AttributesImpl( attributes );
            int refIdx = atts.getIndex ( TAG_COMMON_ATTR_REF );
            atts.setValue ( refIdx, cannonicalRef );
            attributes = atts;
          }
  
          // match tag name and apply transformation logic
          if (TAG_FORM.equals(name))
          {
            startElementForm( uri, name, raw, attributes );
          }
          else if ( TAG_OUTPUT.equals(name) )
          {
            startElementOutput( uri, name, raw, attributes );
          } // end if TAG_OUTPUT
          else if (TAG_INSERTVIOLATIONS.equals(name))
            {
              startElementViolations( uri, name, raw, attributes );
            } // end if TAG_INSERTVIOLATIONS
            
          // if we're within a xf:hidden element
          // and a value sub-element has been provided 
          // in the markup, then it will be left
          // unchanged. Otherwise we will 
          // render the value of the referenced model
          // attribute
          else if ( isHiddenTag && TAG_VALUE.equals( name ) )
          {
      			hasHiddenTagValue = true;
            super.startElement( uri, name, raw, attributes);
          }
           
          // if we are not within an enclosing form
          // then we can't process the following nested tags
          else if (!formStack.isEmpty())
          {
  
            if (
                      TAG_TEXTBOX.equals(name) ||
                      TAG_TEXTAREA.equals(name) ||
                      TAG_PASSWORD.equals(name) ||
                      TAG_SELECTBOOLEAN.equals(name) ||
                      TAG_SELECTONE.equals(name) ||
                      TAG_SELECTMANY.equals(name)
               )
            {
              startElementInputField( uri, name, raw, attributes );
            }
            else if (
                      TAG_CAPTION.equals(name) ||
                      TAG_HINT.equals(name) ||
                      TAG_HELP.equals(name) ||
                      TAG_VALUE.equals(name) 
                     )
           {
             startElementWithOptionalRefAndSimpleContent( uri, name, raw, attributes );
           }
            else if (
  		   TAG_SUBMIT.equals(name) )
  	  {
  	      String continuation = attributes.getValue("continuation");
  	      if (continuation != null) {
  		  WebContinuation kont
  		      = (WebContinuation)((Environment)resolver).getAttribute("kont");
  		  if (kont != null) {
  		      int level = 0;
  		      if (continuation.equals("back")) {
  			  level = 3;
  		      }
  		      AttributesImpl impl = new AttributesImpl(attributes);
  		      int index = impl.getIndex("id");
  		      String id = impl.getValue(index);
  		      String kId = kont.getContinuation(level).getId();
  		      id = kId + ":"+id;
  		      if (index >= 0) {
  			  impl.setValue(index, id);
  		      } else {
  			  impl.addAttribute("", "id", "id", "", id);
  		      }
  		      attributes = impl;
  		  }
  	      } 
  	      super.startElement(uri, name, raw, attributes);
  	  }
            else if (
              TAG_CANCEL.equals(name) ||
              TAG_RESET.equals(name) ||
              TAG_ITEM.equals(name) 
              )
            {
              super.startElement(uri, name, raw, attributes);
            }
            else if (TAG_HIDDEN.equals(name))
            {
              // raise the flag that we're within a hidden element
              // since there are intricacies in 
              // handling the value sub-element
      			  isHiddenTag = true;
  		    	  startElementInputField( uri, name, raw, attributes );
            }          
            else
            {
                getLogger().error("pass through element [" + String.valueOf(name) + "]");
                super.startElement(uri, name, raw, attributes);
            }
          }
        } // end else (not a repeat tag)
      }
      finally
      {
        // reset ignore counter
        this.ignoreHooksCount = 0;
      }
  
  
      if (this.getLogger().isDebugEnabled() == true)
      {
            this.getLogger().debug("END startTransformingElement");
      }
    } // end of startTransformingElement
  
  
    protected void startElementForm(String uri, String name, String raw, Attributes attributes) throws SAXException
    {
      String id = attributes.getValue(TAG_FORM_ATTR_ID);
  
      // currently form elements cannot be nested
      if ( !formStack.isEmpty() )
      {
        String error = "Form nodes should not be nested ! Current form [id=" + formStack.peek() + "], nested form [id=" + String.valueOf(id) + "]";
        getLogger().error( error );
        throw new IllegalStateException( error );
      }
  
      super.startElement(uri, name, raw, attributes);
  
      // load up the referenced form
      Form currentForm =  Form.lookup( objectModel, id );
      
      // if the form wasn't found, we're in trouble
      if (currentForm == null)
      {
        String error = "Form is null [id=" + String.valueOf(id) + "]";
        getLogger().error( error );
        throw new IllegalStateException( error );
      };
      
      
      formStack.push( currentForm );
      
      // memorize the current form view
      // it will be needed when saving expected references to properties
      currentFormView = attributes.getValue(TAG_FORM_ATTR_VIEW);
      
      // clear previously saved form state for this view
      resetSavedModelReferences();
      
    } // end of startElementForm
  
  
  
    protected void startElementViolations(String uri, String name, String raw, Attributes attributes) throws SAXException
    {
  
        // we will either use the locally referenced form id
        // or the global id. At least one of the two must be available
        Form form = null;
        String formAttr = attributes.getValue( TAG_OUTPUT_ATTR_FORM );
        if (formAttr == null)
        {
          if ( formStack.isEmpty() )
          {
            throw new SAXException( "When used outside of a form tag, the output tag requires an '" + TAG_OUTPUT_ATTR_FORM + "' attribute" );
          }
          form = (Form) formStack.peek();
        }
        else
        {
          form = Form.lookup( objectModel, formAttr );
        }
  
        SortedSet violations = form.getViolationsAsSortedSet();
  
        // if there are no violations, there is nothing to show
        if (violations == null)  return;
  
  
        // if we're immediately under the form tag
        // and parent "ref" attribute is not available
        if ( refStack.isEmpty () )
        {
          for (Iterator it = violations.iterator(); it.hasNext();)
          {
            Violation violation = (Violation) it.next();
  
            // render <violation> tag
  
            // set the ref attribute
            AttributesImpl atts;
            if (attributes == null || attributes.getLength() == 0) {
                atts = new AttributesImpl();
            } else {
                atts = new AttributesImpl(attributes);
            }
            // atts.addAttribute( NS, TAG_COMMON_ATTR_REF, NS_PREFIX + ":" + TAG_COMMON_ATTR_REF, "CDATA", violation.getPath());
            atts.addAttribute( null, TAG_COMMON_ATTR_REF, TAG_COMMON_ATTR_REF, "CDATA", violation.getPath());
  
            // now start the element
            super.startElement(uri, TAG_VIOLATION, NS_PREFIX + ":" + TAG_VIOLATION, atts);
  
            // set message
            String vm = violation.getMessage();
            super.characters( vm.toCharArray(), 0, vm.length());
  
            super.endElement(uri, TAG_VIOLATION, NS_PREFIX + ":" + TAG_VIOLATION);
          }
        } // end if (currentRef_ == null)
        else
        {
          Entry entry = (Entry) refStack.peek ();
          String currentRef = (String) entry.getValue ();
          Violation v = new Violation();
          v.setPath( currentRef );
          Collection restViolations = violations.tailSet ( v );
          Iterator rviter = restViolations.iterator ();
          while ( rviter.hasNext () )
          {
            Violation nextViolation = (Violation) rviter.next ();
            // we're only interested in violations
            // with matching reference
            if ( !currentRef.equals (nextViolation.getPath () ) ) break;
  
            // render <violation> tag
            super.startElement(uri, TAG_VIOLATION, NS_PREFIX + ":" + TAG_VIOLATION, attributes );
            // set message
            String vm = nextViolation.getMessage();
            super.characters( vm.toCharArray(), 0, vm.length());
            super.endElement(uri, TAG_VIOLATION, NS_PREFIX + ":" + TAG_VIOLATION);
          }
        }
    } // end of startElementViolations
  
  
  
    /**
     * Since the ouput tag is the only one which can be used
     * outside of a form tag, it needs some special treatment
     *
     */
    protected void startElementOutput(String uri, String name, String raw, Attributes attributes)
      throws SAXException
    {
  
          // we will either use the locally referenced form id
          // or the global id. At least one of the two must be available
          Form form = null;
          String formAttr = attributes.getValue( TAG_OUTPUT_ATTR_FORM );
          if (formAttr == null)
          {
            if ( formStack.isEmpty() )
            {
              throw new SAXException( "When used outside of a form tag, the output tag requires an '" + TAG_OUTPUT_ATTR_FORM + "' attribute" );
            }
            form = (Form) formStack.peek();
          }
          else
          {
            form = Form.lookup( objectModel, formAttr );
          }
          formStack.push( form );
  
          startElementSimpleField( uri, name, raw, attributes );
  
    } // end of startElementOutput
  
  
    /**
     * 
     * Renders elements, which are used for input
     * 
     * TAG_TEXTBOX, TAG_TEXTAREA, TAG_PASSWORD, TAG_SELECTBOOLEAN, 
     * TAG_SELECTONE, TAG_SELECTMANY
     * 
     */
    protected void startElementInputField(String uri, String name, String raw, Attributes attributes )
      throws SAXException
    {
      startElementSimpleField( uri, name, raw, attributes );
      
      String ref = attributes.getValue(TAG_COMMON_ATTR_REF);
      if (ref == null)
      {
         throw new SAXException( name + " element should provide a '" + TAG_COMMON_ATTR_REF + "' attribute" );
      }
      saveModelReferenceForFormView( ref, name );
    }
   
  
    protected void startElementSimpleField(String uri, String name, String raw, Attributes attributes )
      throws SAXException
    {
        String ref = attributes.getValue(TAG_COMMON_ATTR_REF);
  
        if (ref == null)
        {
           throw new SAXException( name + " element should provide a '" + TAG_COMMON_ATTR_REF + "' attribute" );
        }
  
        if ( formStack.isEmpty() )
        {
           throw new SAXException( name + " element should be either nested within a form tag or provide a form attribute" );
        }
  
        Form form = getCurrentForm();
  
        getLogger().debug("[" + String.valueOf( name ) + "] getting value from form [id=" + form.getId() + ", ref=" + String.valueOf(ref) + "]");
  
        // retrieve current value of referenced property
        value_ = form.getValue( ref );
  
        // we will only forward the SAX event once we know
        // that the value of the tag is available
        super.startElement(uri, name, raw, attributes);
  
        getLogger().debug("Value of form [id=" + form.getId() + ", ref=" + String.valueOf(ref) + "] = [" + value_ + "]") ;
  
    	  // Only render value sub-elements
        // at this point
        // if this is not a xf:hidden element.
  	    if( !isHiddenTag ) renderValueSubElements();
       } // end of startElementSimpleField
  
  
    /**
     * Let the form wrapper know that this reference should be expected
     * when data is submitted by the client for the current form view.
     * The name of the XML tag is also saved to help the form populator 
     * find an appropriate default value when one is not provided in the http request.
     */
    protected void saveModelReferenceForFormView( String ref, String name )
    {
      // the xf:form/@view attribute is not mandatory
      // although it is strongly recommended
      if (currentFormView != null)
        {
        Form form = getCurrentForm();
        form.saveExpectedModelReferenceForView( currentFormView, ref, name );
        }
    }
  
    /**
     * When the transformer starts rendering a new form element
     * It needs to reset previously saved references for another 
     * transformation of the same view.
     */  
    protected void resetSavedModelReferences()
    {
      if ( currentFormView != null ) 
      {
        Form form = getCurrentForm();
        form.clearSavedModelReferences( currentFormView );
      }
      
    }
  
    /**
     * Used for elements which are not two directional.
     * They are displayed but cannot be used for submitting new values 
     * 
     * TAG_CAPTION, TAG_HINT, TAG_HELP, TAG_VALUE
     * 
     */
    protected void startElementWithOptionalRefAndSimpleContent(String uri, String name, String raw, Attributes attributes )
      throws SAXException
    {
        String ref = attributes.getValue(TAG_COMMON_ATTR_REF);
  
        if (ref == null) // ref attribute is not provided
        {
           super.startElement( uri, name, raw, attributes );
           return;
        }
  
        if ( formStack.isEmpty() )
        {
           throw new SAXException( name + " element should be either nested within a form tag or provide a form attribute" );
        }
  
        Form form = (Form) formStack.peek();
  
        getLogger().debug("[" + String.valueOf( name ) + "] getting value from form [id=" + form.getId() + ", ref=" + String.valueOf(ref) + "]");
  
        Object value = form.getValue( ref );
  
        // we will only forward the SAX event once we know
        // that the value of the tag is available
        super.startElement(uri, name, raw, attributes);
  
        getLogger().debug("Value of form [id=" + form.getId() + ", ref=" + String.valueOf(ref) + "] = [" + value_ + "]") ;
  
        // Now render the character data inside the tag
        String v = String.valueOf( value );
        super.characters(v.toCharArray(),0,v.length());      
      
    } // end of startElementSimpleFieldWithOptionalRef
   
  
  	/**
  	 * Renders one or more xf:value elements 
       * depending on whether _value is a
  	 * collection, array or not.
  	 *
  	 * @throws SAXException
  	 */
  	private void renderValueSubElements() throws SAXException
  	{
  		// render the value subelement(s)
  		if (value_ instanceof Collection)
  		{
  		  Iterator i=((Collection) value_).iterator();
  		  while (i.hasNext())
  		  {
  			renderValueSubElement( i.next() );
  		  }
  		}
  		else if ( value_ != null && value_.getClass().isArray () )
  		{
  		  int len = Array.getLength ( value_ );
  		  for (int i = 0; i < len; i++ )
  		  {
  			renderValueSubElement( Array.get ( value_, i ) );
  		  }
  		}
  		else
  		{
  		  renderValueSubElement( value_ );
  		}
  	}
  
   
    
    
    /**
     * Outputs a <xf:value> element.
     * Used when transforming XMLForm elements
     * with reference to the model
     *
     * @param vobj provides the text content
     * within the <xf:value> element
     *
     */
    protected void renderValueSubElement( Object vobj )
      throws SAXException
    {
      super.startElement( NS, "value", NS_PREFIX + ":" + "value", NOATTR);
        if (vobj != null)
        {
          String v = String.valueOf( vobj );
          super.characters(v.toCharArray(),0,v.length());
        }
        super.endElement( NS, "value", NS_PREFIX + ":" + "value" );
    }
  
      /**
       * Start processing elements of our namespace.
       * This hook is invoked for each sax event with our namespace.
       * @param uri The namespace of the element.
       * @param name The local name of the element.
       * @param raw The qualified name of the element.
       */
      public void endTransformingElement(
           String uri,
           String name,
           String raw)
      throws ProcessingException, IOException, SAXException
    {
      if (this.getLogger().isDebugEnabled() == true)
      {
          this.getLogger().debug("BEGIN endTransformingElement uri=" + uri + ", name=" + name + ", raw=" + raw + ")");
      }
  
  
      try
      {
          // avoid endless loop for elements in our namespace
          this.ignoreHooksCount = 1;
  
  
       // when the end of an active repeat tag is reached
       // stop recording, unroll the repeat tag content
       // for each node in the node set,
       // then close the repeat tag
       if ( (TAG_REPEAT.equals( name ) ) 
            && (repeatTagDepth == currentTagDepth))
       {
         isRecording = false;
         DocumentFragment docFragment = endRecording();
         unrollRepeatTag( docFragment );
         nodeset = null;
         // close the repeat tag
         super.endElement(uri, name, raw);
       }
       // similarly for an itemset tag
       else if ( (TAG_ITEMSET.equals( name )) 
            && (repeatTagDepth == currentTagDepth))
       {
         isRecording = false;
         DocumentFragment docFragment = endRecording();
         unrollItemSetTag( docFragment );
         nodeset = null;
       }
        // if within a repeat tag, keep recording
        // when recording, nothing is actively processed
       else  if (isRecording)
       {
          // just record the SAX event
          super.endElement(uri, name, raw);
       }
      else // if not a repeat tag
      {
  
          // keep the ref stack in synch with the tree navigation
          if ( !refStack.isEmpty () )
          {
            Entry entry = (Entry) refStack.peek();
            Integer refDepth = (Integer) entry.getKey ();
            if ( currentTagDepth <= refDepth.intValue () )
            {
              refStack.pop();
              cannonicalRef = refStack.isEmpty () ? "" : (String)( (Entry) (refStack.peek ()) ).getValue();
            }
          }
  
  
          if (TAG_INSERTVIOLATIONS.equals(name))
          {
            // all violations were rendered completely in the startElement method
          }
          else if (TAG_FORM.equals(name))
          {
            // pop currentForm from stack since we're getting out of its scope
            formStack.pop();
            super.endElement(uri, name, raw);
          }
          else if (
                  TAG_TEXTBOX.equals(name) ||
                  TAG_TEXTAREA.equals(name) ||
                  TAG_PASSWORD.equals(name) ||
                  TAG_SELECTBOOLEAN.equals(name) ||
                  TAG_SELECTONE.equals(name) ||
                  TAG_SELECTMANY.equals(name) ||
                  TAG_SUBMIT.equals(name) ||
                  TAG_CAPTION.equals( name ) ||
                  TAG_VALUE.equals( name ) ||
                  TAG_HINT.equals( name ) ||
                  TAG_HELP.equals( name ) 
                  )
          { 
            super.endElement(uri, name, raw);
          }
          else if ( TAG_OUTPUT.equals(name) )
          {
            formStack.pop();
            super.endElement(uri, name, raw);
          }
          
          else if (TAG_HIDDEN.equals(name))
          {
      			isHiddenTag = false;
      			hasHiddenTagValue = false;
            // if value sub-element was not 
            // provided in the markup
            // then render the value of the referenced
            // model attribute, like normally done
            // for other elements
            if(! hasHiddenTagValue)
      			{
      				renderValueSubElements();
      			}
              super.endElement(uri, name, raw);
           }
          else
          {
            getLogger().error("unknown element [" + String.valueOf(name) + "]");
            super.endElement(uri, name, raw);
          }
        } // else (not in a recording tag)
      }
      finally
      {
        // reset ignore hooks counter
        this.ignoreHooksCount = 0;
  
        // track the tree depth
        --currentTagDepth;
      }
  
      if (this.getLogger().isDebugEnabled() == true)
      {
        this.getLogger().debug("END endTransformingElement");
      }
  
    } // end of endTransformingElement
  
  
    /**
     * Unroll the repeat tag.
     * For each node in the repeat tag's nodeset selector result,
     * render a <code>group</code> tag with a <code>ref</code>
     * attribute which points to the location of the current node
     * in the nodeset. Within each <code>group</code> tag,
     * output the content of the repeat tag,
     * by resolving all form model references within nested xmlform tags,
     * relative to the <code>ref</code> attribute of the <code>group</code> element.
     *
     * @param docFragment the content of the repeat tag
     * @param nodeset the nodeset selector string
     */
    protected void unrollRepeatTag( DocumentFragment docFragment )
      throws SAXException
    {
      int oldIgnoreHooksCount = ignoreHooksCount;
      try
      {
        // reset ignore hooks counter
        this.ignoreHooksCount = 0;
        Form currentForm = (Form) formStack.peek();
        Collection locations = currentForm.locate( nodeset );
        Iterator iter = locations.iterator();
        // iterate over each node in the nodeset
        while ( iter.hasNext() )
        {
          String nextNodeLocation = (String) iter.next ();
  
          // set the ref attribute to point to the current node
          AttributesImpl atts = new AttributesImpl();
          atts.addAttribute( null, TAG_COMMON_ATTR_REF, TAG_COMMON_ATTR_REF, "CDATA", nextNodeLocation);
  
          super.startElement(NS, TAG_GROUP, NS_PREFIX + ":" + TAG_GROUP, atts);
          if (value_ != null)
          {
            // stream back the recorder repeat content
            DOMStreamer streamer = new DOMStreamer( this, this);
            streamer.stream( docFragment );
          }
  
          super.endElement( NS, TAG_GROUP, NS_PREFIX + ":" + TAG_GROUP );
  
        }
      }
      finally
      {
        ignoreHooksCount = oldIgnoreHooksCount;
      }
    } // unrollRepeatTag
  
  
  
  
    /**
     * Unroll the itemset tag.
     * For each node in the itemset tag's nodeset selector result,
     * render a <code>item</code> tag with a <code>ref</code>
     * attribute which points to the location of the current node
     * in the nodeset.
     * Within each <code>item</code> tag,
     * output the content of the itemset tag,
     * by resolving all model references within nested caption and value tags,
     * relative to the <code>ref</code> attribute of the <code>item</code> element.
     *
     * @param docFragment the content of the repeat tag
     * @param nodeset the nodeset selector string
     */
    protected void unrollItemSetTag( DocumentFragment docFragment )
      throws SAXException
    {
      int oldIgnoreHooksCount = ignoreHooksCount;
      try
      {
        // reset ignore hooks counter
        this.ignoreHooksCount = 0;
  
        Form currentForm = (Form) formStack.peek();
  
        Collection locations = currentForm.locate( nodeset );
        Iterator iter = locations.iterator();
        // iterate over each node in the nodeset
        while ( iter.hasNext() )
        {
          String nextNodeLocation = (String) iter.next ();
  
          // set the ref attribute to point to the current node
          AttributesImpl atts = new AttributesImpl();
          atts.addAttribute( null, TAG_COMMON_ATTR_REF, TAG_COMMON_ATTR_REF, "CDATA", nextNodeLocation);
  
          super.startElement(NS, TAG_ITEM, NS_PREFIX + ":" + TAG_ITEM, atts);
          if (value_ != null)
          {
            // stream back the recorder repeat content
            DOMStreamer streamer = new DOMStreamer( this, this);
            streamer.stream( docFragment );
          }
  
          super.endElement( NS, TAG_ITEM, NS_PREFIX + ":" + TAG_ITEM );
  
        }
      }
      finally
      {
        ignoreHooksCount = oldIgnoreHooksCount;
      }
    } // unrollItemSetTag
  
  
    protected Form getCurrentForm()
    {
      return (Form) formStack.peek();    
    }
  
  
      /**
       * refStack entry.
       */
    private static class Entry implements Map.Entry {
      Object key;
      Object value;
  
      Entry(Object key, Object value) {
          this.key = key;
          this.value = value;
      }
  
      // Map.Entry Ops
  
      public Object getKey() {
          return key;
      }
  
      public Object getValue() {
          return value;
      }
  
      public Object setValue(Object value) {
          Object oldValue = this.value;
          this.value = value;
          return oldValue;
      }
  
      public boolean equals(Object o) {
          if (!(o instanceof Map.Entry))
          return false;
          Map.Entry e = (Map.Entry)o;
  
          return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&
             (value==null ? e.getValue()==null : value.equals(e.getValue()));
      }
  
      public int hashCode() {
          return getKey().hashCode () ^ (value==null ? 0 : value.hashCode());
      }
  
      public String toString() {
          return key+"="+value;
      }
  }
  
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/lib/.cvsignore
  
  	<<Binary file>>
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/overview.html
  
  Index: overview.html
  ===================================================================
  <html>
  <head>
   <title>Demonstration of XMLForm</title>
  </head>
  <body bgcolor="#FFFFFF">
  <h1>Demonstration of XMLForm</h1>
  
  <p>
  See the Apache Cocoon documentation for an overview: 
  <a href="../../docs/howto/xmlform-wizard/howto-xmlform-wizard.html">Cocoon XMLForm How-To</a>
  </p>
  
  <p>
  The Cocoon XMLForm handling framework provides
  <a href="http://www.w3.org/MarkUp/Forms/">W3C XForms</a> based markup,
  <a href="http://www.ascc.net/xml/resource/schematron/schematron.html">Schematron</a>
  instance validation, and automated binding to
  <a href="http://java.sun.com/products/javabeans/">JavaBeans</a> and
  <a href="http://www.w3.org/DOM/">DOM</a> instances.
  <br/>
  It also allows easy deployment of 
  <a href="http://www.xfront.com/REST.html">REST</a>
  style 
  <a href="http://www.w3.org/2002/ws/">Web Services</a>
  , with maximum code reuse between human facing and machine interface.
  </p>
  
  
  <p>
  <b><u>Application</u></b>
  <br>
  Here is the <a href="wizard">XMLForm Cocoon Usage Feedback Wizard Demonstration</a>
  </p>
  
  <p>
  <b><u>Flow-based Application</u></b>
  <br>
  Here is the <a href="flow">Flow-based XMLForm Cocoon Usage Feedback Wizard Demonstration</a>
  </p>
  
  <p>
  <b><u>Web Service</u></b>
  <br>
  Here is the 
  <a  href="UsageFeedbackService/WSDL">
    WSDL descriptor
  </a> 
  for the same application, exposed as a Web Service (REST style).
  <br/>
  
  Click 
  <a href="UsageFeedbackService?firstName=good&amp;publish=false">here for a valid sample request</a>
   <br/>
  
  Click 
  <a href="UsageFeedbackService?firstName=bad&amp;publish=false">here for an invalid sample request</a>.
  </p>
  
  </body>
  </html>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/sitemap.xmap
  
  Index: sitemap.xmap
  ===================================================================
  <?xml version="1.0"?>
  <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
  
    <!-- =========================== Components ================================ -->
    <map:components> 
      <map:transformers default="xslt">
        <map:transformer name="xmlform" src="org.apache.cocoon.transformation.XMLFormTransformer" logger="xmlform.sitemap.transformer"/>
      </map:transformers>
      <map:actions>
        <map:action name="WizardAction" src="org.apache.cocoon.samples.xmlform.WizardAction"  logger="xmlform.sitemap.action.wizard"/>
        <map:action name="UsageFeedbackAction" src="org.apache.cocoon.samples.xmlform.UsageFeedbackAction"  logger="xmlform.sitemap.action.UsageFeedback"/>
      </map:actions>
      <map:flow-interpreters default="JavaScript"/>
      <map:serializers default="html"/>
      <map:matchers default="wildcard"/>
    </map:components>
  
  
  <!-- =========================== Views =================================== -->
  
  <!--
    The debug view can be used to output an intermediate 
    snapshot of the pipeline.
    Pass cocoon-view=debug as a URL parameter to see
    the pipeline output produced by the transofrmer
    labeled "debug". You can move the label to different
    transformers to understand each processing
    stage better.
  -->
  <map:views>
    <map:view name="debug" from-label="debug">
      <map:serialize type="xml"/>
    </map:view>
    <map:view name="xml" from-label="xml">
      <map:serialize type="xml"/>
    </map:view>
  </map:views>
  
    <!-- =========================== Resources ================================= -->
  
    <map:resources>
    </map:resources>
  
    <!-- =========================== Pipelines ================================= -->
      <map:flow language="JavaScript">
        <map:script src="flow/feedbackWizard.js"/>
      </map:flow>
  
    <map:pipelines> 
    
      <map:pipeline>
  
        <map:match pattern="">
          <map:redirect-to uri="overview.html"/>
        </map:match>
  
        <map:match pattern="overview.html">
         <map:read src="overview.html"/>
        </map:match>
  
      </map:pipeline>
  
    
      <map:pipeline>
  
        <!-- A non-trivial interactive example - Cocoon Usage Feedback Wizard -->
        <map:match pattern="wizard*">
          <map:act type="WizardAction">
  
            <!-- XMLForm parameters for the AbstractXMLFormAction -->
            <map:parameter name="xmlform-validator-schema-ns" value="http://www.ascc.net/xml/schematron"/>
            <map:parameter name="xmlform-validator-schema" value="schematron/wizard-xmlform-sch-report.xml"/>
            <map:parameter name="xmlform-id" value="form-feedback"/>
            <map:parameter name="xmlform-scope" value="session"/>
            <map:parameter name="xmlform-model" value="org.apache.cocoon.samples.xmlform.UserBean"/>
  
         
  	      <!-- original XMLForm document -->
  	      <map:generate src="wizard/{page}.xml"/>
  	      
  	      <!-- populating the document with model instance data -->
  	      <map:transform type="xmlform"  label="xml"/>
  	
  	      <!-- personalizing the look and feel of the form controls  -->
  	      <map:transform type="xalan" src="stylesheets/wizard2html.xsl" />
  	
  	      <!-- Transforming the XMLForm controls to HTML controls -->
  	      <map:transform src="context://stylesheets/system/xmlform2html.xslt" />
  	      
  	      <!-- sending the HTML back to the browser -->
  	      <map:serialize type="html" label="debug"/>
  	      
          </map:act>
        </map:match>  
      </map:pipeline>
      
      <map:pipeline>
  
        <!-- The same application, exposed as a Web Service (REST style) -->
        
        
        <!-- WSDL descriptor -->
        <map:match pattern="UsageFeedbackService/WSDL">
            <map:generate src="webservice/usagefeedback.wsdl"/>
            <map:serialize type="xml"/>
  	  </map:match>
        
        
        <!-- The REST resource (or Web Service) -->
        <map:match pattern="UsageFeedbackService">
          <map:act type="UsageFeedbackAction">
  
            <!-- Parameters for the AbstractXMLFormAction -->
            <map:parameter name="xmlform-validator-schema-ns" value="http://www.ascc.net/xml/schematron"/>
            <map:parameter name="xmlform-validator-schema" value="schematron/wizard-xmlform-sch-report.xml"/>
            <map:parameter name="xmlform-id" value="form-feedback"/>
            <map:parameter name="xmlform-scope" value="request"/>
            <map:parameter name="xmlform-model" value="org.apache.cocoon.samples.xmlform.UserBean"/>
  
            <!-- Response content and transformation logic -->
            <map:generate src="webservice/{page}.xml"/>
            <map:transform type="xmlform"  label="debug, xml"/>
            <map:serialize type="xml"/>
          </map:act>
        </map:match>  
      </map:pipeline>
      
      
    
      <map:pipeline>
  
        <!-- The same application, using the Cocoon Flow Layer -->
  
        <map:match pattern="flow">
          <map:call function="xmlForm">
            <map:parameter name="xmlform-function" value="feedbackWizard"/>
  	  <map:parameter name="xmlform-id" value="form-feedback"/>
            <map:parameter name="xmlform-validator-schema-ns" value="http://www.ascc.net/xml/schematron"/>
            <map:parameter name="xmlform-validator-schema" value="schematron/wizard-xmlform-sch-report.xml"/>
            <map:parameter name="xmlform-scope" value="session"/>
          </map:call>
        </map:match>
  
        <map:match pattern="flow/*.xml">
  	      <!-- original XMLForm document -->
  	      <map:generate src="flow/{1}.xml"/>
  	      
  	      <!-- populating the document with model instance data -->
  	      <map:transform type="xmlform"  label="xml"/>
  	
  	      <!-- personalizing the look and feel of the form controls  -->
  	      <map:transform type="xalan" src="stylesheets/wizard2html.xsl" />
  	
  	      <!-- Transforming the XMLForm controls to HTML controls -->
  	      <map:transform src="context://stylesheets/system/xmlform2html.xslt" />
  	      
  	      <!-- sending the HTML back to the browser -->
  	      <map:serialize type="html" label="debug"/>
  	</map:match>	      
      </map:pipeline>
    </map:pipelines> 
    
  </map:sitemap>
  <!-- end of file -->
  
  
  
  
  
  
  
  
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/flow/confirm.xml
  
  Index: confirm.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
  
  	XMLForm instance document for the Cocoon Feedback Wizard.
  
   	author: Torsten Curdt, tcurdt@dff.st, March 2002
      author: Ivelin Ivanov, ivelin@apache.org, April 2002
      author: Simon Price <pr...@bristol.ac.uk>, September 2002
  
  -->
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
    <xf:form id="form-feedback" view="confirm" action="flow">
      <xf:caption>Confirm Input</xf:caption>
      <!-- from page1 -->
      <xf:output ref="firstName">
        <xf:caption>First Name</xf:caption>
      </xf:output>
      <xf:output ref="lastName">
        <xf:caption>Last Name</xf:caption>
      </xf:output>
      <xf:output ref="email">
        <xf:caption>Email</xf:caption>
      </xf:output>
      <xf:output ref="age">
        <xf:caption>Age</xf:caption>
        <xf:violations class="error"/>
      </xf:output>
      <xf:group ref="/">
        <xf:caption>Professional roles</xf:caption>
        <xf:repeat nodeset="role">
          <xf:output ref="."/>
        </xf:repeat>
      </xf:group>
      <xf:group ref="/">
        <xf:caption>Personal hobbies</xf:caption>
        <xf:repeat nodeset="hobby">
          <xf:output ref="."/>
        </xf:repeat>
      </xf:group>
      <xf:output ref="hidden">
        <xf:caption>Hidden attribute</xf:caption>
      </xf:output>
      <!-- from page2 -->
      <xf:output ref="number">
        <xf:caption>Number of installations</xf:caption>
      </xf:output>
      <xf:output ref="liveUrl">
        <xf:caption>Live URL</xf:caption>
      </xf:output>
      <xf:output ref="publish">
        <xf:caption>Publish URL</xf:caption>
      </xf:output>
      <!-- from page3 -->
      <xf:output ref="system/os">
        <xf:caption>OS</xf:caption>
      </xf:output>
      <xf:output ref="system/processor">
        <xf:caption>Processor</xf:caption>
      </xf:output>
      <xf:output ref="system/@ram">
        <xf:caption>RAM</xf:caption>
      </xf:output>
      <xf:output ref="system/servletEngine">
        <xf:caption>Servlet Engine</xf:caption>
      </xf:output>
      <xf:output ref="system/javaVersion">
        <xf:caption>Java Version</xf:caption>
      </xf:output>
      <xf:group ref="/" id="favorites_group">
        <xf:caption>Favorite web sites</xf:caption>
        <xf:repeat nodeset="favorite[position() &lt;= 3]" id="favorites">
          <xf:output ref="." class="info">
            <xf:caption>URL: </xf:caption>
          </xf:output>
        </xf:repeat>
      </xf:group>
      <!-- submit -->
      <xf:submit id="prev" continuation="back" class="button">
        <xf:caption>Prev</xf:caption>
        <xf:hint>Go to previous page</xf:hint>
      </xf:submit>
      <xf:submit id="next" continuation="forward" class="button">
        <xf:caption>Finish</xf:caption>
        <xf:hint>Finish the wizard</xf:hint>
      </xf:submit>
    </xf:form>
    <xf:output ref="count" id="show_count" form="form-feedback" class="info">
      <xf:caption>Visits Count</xf:caption>
    </xf:output>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/flow/deployment.xml
  
  Index: deployment.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
  
  	XMLForm instance document for the Cocoon Feedback Wizard.
  
   	author: Torsten Curdt, tcurdt@dff.st, March 2002
      author: Ivelin Ivanov, ivelin@apache.org, April 2002
      author: Simon Price <pr...@bristol.ac.uk>, September 2002
  
  -->
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
  	<xf:form id="form-feedback" view="deployment" action="flow" method="GET">
  		<xf:caption>Cocoon Deployment Information</xf:caption>
  		<error>
  			<xf:violations class="error"/>
  		</error>
  		<xf:textbox ref="/number">
  			<xf:caption>Number of deployments</xf:caption>
  			<xf:violations class="error"/>
  		</xf:textbox>
  		<xf:textbox ref="/liveUrl">
  			<xf:caption>Live URL</xf:caption>
  			<xf:help>You must enter a valid URL</xf:help>
  			<xf:violations class="error"/>
  		</xf:textbox>
  		<xf:selectBoolean ref="/publish">
  			<xf:caption>Publish</xf:caption>
  		</xf:selectBoolean>
  		<xf:group nodeset="" id="favorites_group">
  			<xf:caption>Favorite web sites</xf:caption>
  			<!-- 
                repeat is a very powerful iterator tag,
                because it iterates over a nodeset resulting from
                the 'nodeset' selector attribute.
                Very similar to xslt's for-each tag.
  
                In this case we iterate over the top three favorite
                web sites.
              -->
  			<xf:repeat nodeset="favorite[position() &lt;= 3]" id="favorites">
  				<xf:textbox ref="." class="info">
  					<xf:caption>URL:</xf:caption>
  				</xf:textbox>
  			</xf:repeat>
  		</xf:group>
  		<xf:submit id="prev" continuation="back" class="button">
  			<xf:caption>Prev</xf:caption>
  			<xf:hint>Go to previous page</xf:hint>
  		</xf:submit>
  		<xf:submit id="next" continuation="forward" class="button">
  			<xf:caption>Next</xf:caption>
  			<xf:hint>Go to next page</xf:hint>
  		</xf:submit>
  	</xf:form>
  	<xf:output ref="count" id="show_count" form="form-feedback" class="info">
  		<xf:caption>Visits Count</xf:caption>
  	</xf:output>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/flow/end.xml
  
  Index: end.xml
  ===================================================================
  <?xml version="1.0" ?>
  <document>
      <br/><br/><br/>
      <table align="center" width="50%" cellspacing="20">
          <tr>
              <td align="center">
                  <h1>
                      Congratulations, Wizard Complete!
                  </h1>
              </td>
          </tr>
  
          <tr>
              <td align="center" class="info">
                  <code>
                      Your feedback form was processed successfully.
                  </code>
              </td>
          </tr>
           
          <tr>
              <td align="center">
                  <h3>
                      <a href="">Go to home page.</a>
                  </h3>
              </td>
          </tr>
      </table>
  </document>
  
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/flow/feedbackWizard.js
  
  Index: feedbackWizard.js
  ===================================================================
  // XML Form Feedback Wizard Application
  
  cocoon.load("resource://org/apache/cocoon/components/flow/javascript/xmlForm.js");
  
  function feedbackWizard(xform) {
      var bean = {
          firstName: "Donald",
          lastName: "Duck",
          email: "donald_duck@disneyland.com",
          age: 5,
          number: 1,
          liveUrl: "http://",
          publish: true,
          hidden: true,
          count: 1,
          notes: "<your notes here>",
          favorite: ["http://xml.apache/org/cocoon", 
                     "http://jakarta.apache.org",
                     "http://www.google.com",
                     "http://www.slashdot.com",
                     "http://www.yahoo.com"],
          hobby: ["swim", "movies", "ski", "gym", "soccer"],
          allHobbies: [
              {
                  key: "swim",
                  value: "Swimming"
              },
              {
                  key: "gym", 
                  value: "Body Building"
              },
              {
                  key: "ski", 
                  value: "Skiing"
              },
              {
                  key: "run", 
                  value: "Running"
              },
              {  
                  key: "football", 
                  value: "Football"
              },
              {
                  key: "read",
                  value: "Reading" 
              },
              {
                  key: "write",
                  value: "Writing"
              },
              {
                  key: "soccer:",
                  value: "Soccer" 
              },
              {
                  key: "blog",
                  value: "Blogging" 
              }],
          role: ["Hacker", "Executive"],
          system: {
              os: "Unix",
              processor: "p4",
              ram: 512,
              servletEngine: "Tomcat",
              javaVersion: "1.3",
          }
      }
  
      xform.setModel(bean);
  
      xform.sendView("userIdentity", 
                     "flow/userIdentity.xml",
                     function(xform) {
          var bean = xform.getModel();
          print("I can also do validation in JavaScript");
          print("age = "+xform.getValue("number(/age)"));
          print("role = "+bean.role);
          if (bean.age > 40) {
              xform.addViolation("/age", "Hey, you're too old");
          }
      });
      print("handling user identity");
  
      xform.sendView("deployment", 
                     "flow/deployment.xml", 
                     function(xform) {
          var bean = xform.getModel();
          print("I can also do validation in JavaScript");
          if (bean.publish) {
              xform.addViolation("/publish", "Sorry, I won't let you publish");
          }
      });
      print("handling deployment");
  
      xform.sendView("system", "flow/system.xml");
      print("handling system");
  
      xform.sendView("confirm", "flow/confirm.xml");
      print("handling confirm");
  
      xform.finish("flow/end.xml");
      print("done");
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/flow/start.xml
  
  Index: start.xml
  ===================================================================
  <?xml version="1.0" ?>
  
  <document>
      <br/><br/><br/>
      <table align="center" width="50%" cellspacing="20">
          <tr>
              <td align="center">
                  <h1>
                      Welcome !
                  </h1>
              </td>
          </tr>
  
          <tr>
              <td align="center" class="info">
                  <p>
                  This wizard will collect feedback information
                  for the     
                  <a href="http://xml.apache.org/cocoon/">Apache Cocoon</a>
                  project.
                  </p>
                  <p>
                   See <a href="overview.html">overview</a> documentation.
                  </p>
              </td>
          </tr>
           
          <tr>
              <td align="center">
                  <h3>
                      <a href="flow?cocoon-action-start=true">
                          Start!
                      </a>
                  </h3>
              </td>
          </tr>
      </table>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/flow/system.xml
  
  Index: system.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
  
  	XMLForm instance document for the Cocoon Feedback Wizard.
  
   	author: Torsten Curdt, tcurdt@dff.st, March 2002
      author: Ivelin Ivanov, ivelin@apache.org, April 2002
      author: Simon Price <pr...@bristol.ac.uk>, September 2002
  
  -->
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
    <xf:form id="form-feedback" view="system" action="flow" method="GET">
      <xf:caption>System Information</xf:caption>
      <error>
        <xf:violations class="error"/>
      </error>
      <xf:group ref="/system">
        <xf:selectOne ref="os" selectUIType="radio">
          <xf:caption>OS</xf:caption>
          <xf:item id="unix">
            <xf:caption>Unix/Linux</xf:caption>
            <xf:value>Unix</xf:value>
          </xf:item>
          <xf:item id="mac">
            <xf:caption>Mac OS/X</xf:caption>
            <xf:value>Mac OS/X</xf:value>
          </xf:item>
          <xf:item id="win">
            <xf:caption>Windows 95/98/NT/2000/XP</xf:caption>
            <xf:value>Windows</xf:value>
          </xf:item>
          <xf:item id="other">
            <xf:caption>Other</xf:caption>
            <xf:value>Other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:selectOne ref="processor">
          <xf:caption>Processor</xf:caption>
          <xf:item>
            <xf:caption>AMD/Athlon</xf:caption>
            <xf:value>Athlon</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>AMD/Duron</xf:caption>
            <xf:value>Duron</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium Celeron</xf:caption>
            <xf:value>Celeron</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium III</xf:caption>
            <xf:value>p3</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium IV</xf:caption>
            <xf:value>p4</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:textbox ref="@ram">
          <xf:caption>RAM</xf:caption>
          <xf:violations class="error"/>
        </xf:textbox>
        <xf:selectOne ref="servletEngine">
          <xf:caption>Servlet Engine</xf:caption>
          <xf:item>
            <xf:caption>Tomcat</xf:caption>
            <xf:value>Tomcat</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Jetty</xf:caption>
            <xf:value>Jetty</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Resin</xf:caption>
            <xf:value>Resin</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Weblogic</xf:caption>
            <xf:value>weblogic</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>WebSphere</xf:caption>
            <xf:value>WebSphere</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:selectOne ref="javaVersion">
          <xf:caption>Java Version</xf:caption>
          <xf:item>
            <xf:caption>1.1</xf:caption>
            <xf:value>1.1</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.2</xf:caption>
            <xf:value>1.2</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.3</xf:caption>
            <xf:value>1.3</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.4</xf:caption>
            <xf:value>1.4</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>Other</xf:value>
          </xf:item>
        </xf:selectOne>
      </xf:group>
      <xf:submit id="prev" continuation="back" class="button">
        <xf:caption>Prev</xf:caption>
        <xf:hint>Go to previous page</xf:hint>
      </xf:submit>
      <xf:submit id="next" continuation="forward" class="button">
        <xf:caption>Next</xf:caption>
        <xf:hint>Go to next page</xf:hint>
      </xf:submit>
    </xf:form>
    <xf:output ref="count" id="show_count" form="form-feedback" class="info">
      <xf:caption>Visits Count</xf:caption>
    </xf:output>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/flow/userIdentity.xml
  
  Index: userIdentity.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
  
  	XMLForm instance document for the Cocoon Feedback Wizard.
  
      author: Ivelin Ivanov, ivelin@apache.org, July 2002
   	author: Torsten Curdt, tcurdt@dff.st, March 2002
      author: Simon Price <pr...@bristol.ac.uk>, September 2002
  
  -->
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
    <xf:form id="form-feedback" view="userIdentity" action="flow" method="GET">
      <xf:caption>Personal Information</xf:caption>
      <error>
        <xf:violations class="error"/>
      </error>
      <xf:textbox ref="/firstName">
        <xf:caption>First Name</xf:caption>
        <xf:violations class="error"/>
      </xf:textbox>
      <xf:textbox ref="/lastName">
        <xf:caption>Last Name</xf:caption>
        <xf:violations class="error"/>
      </xf:textbox>
      <xf:textbox ref="/email">
        <xf:caption>Email</xf:caption>
        <xf:help>Please check this carefully</xf:help>
        <xf:violations class="error"/>
      </xf:textbox>
      <xf:textbox ref="/age">
        <xf:caption>Age</xf:caption>
        <xf:violations class="error"/>
      </xf:textbox>
      <xf:selectMany ref="/role" selectUIType="listbox">
        <xf:caption>Professional roles</xf:caption>
        <xf:help>Select one or more</xf:help>
        <xf:item>
          <xf:caption>Geek</xf:caption>
          <xf:value>Geek</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Hacker</xf:caption>
          <xf:value>Hacker</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Student</xf:caption>
          <xf:value>Student</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>University Professor</xf:caption>
          <xf:value>University Professor</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Software Developer</xf:caption>
          <xf:value>Developer</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Technical Leader</xf:caption>
          <xf:value>Tech Lead</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Development Manager</xf:caption>
          <xf:value>Development Manager</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Executive</xf:caption>
          <xf:value>Executive</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Heir of the Apache tribe</xf:caption>
          <xf:value>Heir of the Apache tribe</xf:value>
        </xf:item>
      </xf:selectMany>
      <xf:selectMany ref="/hobby" selectUIType="checkbox">
        <xf:caption>Hobbies</xf:caption>
        <xf:itemset nodeset="allHobbies">
          <xf:caption ref="value"/>
          <xf:value ref="key"/>
        </xf:itemset>
      </xf:selectMany>
      <xf:textarea ref="notes" style="width:8cm; height:3cm">
        <xf:caption>Additional Notes</xf:caption>
      </xf:textarea>
      <!-- hidden model attribute -->
      <xf:hidden ref="hidden">
        <xf:value>true</xf:value>
      </xf:hidden>
      <xf:submit id="next" continuation="foward" class="button">
        <xf:caption>Next</xf:caption>
        <xf:hint>Go to next page</xf:hint>    
      </xf:submit>
    </xf:form>
    <xf:output ref="count" id="show_count" form="form-feedback" class="info">
      <xf:caption>Visits Count</xf:caption>
    </xf:output>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/schematron/wizard-xmlform-sch-report.xml
  
  Index: wizard-xmlform-sch-report.xml
  ===================================================================
  <?xml version="1.0" ?>
  <!--
  
  	Validating Schematron schema for the xmlform example wizard
    
    Schematron Schema language home page:
    http://www.ascc.net/xml/schematron/
    
  	Author: Ivelin Ivanov, ivelin@apache.org, April 2002
  
  -->
  <schema ns="http://xml.apache.cocoon/xmlform"
  	xmlns="http://www.ascc.net/xml/schematron">
  	<title>Schema for the XML Form example</title>
  	<phase id="userIdentity">
  		<p>For user identity information.</p>
  		<active pattern="user"/>
  	</phase>
  	<phase id="deployment">
  		<p>For deployment info page.</p>
  		<active pattern="dep" />
  	</phase>
  	<phase id="system">
  		<p>For system info page.</p>
  		<active pattern="sys" />
  	</phase>
  	<phase id="confirm">
  		<p>For final total validation and tracking some tricky problems.</p>
  		<active pattern="user" />
  		<active pattern="dep" />
  		<active pattern="sys" />
  	</phase>
  	<pattern name="User Info Validation Pattern" id="user">
  		<rule context="/firstName">
  			<assert test="string-length(.) &gt; 3">First name <anametag/> 
  				<wrapper>should</wrapper> be at least 4 characters.</assert>
  			<assert test="string-length(.) &lt; 20">First name should be less
  				than 20 characters.</assert>
  		</rule>
  		<rule context="/lastName">
  			<assert test="string-length(.) &gt; 3">Last name should be at least
  				4 characters.</assert>
  			<assert test="string-length(.) &lt; 20">Last name should be less
  				than 20 characters.</assert>
  		</rule>
  		<rule context="/email">
  			<assert test="contains( string(.),'@')">Email format is invalid.</assert>
  		</rule>
  		<rule context="/age">
  			<assert test="number() &gt; 0 and number(.) &lt; 200">Age should be
  				a reasonably big positive number.</assert>
  		</rule>
  	</pattern>
  	<pattern name="Deployment Information Validation Pattern" id="dep">
  		<rule context="/number">
  			<assert test="number() &gt; 0">The number of deployments must be
  				non-negative ( hopefully positive :-> ) .</assert>
  		</rule>
  		<rule context="/">
  			<!-- 
          If the site is to be published, then verify the URL.
          Note: This assertion demonstrates the unique ability of 
          Schematron to test document node dependencies.
          This is not possible to do with XML Schema and Relax NG.
         -->
  			<assert
  				test="not(string(publish) = 'true') or (starts-with(liveUrl, 'http://') and contains( string(liveUrl),'.') ) "
  				>The URL of the published site is invalid.</assert>
  		</rule>
  	</pattern>
  	<pattern name="System Information Validation Pattern" id="sys">
  		<rule context="/system/@ram">
  			<assert test="number() &gt; 0">The RAM value should be a positive
  				number, denoting the memory in MB (e.g. 128, 512, etc.).</assert>
  		</rule>
  	</pattern>
  </schema>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/stylesheets/wizard2html.xsl
  
  Index: wizard2html.xsl
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <!--
  	Cocoon Feedback Wizard XMLForm processing and displaying stylesheet.	
    
    This stylesheet merges an XMLForm document into 
    a final document. It includes other presentational
    parts of a page orthogonal to the xmlform.
  
    author: Ivelin Ivanov, ivelin@apache.org, May 2002
    author: Konstantin Piroumian <kp...@protek.com>, September 2002
    author: Simon Price <pr...@bristol.ac.uk>, September 2002
  
  -->
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  	xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002"
  	exclude-result-prefixes="xalan" >
  	<xsl:template match="document">
  		<html>
  			<head>
  				<title>XMLForm - Cocoon Feedback Wizard</title>
  				<style type="text/css"> <![CDATA[
                H1{font-family : sans-serif,Arial,Tahoma;color : white;background-color : #0086b2;} 
                BODY{font-family : sans-serif,Arial,Tahoma;color : black;background-color : white;} 
                B{color : white;background-color : blue;} 
                HR{color : #0086b2;}
                input { background-color: #FFFFFF; color: #000099; border: 1px solid #0000FF; }		
                table { background-color: #EEEEEE; color: #000099; font-size: x-small; border: 2px solid brown;}
                select { background-color: #FFFFFF; color: #000099 }
               .caption { line-height: 195% }
               .error { color: #FF0000; }	      
               .help { color: #0000FF; font-style: italic; }
               .invalid { color: #FF0000; border: 2px solid #FF0000; }
               .info { color: #0000FF; border: 1px solid #0000FF; }
               .repeat { border: 0px inset #999999;border: 1px inset #999999; width: 100%; }
               .group { border: 0px inset #999999;border: 0px inset #999999;  width: 100%; }
               .sub-table { border: none; }
               .button { background-color: #FFFFFF; color: #000099; border: 1px solid #666666; width: 70px; }
               .plaintable { border: 0px inset black;border: 0px inset black; width: 100%; }
                ]]> </style>
  			</head>
  			<body>
  				<xsl:apply-templates />
  			</body>
  		</html>
  	</xsl:template>
  	<xsl:template match="xf:form">
  		<xf:form method="post">
  			<xsl:copy-of select="@*" />
  			<br/>
  			<br/>
  			<br/>
  			<br/>
  			<table align="center" border="0">
  				<tr>
  					<td align="center" colspan="3">
  						<h1>
  							<xsl:value-of select="xf:caption"/>
  							<hr/>
  						</h1>
  					</td>
  				</tr>
  				<xsl:if test="count(error/xf:violation) > 0">
  					<tr>
  						<td align="left" colspan="3"
  							class="{error/xf:violation[1]/@class}">
  							<p>* There are [<b><xsl:value-of
  								select="count(error/xf:violation)"/></b>] 
  								errors. Please fix these errors and submit the
  								form again.</p>
  							<p>
  								<xsl:variable name="localViolations"
  									select=".//xf:*[ child::xf:violation ]"/>
  								<xsl:for-each select="error/xf:violation">
  									<xsl:variable name="eref" select="./@ref"/>
  									<xsl:if
  										test="count ($localViolations[ @ref=$eref ]) = 0"
  										>* <xsl:value-of select="." /> <br/> </xsl:if>
  								</xsl:for-each>
  							</p>
  							<p/>
  						</td>
  					</tr>
  				</xsl:if>
  				<xsl:for-each select="*[name() != 'xf:submit']">
  					<xsl:choose>
  						<xsl:when test="name() = 'error'"/>
  						<xsl:when test="name() = 'xf:caption'"/>
  						<xsl:when test="xf:*">
  							<xsl:apply-templates select="."/>
  						</xsl:when>
  						<xsl:otherwise>
  							<xsl:copy-of select="."/>
  						</xsl:otherwise>
  					</xsl:choose>
  				</xsl:for-each>
  				<tr>
  					<td align="center" colspan="3">
  						<xsl:for-each select="*[name() = 'xf:submit']">
  							<xsl:copy-of select="." />
  							<xsl:text>
  							</xsl:text>
  						</xsl:for-each>
  					</td>
  				</tr>
  			</table>
  		</xf:form>
  	</xsl:template>
  	<xsl:template match="xf:repeat">
  		<tr width="100%">
  			<td colspan="3" width="100%">
  				<table class="repeat">
  					<xsl:apply-templates select="*"/>
  				</table>
  			</td>
  		</tr>
  	</xsl:template>
  	<xsl:template match="xf:group">
  		<tr width="100%">
  			<td width="100%" colspan="2">
  				<table class="group" border="0">
  					<tr>
  						<td align="left">
  							<xsl:value-of select="xf:caption" />
  						</td>
  					</tr>
  					<xsl:apply-templates select="*"/>
  				</table>
  			</td>
  		</tr>
  	</xsl:template>
  	<xsl:template match="xf:output[@form]">
  		<div align="center">
  			<hr width="30%"/>
  			<br/>
  			<font size="-1">
  				<code> <xsl:value-of select="xf:caption" /> : <xsl:copy-of
  					select="." /> </code>
  			</font>
  			<br/>
  		</div>
  	</xsl:template>
  	<xsl:template match="xf:caption"/>
  	<xsl:template match="xf:*">
  		<tr>
  			<td align="left" valign="top">
  				<p class="caption">
  					<xsl:value-of select="xf:caption" />
  				</p>
  			</td>
  			<td align="left">
  				<table class="plaintable">
  					<tr>
  						<td align="left">
  							<xsl:copy-of select="." />
  						</td>
  						<xsl:if test="xf:violation">
  							<td align="left" class="{xf:violation[1]/@class}"
  								width="100%">
  								<xsl:for-each select="xf:violation">* 
  									<xsl:value-of select="." /> <br/> </xsl:for-each>
  							</td>
  						</xsl:if>
  					</tr>
  				</table>
  				<xsl:if test="xf:help">
  					<div class="help">
  						<xsl:value-of select="xf:help" />
  					</div>
  					<br />
  				</xsl:if>
  			</td>
  		</tr>
  	</xsl:template>
  	<xsl:template match="*">
  		<xsl:copy-of select="." />
  	</xsl:template>
  </xsl:stylesheet>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/webservice/error.xml
  
  Index: error.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
      XMLForm instance document for the Cocoon Usage Feedback Web Service.
      Author: Ivelin Ivanov, ivelin@apache.org, July 2002
  -->
  
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
    <error>
  	  <xf:violations form="form-feedback"/>
    </error>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/webservice/ok.xml
  
  Index: ok.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
      XMLForm instance document for the Cocoon Usage Feedback Web Service.
      Author: Ivelin Ivanov, ivelin@apache.org, July 2002
  -->
  
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
    <ok/>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/webservice/usagefeedback.wsdl
  
  Index: usagefeedback.wsdl
  ===================================================================
  <?xml version="1.0" encoding="utf-8"?>
  <!--
    WSDL Descriptor for the Cocoon Usage Feedback demo application exposed as a 
    Web Service (REST style).
  -->
  <definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:s0="http://www.cocoonhive.org/cocoonbook/2002/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://www.cocoonhive.org/cocoonbook/2002/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://schemas.xmlsoap.org/wsdl/
  http://schemas.xmlsoap.org/wsdl/">
  
    <!-- 
    The root WSDL element references a set of related standards 
    which you may not be familiar with.
    Do not worry, this most probably means that you do not need them yet.
  -->
  
    <!-- First we will describe the input parameters -->
    <message name="UsageFeedbackHttpGetIn">
    
      <!-- 
        Usually request parameters are of type xsd:string.
        However, a more restricting type can be used if the WSDL file is accompanied by
        an XML Schema document which enumerates the constraints.
        For example regular expression patterns, enumerations and number precision 
        can be enforced with custom types.
        -->
      <part name="firstName" type="xsd:string"/>
      <part name="lastName" type="xsd:string"/>
      <part name="email" type="xsd:string"/>
      <part name="age" type="xsd:nonNegativeInteger"/>
  
      <!-- 
      The "hobby" element is interesting in that it has one parameter name with multiple values. 
      It is well described with the XForms selectMany element, but it cannot be expressed with the current WSDL syntax. 
      Therefore, alternative avenues, like this inline remark, need to be used to annotate that the parameter type is a list of strings.   
      -->
      <part name="hobby" type="xsd:string"/>
      
      
      <!-- 
      Another feature not supported by WSDL directly is specifying optional input parameters for 
      HTTP GET binding.
      For example, the "favorite" parameters are not required by the UsageFeedback application.
      Again, this inline remark will communicate to the client this information.
      -->
      <part name="favorite[1]" type="xsd:string"/>
      <part name="favorite[2]" type="xsd:string"/>
      <part name="favorite[3]" type="xsd:string"/>
      
      <part name="hidden" type="xsd:boolean"/>
      <part name="number" type="xsd:string"/>
      <part name="liveUrl" type="xsd:string"/>
      <part name="publish" type="xsd:boolean"/>
      <part name="system/os" type="xsd:string"/>
      <part name="system/processor" type="xsd:string"/>
      <part name="system/@ram" type="xsd:nonNegativeInteger"/>
      <part name="system/servletEngine" type="xsd:string"/>
      <part name="system/javaVersion" type="xsd:string"/>
    </message>
    <!-- Next, we define the format of the output message -->
    <message name="UsageFeedbackHttpGetOut">
      <part name="Body" element="html:html"/>
    </message>
    <portType name="UsageFeedbackHttpGet">
      <operation name="UsageFeedback">
        <documentation>
          Returns document with OK or Error message in XML format.  
          If the operation succeeds the output document will be:
          <![CDATA[
          <document>
            <ok/>
          </document>
          ]]>
          Otherwise the response will look similar to:
          <![CDATA[
          <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
            <error>
              <xf:violation ref="/lastName">Last name should be at least 4 characters.</xf:violation> 
            </error>
          </document>
          ]]></documentation>
        <input message="s0:HelloWorldHttpGetIn"/>
        <output message="s0:HelloWorldHttpGetOut"/>
      </operation>
    </portType>
    
    <!-- 
      This WSDL file describes only one REST resource - WSUsageFeedback
      accesible via HttpGet.
      The complete URI of the resource is 
       http://localhost:8080/cocoon/samples/xmlform/wizard/UsageFeedbackService?firstName=...
    -->
    <binding name="UsageFeedbackHttpGet" type="s0:UsageFeedbackHttpGet">
      <http:binding verb="GET"/>
      <operation name="WSUsageFeedback">
        <http:operation location="/UsageFeedbackService"/>
        <input>
          <http:urlEncoded/>
        </input>
        <output>
          <mime:mimeXml part="Body"/>
        </output>
      </operation>
    </binding>
    <service name="UsageFeedback">
      <port name="UsageFeedbackHttpGet" binding="s0:UsageFeedbackHttpGet">
        <http:address location="http://localhost:8080/cocoon/samples/xmlform"/>
      </port>
    </service>
  </definitions>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/wizard/Readme.txt
  
  Index: Readme.txt
  ===================================================================
  This example use a more cleaner approach. The views are defined
  in XML and the stylesheet only renders into the desired media.
  Inserting of instance data will happen from within a transformer.
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/wizard/confirm.xml
  
  Index: confirm.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
  
  	XMLForm instance document for the Cocoon Feedback Wizard.
  
   	author: Torsten Curdt, tcurdt@dff.st, March 2002
      author: Ivelin Ivanov, ivelin@apache.org, April 2002
      author: Simon Price <pr...@bristol.ac.uk>, September 2002
  
  -->
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
    <xf:form id="form-feedback" view="confirm" action="wizard">
      <xf:caption>Confirm Input</xf:caption>
      <!-- from page1 -->
      <xf:output ref="firstName">
        <xf:caption>First Name</xf:caption>
      </xf:output>
      <xf:output ref="lastName">
        <xf:caption>Last Name</xf:caption>
      </xf:output>
      <xf:output ref="email">
        <xf:caption>Email</xf:caption>
      </xf:output>
      <xf:output ref="age">
        <xf:caption>Age</xf:caption>
        <xf:violations class="error"/>
      </xf:output>
      <xf:group ref="/">
        <xf:caption>Professional roles</xf:caption>
        <xf:repeat nodeset="role">
          <xf:output ref="."/>
        </xf:repeat>
      </xf:group>
      <xf:group ref="/">
        <xf:caption>Personal hobbies</xf:caption>
        <xf:repeat nodeset="hobby">
          <xf:output ref="."/>
        </xf:repeat>
      </xf:group>
      <xf:output ref="hidden">
        <xf:caption>Hidden attribute</xf:caption>
      </xf:output>
      <!-- from page2 -->
      <xf:output ref="number">
        <xf:caption>Number of installations</xf:caption>
      </xf:output>
      <xf:output ref="liveUrl">
        <xf:caption>Live URL</xf:caption>
      </xf:output>
      <xf:output ref="publish">
        <xf:caption>Publish URL</xf:caption>
      </xf:output>
      <!-- from page3 -->
      <xf:output ref="system/os">
        <xf:caption>OS</xf:caption>
      </xf:output>
      <xf:output ref="system/processor">
        <xf:caption>Processor</xf:caption>
      </xf:output>
      <xf:output ref="system/@ram">
        <xf:caption>RAM</xf:caption>
      </xf:output>
      <xf:output ref="system/servletEngine">
        <xf:caption>Servlet Engine</xf:caption>
      </xf:output>
      <xf:output ref="system/javaVersion">
        <xf:caption>Java Version</xf:caption>
      </xf:output>
      <xf:group ref="/" id="favorites_group">
        <xf:caption>Favorite web sites</xf:caption>
        <xf:repeat nodeset="favorite[position() &lt;= 3]" id="favorites">
          <xf:output ref="." class="info">
            <xf:caption>URL: </xf:caption>
          </xf:output>
        </xf:repeat>
      </xf:group>
      <!-- submit -->
      <xf:submit id="prev" class="button">
        <xf:caption>Prev</xf:caption>
        <xf:hint>Go to previous page</xf:hint>
      </xf:submit>
      <xf:submit id="next" class="button">
        <xf:caption>Finish</xf:caption>
        <xf:hint>Finish the wizard</xf:hint>
      </xf:submit>
    </xf:form>
    <xf:output ref="count" id="show_count" form="form-feedback" class="info">
      <xf:caption>Visits Count</xf:caption>
    </xf:output>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/wizard/deployment.xml
  
  Index: deployment.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
  
  	XMLForm instance document for the Cocoon Feedback Wizard.
  
   	author: Torsten Curdt, tcurdt@dff.st, March 2002
      author: Ivelin Ivanov, ivelin@apache.org, April 2002
      author: Simon Price <pr...@bristol.ac.uk>, September 2002
  
  -->
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
  	<xf:form id="form-feedback" view="deployment" action="wizard" method="GET">
  		<xf:caption>Cocoon Deployment Information</xf:caption>
  		<error>
  			<xf:violations class="error"/>
  		</error>
  		<xf:textbox ref="/number">
  			<xf:caption>Number of deployments</xf:caption>
  			<xf:violations class="error"/>
  		</xf:textbox>
  		<xf:textbox ref="/liveUrl">
  			<xf:caption>Live URL</xf:caption>
  			<xf:help>You must enter a valid URL</xf:help>
  			<xf:violations class="error"/>
  		</xf:textbox>
  		<xf:selectBoolean ref="/publish">
  			<xf:caption>Publish</xf:caption>
  		</xf:selectBoolean>
  		<xf:group nodeset="" id="favorites_group">
  			<xf:caption>Favorite web sites</xf:caption>
  			<!-- 
                repeat is a very powerful iterator tag,
                because it iterates over a nodeset resulting from
                the 'nodeset' selector attribute.
                Very similar to xslt's for-each tag.
  
                In this case we iterate over the top three favorite
                web sites.
              -->
  			<xf:repeat nodeset="favorite[position() &lt;= 3]" id="favorites">
  				<xf:textbox ref="." class="info">
  					<xf:caption>URL:</xf:caption>
  				</xf:textbox>
  			</xf:repeat>
  		</xf:group>
  		<xf:submit id="prev" class="button">
  			<xf:caption>Prev</xf:caption>
  			<xf:hint>Go to previous page</xf:hint>
  		</xf:submit>
  		<xf:submit id="next" class="button">
  			<xf:caption>Next</xf:caption>
  			<xf:hint>Go to next page</xf:hint>
  		</xf:submit>
  	</xf:form>
  	<xf:output ref="count" id="show_count" form="form-feedback" class="info">
  		<xf:caption>Visits Count</xf:caption>
  	</xf:output>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/wizard/end.xml
  
  Index: end.xml
  ===================================================================
  <?xml version="1.0" ?>
  <document>
      <br/><br/><br/>
      <table align="center" width="50%" cellspacing="20">
          <tr>
              <td align="center">
                  <h1>
                      Congratulations, Wizard Complete!
                  </h1>
              </td>
          </tr>
  
          <tr>
              <td align="center" class="info">
                  <code>
                      Your feedback form was processed successfully.
                  </code>
              </td>
          </tr>
           
          <tr>
              <td align="center">
                  <h3>
                      <a href="wizard">Go to home page.</a>
                  </h3>
              </td>
          </tr>
      </table>
  </document>
  
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/wizard/start.xml
  
  Index: start.xml
  ===================================================================
  <?xml version="1.0" ?>
  
  <document>
      <br/><br/><br/>
      <table align="center" width="50%" cellspacing="20">
          <tr>
              <td align="center">
                  <h1>
                      Welcome !
                  </h1>
              </td>
          </tr>
  
          <tr>
              <td align="center" class="info">
                  <p>
                  This wizard will collect feedback information
                  for the     
                  <a href="http://cocoon.apache.org/">Apache Cocoon</a>
                  project.
                  </p>
                  <p>
                   See <a href="overview.html">overview</a> documentation.
                  </p>
              </td>
          </tr>
           
          <tr>
              <td align="center">
                  <h3>
                      <a href="wizard?cocoon-action-start=true">
                          Start!
                      </a>
                  </h3>
              </td>
          </tr>
      </table>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/wizard/system.xml
  
  Index: system.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
  
  	XMLForm instance document for the Cocoon Feedback Wizard.
  
   	author: Torsten Curdt, tcurdt@dff.st, March 2002
      author: Ivelin Ivanov, ivelin@apache.org, April 2002
      author: Simon Price <pr...@bristol.ac.uk>, September 2002
  
  -->
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
    <xf:form id="form-feedback" view="system" action="wizard" method="GET">
      <xf:caption>System Information</xf:caption>
      <error>
        <xf:violations class="error"/>
      </error>
      <xf:group ref="/system">
        <xf:selectOne ref="os" selectUIType="radio">
          <xf:caption>OS</xf:caption>
          <xf:item id="unix">
            <xf:caption>Unix/Linux</xf:caption>
            <xf:value>Unix</xf:value>
          </xf:item>
          <xf:item id="mac">
            <xf:caption>Mac OS/X</xf:caption>
            <xf:value>Mac OS/X</xf:value>
          </xf:item>
          <xf:item id="win">
            <xf:caption>Windows 95/98/NT/2000/XP</xf:caption>
            <xf:value>Windows</xf:value>
          </xf:item>
          <xf:item id="other">
            <xf:caption>Other</xf:caption>
            <xf:value>Other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:selectOne ref="processor">
          <xf:caption>Processor</xf:caption>
          <xf:item>
            <xf:caption>AMD/Athlon</xf:caption>
            <xf:value>Athlon</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>AMD/Duron</xf:caption>
            <xf:value>Duron</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium Celeron</xf:caption>
            <xf:value>Celeron</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium III</xf:caption>
            <xf:value>p3</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium IV</xf:caption>
            <xf:value>p4</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:textbox ref="@ram">
          <xf:caption>RAM</xf:caption>
          <xf:violations class="error"/>
        </xf:textbox>
        <xf:selectOne ref="servletEngine">
          <xf:caption>Servlet Engine</xf:caption>
          <xf:item>
            <xf:caption>Tomcat</xf:caption>
            <xf:value>Tomcat</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Jetty</xf:caption>
            <xf:value>Jetty</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Resin</xf:caption>
            <xf:value>Resin</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Weblogic</xf:caption>
            <xf:value>weblogic</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>WebSphere</xf:caption>
            <xf:value>WebSphere</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:selectOne ref="javaVersion">
          <xf:caption>Java Version</xf:caption>
          <xf:item>
            <xf:caption>1.1</xf:caption>
            <xf:value>1.1</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.2</xf:caption>
            <xf:value>1.2</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.3</xf:caption>
            <xf:value>1.3</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.4</xf:caption>
            <xf:value>1.4</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>Other</xf:value>
          </xf:item>
        </xf:selectOne>
      </xf:group>
      <xf:submit id="prev" class="button">
        <xf:caption>Prev</xf:caption>
        <xf:hint>Go to previous page</xf:hint>
      </xf:submit>
      <xf:submit id="next" class="button">
        <xf:caption>Next</xf:caption>
        <xf:hint>Go to next page</xf:hint>
      </xf:submit>
    </xf:form>
    <xf:output ref="count" id="show_count" form="form-feedback" class="info">
      <xf:caption>Visits Count</xf:caption>
    </xf:output>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/samples/wizard/userIdentity.xml
  
  Index: userIdentity.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
  
  	XMLForm instance document for the Cocoon Feedback Wizard.
  
      author: Ivelin Ivanov, ivelin@apache.org, July 2002
   	author: Torsten Curdt, tcurdt@dff.st, March 2002
      author: Simon Price <pr...@bristol.ac.uk>, September 2002
  
  -->
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
    <xf:form id="form-feedback" view="userIdentity" action="wizard" method="GET">
      <xf:caption>Personal Information</xf:caption>
      <error>
        <xf:violations class="error"/>
      </error>
      <xf:textbox ref="/firstName">
        <xf:caption>First Name</xf:caption>
        <xf:violations class="error"/>
      </xf:textbox>
      <xf:textbox ref="/lastName">
        <xf:caption>Last Name</xf:caption>
        <xf:violations class="error"/>
      </xf:textbox>
      <xf:textbox ref="/email">
        <xf:caption>Email</xf:caption>
        <xf:help>Please check this carefully</xf:help>
        <xf:violations class="error"/>
      </xf:textbox>
      <xf:textbox ref="/age">
        <xf:caption>Age</xf:caption>
        <xf:violations class="error"/>
      </xf:textbox>
      <xf:selectMany ref="/role" selectUIType="listbox">
        <xf:caption>Professional roles</xf:caption>
        <xf:help>Select one or more</xf:help>
        <xf:item>
          <xf:caption>Geek</xf:caption>
          <xf:value>Geek</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Hacker</xf:caption>
          <xf:value>Hacker</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Student</xf:caption>
          <xf:value>Student</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>University Professor</xf:caption>
          <xf:value>University Professor</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Software Developer</xf:caption>
          <xf:value>Developer</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Technical Leader</xf:caption>
          <xf:value>Tech Lead</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Development Manager</xf:caption>
          <xf:value>Development Manager</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Executive</xf:caption>
          <xf:value>Executive</xf:value>
        </xf:item>
        <xf:item>
          <xf:caption>Heir of the Apache tribe</xf:caption>
          <xf:value>Heir of the Apache tribe</xf:value>
        </xf:item>
      </xf:selectMany>
      <xf:selectMany ref="/hobby" selectUIType="checkbox">
        <xf:caption>Hobbies</xf:caption>
        <xf:itemset nodeset="allHobbies">
          <xf:caption ref="value"/>
          <xf:value ref="key"/>
        </xf:itemset>
      </xf:selectMany>
      <xf:textarea ref="notes" style="width:8cm; height:3cm">
        <xf:caption>Additional Notes</xf:caption>
      </xf:textarea>
      <!-- hidden model attribute -->
      <xf:hidden ref="hidden">
        <xf:value>true</xf:value>
      </xf:hidden>
      <xf:submit id="next" class="button">
        <xf:caption>Next</xf:caption>
        <xf:hint>Go to next page</xf:hint>    
      </xf:submit>
    </xf:form>
    <xf:output ref="count" id="show_count" form="form-feedback" class="info">
      <xf:caption>Visits Count</xf:caption>
    </xf:output>
  </document>
  
  
  
  1.4       +11 -18    cocoon-2.1/src/test/org/apache/cocoon/components/validation/test/ZValidationTest.java
  
  Index: ZValidationTest.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/test/org/apache/cocoon/components/validation/test/ZValidationTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ZValidationTest.java	18 Mar 2003 01:01:27 -0000	1.3
  +++ ZValidationTest.java	25 Apr 2003 08:34:59 -0000	1.4
  @@ -56,8 +56,9 @@
   import org.apache.cocoon.components.validation.Violation;
   import org.xml.sax.InputSource;
   
  -import java.io.File;
  -import java.io.FileInputStream;
  +//import java.io.File;
  +//import java.io.FileInputStream;
  +import java.io.InputStream;
   import java.util.Iterator;
   import java.util.List;
   import java.util.ArrayList;
  @@ -82,13 +83,15 @@
   
       private void testSchema(String schema, String phase, List violations) {
           // use custom schema
  -        File file = new File(schema);
  -        if (!file.exists()) {
  +        //File file = new File(schema);
  +        InputStream in = getClass().getClassLoader().getResourceAsStream(schema);
  +        
  +        if (in==null) {
               fail("Error: schema file " + schema + " not found");
           }
   
           try {
  -            InputSource is = new InputSource(new FileInputStream(file));
  +            InputSource is = new InputSource(in);
               SchemaFactory schf =
                   SchemaFactory.lookup(SchemaFactory.NAMESPACE_SCHEMATRON);
               Schema sch = schf.compileSchema(is);
  @@ -168,8 +171,7 @@
           violation.setMessage("The counter should be > 0.");
           violations.add(violation);
   
  -        testSchema("src/test/org/apache/cocoon/components/validation/test/zxmlform-sch-report-test.xml",
  -                   null, violations);
  +        testSchema("org/apache/cocoon/components/validation/test/zxmlform-sch-report-test.xml", null, violations);
       }
   
       public void testSchema_PhaseNew() {
  @@ -186,15 +188,6 @@
           violation.setMessage("Animal name should be at least 4 characters.");
           violations.add(violation);
   
  -        testSchema("src/test/org/apache/cocoon/components/validation/test/zxmlform-sch-report-test.xml",
  -                   "New", violations);
  -    }
  -
  -    /**
  -     * The main program for this test.
  -     */
  -    public static void main(final String[] args) throws Exception {
  -        final String[] testCaseName = { ZValidationTest.class.getName() };
  -        TestRunner.main(testCaseName);
  +        testSchema("org/apache/cocoon/components/validation/test/zxmlform-sch-report-test.xml", "New", violations);
       }
   }
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/test/org/apache/cocoon/components/xmlform/TestBean.java
  
  Index: TestBean.java
  ===================================================================
  package org.apache.cocoon.components.xmlform;
  
  import org.apache.avalon.framework.CascadingRuntimeException;
  
  import org.w3c.dom.*;
  
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Set;
  
  /**
   *
   * A sample domain object used as a Form model.
   * Notice that it has mixed content: 
   * JavaBean properties and 
   * DOM Nodes, which are handled correctly by the
   * framework when referenced via XPath.
   *
   * @version CVS $Id: TestBean.java,v 1.1 2003/04/25 08:34:59 stephan Exp $
   */
  public class TestBean
  {
    private int count = 1;
    private short numInstalls = 1; 
    private String liveUrl = "http://";
    private boolean publish = true;
    private List favorites = new ArrayList();
    
    private boolean hidden = false; 
    
    private Node system;
  
    public TestBean() {
        initSystem();
        initFavorites();
    }
  
    public String getLiveUrl() {
        return liveUrl;
    }
  
    public void setLiveUrl( String newUrl ) {
        liveUrl = newUrl;
    }
  
    public short getNumber() {
        return numInstalls;
    }
    
    public void setNumber( short num ) {
        numInstalls = num;
    }
    
    public boolean getPublish() {
        return publish;
    }
    
    public void setPublish(boolean newPublish) {
        publish = newPublish;
    }
    
    
    public Node getSystem() {
        return system;
    }
  
    public void setSystem( Node newSystem ) {
        system = newSystem;
    }
  
    public boolean getHidden() {
        return hidden;
    }
   
    public void setHidden(boolean newHidden) {
        hidden = newHidden;
    }
  
    public int getCount() {
      return count;
    }
  
    public void incrementCount() {
      count++;
    }
  
    public List getFavorite()
    {
      return favorites;
    }
  
    public void setFavorite( List newFavorites )
    {
      favorites = newFavorites;
    }
  
    public void initSystem()
    {
      DOMImplementation impl;
      try
      {
        // Find the implementation
        DocumentBuilderFactory factory
         = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(false);
        factory.setValidating ( false );
        DocumentBuilder builder = factory.newDocumentBuilder();
        impl = builder.getDOMImplementation();
      }
      catch (Exception ex)
      {
        throw new CascadingRuntimeException("Failed to initialize DOM factory.", ex);
      }
  
      // initialize system as dom node
      Document doc = impl.createDocument( null, "XMLForm_Wizard_System_Node", null);
      Node rootElement = doc.getDocumentElement();
  
      Node os = doc.createElement ( "os" );
      Text text = doc.createTextNode( "Linux" );
      os.appendChild(text);
      rootElement.appendChild( os );
  
      Node processor = doc.createElement ( "processor" );
      text = doc.createTextNode( "p4" );
      processor.appendChild(text);
      rootElement.appendChild( processor );
  
      Attr ram = doc.createAttribute ( "ram" );
      ram.setValue ( "512" );
      NamedNodeMap nmap = rootElement.getAttributes();
      nmap.setNamedItem ( ram );
  
      Node servletEngine = doc.createElement ( "servletEngine" );
      text = doc.createTextNode( "Tomcat" );
      servletEngine.appendChild(text);
      rootElement.appendChild( servletEngine );
  
      Node javaVersion = doc.createElement ( "javaVersion" );
      text = doc.createTextNode( "1.3" );
      javaVersion.appendChild(text);
      rootElement.appendChild( javaVersion );
  
      system = rootElement;
  
    }
  
    public void initFavorites()
    {
      favorites.add( "http://cocoon.apache.org" );
      favorites.add( "http://jakarta.apache.org" );
      favorites.add( "http://www.google.com" );
      favorites.add( "http://www.slashdot.org" );
      favorites.add( "http://www.yahoo.com" );
    }
  
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/test/org/apache/cocoon/components/xmlform/TestXMLFormAction.java
  
  Index: TestXMLFormAction.java
  ===================================================================
  /* 
   * $Revision: 1.1 $
   * $Date: 2003/04/25 08:34:59 $
   *
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   *
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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 based on software copyright (c) 2001, Plotnix, Inc,
   * <http://www.plotnix.com/>.
   * For more information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.cocoon.components.xmlform;
  
  import org.apache.cocoon.acting.AbstractXMLFormAction;
  import org.apache.cocoon.components.xmlform.Form;
  import org.apache.cocoon.components.xmlform.FormListener;
  
  import java.util.Map;
  
  public class TestXMLFormAction extends AbstractXMLFormAction
    implements FormListener
  {
  
    // different form views
    // participating in the wizard
    final String VIEW_START = "start";
    final String VIEW_FIRST = "view1";
    final String VIEW_SECOND = "view2";
  
    // action commands used in the wizard
    final String CMD_START = "start";
    final String CMD_NEXT = "next";
    final String CMD_PREV = "prev";
  
    public Map prepare()
    { 
      if ( getCommand() == null )
          return page( VIEW_START );
      else if ( getCommand().equals( CMD_START ) )
        return page( VIEW_FIRST );
      else if ( Form.lookup ( getObjectModel(), getFormId() ) == null)
          return page( VIEW_START );
  
      return super.PREPARE_RESULT_CONTINUE;
    }
  
    public Map perform ()
    {
      TestBean model = (TestBean) getForm().getModel();
      model.incrementCount();
  
      if ((getCommand().equals(CMD_NEXT)) &&
          (getForm().getViolations () != null))
          return page( getFormView() );
      else
      {
        getForm().clearViolations();
  
        // get the user submitted command (through a submit button)
        String command = getCommand();
        // get the form view which was submitted
        String formView = getFormView();
  
        // apply state machine (flow control) rules
        if ( formView.equals ( VIEW_FIRST ) )
        {
          if (command.equals( CMD_NEXT ) )
            return page( VIEW_SECOND );
          else if( command.equals( CMD_PREV ) )
            return page( VIEW_START );
        }
        else if (formView.equals ( VIEW_SECOND ) )
        {
          if ( command.equals( CMD_NEXT ) )
            return page(VIEW_START);
          else if( command.equals( CMD_PREV ) )
            return page( VIEW_FIRST );
        }
      }
  
      return page( VIEW_START );
    }
  
    public void reset( Form form )
    {
      return;
    }
  
    public boolean filterRequestParameter (Form form, String parameterName)
    {
      return false;
    }
  }
  
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/test/org/apache/cocoon/components/xmlform/XMLFormTestCase.java
  
  Index: XMLFormTestCase.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 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  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.cocoon.components.xmlform;
  
  import java.util.Map;
  
  import org.apache.avalon.framework.parameters.Parameters;
  
  import org.apache.cocoon.AbstractCompositeTestCase;
  
  /**
   *
   *
   * @author <a href="mailto:stephan@apache.org">Stephan Michels </a>
   * @version CVS $Id: XMLFormTestCase.java,v 1.1 2003/04/25 08:34:59 stephan Exp $
   */
  public class XMLFormTestCase extends AbstractCompositeTestCase {
  
      public XMLFormTestCase(String name) {
          super(name);
      }
  
      public void testXMLForm() {
  
          getRequest().addParameter("cocoon-action-start", "true");
  
          Parameters parameters = new Parameters();
          parameters.setParameter("xmlform-validator-schema-ns", "http://www.ascc.net/xml/schematron");
          parameters.setParameter("xmlform-validator-schema", "resource://org/apache/cocoon/components/xmlform/testschema.xml");
          parameters.setParameter("xmlform-id", "testform");
          parameters.setParameter("xmlform-scope", "session");
          parameters.setParameter("xmlform-model", "org.apache.cocoon.components.xmlform.TestBean");
  
          Map result = act("xmlform", null, parameters);
  
          assertNotNull("Test if resource exists", result);
          assertEquals("Test for parameter", "view1", (String)result.get("page"));
  
          String testform1 = "resource://org/apache/cocoon/components/xmlform/testform1.xml";
          String testresult1 = "resource://org/apache/cocoon/components/xmlform/testresult1.xml";
  
          assertEqual(load(testresult1), transform("xmlform", testform1, new Parameters(), load(testform1)));
  
          // Second request
  
          getRequest().reset();
          getRequest().addParameter("cocoon-xmlform-view", "view1");
          getRequest().addParameter("/system/os", "Other");
          getRequest().addParameter("/system/processor", "p3");
          getRequest().addParameter("/system/@ram", "1024");
          getRequest().addParameter("/system/servletEngine", "Jetty");
          getRequest().addParameter("/system/javaVersion", "1.3");
          getRequest().addParameter("cocoon-action-next", "true");
  
          result = act("xmlform", null, parameters);
  
          assertNotNull("Test if resource exists", result);
          assertEquals("Test for parameter", "view2", (String)result.get("page"));
  
          String testform2 = "resource://org/apache/cocoon/components/xmlform/testform2.xml";
          String testresult2 = "resource://org/apache/cocoon/components/xmlform/testresult2.xml";
  
          //print(transform("xmlform", testform2, new Parameters(), load(testform2)));
  
          assertEqual(load(testresult2), transform("xmlform", testform1, new Parameters(), load(testform2)));
  
          // Third request
  
          getRequest().reset();
          getRequest().addParameter("cocoon-xmlform-view", "view2");
          getRequest().addParameter("/number", "3");
          getRequest().addParameter("/liveUrl", "http://xml.apache.org");
          getRequest().addParameter("/publish", "false"); 
          getRequest().addParameter("/favorite[1]/.", "http://cocoon.apache.org");
          getRequest().addParameter("/favorite[2]/.", "http://jakarta.apache.org");
          getRequest().addParameter("/favorite[3]/.", "http://www.google.com");
          getRequest().addParameter("cocoon-action-next", "true");
  
          result = act("xmlform", null, parameters);
  
          assertNotNull("Test if resource exists", result);
          assertEquals("Test for parameter", "start", (String)result.get("page"));
      }
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/test/org/apache/cocoon/components/xmlform/XMLFormTestCase.xtest
  
  Index: XMLFormTestCase.xtest
  ===================================================================
  <?xml version="1.0" ?>
  <testcase>
   <annotation>
    Test Cases: XMLForm
   </annotation>
  
   <logkit>
    <factories>
     <factory type="stream" class="org.apache.avalon.excalibur.logger.factory.StreamTargetFactory"/>
    </factories>
    <targets>
     <stream id="root">
      <stream>System.out</stream>
      <format type="extended">
       %7.7{priority} %5.5{time}   [%9.9{category}] (%{context}): %{message}\n%{throwable}
      </format>
     </stream>
    </targets>
    <categories>
     <category name="test" log-level="WARN">
      <log-target id-ref="root"/>
     </category>
    </categories>
   </logkit>
  
   <context/>
  
   <roles>
    <role name="org.apache.excalibur.xml.sax.SAXParser"
          shorthand="xml-parser"
          default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
  
    <role name="org.apache.excalibur.source.SourceFactorySelector"
          shorthand="source-factories"
          default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector"/>
  
    <role name="org.apache.excalibur.source.SourceResolver"
          shorthand="source-resolver"
          default-class="org.apache.excalibur.source.impl.SourceResolverImpl"/>
  
    <role name="org.apache.cocoon.acting.ActionSelector"
          shorthand="actions"
          default-class="org.apache.cocoon.sitemap.DefaultSitemapComponentSelector"/>
  
    <role name="org.apache.cocoon.transformation.TransformerSelector"
          shorthand="transformers"
          default-class="org.apache.cocoon.sitemap.DefaultSitemapComponentSelector"/>
   </roles>
  
   <components>
    <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
     <parameter name="validate" value="false"/>
     <parameter name="namespace-prefixes" value="false"/>
     <parameter name="stop-on-warning" value="true"/>
     <parameter name="stop-on-recoverable-error" value="true"/>
     <parameter name="reuse-parsers" value="false"/>
    </xml-parser>
  
    <source-factories>
     <component-instance class="org.apache.excalibur.source.impl.ResourceSourceFactory" name="resource"/>
     <component-instance class="org.apache.excalibur.source.impl.URLSourceFactory" name="*"/>
    </source-factories>
  
    <source-resolver class="org.apache.excalibur.source.impl.SourceResolverImpl"/>
  
    <actions logger="test">
     <component-instance class="org.apache.cocoon.components.xmlform.TestXMLFormAction" 
                         name="xmlform"/>
    </actions>
  
    <transformers logger="test">
     <component-instance class="org.apache.cocoon.transformation.XMLFormTransformer" 
                         name="xmlform"/>
    </transformers>
   </components>
  
  </testcase>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/test/org/apache/cocoon/components/xmlform/testform1.xml
  
  Index: testform1.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
  
  	XMLForm instance document for the Cocoon Feedback Wizard.
  
   	author: Torsten Curdt, tcurdt@dff.st, March 2002
      author: Ivelin Ivanov, ivelin@apache.org, April 2002
      author: Simon Price <pr...@bristol.ac.uk>, September 2002
  
  -->
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
    <xf:form id="testform" view="view1" action="wizard" method="GET">
      <xf:caption>System Information</xf:caption>
      <error>
        <xf:violations class="error"/>
      </error>
      <xf:group ref="/system">
        <xf:selectOne ref="os" selectUIType="radio">
          <xf:caption>OS</xf:caption>
          <xf:item id="unix">
            <xf:caption>Unix/Linux</xf:caption>
            <xf:value>Unix</xf:value>
          </xf:item>
          <xf:item id="mac">
            <xf:caption>Mac OS/X</xf:caption>
            <xf:value>Mac OS/X</xf:value>
          </xf:item>
          <xf:item id="win">
            <xf:caption>Windows 95/98/NT/2000/XP</xf:caption>
            <xf:value>Windows</xf:value>
          </xf:item>
          <xf:item id="other">
            <xf:caption>Other</xf:caption>
            <xf:value>Other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:selectOne ref="processor">
          <xf:caption>Processor</xf:caption>
          <xf:item>
            <xf:caption>AMD/Athlon</xf:caption>
            <xf:value>Athlon</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>AMD/Duron</xf:caption>
            <xf:value>Duron</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium Celeron</xf:caption>
            <xf:value>Celeron</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium III</xf:caption>
            <xf:value>p3</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium IV</xf:caption>
            <xf:value>p4</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:textbox ref="@ram">
          <xf:caption>RAM</xf:caption>
          <xf:violations class="error"/>
        </xf:textbox>
        <xf:selectOne ref="servletEngine">
          <xf:caption>Servlet Engine</xf:caption>
          <xf:item>
            <xf:caption>Tomcat</xf:caption>
            <xf:value>Tomcat</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Jetty</xf:caption>
            <xf:value>Jetty</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Resin</xf:caption>
            <xf:value>Resin</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Weblogic</xf:caption>
            <xf:value>weblogic</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>WebSphere</xf:caption>
            <xf:value>WebSphere</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:selectOne ref="javaVersion">
          <xf:caption>Java Version</xf:caption>
          <xf:item>
            <xf:caption>1.1</xf:caption>
            <xf:value>1.1</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.2</xf:caption>
            <xf:value>1.2</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.3</xf:caption>
            <xf:value>1.3</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.4</xf:caption>
            <xf:value>1.4</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>Other</xf:value>
          </xf:item>
        </xf:selectOne>
      </xf:group>
      <xf:submit id="prev" class="button">
        <xf:caption>Prev</xf:caption>
        <xf:hint>Go to previous page</xf:hint>
      </xf:submit>
      <xf:submit id="next" class="button">
        <xf:caption>Next</xf:caption>
        <xf:hint>Go to next page</xf:hint>
      </xf:submit>
    </xf:form>
    <xf:output ref="count" id="show_count" form="testform" class="info">
      <xf:caption>Visits Count</xf:caption>
    </xf:output>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/test/org/apache/cocoon/components/xmlform/testform2.xml
  
  Index: testform2.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
  
  	XMLForm instance document for the Cocoon Feedback Wizard.
  
   	author: Torsten Curdt, tcurdt@dff.st, March 2002
      author: Ivelin Ivanov, ivelin@apache.org, April 2002
      author: Simon Price <pr...@bristol.ac.uk>, September 2002
  
  -->
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
  	<xf:form id="testform" view="view2" action="wizard" method="GET">
  		<xf:caption>Cocoon Deployment Information</xf:caption>
  		<error>
  			<xf:violations class="error"/>
  		</error>
  		<xf:textbox ref="/number">
  			<xf:caption>Number of deployments</xf:caption>
  			<xf:violations class="error"/>
  		</xf:textbox>
  		<xf:textbox ref="/liveUrl">
  			<xf:caption>Live URL</xf:caption>
  			<xf:help>You must enter a valid URL</xf:help>
  			<xf:violations class="error"/>
  		</xf:textbox>
  		<xf:selectBoolean ref="/publish">
  			<xf:caption>Publish</xf:caption>
  		</xf:selectBoolean>
  		<xf:group nodeset="" id="favorites_group">
  			<xf:caption>Favorite web sites</xf:caption>
  			<!-- 
                repeat is a very powerful iterator tag,
                because it iterates over a nodeset resulting from
                the 'nodeset' selector attribute.
                Very similar to xslt's for-each tag.
  
                In this case we iterate over the top three favorite
                web sites.
              -->
  			<xf:repeat nodeset="favorite[position() &lt;= 3]" id="favorites">
  				<xf:textbox ref="." class="info">
  					<xf:caption>URL:</xf:caption>
  				</xf:textbox>
  			</xf:repeat>
  		</xf:group>
  		<xf:submit id="prev" class="button">
  			<xf:caption>Prev</xf:caption>
  			<xf:hint>Go to previous page</xf:hint>
  		</xf:submit>
  		<xf:submit id="next" class="button">
  			<xf:caption>Next</xf:caption>
  			<xf:hint>Go to next page</xf:hint>
  		</xf:submit>
  	</xf:form>
  	<xf:output ref="count" id="show_count" form="testform" class="info">
  		<xf:caption>Visits Count</xf:caption>
  	</xf:output>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/test/org/apache/cocoon/components/xmlform/testresult1.xml
  
  Index: testresult1.xml
  ===================================================================
  <?xml version="1.0"?>
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
    <xf:form action="wizard" id="testform" method="GET" view="view1">
      <xf:caption>System Information</xf:caption>
      <error/>
      <xf:group ref="/system">
        <xf:selectOne ref="/system/os" selectUIType="radio">
          <xf:value>Linux</xf:value>
          <xf:caption>OS</xf:caption>
          <xf:item id="unix">
            <xf:caption>Unix/Linux</xf:caption>
            <xf:value>Unix</xf:value>
          </xf:item>
          <xf:item id="mac">
            <xf:caption>Mac OS/X</xf:caption>
            <xf:value>Mac OS/X</xf:value>
          </xf:item>
          <xf:item id="win">
            <xf:caption>Windows 95/98/NT/2000/XP</xf:caption>
            <xf:value>Windows</xf:value>
          </xf:item>
          <xf:item id="other">
            <xf:caption>Other</xf:caption>
            <xf:value>Other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:selectOne ref="/system/processor">
          <xf:value>p4</xf:value>
          <xf:caption>Processor</xf:caption>
          <xf:item>
            <xf:caption>AMD/Athlon</xf:caption>
            <xf:value>Athlon</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>AMD/Duron</xf:caption>
            <xf:value>Duron</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium Celeron</xf:caption>
            <xf:value>Celeron</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium III</xf:caption>
            <xf:value>p3</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Pentium IV</xf:caption>
            <xf:value>p4</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:textbox ref="/system/@ram">
          <xf:value>512</xf:value>
          <xf:caption>RAM</xf:caption>
        </xf:textbox>
        <xf:selectOne ref="/system/servletEngine">
          <xf:value>Tomcat</xf:value>
          <xf:caption>Servlet Engine</xf:caption>
          <xf:item>
            <xf:caption>Tomcat</xf:caption>
            <xf:value>Tomcat</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Jetty</xf:caption>
            <xf:value>Jetty</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Resin</xf:caption>
            <xf:value>Resin</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Weblogic</xf:caption>
            <xf:value>weblogic</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>WebSphere</xf:caption>
            <xf:value>WebSphere</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>other</xf:value>
          </xf:item>
        </xf:selectOne>
        <xf:selectOne ref="/system/javaVersion">
          <xf:value>1.3</xf:value>
          <xf:caption>Java Version</xf:caption>
          <xf:item>
            <xf:caption>1.1</xf:caption>
            <xf:value>1.1</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.2</xf:caption>
            <xf:value>1.2</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.3</xf:caption>
            <xf:value>1.3</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>1.4</xf:caption>
            <xf:value>1.4</xf:value>
          </xf:item>
          <xf:item>
            <xf:caption>Other</xf:caption>
            <xf:value>Other</xf:value>
          </xf:item>
        </xf:selectOne>
      </xf:group>
      <xf:submit class="button" id="prev">
        <xf:caption>Prev</xf:caption>
        <xf:hint>Go to previous page</xf:hint>
      </xf:submit>
      <xf:submit class="button" id="next">
        <xf:caption>Next</xf:caption>
        <xf:hint>Go to next page</xf:hint>
      </xf:submit>
    </xf:form>
    <xf:output class="info" form="testform" id="show_count" ref="count">
      <xf:value>1</xf:value>
      <xf:caption>Visits Count</xf:caption>
    </xf:output>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/test/org/apache/cocoon/components/xmlform/testresult2.xml
  
  Index: testresult2.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
    <xf:form action="wizard" id="testform" method="GET" view="view2">
      <xf:caption>Cocoon Deployment Information</xf:caption>
      <error/>
      <xf:textbox ref="/number">
        <xf:value>1</xf:value>
        <xf:caption>Number of deployments</xf:caption>
      </xf:textbox>
      <xf:textbox ref="/liveUrl">
        <xf:value>http://</xf:value>
        <xf:caption>Live URL</xf:caption>
        <xf:help>You must enter a valid URL</xf:help>
      </xf:textbox>
      <xf:selectBoolean ref="/publish">
        <xf:value>true</xf:value>
        <xf:caption>Publish</xf:caption>
      </xf:selectBoolean>
      <xf:group id="favorites_group" nodeset="">
        <xf:caption>Favorite web sites</xf:caption>
        <xf:repeat id="favorites" nodeset="favorite[position() &lt;= 3]">
          <xf:group ref="/favorite[1]">
            <xf:textbox class="info" ref="/favorite[1]/.">
              <xf:value>http://cocoon.apache.org</xf:value>
              <xf:caption>URL:</xf:caption>
            </xf:textbox>
          </xf:group>
          <xf:group ref="/favorite[2]">
            <xf:textbox class="info" ref="/favorite[2]/.">
              <xf:value>http://jakarta.apache.org</xf:value>
              <xf:caption>URL:</xf:caption>
            </xf:textbox>
          </xf:group>
          <xf:group ref="/favorite[3]">
            <xf:textbox class="info" ref="/favorite[3]/.">
              <xf:value>http://www.google.com</xf:value>
              <xf:caption>URL:</xf:caption>
            </xf:textbox>
          </xf:group>
        </xf:repeat>
      </xf:group>
      <xf:submit class="button" id="prev">
        <xf:caption>Prev</xf:caption>
        <xf:hint>Go to previous page</xf:hint>
      </xf:submit>
      <xf:submit class="button" id="next">
        <xf:caption>Next</xf:caption>
        <xf:hint>Go to next page</xf:hint>
      </xf:submit>
    </xf:form>
    <xf:output class="info" form="testform" id="show_count" ref="count">
      <xf:value>2</xf:value>
      <xf:caption>Visits Count</xf:caption>
    </xf:output>
  </document>
  
  
  
  1.1                  cocoon-2.1/src/blocks/xmlform/test/org/apache/cocoon/components/xmlform/testschema.xml
  
  Index: testschema.xml
  ===================================================================
  <?xml version="1.0" ?>
  <!--
  
  	Validating Schematron schema for the xmlform example wizard
    
    Schematron Schema language home page:
    http://www.ascc.net/xml/schematron/
    
  	Author: Ivelin Ivanov, ivelin@apache.org, April 2002
  
  -->
  <schema ns="http://xml.apache.cocoon/xmlform"
  	xmlns="http://www.ascc.net/xml/schematron">
  	<title>Schema for the XML Form example</title>
  	<phase id="userIdentity">
  		<p>For user identity information.</p>
  		<active pattern="user"/>
  	</phase>
  	<phase id="deployment">
  		<p>For deployment info page.</p>
  		<active pattern="dep" />
  	</phase>
  	<phase id="system">
  		<p>For system info page.</p>
  		<active pattern="sys" />
  	</phase>
  	<phase id="confirm">
  		<p>For final total validation and tracking some tricky problems.</p>
  		<active pattern="user" />
  		<active pattern="dep" />
  		<active pattern="sys" />
  	</phase>
  	<pattern name="User Info Validation Pattern" id="user">
  		<rule context="/firstName">
  			<assert test="string-length(.) &gt; 3">First name <anametag/> 
  				<wrapper>should</wrapper> be at least 4 characters.</assert>
  			<assert test="string-length(.) &lt; 20">First name should be less
  				than 20 characters.</assert>
  		</rule>
  		<rule context="/lastName">
  			<assert test="string-length(.) &gt; 3">Last name should be at least
  				4 characters.</assert>
  			<assert test="string-length(.) &lt; 20">Last name should be less
  				than 20 characters.</assert>
  		</rule>
  		<rule context="/email">
  			<assert test="contains( string(.),'@')">Email format is invalid.</assert>
  		</rule>
  		<rule context="/age">
  			<assert test="number() &gt; 0 and number(.) &lt; 200">Age should be
  				a reasonably big positive number.</assert>
  		</rule>
  	</pattern>
  	<pattern name="Deployment Information Validation Pattern" id="dep">
  		<rule context="/number">
  			<assert test="number() &gt; 0">The number of deployments must be
  				non-negative ( hopefully positive :-> ) .</assert>
  		</rule>
  		<rule context="/">
  			<!-- 
          If the site is to be published, then verify the URL.
          Note: This assertion demonstrates the unique ability of 
          Schematron to test document node dependencies.
          This is not possible to do with XML Schema and Relax NG.
         -->
  			<assert
  				test="not(string(publish) = 'true') or (starts-with(liveUrl, 'http://') and contains( string(liveUrl),'.') ) "
  				>The URL of the published site is invalid.</assert>
  		</rule>
  	</pattern>
  	<pattern name="System Information Validation Pattern" id="sys">
  		<rule context="/system/@ram">
  			<assert test="number() &gt; 0">The RAM value should be a positive
  				number, denoting the memory in MB (e.g. 128, 512, etc.).</assert>
  		</rule>
  	</pattern>
  </schema>
  
  
  
  1.14      +0 -1      cocoon-2.1/src/webapp/WEB-INF/cocoon.xconf
  
  Index: cocoon.xconf
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/webapp/WEB-INF/cocoon.xconf,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- cocoon.xconf	19 Apr 2003 20:38:22 -0000	1.13
  +++ cocoon.xconf	25 Apr 2003 08:35:01 -0000	1.14
  @@ -154,7 +154,6 @@
       <component-instance logger="core.modules.input" name="xmlmeta"      class="org.apache.cocoon.components.modules.input.XMLMetaModule"/>
       <component-instance logger="core.modules.input" name="mapmeta"      class="org.apache.cocoon.components.modules.input.MapMetaModule"/>
       <component-instance logger="core.modules.input" name="datemeta"     class="org.apache.cocoon.components.modules.input.DateMetaInputModule"/>
  -    <component-instance logger="core.modules.input" name="xmlform"      class="org.apache.cocoon.components.modules.input.XMLFormInput"/>
       <component-instance logger="core.modules.input" name="jxpath"       class="org.apache.cocoon.components.modules.input.JXPathMetaModule"/>
       <component-instance logger="core.modules.input" name="simplemap"    class="org.apache.cocoon.components.modules.input.SimpleMappingMetaModule"/>
       <component-instance logger="core.modules.input" name="chain"    class="org.apache.cocoon.components.modules.input.ChainMetaModule">
  
  
  
  1.10      +1 -18     cocoon-2.1/src/webapp/samples/samples.xml
  
  Index: samples.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/webapp/samples/samples.xml,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- samples.xml	27 Mar 2003 17:55:45 -0000	1.9
  +++ samples.xml	25 Apr 2003 08:35:02 -0000	1.10
  @@ -78,23 +78,6 @@
      </sample>
     </group>
     
  -  <group name="XMLForm: Form Handling and Web Services">
  -    <sample name="Documentation" href="xmlform/overview.html">
  -    Introduction to Cocoon's form handling framework,
  -    which provides W3C XForms based markup, Schematron instance validation,
  -    and automated binding to JavaBeans and DOM instances. 
  -    Also shows that XMLForm based applications are readily available as Web Services (REST style).  
  -   </sample>
  -    <sample name="Example" href="xmlform/wizard">
  -    Presents a sophisticated form handling demo ...
  -    multi-page wizard with two-way navigation.
  -   </sample>
  -    <sample name="WSDL" href="xmlform/UsageFeedbackService/WSDL">
  -	Example WSDL descriptor for the same application, 
  -	exposed as a Web Service.     
  -   </sample>
  -  </group>
  -  
     <group name="System Tools And Pages">
      <sample name="Status Page" href="status.html">
       This page shows the current internal status of cocoon, along with