ivelin 02/05/20 00:19:26
Added: src/java/org/apache/cocoon/components/validation Schema.java
SchemaFactory.java Validator.java Violation.java
ZNestedBean.java ZTestBean.java
ZValidationTest.java zxmlform-sch-report-test.xml
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 Types.java
src/java/org/apache/cocoon/samples/xmlform UserBean.java
WizardAction.java
src/webapp/mount/xmlform README.txt sitemap.xmap
src/webapp/mount/xmlform/schematron
wizard-xmlform-sch-report.xml
src/webapp/mount/xmlform/stylesheets wizard2html.xsl
src/webapp/mount/xmlform/wizard Readme.txt confirm.xml
deployment.xml end.xml start.xml system.xml
userIdentity.xml
Log:
moved XMLForm from scratchpad to main tree
added link to XMLForm Wizard demo from sample-apps page
Revision Changes Path
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/Schema.java
Index: Schema.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/Schema.java,v
1.1 2002/05/20 07:19:24 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:24 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation;
/**
*
* Created on Sat, April 6, 2002
*
* @author [EMAIL PROTECTED]
*/
public interface Schema
{
public Validator newValidator() throws InstantiationException;
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/SchemaFactory.java
Index: SchemaFactory.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/SchemaFactory.java,v
1.1 2002/05/20 07:19:24 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:24 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation;
import java.io.IOException;
import org.xml.sax.SAXParseException;
import org.xml.sax.InputSource;
/**
*
* Responsible for creating new instances of Schemas
* for different Schema languages
*
* @author [EMAIL PROTECTED]
*/
public abstract class SchemaFactory
{
public static String NAMESPACE_SCHEMATRON =
"http://www.ascc.net/xml/schematron";
/** Creates a new instance of ValidatorFactory */
public SchemaFactory ()
{
}
/**
* This method creates an instance of a ValidatorFactory
* using the JDK 1.3 META-INF/services mechanism.
* The idea is borrowed from JARV
*
http://iso-relax.sourceforge.net/apiDoc/org/iso_relax/verifier/VerifierFactory.html
*
* @param ns the namespace of the schema language
* @return ValidatorFactory
* @throws InstantiationException when a factory could not be created
*/
public static SchemaFactory lookup(java.lang.String ns)
throws InstantiationException
{
// currently hardcoded implementation for Schematron
// until another schema validator is implemented
/* @todo create SchematronValidatorFactory */
if ( ns.equals ( NAMESPACE_SCHEMATRON ) )
return new
org.apache.cocoon.components.validation.schematron.SchematronFactory();
return null;
}
/**
* Loads and compiles a Schema instance
*
* @param InputSource the SAX input source containing the Schema document
* @return Schema the compiled schema instance
* @throws InstantiationException when the Schema could not be loaded or
compiled
*/
public abstract Schema compileSchema(InputSource is)
throws InstantiationException;
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/Validator.java
Index: Validator.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/Validator.java,v
1.1 2002/05/20 07:19:24 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:24 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation;
import java.util.SortedSet;
/**
*
* Created on Sat, April 6, 2002
*
* @author [EMAIL PROTECTED]
*/
public interface Validator
{
/**
* Validates an instance against a schema and returns a set of errors.
*
* Validator is not thread safe and is not re-entrant.
*
* @param instance The instance can be either a DOM node or a JavaBean.
* @return SortedSet of ValidityViolation(s). The set is sorted by
ValidityViolation.getPath()
*
* @throws RuntimeException if the validation process fails
* Should not happen in a normal environment.
*/
SortedSet validate(Object instance);
/**
* This property can be used for partial document validation.
* The concept is borrowed from the Schematron schema
* Not all schemas support partial validation
*/
public String PROPERTY_PHASE =
"http://xml.apache.org/cocoon/validator/phase";
/**
* @param property name
* @param value property value
* @throws IllegalArgumentException when the property is not supported
*/
public void setProperty(java.lang.String property, java.lang.Object value)
throws java.lang.IllegalArgumentException;
/**
* @param property name
* @return the property value
* @throws IllegalArgumentException when the property is not supported
*/
public java.lang.Object getProperty(java.lang.String property)
throws java.lang.IllegalArgumentException;
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/Violation.java
Index: Violation.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/Violation.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation;
/**
* Encapsulates an error condition which was triggered
* by a violation of the document validity during
* validation
*
* @author [EMAIL PROTECTED]
*/
public class Violation implements java.lang.Comparable
{
/**
* @return the XPath location of the Violation
*/
public String getPath()
{
return xpath_;
}
/**
* set the XPath location of the Violation
*/
public void setPath( String xpath )
{
xpath_ = xpath;
}
/**
* @return the error message
*/
public String getMessage ()
{
return message_;
}
/**
* set the error message
*/
public void setMessage ( String message )
{
message_ = message;
}
public boolean equals(Object obj)
{
if (obj == null) return false;
if (obj == this) return true;
if ( !(obj instanceof Violation) )
throw new java.lang.IllegalArgumentException( "Can only compare to
a Violation object" );
Violation v = (Violation) obj;
if
(
getPath().equals ( v.getPath() )
&&
getMessage().equals ( v.getMessage() )
)
return true;
else return false;
}
public int hashCode()
{
return (getPath().hashCode () ^ getMessage().hashCode());
}
public int compareTo(Object obj)
{
if (obj == null) return 1;
if (obj == this) return 0;
if ( !(obj instanceof Violation) )
throw new java.lang.IllegalArgumentException( "Can only compare to
a Violation object" );
Violation v = (Violation) obj;
int primaryResult = getPath().compareTo ( v.getPath () );
if (primaryResult != 0) return primaryResult;
else
{
if (getMessage () == null)
{
if (v.getMessage() == null) return 0;
else return -1;
}
else return (getMessage().compareTo( v.getMessage () ) );
}
}
private String xpath_;
private String message_;
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/ZNestedBean.java
Index: ZNestedBean.java
===================================================================
package org.apache.cocoon.components.validation;
/**
* just a test bean
*/
public class ZNestedBean
{
private String kind = "mammal";
public void setKind(String newKind)
{
kind = newKind;
}
public String getKind()
{
return kind;
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/ZTestBean.java
Index: ZTestBean.java
===================================================================
package org.apache.cocoon.components.validation;
import java.util.List;
import java.util.ArrayList;
/**
* just a test bean
*/
public class ZTestBean {
private String name = "dog";
private String scope = "galaxy";
private int count = 0;
private ArrayList preferences = new ArrayList();
private ZNestedBean personal = new ZNestedBean();
public ZTestBean (){
preferences.add("likeVodka");
preferences.add("likeSkiing");
}
public ZTestBean (String newName, String newScope){
this();
name= newName;
scope=newScope;
}
public String getName() {
return name;
}
public void setName(String newName) {
name = newName;
}
public void setScope(String newScope) {
scope = newScope;
}
public String getScope() {
return scope;
}
public ArrayList getPreferences()
{
return preferences;
}
public ZNestedBean getPersonalInfo()
{
return personal;
}
public void setPersonalInfo( ZNestedBean newPersonal )
{
personal = newPersonal;
}
public int getCount() {
return count;
}
public void incrementCount() {
count++;
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/ZValidationTest.java
Index: ZValidationTest.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/ZValidationTest.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation;
// Java classes
import java.util.Iterator;
import java.util.SortedSet;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.File;
// XML classes
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.TransformerException;
import org.xml.sax.InputSource;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
// java classes
import java.util.Properties;
import org.apache.cocoon.components.validation.SchemaFactory;
import org.apache.cocoon.components.validation.Schema;
import org.apache.cocoon.components.validation.Validator;
import org.apache.cocoon.components.validation.Violation;
import org.apache.cocoon.components.validation.ZTestBean;
/**
*
* Test class for the Validation API
*
* Takes 2 command line arguments.
*
* First is the location of a Schematron Schema file
* Second is the validation phase to use
*
*/
public class ZValidationTest
{
/**
* Method main
*/
public static void main(String args[])
throws Exception
{
System.out.println("\n=== Java based Schematron validation ===");
if (args.length < 1) {
System.err.println("Usage: java Schematron <schema.xml> " +
"[phase] ");
return;
}
// use custom schema
File file = new File( args[0] );
if ( !file.exists () ) throw new Exception("Error: schema file not
found !");
InputStream istrm = new FileInputStream ( file );
InputSource is = new InputSource ( istrm );
SchemaFactory schf = SchemaFactory.lookup(
SchemaFactory.NAMESPACE_SCHEMATRON );
Schema sch = schf.compileSchema( is );
Validator validator = sch.newValidator();
// set preprocessor parameters
if (args.length > 1)
validator.setProperty("phase", new String(args[1]));
ZTestBean tbean = new ZTestBean();
// measure validation speed
long time = System.currentTimeMillis ();
int i = 0;
SortedSet violations = null;
for (; i < 100; i++)
{
// perform validation
violations = validator.validate( tbean );
}
time = System.currentTimeMillis () - time;
System.out.println( "\nValidation performance:");
System.out.println( " validate() executed " + i + " times for a total
of " + time + " ms");
System.out.println( "Avarage validation time: " + (time/i) + " ms " );
// everything ok?
if (violations == null)
{
System.out.println("\nValidation ok, no messages generated");
}
else {
System.out.println("Validation encountered errors. Messages :");
Iterator viter = violations.iterator();
while (viter.hasNext ())
{
Violation v = (Violation) viter.next();
System.out.println("Validity violation path: " + v.getPath() + ",
message: " + v.getMessage() );
}
}
System.out.println("\n=== Schematron validation done ===");
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/zxmlform-sch-report-test.xml
Index: zxmlform-sch-report-test.xml
===================================================================
<?xml version="1.0" ?>
<!--
Sample Schematron schema for the ZValidationTest
Pass this file as a first argument on the command line to ZValidationTest
Ivelin Ivanov, [EMAIL PROTECTED]
-->
<schema ns="http://xml.apache.cocoon/xmlform"
xmlns="http://www.ascc.net/xml/schematron">
<title>Schema for the XML Form example</title>
<phase id="New">
<p>For creating new documents.</p>
<active pattern="mini"/>
</phase>
<phase id="Draft">
<p>For fast validation of draft documents.</p>
<active pattern="required" />
</phase>
<phase id="Full">
<p>For final validation and tracking some tricky problems.</p>
<active pattern="mini" />
<active pattern="required" />
<active pattern="extra" />
</phase>
<pattern name="A Simple Validation Pattern" id="mini">
<rule context="name">
<assert test="string-length(.) > 3" diagnostics="dname
dcount">Animal name should be at least 4 characters.</assert>
<assert test="string-length(.) < 10">Animal name
should be less than 10 characters.</assert>
</rule>
<rule context="scope">
<assert test="normalize-space(.) = 'session' or
normalize-space(.) = 'request'">Scope should be request or session.</assert>
</rule>
</pattern>
<pattern name="Required Validation Pattern" id="required">
<rule context="count">
<assert test="number(.) > 0" diagnostics="dcount"> The
counter should be > 0.</assert>
</rule>
</pattern>
<pattern name="Extra Simple Validation Pattern" id="extra">
a pattern
<rule context="/personalInfo/type"> a rule
<assert test="text(.) = 'mammal'"> Animal type should
be mammal</assert>
<report test="text(.) != 'mammal'"> Animal is not
mammal</report>
</rule>
</pattern>
<diagnostics>
<diagnostic id="dname">
Animals rarely have names shorter than 5 characters.
Dog and Cat are among the rare exceptions.
All right, all right, don't hold me to these words, this is
just a sloppy test after all.
</diagnostic>
<diagnostic id="dcount">
The animal counter simply keeps track of the number of times
this animal was visited .
</diagnostic>
</diagnostics>
</schema>
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/ActivePattern.java
Index: ActivePattern.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/ActivePattern.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation.schematron;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
* Represents a Schematron phase
* <active pattern="some"> element
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class ActivePattern
{
private String pattern_;
/**
* Returns the active pattern name
*/
public String getPattern()
{
return pattern_;
}
/**
* Sets the active pattern name
*/
public void setPattern( String pattern )
{
pattern_ = pattern;
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/Assert.java
Index: Assert.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/Assert.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation.schematron;
/**
* Represents a Schematron assert element
*
* example:
* <assert test="count(ear)=2">A <name/> element should contain two
<emph>ear</emph> elements.</assert>
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class Assert
{
private String test_;
private String message_;
private String diagnostics_;
/**
* Returns the test attribute
*/
public String getTest()
{
return test_;
}
/**
* Sets the test attribute
*/
public void setTest( String newTest )
{
test_ = newTest;
}
/**
* Returns the message for to the element
*/
public String getMessage()
{
return message_;
}
/**
* Sets the message for to the element
*/
public void setMessage( String newMessage )
{
message_ = newMessage;
}
/**
* Returns the diagnostics list
*/
public String getDiagnostics()
{
return diagnostics_;
}
/**
* Sets the diagnostics list
*/
public void setDiagnostics( String newDiagnostics )
{
diagnostics_ = newDiagnostics;
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/Pattern.java
Index: Pattern.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/Pattern.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation.schematron;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
* Represents a Schematron pattern
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class Pattern
{
private String name_;
private String id_;
private ArrayList rules_ = new ArrayList ();
/**
* Returns the id of the pattern
*/
public String getId()
{
return id_;
}
/**
* Sets the id of the pattern
*/
public void setId( String newId )
{
id_ = newId;
}
/**
* Returns the name of the pattern
*/
public String getName()
{
return name_;
}
/**
* Sets the name of the pattern
*/
public void setName( String newName )
{
name_ = newName;
}
/**
* Returns the list of rules
*/
public List getRule()
{
return rules_;
}
/**
* Sets the list of rules
*/
public void setRule(Collection newRules)
{
rules_ = new ArrayList();
rules_.addAll ( newRules );
}
/**
* Add a rule to the list
*/
public void addRule(Rule r)
{
rules_.add ( r );
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/Phase.java
Index: Phase.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/Phase.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation.schematron;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
* Represents a Schematron phase element
*
* Example:
* <phase id="basicValidation">
* <active pattern="text" />
* <active pattern="tables" />
* <active pattern="attributePresence" />
* </phase>
*
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class Phase
{
private String id_;
private ArrayList active_ = new ArrayList ();
/**
* Returns the id of the phase
*/
public String getId()
{
return id_;
}
/**
* Sets the id of the phase
*/
public void setId( String newId )
{
id_ = newId;
}
/**
* Returns the list of active patterns
*/
public List getActive()
{
return active_;
}
/**
* Sets the list of active patterns
*/
public void setActive(Collection newActivePatterns)
{
active_ = new ArrayList();
active_.addAll ( newActivePatterns );
}
/**
* Add a pattern to the list of active patterns
*/
public void addActive(ActivePattern p)
{
active_.add ( p );
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/Report.java
Index: Report.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/Report.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation.schematron;
/**
* Represents a Schematron report element
*
* <report test="when">message</report>
* is equivalent to
* <assert test="not(when)">message</assert>
*
* example:
* <report test="bone">This dog has a bone.</report>
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class Report extends Assert
{
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/Rule.java
Index: Rule.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/Rule.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation.schematron;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
/**
* Represents a Schematron rule element
*
* From the Schematron specification:
*
* example:
* <rule context="dog">
* <assert test="count(ear) = 2">A 'dog' element should contain two 'ear'
elements.</assert>
* <report test="bone">This dog has a bone.</report>
* </rule>
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class Rule
{
private String context_;
private ArrayList asserts_ = new ArrayList ();
private ArrayList reports_ = new ArrayList ();
/**
* Returns the context of the pattern
*/
public String getContext()
{
return context_;
}
/**
* Sets the context of the pattern
*/
public void setContext( String newContext )
{
context_ = newContext;
}
/**
* Returns the list of the assertion rules
*/
public List getAssert()
{
return asserts_;
}
/**
* Sets the the list of the assertion rules
*/
public void setAssert(Collection newAsserts)
{
asserts_ = new ArrayList();
asserts_.addAll ( newAsserts );
}
/**
* Add an assert rule
*/
public void addAssert(Assert a)
{
asserts_.add ( a );
}
/**
* Returns the list of the report rules
*/
public List getReport()
{
return reports_;
}
/**
* Sets the list of the report rules
*/
public void setReport(Collection newReports)
{
reports_ = new ArrayList();
reports_.addAll ( newReports );
}
/**
* Add a report rule
*/
public void addReport(Report r)
{
reports_.add ( r );
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/SchematronFactory.java
Index: SchematronFactory.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/SchematronFactory.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation.schematron;
import java.io.OutputStreamWriter;
import java.io.InputStream;
// java classes
import java.util.Properties;
import java.util.List;
import java.io.IOException;
import java.net.URL;
// XML classes
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
// logger
import org.apache.log.Hierarchy;
import org.apache.log.Logger;
import org.apache.log.Priority;
// JXPath classes
import org.apache.commons.jxpath.JXPathContext;
// Cocoon classes
import org.apache.cocoon.components.validation.SchemaFactory;
import org.apache.cocoon.components.validation.Schema;
/**
* A helper class which builds a SchematronSchema instance object
* from a DOM source
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class SchematronFactory extends SchemaFactory
{
/**
* the schema name space prefix used in the schema document
*/
private String schemaPrefix_;
/**
* the default schema name space prefix
*/
private String defaultSchemaPrefix_ = "sch";
/*
* private logger
*/
private Logger logger = setupLogger();
//
// Constructors
//
/**
* initialize logger
*/
protected Logger setupLogger()
{
Logger logger = Hierarchy.getDefaultHierarchy().getLoggerFor("XmlForm");
logger.setPriority( Priority.ERROR );
return logger;
}
/**
* Builds a new Schema instance from
* the given XML InputSource
*
* @param schemaSrc
* the Schema document XML InputSource
*/
public Schema compileSchema(InputSource schemaSrc)
throws InstantiationException
{
SchematronSchema schema = null;
try {
// load Schema file into a DOM document
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance ();
DocumentBuilder dbld = dbf.newDocumentBuilder ();
Document document = dbld.parse( schemaSrc );
schema = buildSchema( document );
} catch (Exception e) {
logger.error("!!! Failed loading Schematron schema", e);
throw new RuntimeException(" !!! Failed loading Schematron schema:
\n" + e);
}
return schema;
} // build
/**
* Build Schematron schema object from a DOM document
* @ param doc DOM document containing the schema
*
*/
protected SchematronSchema buildSchema( Document doc )
{
SchematronSchema schema = new SchematronSchema();
boolean errors = false;
doc.getNamespaceURI ();
doc.getPrefix ();
// Initialize the JXPath context
Element root = doc.createElement ( "root" );
Element schemaElement = doc.getDocumentElement ();
schemaPrefix_ = schemaElement.getPrefix ();
root.appendChild ( schemaElement );
JXPathContext jxpContext = JXPathContext.newContext ( root );
jxpContext.setLenient(false);
// Bind sch:schema element
// schema title
String title = (String) jxpContext.getValue ( "/schema/title",
String.class );
schema.setTitle( title );
logger.debug( "Schema title: " + schema.getTitle());
bindPatterns( schema, jxpContext );
bindPhases( schema, jxpContext );
return schema;
}
/**
* populates the patterns elements from the dom tree
*
* @param schema the schema instance
* @param jxpContext
*/
protected void bindPatterns( SchematronSchema schema, JXPathContext
jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// schema patterns
int ptCount = ((Integer) jxpContext.getValue ( "count(/schema/pattern)",
Integer.class )).intValue();
logger.debug( "\nNumber of patterns: " + ptCount);
for (int i = 1; i <= ptCount; i++)
{
logger.debug( "Pattern# : " + i);
Pattern pattern = new Pattern();
String ptprefix = "/schema/pattern[" + i + "]";
String name = (String) jxpContext.getValue ( ptprefix + "/@name",
String.class );
pattern.setName( name );
logger.debug( "Pattern name : " + pattern.getName());
String id = (String) jxpContext.getValue ( ptprefix + "/@id",
String.class );
pattern.setId( id );
logger.debug( "Pattern id : " + pattern.getId() );
bindRules( pattern, ptprefix, jxpContext );
schema.addPattern( pattern );
}
}
/**
* populates the rules elements for a pattern
* from the dom tree
*
* @param pattern
* @param pathPrefix pattern path prefix
* @param jxpContext JXPathContext
*/
protected void bindRules( Pattern pattern, String pathPrefix, JXPathContext
jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// schema rules
int ruleCount = ((Integer) jxpContext.getValue ( "count(" + pathPrefix +
"/rule)", Integer.class )).intValue();
logger.debug( "\nNumber of rules: " + ruleCount);
for (int i = 1; i <= ruleCount; i++)
{
logger.debug( "Rule# : " + i);
Rule rule = new Rule();
String rulePrefix = pathPrefix + "/rule[" + i + "]";
String context = (String) jxpContext.getValue ( rulePrefix +
"/@context", String.class );
rule.setContext( context );
logger.debug( "Rule context : " + rule.getContext());
bindAsserts( rule, rulePrefix, jxpContext );
pattern.addRule( rule );
}
}
/**
* populates the assert elements for a rule
* from the dom tree
*
* @param rule
* @param pathPrefix rule path prefix
* @param jxpContext JXPathContext
*/
protected void bindAsserts( Rule rule, String pathPrefix, JXPathContext
jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// schema reports
int elementCount = ((Integer) jxpContext.getValue ( "count(" + pathPrefix
+ "/assert)", Integer.class )).intValue();
logger.debug( "\nNumber of asserts: " + elementCount);
for (int i = 1; i <= elementCount; i++)
{
logger.debug( "Assert# : " + i);
Assert assert = new Assert();
String assertPrefix = pathPrefix + "/assert[" + i + "]";
String test = (String) jxpContext.getValue ( assertPrefix + "/@test",
String.class );
assert.setTest( test );
logger.debug( "Assert test : " + assert.getTest());
// since diagnostics is a non-mandatory element
// we will try to get its value in a lenient mode
jxpContext.setLenient(true);
String diagnostics = (String) jxpContext.getValue ( assertPrefix +
"/@diagnostics", String.class );
assert.setDiagnostics( diagnostics );
logger.debug( "Assert diagnostics : " + assert.getDiagnostics());
jxpContext.setLenient(false);
String message = (String) jxpContext.getValue ( assertPrefix,
String.class );
assert.setMessage( message );
logger.debug( "Assert message : " + assert.getMessage());
rule.addAssert( assert );
}
}
/**
* populates the assert elements for a rule
* from the dom tree
*
* @param rule
* @param pathPrefix rule path prefix
* @param jxpContext JXPathContext
*/
protected void bindRerports( Rule rule, String pathPrefix, JXPathContext
jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// schema reports
int elementCount = ((Integer) jxpContext.getValue ( "count(" + pathPrefix
+ "/report)", Integer.class )).intValue();
logger.debug( "\nNumber of reports: " + elementCount);
for (int i = 1; i <= elementCount; i++)
{
logger.debug( "Report# : " + i);
Report report = new Report();
String assertPrefix = pathPrefix + "/report[" + i + "]";
String test = (String) jxpContext.getValue ( assertPrefix + "/@test",
String.class );
report.setTest( test );
logger.debug( "Report test : " + report.getTest());
// since diagnostics is a non-mandatory element
// we will try to get its value in a lenient mode
jxpContext.setLenient(true);
String diagnostics = (String) jxpContext.getValue ( assertPrefix +
"/@diagnostics", String.class );
report.setDiagnostics( diagnostics );
logger.debug( "Report diagnostics : " + report.getDiagnostics());
jxpContext.setLenient(false);
String message = (String) jxpContext.getValue ( assertPrefix,
String.class );
report.setMessage( message );
logger.debug( "Report message : " + report.getMessage());
rule.addReport( report );
}
}
/**
* populates the phases elements from the dom tree
*
* @param schema the schema instance
* @param jxpContext
*/
protected void bindPhases( SchematronSchema schema, JXPathContext
jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// schema phases
int phaseCount = ((Integer) jxpContext.getValue ( "count(/schema/phase)",
Integer.class )).intValue();
logger.debug( "\nNumber of phases: " + phaseCount);
for (int i = 1; i <= phaseCount; i++)
{
logger.debug( "phase# : " + i);
Phase phase = new Phase();
String phprefix = "/schema/phase[" + i + "]";
String id = (String) jxpContext.getValue ( phprefix + "/@id",
String.class );
phase.setId( id );
logger.debug( "phase id : " + phase.getId());
bindPhaseActivePatterns( phase, phprefix, jxpContext );
schema.addPhase( phase );
}
}
protected void bindPhaseActivePatterns( Phase phase, String pathPrefix,
JXPathContext jxpContext)
{
// ensure that mandatory elements which are not found
// will result in Exception
jxpContext.setLenient(false);
// phase active patterns
int elementCount = ((Integer) jxpContext.getValue ( "count(" + pathPrefix
+ "/active)", Integer.class )).intValue();
logger.debug( "Number of active patterns: " + elementCount);
for (int i = 1; i <= elementCount; i++)
{
logger.debug( "active pattern # : " + i);
ActivePattern activePattern = new ActivePattern();
String assertPrefix = pathPrefix + "/active[" + i + "]";
String pt = (String) jxpContext.getValue ( assertPrefix + "/@pattern",
String.class );
activePattern.setPattern( pt );
logger.debug( "Phase active pattern : " + activePattern.getPattern());
phase.addActive( activePattern );
}
}
/*
* Replace all occurances of sch: with the actual Schema prefix used in the
document
*
* @todo fix this implementaion. There are problems with DOM.
* Returns null instead of the actual namespace prefix (e.g. "sch") as
expected.
*/
protected String fixns( String path )
{
// Ironicly, at the time I am writing this
// JDK 1.4 is offering String.replaceAll(regex, str)
// I don't use it however for backward compatibility
StringBuffer strbuf = new StringBuffer( path );
int i = 0;
int j = 0;
String dprefix = defaultSchemaPrefix_ + ":";
int dplen = dprefix.length();
while ( ( j = path.indexOf ( dprefix, i ) ) >= 0 )
{
strbuf.append ( path.substring ( i, j ) );
strbuf.append ( schemaPrefix_ );
strbuf.append ( ':' );
i = j + dplen;
}
strbuf.append( path.substring ( i ) );
return strbuf.toString ();
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/SchematronSchema.java
Index: SchematronSchema.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/SchematronSchema.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation.schematron;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.cocoon.components.validation.Schema;
import org.apache.cocoon.components.validation.Validator;
/**
* Represents a Schematron Schema
*
* Specification:
* http://www.ascc.net/xml/resource/schematron/Schematron2000.html
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class SchematronSchema implements Schema
{
private String title_;
private ArrayList patterns_ = new ArrayList();
private ArrayList phases_ = new ArrayList();
/**
* Returns the message for to the element
*/
public String getTitle()
{
return title_;
}
/**
* Sets the message for to the element
*/
public void setTitle( String newTitle )
{
title_ = newTitle;
}
/**
* Returns a list of the patterns which
* contain messages that failed during validation
*/
public List getPattern()
{
return patterns_;
}
/**
* Sets the list of the patterns which
* contain messages that failed during validation
*/
public void setPattern(Collection newPatterns)
{
patterns_ = new ArrayList();
patterns_.addAll ( newPatterns );
}
/**
* Add a pattern to the list
*/
public void addPattern(Pattern p)
{
patterns_.add ( p );
}
/**
* Returns the list of schema phases
*/
public List getPhase()
{
return phases_;
}
/**
* Sets the list of schema phases
*/
public void setPhase(Collection newPhases)
{
phases_ = new ArrayList();
phases_.addAll ( newPhases );
}
/**
* Add a pattern to the list
*/
public void addPhase(Phase p)
{
phases_.add ( p );
}
public Validator newValidator () throws InstantiationException
{
return new SchematronValidator( this );
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/SchematronValidator.java
Index: SchematronValidator.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/SchematronValidator.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation.schematron;
import java.io.OutputStreamWriter;
import java.io.InputStream;
// java classes
import java.util.Properties;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.SortedSet;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.File;
import java.net.URL;
// XML classes
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
// logger
import org.apache.log.Hierarchy;
import org.apache.log.Logger;
import org.apache.log.Priority;
// JXPath classes
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
// Cocoon classes
import org.apache.cocoon.components.validation.Validator;
/**
* An object representing a single Schematron schema, used to validate
* multiple XML instances.
*
* This implementation can validate JavaBeans and DOM documents.
* It is based exclusively on the JXPath library from the Jakarta Commons
project.
* See http://jakarta.apache.org/commons/
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class SchematronValidator implements Validator
{
/** The schema instance for this Validator
* It is initialized once when a new Validator instance
* is created and used multiple times for validating
* different JavaBeans/DOM objects against the schema
*/
private SchematronSchema schema_;
/**
* lookup map, with phase id keys.
* Used for efficiency when validating by phase
*/
private Map phaseMap_ = new HashMap();
/**
* the schema name space prefix used in the schema document
*/
private String schemaPrefix_;
/**
* the default schema name space prefix
*/
private String defaultSchemaPrefix_ = "sch";
/*
* Schematron Phase property
*/
private String phaseProperty_ = null;
/*
* private logger
*/
private Logger logger = setupLogger();
//
// Constructors
//
/**
* Constructs a new Validator object for a given Schematron schema.
*
* @param schema
* The Schematron schema
*/
public SchematronValidator (SchematronSchema schema)
{
schema_ = schema;
preparePhaseMap();
}
//
// helper methods for the constructors
//
/**
* initialize logger
*/
protected Logger setupLogger()
{
Logger logger = Hierarchy.getDefaultHierarchy().getLoggerFor("XmlForm");
logger.setPriority( Priority.ERROR );
return logger;
}
protected void preparePhaseMap()
{
Map patternMap = new HashMap();
Iterator ptiter = schema_.getPattern().iterator();
while (ptiter.hasNext())
{
Pattern pattern = (Pattern) ptiter.next();
patternMap.put( pattern.getId(), pattern );
}
Iterator phiter = schema_.getPhase().iterator();
while (phiter.hasNext())
{
Phase phase = (Phase) phiter.next();
List activePatterns = new ArrayList();
phaseMap_.put( phase.getId(), activePatterns );
Iterator activeIter = phase.getActive().iterator();
while (activeIter.hasNext())
{
ActivePattern active = (ActivePattern) activeIter.next();
activePatterns.add( patternMap.get( active.getPattern() ) );
}
}
}
//
// public methods
//
/**
* Performs validation of the passed JavaBean or DOM object.
*
* This method tries to find the "phase" attribute
* and runs the active patterns for the phase.
* If phase not found, the method will try to match all patterns
*
*
* @param jbean The JavaBean or DOM object to be validated.
* @param props Properties which control different aspects of the
* validation process. This method only looks for the phase property.
* Another implementation may use other.
*
* @return A Result object which represents the result
* of the validation.
*/
public SortedSet validate( Object jbean )
{
List patterns = null;
if (phaseProperty_ != null)
{
patterns = getPatternsForPhase( phaseProperty_ );
logger.debug(" Validating for phase: " + phaseProperty_);
}
else
{
patterns = schema_.getPattern();
logger.debug(" Validating all patterns. No phase provided ");
}
ValidationResult vres = new ValidationResult();
if (patterns != null)
{
// create the JXPathContext
// which will be used to validate each rule
JXPathContext jxpContext = JXPathContext.newContext( jbean );
Iterator iter = patterns.iterator ();
while (iter.hasNext ())
{
Pattern resultPattern = evalPattern( jxpContext, (Pattern)
iter.next());
// if the resultPattern is null,
// then it passed successfully
if ( resultPattern != null) vres.addPattern( resultPattern );
}
}
return vres.toSortedSet();
}
/**
* return the list of patterns listed
* as <active/> elements of <phase/>
*
* @param phase name of the phase
* @return List of patterns
*/
protected List getPatternsForPhase( String phase )
{
return (List) phaseMap_.get( phase );
}
/**
* Returns pattern with rules which failed during validation.
* The context attribute of each rule in the result pattern
* contains the exact location of the failed element
* unlike the context attribute of the original pattern which
* is an XSLT production pattern
*
* @param jxpContext The JXPathContext being validated
* @param pattern The production schema pattern to be evaluated
* @return pattern with rules wich failed during validation.
*/
protected Pattern evalPattern( JXPathContext jxpContext, Pattern pattern)
{
// copy attributes
Pattern resultPattern = new Pattern();
resultPattern.setName( pattern.getName() );
resultPattern.setId( pattern.getId() );
// evaluate rules
Iterator iter = pattern.getRule().iterator();
while (iter.hasNext())
{
List failedRules = evalRule(jxpContext, (Rule) iter.next () );
// if there were failed rules
// add them to the list of other failed rules
if (failedRules.size () > 0)
{
failedRules.addAll ( resultPattern.getRule() );
resultPattern.setRule ( failedRules );
}
}
// if there are no failed rules return null
if (resultPattern.getRule().size() == 0) return null;
else return resultPattern;
}
/**
* Returns rules with asserts or reports which failed during validation.
* The context attribute of each rule in the result pattern
* contains the exact location of the failed element
* unlike the context attribute of the original pattern which
* is an XSLT production pattern
*
* @param jxpContext The JXPath context being validated
* @param rule The original pattern rule to be evaluated
* @return pattern with rules wich failed during validation.
*/
protected List evalRule( JXPathContext jxpContext, Rule rule )
{
List elements = jxpContext.locate( rule.getContext() );
List failedRules = new ArrayList();
Iterator pointerIter = elements.iterator ();
while ( pointerIter.hasNext() )
{
Pointer ptr = (Pointer) pointerIter.next ();
// prepare result Rule
Rule nextFailedRule = new Rule();
nextFailedRule.setContext( ptr.asPath() );
// switch to the context of the rule
JXPathContext localJxpContext = JXPathContext.newContext( jxpContext,
ptr.getValue() );
// evaluate asserts
Iterator assertIter = rule.getAssert().iterator();
while (assertIter.hasNext())
{
Assert assert = (Assert) assertIter.next();
// if an assert test fails, then it should be added
// to the result
boolean passed = evalTest( localJxpContext, assert.getTest() );
if (!passed)
{
nextFailedRule.addAssert ( assert );
}
}
// evaluate reports
Iterator reportIter = rule.getReport().iterator();
while (reportIter.hasNext())
{
Report report = (Report) reportIter.next();
// if a report test passes, then it should be added
// to the result
boolean passed = evalTest( localJxpContext, report.getTest() );
if (passed)
{
nextFailedRule.addReport ( report );
}
}
// if the nextFailedRule is non empty,
// then add it to the list of failed rules
if (nextFailedRule.getAssert().size() > 0 ||
nextFailedRule.getReport().size() > 0)
{
failedRules.add( nextFailedRule );
}
}
return failedRules;
}
/**
* Test an XPath expression in a context
*
* @param jxpContext The JXPath context being validated
* @param String The XPath expression
* @return boolean result of evaluation
*/
protected boolean evalTest( JXPathContext jxpContext, String test )
{
Boolean passed = (Boolean) jxpContext.getValue( test, Boolean.class);
return passed.booleanValue ();
}
/**
* @param property name
* @return the property value
* @throws IllegalArgumentException when the property is not supported
*/
public java.lang.Object getProperty (java.lang.String property) throws
java.lang.IllegalArgumentException
{
if (property.equals ( Validator.PROPERTY_PHASE ) ) return phaseProperty_;
else throw new IllegalArgumentException(" Property " + property + " is
not supported");
}
/**
* @param property name
* @param value property value
* @throws IllegalArgumentException when the property is not supported
*/
public void setProperty (java.lang.String property, java.lang.Object value)
throws java.lang.IllegalArgumentException
{
if ( property.equals ( Validator.PROPERTY_PHASE ) && ( value == null ||
(value instanceof String)) )
{
phaseProperty_ = (String) value;
}
else
throw new IllegalArgumentException(" Property " + property + " is not
supported or value is invalid");
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/ValidationResult.java
Index: ValidationResult.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/validation/schematron/ValidationResult.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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.validation.schematron;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.cocoon.components.validation.Violation;
/**
* Represents the result of a Schematron validation process
*
* <validationResult>
* list of <pattern> elements with <rule> subelements
* </validationResult>
*
* @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED]
*/
public class ValidationResult
{
private ArrayList patterns_ = new ArrayList();
/**
* Returns a list of the patterns which
* contain rules that failed during validation
*/
public List getPattern()
{
return patterns_;
}
/**
* Sets the list of the patterns which
* contain rules that failed during validation
*/
public void setPattern(Collection newPatterns)
{
patterns_ = new ArrayList();
patterns_.addAll ( newPatterns );
}
/**
* Add a pattern to the list
*/
public void addPattern(Pattern p)
{
patterns_.add ( p );
}
public boolean isEmpty ()
{
return patterns_.isEmpty ();
}
/**
* adds all errors to a sorted list
* Key is XPath of each error location
*
* @todo implement this method !!!
* @return SortedSet
*/
public SortedSet toSortedSet()
{
if ( isEmpty() ) return null;
SortedSet violations = new TreeSet();
Iterator piter = getPattern().iterator();
while (piter.hasNext ())
{
Pattern pattern = (Pattern)piter.next ();
// System.out.println("Pattern name: " + pattern.getName() + ", id: " +
pattern.getId() );
Iterator ruleIter = pattern.getRule().iterator();
while (ruleIter.hasNext ())
{
Rule rule = (Rule)ruleIter.next ();
// System.out.println(" Rule name: " + rule.getContext() );
Iterator assertIter = rule.getAssert().iterator();
while (assertIter.hasNext ())
{
Assert assert = (Assert)assertIter.next ();
// add the next assert to the violations set
Violation v = new Violation();
v.setPath( rule.getContext() );
v.setMessage( assert.getMessage() );
violations.add( v );
// System.out.println(" Assert test: " + assert.getTest() +
", message: " + assert.getMessage() );
}
Iterator reportIter = rule.getReport().iterator();
while (reportIter.hasNext ())
{
Report report = (Report)reportIter.next ();
// add the next report to the violations set
Violation v = new Violation();
v.setPath( rule.getContext() );
v.setMessage( report.getMessage() );
violations.add( v );
// System.out.println(" Report test: " + report.getTest() +
", message: " + report.getMessage() );
}
}
}
return violations;
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/xmlform/Form.java
Index: Form.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xmlform/Form.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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 java.util.Collection;
import java.util.Enumeration;
import java.util.SortedSet;
import java.util.Set;
import java.util.HashSet;
import java.util.TreeSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Collections;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
//import org.apache.commons.jxpath.ri.model.dom.DOMAttributePointer;
import org.apache.cocoon.Constants;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.components.validation.Validator;
import org.apache.cocoon.components.validation.Violation;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
/**
* <p>
* Encapsulates a form bean and the validation result
* in a single class. It is created automatically by the
* FormValidatingAction
* </p>
*
* NOTE: This class is NOT thread safe
*
* @author Ivelin Ivanov, [EMAIL PROTECTED]
* @version $Revision: 1.1 $ $Date: 2002/05/20 07:19:25 $
*/
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 SortedSet getViolations()
{
return violations_;
}
public void clearViolations()
{
violations_ = 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" );
Pointer pointer = jxcontext_.locateValue( xpath );
setValue( pointer, value );
}
public void setValue(String xpath, Object[] values)
{
Pointer pointer = jxcontext_.locateValue( xpath );
Object property = pointer.getValue();
// 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() )
{
java.lang.System.arraycopy(
values, 0,
property, 0,
values.length );
}
else if (property instanceof Collection)
{
Collection cl = (Collection) property;
cl.clear();
cl.addAll ( java.util.Arrays.asList ( values ) );
}
// otherwise set the value of the first element
// (and the only) from the values array
else
{
this.setValue( pointer, values[0] );
}
}
protected void setValue( Pointer pointer, Object value)
{
Object property = pointer.getValue();
if ( property != null )
{
// handle DOM elements
if (property instanceof Element)
{
String textPath = pointer.asPath() + "/text()";
setValue( textPath, value );
}
else if (property instanceof Text)
{
Text node = (Text) property;
node.setNodeValue ( value.toString() );
}
/*
else if (pointer instanceof DOMAttributePointer)
{
Attr node = (Attr) ( ( (DOMAttributePointer)pointer).getBaseValue()
);
node.setNodeValue ( value.toString() );
}
*/
else
{
Object newValue = convertType( value, property.getClass () );
pointer.setValue( newValue );
}
}
// set null value
else pointer.setValue( value );
}
/**
* Attempts to convert the request parameter
* String value to the actual model property type
*/
public Object convertType(Object value, Class requiredType)
{
value = Types.convert(value, requiredType);
return value;
}
/**
* 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" );
Pointer pointer = jxcontext_.locateValue( xpath );
Object property = pointer.getValue();
if ( property != null)
{
// handle DOM elements
if (property instanceof Element)
{
String textPath = pointer.asPath() + "/text()";
property = getValue( textPath );
}
else if (property instanceof Text)
{
Text node = (Text) property;
property = node.getData();
}
}
return property;
}
/**
* Resolves a nodeset selector
* into a list of concrete node locations
* @param xpath the nodeset selector
*
* @return a Set of XPath strings pointint to
* each nodeset satisfying the nodeset selector
*
*/
public Set locate( String xpathSelector )
{
if (model_ == null)
throw new IllegalStateException( "Form model not set" );
Set nodeset = new HashSet();
Iterator iter = jxcontext_.locate( xpathSelector ).iterator ();
while ( iter.hasNext() )
{
Pointer nextPointer = (Pointer) iter.next();
nodeset.add ( nextPointer.asPath() );
}
return nodeset;
}
/**
* Performs complete validation
* of the form model
*/
public boolean validate()
{
return validate( null );
}
/**
*
* @param 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 );
violations_ = validator_.validate( model_ );
if (violations_ == null) return true;
else return false;
}
/**
* <p>
* Populates an HTML Form POST into the XMLForm model (JavaBean or DOM
node).
*
* 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
*
*
* @todo provide a more sophisticated examples with checkboxes, multi
choice,
* radio button, text area, file upload, etc.
* </p>
*/
public void populate( Map objectModel )
{
// clean violations_ set
violations_ = null;
// let listeners know that
// population is about to start
reset();
// generic data format violations
// gathered during population
SortedSet pviolations = new TreeSet();
Request request =getRequest( objectModel );
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 );
try
{
setValue( path, values );
}
catch (IllegalArgumentException ex)
{
Violation v = new Violation();
v.setPath( path );
v.setMessage( VIOLATION_MESSAGE_DATA_FORMAT_ERROR );
pviolations.add( v );
}
} // while
// validate form model
autoValidate( objectModel );
// merge violation sets
if ( violations_ != null)
{
violations_.addAll( pviolations );
}
else
{
if ( !pviolations.isEmpty () ) violations_ = pviolations;
}
}
/**
*
* Convenience method invoked after populate()
* By default it performs Form model validation.
* If default validation is not necessary or the validation
* criteria needs to be different, subclasses can override
* this method to change the behaviour.
*
*/
protected void autoValidate( Map objectModel )
{
// perform validation for the phase
// which matches the name of the current form view
// if one is available
String formView = getFormView( objectModel );
if ( formView != null)
{
validate( formView );
}
}
/**
* filters custom request parameter
* not refering to the model
*
* @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 ) )
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 objectModel )
{
Request request =getRequest( objectModel );
return (String) getRequest( objectModel ).getParameter (
Form.FORM_VIEW_PARAM );
}
/**
*
* This method is called before
* the form is populated with request parameters.
*
* Semanticly 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 objectMap
* @param id the form id
*/
public static Form lookup ( Map objectModel, String id )
{
Request request =getRequest( objectModel );
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 objectMap
* @param id the form id
*/
public static void remove ( Map objectModel, String id )
{
Request request =getRequest( objectModel );
request.removeAttribute( id );
Session session = request.getSession( false );
if (session != null) session.removeAttribute( id );
}
/**
* Saves the form in the request or session
*
* @param objectMap
* @param isSessionScope if true the form will be bound in the session,
otherwise request
*/
public void save ( Map objectModel, String scope )
{
Request request =getRequest( objectModel );
if ( lookup( objectModel, 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 objectModel )
{
return (Request)objectModel.get(ObjectModelHelper.REQUEST_OBJECT);
}
/** the set of violations the model commited during validation */
private SortedSet violations_ = null;
/** 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
*
* @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;
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/xmlform/FormListener.java
Index: FormListener.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xmlform/FormListener.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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;
/**
* <p>
* Defines events fired by a Form object
*
* </p>
*
*
* @author Ivelin Ivanov, [EMAIL PROTECTED]
* @version $Revision: 1.1 $ $Date: 2002/05/20 07:19:25 $
*/
public interface FormListener
{
/**
* This method is called before
* the form is populated with request parameters.
*
* Semanticly 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
*
*/
public void reset( Form form );
/**
* filters custom request parameter
* not refering to the model
*/
public boolean filterRequestParameter( Form form, String parameterName );
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/xmlform/Types.java
Index: Types.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xmlform/Types.java,v
1.1 2002/05/20 07:19:25 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:25 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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 java.util.*;
import java.lang.reflect.*;
import org.apache.commons.jxpath.*;
/**
*
* Temporary replacement of the JXPath Type class
* while Dmitri implements conversion constructor
* lookup.
*
* see hasConversionConstructor()
*
*
* @author Dmitri Plotnikov
* @version $Revision: 1.1 $ $Date: 2002/05/20 07:19:25 $
*/
public class Types {
public static final int NO_MATCH = 0;
public static final int APPROXIMATE_MATCH = 1;
public static final int EXACT_MATCH = 2;
private static final Object[] EMPTY_ARRAY = new Object[0];
public static Constructor lookupConstructor(Class targetClass, Object[]
parameters){
boolean tryExact = true;
int count = parameters.length;
Class types[] = new Class[count];
for (int i = 0; i < count; i++){
Object param = parameters[i];
if (param != null){
types[i] = param.getClass();
}
else {
types[i] = null;
tryExact = false;
}
}
Constructor constructor = null;
if (tryExact){
// First - without type conversion
try {
constructor = targetClass.getConstructor(types);
if (constructor != null){
return constructor;
}
}
catch (NoSuchMethodException ex){
}
}
int currentMatch = 0;
boolean ambiguous = false;
// Then - with type conversion
Constructor[] constructors = targetClass.getConstructors();
for (int i = 0; i < constructors.length; i++){
int match =
Types.matchParameterTypes(constructors[i].getParameterTypes(), parameters);
if (match != Types.NO_MATCH){
if (match > currentMatch){
constructor = constructors[i];
currentMatch = match;
ambiguous = false;
}
else if (match == currentMatch){
ambiguous = true;
}
}
}
if (ambiguous){
throw new RuntimeException("Ambigous constructor " +
Arrays.asList(parameters));
}
return constructor;
}
public static Method lookupStaticMethod(Class targetClass, String name,
Object[] parameters){
boolean tryExact = true;
int count = parameters.length;
Class types[] = new Class[count];
for (int i = 0; i < count; i++){
Object param = parameters[i];
if (param != null){
types[i] = param.getClass();
}
else {
types[i] = null;
tryExact = false;
}
}
Method method = null;
if (tryExact){
// First - without type conversion
try {
method = targetClass.getMethod(name, types);
if (method != null &&
Modifier.isStatic(method.getModifiers())){
return method;
}
}
catch (NoSuchMethodException ex){
}
}
int currentMatch = 0;
boolean ambiguous = false;
// Then - with type conversion
Method[] methods = targetClass.getMethods();
for (int i = 0; i < methods.length; i++){
if (Modifier.isStatic(methods[i].getModifiers()) &&
methods[i].getName().equals(name)){
int match =
Types.matchParameterTypes(methods[i].getParameterTypes(), parameters);
if (match != Types.NO_MATCH){
if (match > currentMatch){
method = methods[i];
currentMatch = match;
ambiguous = false;
}
else if (match == currentMatch){
ambiguous = true;
}
}
}
}
if (ambiguous){
throw new RuntimeException("Ambigous method call: " + name);
}
return method;
}
public static Method lookupMethod(Class targetClass, String name,
Object[] parameters){
if (parameters.length < 1 || parameters[0] == null){
return null;
}
if (Types.matchType(targetClass, parameters[0]) == Types.NO_MATCH){
return null;
}
targetClass = convert(parameters[0], targetClass).getClass();
boolean tryExact = true;
int count = parameters.length - 1;
Class types[] = new Class[count];
Object arguments[] = new Object[count];
for (int i = 0; i < count; i++){
Object param = parameters[i+1];
arguments[i] = param;
if (param != null){
types[i] = param.getClass();
}
else {
types[i] = null;
tryExact = false;
}
}
Method method = null;
if (tryExact){
// First - without type conversion
try {
method = targetClass.getMethod(name, types);
if (method != null &&
!Modifier.isStatic(method.getModifiers())){
return method;
}
}
catch (NoSuchMethodException ex){
}
}
int currentMatch = 0;
boolean ambiguous = false;
// Then - with type conversion
Method[] methods = targetClass.getMethods();
for (int i = 0; i < methods.length; i++){
if (!Modifier.isStatic(methods[i].getModifiers()) &&
methods[i].getName().equals(name)){
int match =
Types.matchParameterTypes(methods[i].getParameterTypes(), arguments);
if (match != Types.NO_MATCH){
if (match > currentMatch){
method = methods[i];
currentMatch = match;
ambiguous = false;
}
else if (match == currentMatch){
ambiguous = true;
}
}
}
}
if (ambiguous){
throw new RuntimeException("Ambigous method call: " + name);
}
return method;
}
public static int matchParameterTypes(Class types[], Object parameters[]){
if (types.length != parameters.length){
return NO_MATCH;
}
int totalMatch = EXACT_MATCH;
for (int i = 0; i < types.length; i++){
int match = matchType(types[i], parameters[i]);
if (match == NO_MATCH){
return NO_MATCH;
}
if (match < totalMatch){
totalMatch = match;
}
}
return totalMatch;
}
public static int matchType(Class expected, Object object){
if (object == null){
return APPROXIMATE_MATCH;
}
Class actual = object.getClass();
if (expected.equals(actual)){
return EXACT_MATCH;
}
if (expected.isAssignableFrom(actual)){
return EXACT_MATCH;
}
if (canConvert(object, expected)){
return APPROXIMATE_MATCH;
}
return NO_MATCH;
}
public static boolean canConvert(Object object, Class toType){
Class fromType = object.getClass();
if (fromType.equals(toType)){
return true;
}
if (toType.isAssignableFrom(fromType)){
return true;
}
if (toType == String.class){
return true;
}
if (hasConversionConstructor( toType, new Object[] {object} ))
{
return true;
}
if (object instanceof Boolean){
if (toType == boolean.class ||
Number.class.isAssignableFrom(toType)){
return true;
}
}
else if (object instanceof Number){
if (toType.isPrimitive() ||
Number.class.isAssignableFrom(toType)){
return true;
}
}
else if (object instanceof Character){
if (toType == char.class){
return true;
}
}
else if (object instanceof String){
if (toType.isPrimitive()){
return true;
}
}
else if (object instanceof ExpressionContext){
if (Collection.class.isAssignableFrom(toType)){
return true;
}
// TBD: array arguments
Object value =
((ExpressionContext)object).getContextNodePointer().getValue();
return canConvert(value, toType);
}
// TBD: date conversion to/from string
return false;
}
public static Object convert(Object object, Class toType){
if (object == null){
return null;
}
if (object instanceof ExpressionContext){
if (Collection.class.isAssignableFrom(toType)){
List list = ((ExpressionContext)object).getContextNodeList();
Collection result = new ArrayList();
if (toType == List.class || toType == ArrayList.class){
result = new ArrayList();
}
else if (toType == Vector.class){
result = new Vector();
}
else if (toType == Set.class || toType == HashSet.class){
result = new HashSet();
}
int count = list.size();
for (int i = 0; i < count; i++){
Pointer ptr = (Pointer)list.get(i);
result.add(ptr.getValue());
}
return result;
}
else {
Object value =
((ExpressionContext)object).getContextNodePointer().getValue();
return convert(value, toType);
}
}
Class fromType = object.getClass();
if (fromType.equals(toType) || toType.isAssignableFrom(fromType)){
return object;
}
if (toType == String.class){
return object.toString();
}
if (object instanceof Boolean){
if (toType == boolean.class){
return object;
}
boolean value = ((Boolean)object).booleanValue();
return allocateNumber(toType, value ? 1 : 0);
}
else if (object instanceof Number){
double value = ((Number)object).doubleValue();
if (toType == boolean.class || toType == Boolean.class){
return value == 0.0 ? Boolean.FALSE : Boolean.TRUE;
}
if (toType.isPrimitive() ||
Number.class.isAssignableFrom(toType)){
return allocateNumber(toType, value);
}
}
else if (object instanceof Character){
if (toType == char.class){
return object;
}
}
else if (object instanceof String){
if (toType == boolean.class || toType == Boolean.class){
return new Boolean((String)object);
}
if (toType == char.class || toType == Character.class){
return new Character(((String)object).charAt(0));
}
if (toType == byte.class || toType == Byte.class){
return new Byte((String)object);
}
if (toType == short.class || toType == Short.class){
return new Short((String)object);
}
if (toType == int.class || toType == Integer.class){
return new Integer((String)object);
}
if (toType == long.class || toType == Long.class){
return new Long((String)object);
}
if (toType == float.class || toType == Float.class){
return new Float((String)object);
}
if (toType == double.class || toType == Double.class){
return new Double((String)object);
}
}
Object[] params = new Object[] {object};
if (hasConversionConstructor( toType, params ))
{
Constructor constructor = lookupConstructor( toType, params);
try
{
return constructor.newInstance ( params );
}
catch (Exception ex)
{
throw new RuntimeException("Instantiation failed for Class [" +
toType +"], and constructor with parameter value [" + object + "]" + "\n" + ex);
}
}
return object;
}
private static Number allocateNumber(Class type, double value){
if (type == Byte.class || type == byte.class){
return new Byte((byte)value);
}
if (type == Short.class || type == short.class){
return new Short((short)value);
}
if (type == Integer.class || type == int.class){
return new Integer((int)value);
}
if (type == Long.class || type == long.class){
return new Long((long)value);
}
if (type == Float.class || type == float.class){
return new Float((float)value);
}
if (type == Double.class || type == double.class){
return new Double(value);
}
return null;
}
/**
* tests for conversion constructor
* which will allow:
* toType o = new toType( fromTypeInstance )
*
*/
protected static boolean hasConversionConstructor( Class toType, Object[]
parameters )
{
java.lang.reflect.Constructor constructor = null;
constructor = lookupConstructor( toType, parameters);
if (constructor != null) return true;
else return false;
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/samples/xmlform/UserBean.java
Index: UserBean.java
===================================================================
package org.apache.cocoon.samples.xmlform;
import java.util.Set;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
/**
*
* 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.
*
*/
public class UserBean
{
private String fname = "Donald";
private String lname = "Duck";
private String email = "[EMAIL PROTECTED]";
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 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 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 RuntimeException("Failed to initialize DOM factory. Root
cause: \n" + 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 List getFavorite()
{
return favorites;
}
public void setFavorite( List newFavorites )
{
favorites = newFavorites;
}
public void initRoles()
{
roles = new ArrayList();
}
public void initHobbies()
{
hobbies = new String[] {"", "", "", "", ""};
}
public void initFavorites()
{
favorites.add( "http://xml.apache.org/cocoon" );
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
xml-cocoon2/src/java/org/apache/cocoon/samples/xmlform/WizardAction.java
Index: WizardAction.java
===================================================================
/*
* $Header:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/samples/xmlform/WizardAction.java,v
1.1 2002/05/20 07:19:26 ivelin Exp $
* $Revision: 1.1 $
* $Date: 2002/05/20 07:19:26 $
*
* ====================================================================
* 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 [EMAIL PROTECTED]
*
* 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;
// Java classes
import java.util.Map;
import java.util.HashMap;
import java.util.SortedSet;
import java.util.Iterator;
import java.util.Properties;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.File;
// XML classes
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.TransformerException;
import org.xml.sax.InputSource;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
// Framework classes
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.excalibur.pool.Poolable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
// Cocoon classes
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.acting.*;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.Context;
// Schematron classes
import org.apache.cocoon.components.validation.SchemaFactory;
import org.apache.cocoon.components.validation.Schema;
import org.apache.cocoon.components.validation.Validator;
import org.apache.cocoon.components.validation.Violation;
// Cocoon Form
import org.apache.cocoon.acting.AbstractXMLFormAction;
import org.apache.cocoon.components.xmlform.Form;
import org.apache.cocoon.components.xmlform.FormListener;
/**
* This action demonstrates
* a relatively complex form handling scenario.
*
* @author Ivelin Ivanov <[EMAIL PROTECTED]>
*/
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.
*
*
* @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>if getCommand().equals("Cancel") return page("input");</pre>
*
*/
protected Map prepare()
{
if ( getCommand() == null )
{
// initial link
return page( VIEW_START );
}
else if ( Form.lookup ( getObjectModel(), getFormId() ) == null)
{
// session expired
return page( VIEW_START );
}
else if ( getCommand().equals( CMD_START ) )
{
// reset state by removing old form
// if one exists
Form.remove( getObjectModel(), getFormId() );
getForm().addFormListener( this );
return page( VIEW_USERID );
}
// get ready for action
// if not ready return page("whereNext");
return null;
}
/**
* Invoked after form population
*
* 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 control flow 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 control flow
// 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 control flow 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 ) )
{
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 Form.populate()
* before population starts.
*
* This is the place to handle unchecked checkboxes.
*
*/
public void reset( Form form )
{
// based on the current form view
// make some decisions regarding checkboxes, etc.
String formView = getFormView();
if ( formView.equals ( VIEW_DEPLOYMENT ) )
{
// deal with the publish checkbox
form.setValue( "/publish", Boolean.FALSE );
}
else if ( formView.equals ( VIEW_USERID ) )
{
// deal with the publish checkbox
UserBean ub = (UserBean) form.getModel();
ub.initRoles ();
}
}
/**
* 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)
{
// TBD
return false;
}
public String getFile( String FileName ) {
try
{
final String FILE_PREFIX = "file:";
String path = getSourceResolver().resolve(FileName).getSystemId();
if(path.startsWith(FILE_PREFIX))
path = path.substring(FILE_PREFIX.length());
return path;
}
catch(Exception e)
{
getLogger().error("could not read mapping file",e);
return null;
}
}
private Validator validator_ = null;
private boolean initialized_ = false;
}
1.1 xml-cocoon2/src/webapp/mount/xmlform/README.txt
Index: README.txt
===================================================================
The XMLForm framework is inspired by Apache Jakarta Struts and W3C XForms.
Its goal is to:
* Ease the development of sophisticated web applications utilizing complex
data types and multi-page transactions
* Provide an automated 2 way mapping between HTML Forms <-> XML <-> JavaBeans
* Use standard XML validation languages like XML Schema, Relax-NG, Schematron
for data validation
* Promote natural reuse of validation, binding and business logic between
cocoon actions (which are best utilized for interactive clients driven web
applications ) and web services (which are in turn becoming the standard
machine-to-machine web technology)
* In doing so, utilize as much as possible of the existing cocoon 2
technology. More specifically: actions, action sets, cocoon-action parameters
and transformers.
* Utilize existing XPath tools like JXPath for read/write access to
JavaBeans, DOM nodes and mixed
objects.
--------------------------------------------------------------------------------------------
The current implementation offers the following features:
1) Automated 2 way binding of HTML Forms to JavaBeans (and DOM nodes) through
XPath
2) Automatic validation of JavaBeans(and DOM nodes) through Schematron schemas
3) Intermediate XForms like XML markup for form views
--------------------------------------------------------------------------------------------
To try the demo, link to:
http://localhost:8080/cocoon/mount/xmlform/wizard.html
--------------------------------------------------------------------------------------------
For questions contact:
Ivelin Ivanov, [EMAIL PROTECTED]
--------------------------------------------------------------------------------------------
Following is a summary provided by Daniel Fagerstrom <[EMAIL PROTECTED]>
Background
----------
The aim of XMLForm, is to build and edit an xml document (called the
instance), subject to constraints from some schema (XMLSchema, Schematron,
...), through a sequence of form pages. The instance is either a
dom-document or a Java bean-structure or a mix. XMLForm consist, of
three main components:
* Form - is responsible for the instance and validation of it. Form objects
are stored in request attributes for one page forms and session attributes
for wizards (multi page forms). A Form can be populated from the request
parameters. This is the "model in MVC terms.
* XMLFormTransformer - takes a form descriptor, (similar to XForms) as input
and fill it with data and error messages from a Form object that is
referred in an attribute. This is the "view" in MVC terms.
* AbstractXMLFormAction, (WizardAction) - creates the Form object if
necessary and populates it with data based on the request parameters. It can
also take care of flow handling and checkbox state. This is the "controller"
in MVC terms.
--------------------------------------------------------------------------------------------
Following are copies of the announcement emails send to the Cocoon
development mailing list.
[email protected] <[email protected]>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----- Original Message -----
From: "Ivelin Ivanov" <[EMAIL PROTECTED]>
To: <[email protected]>
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" <[EMAIL PROTECTED]>
To: <[email protected]>
Cc: "Sam Robertson" <[EMAIL PROTECTED]>; "Torsten Curdt" <[EMAIL PROTECTED]>;
"Dmitri Plotnikov" <[EMAIL PROTECTED]>; <[EMAIL PROTECTED]>; <[EMAIL
PROTECTED]>; <[EMAIL PROTECTED]>; <[EMAIL PROTECTED]>; <[EMAIL PROTECTED]>
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" <[EMAIL PROTECTED]>
To: <[email protected]>
Cc: "Oliver Becker" <[EMAIL PROTECTED]>; "Rick Jelliffe" <[EMAIL PROTECTED]>;
"Dmitri Plotnikov" <[EMAIL PROTECTED]>
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 xml-cocoon2/src/webapp/mount/xmlform/sitemap.xmap
Index: sitemap.xmap
===================================================================
<?xml version="1.0"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<!-- =========================== Components
================================ -->
<map:components>
<map:actions>
<map:action name="WizardAction"
src="org.apache.cocoon.samples.xmlform.WizardAction" logger="webapp.xmlform"/>
</map:actions>
<map:generators default="file"/>
<map:transformers default="xslt">
<map:transformer name="xmlform"
src="org.apache.cocoon.transformation.XMLFormTransformer"
logger="webapp.xmlform"/>
</map:transformers>
<map:readers default="resource"/>
<map:serializers default="html"/>
<map:selectors default="browser"/>
<map:matchers default="wildcard">
<map:matcher name="wildcard"
src="org.apache.cocoon.matching.WildcardURIMatcherFactory"/>
</map:matchers>
</map:components>
<!-- =========================== Resources
================================= -->
<map:resources>
</map:resources>
<!-- =========================== Pipelines
================================= -->
<map:pipelines>
<map:pipeline>
<map:match pattern="">
<map:redirect-to uri="wizard.html"/>
</map:match>
<!-- A non-trivial example - Feedback Wizard -->
<map:match pattern="wizard.html">
<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"/>
<!-- Content transformation logic -->
<map:generate src="wizard/{page}.xml"/>
<map:transform type="xmlform" label="xml"/>
<map:transform src="stylesheets/wizard2html.xsl"/>
<map:transform src="../../stylesheets/xmlform/xmlform2html.xsl"/>
<map:serialize type="html"/>
</map:act>
</map:match>
</map:pipeline>
</map:pipelines>
</map:sitemap>
<!-- end of file -->
1.1
xml-cocoon2/src/webapp/mount/xmlform/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, [EMAIL PROTECTED], 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(.) > 3"
diagnostics="dname dcount">
First name should be at least 4 characters.
</assert>
<assert test="string-length(.) < 20">
First name should be less than 20 characters.
</assert>
</rule>
<rule context="/lastName">
<assert test="string-length(.) > 3"
diagnostics="dname dcount">
Last name should be at least 4 characters.
</assert>
<assert test="string-length(.) < 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() > 0 and number(.) < 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() > 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() > 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
xml-cocoon2/src/webapp/mount/xmlform/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, [EMAIL PROTECTED], May 2002
original Author: Konstantin Piroumian, [EMAIL PROTECTED], 21-Feb-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 : #0086b2;}
HR{color : #0086b2;}
input { background-color: #FFFFFF; color:
#000099 }
table { background-color: #EEEEEE; color:
#000099; font-size: x-small; border: 2px solid brown;}
select { background-color: #FFFFFF; color:
#000099 }
.error { color: #FF0000; }
.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; }
]]>
</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:copy-of select="." />
<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="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">
<xsl:apply-templates select="*"/>
</table>
</td>
</tr>
</xsl:template>
<xsl:template match="xf:[EMAIL PROTECTED]">
<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:*">
<tr>
<td align="left">
<xsl:value-of select="xf:caption" />
</td>
<td>
<xsl:copy-of select="." />
</td>
<xsl:if test="xf:violation">
<td 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>
</xsl:template>
<xsl:template match="*">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
1.1 xml-cocoon2/src/webapp/mount/xmlform/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 xml-cocoon2/src/webapp/mount/xmlform/wizard/confirm.xml
Index: confirm.xml
===================================================================
<?xml version="1.0" ?>
<!--
XMLForm instance document for the Cocoon Feedback Wizard.
Original Author: Torsten Curdt, [EMAIL PROTECTED], March 2002
Author: Ivelin Ivanov, [EMAIL PROTECTED], April 2002
-->
<document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
<xf:form id="form-feedback" view="confirm" action="wizard.html">
<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>
<!-- 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() <= 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:submit>
<xf:submit id="next" class="button">
<xf:caption>Finish</xf:caption>
</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
xml-cocoon2/src/webapp/mount/xmlform/wizard/deployment.xml
Index: deployment.xml
===================================================================
<?xml version="1.0" ?>
<!--
XMLForm instance document for the Cocoon Feedback Wizard.
Original Author: Torsten Curdt, [EMAIL PROTECTED], March 2002
Author: Ivelin Ivanov, [EMAIL PROTECTED], April 2002
-->
<document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
<xf:form id="form-feedback" view="deployment" action="wizard.html">
<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: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
a 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() <= 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:submit>
<xf:submit id="next" class="button">
<xf:caption>Next</xf:caption>
</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 xml-cocoon2/src/webapp/mount/xmlform/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.html">Go to home page.</a>
</h3>
</td>
</tr>
</table>
</document>
1.1 xml-cocoon2/src/webapp/mount/xmlform/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">
<code>
This wizard will collect feedback information
for the
<a href="http://xml.apache.org/cocoon">Apache Cocoon</a>
project !
</code>
</td>
</tr>
<tr>
<td align="center">
<h3>
<a href="wizard.html?cocoon-action-start=true">
Start!
</a>
</h3>
</td>
</tr>
</table>
</document>
1.1 xml-cocoon2/src/webapp/mount/xmlform/wizard/system.xml
Index: system.xml
===================================================================
<?xml version="1.0" ?>
<!--
XMLForm instance document for the Cocoon Feedback Wizard.
Original Author: Torsten Curdt, [EMAIL PROTECTED], March 2002
Author: Ivelin Ivanov, [EMAIL PROTECTED], April 2002
-->
<document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
<xf:form id="form-feedback" view="system" action="wizard.html">
<xf:caption>System Information</xf:caption>
<error>
<xf:violations class="error"/>
</error>
<xf:group ref="/system">
<xf:selectOne ref="os">
<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</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:submit>
<xf:submit id="next" class="button">
<xf:caption>Next</xf:caption>
</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
xml-cocoon2/src/webapp/mount/xmlform/wizard/userIdentity.xml
Index: userIdentity.xml
===================================================================
<?xml version="1.0" ?>
<!--
XMLForm instance document for the Cocoon Feedback Wizard.
Original Author: Torsten Curdt, [EMAIL PROTECTED], March 2002
Author: Ivelin Ivanov, [EMAIL PROTECTED], April 2002
-->
<document xmlns:xf="http://xml.apache.org/cocoon/xmlform/2002">
<xf:form id="form-feedback" view="userIdentity" action="wizard.html">
<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: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: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:submit id="next" class="button">
<xf:caption>Next</xf:caption>
</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>
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]