ivelin 02/04/07 00:58:28 Modified: src/scratchpad/src/org/apache/cocoon/samples/xmlform TestBean.java ValidatingFormAction.java src/scratchpad/src/org/apache/cocoon/validation/schematron SchematronSchema.java ValidationResult.java src/scratchpad/webapp/mount/xmlform formbean2html-Demo2.xsl insertFormBean-Demo2.xml sitemap.xmap src/scratchpad/webapp/mount/xmlform/castor-mappings test-mapping.xml Added: src/scratchpad/src/org/apache/cocoon/validation Schema.java SchemaFactory.java Validator.java Violation.java ZNestedBean.java ZTestBean.java ZValidationTest.java zxmlform-sch-report-test.xml src/scratchpad/src/org/apache/cocoon/validation/schematron SchematronFactory.java SchematronValidator.java src/scratchpad/src/org/apache/cocoon/xmlform Form.java Removed: src/scratchpad/src/org/apache/cocoon/validation/schematron SchemaBuilder.java Validator.java ZSchematronTest.java Log: Cocoon XMLForm update. Clean-up and preparation for another framework extension round. - Abstract validation API improved with ideas from JARV & Preceptor - Castor mapping is no longer required for the Form Instance and Violations - formbean2html-Demo2.xsl size reduced by 30% by better use of XSLT - insertFormBean-Demo2.xml reduced to one line - FormValidationAction refactored and prepared to become generic XMLFormAction . Revision Changes Path 1.2 +1 -1 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/samples/xmlform/TestBean.java Index: TestBean.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/samples/xmlform/TestBean.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- TestBean.java 4 Apr 2002 12:28:49 -0000 1.1 +++ TestBean.java 7 Apr 2002 08:58:27 -0000 1.2 @@ -12,7 +12,7 @@ public TestBean(){ preferences.add("likeVodka"); - preferences.add("likeSkiing"); + preferences.add("likeSkiing"); } public TestBean(String newName,String newScope){ 1.2 +124 -44 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/samples/xmlform/ValidatingFormAction.java Index: ValidatingFormAction.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/samples/xmlform/ValidatingFormAction.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ValidatingFormAction.java 4 Apr 2002 12:28:49 -0000 1.1 +++ ValidatingFormAction.java 7 Apr 2002 08:58:27 -0000 1.2 @@ -1,12 +1,12 @@ /* - * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/samples/xmlform/ValidatingFormAction.java,v 1.1 2002/04/04 12:28:49 ivelin Exp $ - * $Revision: 1.1 $ - * $Date: 2002/04/04 12:28:49 $ + * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/samples/xmlform/ValidatingFormAction.java,v 1.2 2002/04/07 08:58:27 ivelin Exp $ + * $Revision: 1.2 $ + * $Date: 2002/04/07 08:58:27 $ * * ==================================================================== * The Apache Software License, Version 1.1 * - * + * * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. @@ -65,6 +65,8 @@ // 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; @@ -89,11 +91,15 @@ import org.apache.cocoon.environment.Context; // Schematron classes -import org.apache.cocoon.validation.schematron.Validator; -import org.apache.cocoon.validation.schematron.ValidationResult; - +import org.apache.cocoon.validation.SchemaFactory; +import org.apache.cocoon.validation.Schema; +import org.apache.cocoon.validation.Validator; +import org.apache.cocoon.validation.Violation; +// Cocoon Form import org.apache.cocoon.xmlform.FormBeanBinder; +import org.apache.cocoon.xmlform.Form; +import org.apache.cocoon.xmlform.ValidationResult; /** * This simple action demonstrates binding between @@ -102,15 +108,13 @@ */ public class ValidatingFormAction extends AbstractAction { - private final String formName_ = "xmlForm"; - private Validator validator_; - - public ValidatingFormAction() - { - } + public static final String OBJECT_MAP_NEXT_PAGE = "nextPage"; + private final String formName_ = "xmlForm"; + private Validator validator_; - public synchronized void setup(SourceResolver resolver) throws org.xml.sax.SAXException, java.io.IOException + public synchronized void setup(SourceResolver resolver) + throws InstantiationException, java.io.IOException { // initialize the schematron Validor with a schema files String fileLocation = getFile( resolver, "schematron/xmlform-sch-report-Demo2.xml" ); @@ -118,7 +122,9 @@ if ( !file.exists () ) throw new RuntimeException("Error: schema file not found !"); InputStream istrm = new FileInputStream ( file ); InputSource is = new InputSource ( istrm ); - validator_ = new Validator( is ); + SchemaFactory schf = SchemaFactory.lookup ( SchemaFactory.NAMESPACE_SCHEMATRON ); + Schema sch = schf.compileSchema ( is ); + validator_ = sch.newValidator(); } @@ -129,42 +135,39 @@ // initialize validator if necessary if (validator_ == null ) setup( resolver ); - String formName = "xmlForm"; - // reset the session state if requested - if ( request.getParameter("reset") != null) session.removeAttribute( formName ); - - TestBean jBean = (TestBean) session.getAttribute( formName ); - if (jBean == null) + if ( request.getParameter("reset") != null) session.removeAttribute( formName_ ); + + Form form = (Form) session.getAttribute( formName_ ); + if (form == null) { // first time here, populate the bean with initial values - jBean = new TestBean(); - session.setAttribute( formName, jBean); + form = new Form(); + form.setInstance( new TestBean() ); + session.setAttribute( formName_, form ); } - else - { - // been here before, update the bean with client's values - FormBeanBinder.bind(request, jBean); - } - // validate state of the bean against a Schematron schema. - // Schema Phase is "Full" - Properties props = new Properties(); - props.put("phase", "Full"); - ValidationResult vres = validator_.validate(jBean, props); - // if the validation result is not empty, then - // make the validation result available to the pipeline - // it can be later checked by a <map:selector/> - // or inserted in the SAX stream by a CastorTransformer - // or maybe even both - if (!vres.isEmpty()) - { - request.setAttribute ( formName + "ValidationResult", vres ); - } - request.setAttribute ( "validationPassed", new Boolean( vres.isEmpty() ) ); + TestBean jBean = (TestBean) form.getInstance(); + + // call prepare in case the bean needs to massaged before population + prepare( jBean ); + + // update the bean with request parameter values + FormBeanBinder.bind(request, jBean); + // apply additional buziness logic to the bean jBean.incrementCount(); - return objectModel; + // validate state of the bean against a Schematron schema. + // Schema Phase is "Full" + SortedSet violations = validate( objectModel, form, "Full" ); + + // set the nextPage control flow parameter + // according to the validation result + if (violations != null) + return nextPage("input"); + else + return nextPage( "success" ); + } public String getFile(SourceResolver sr, String FileName) { @@ -183,5 +186,82 @@ } } + + /** + * Called to determine the exit point of an action. + * The pageName is made available in the objectMap, + * which can be then referenced in the pipeline + * @param pageName logical name for a next page + * @return Map a pipeline objectMap containing the pageName + * + */ + protected Map nextPage( String pageName ) + { + Map objectModel = new HashMap(); + objectModel.put( OBJECT_MAP_NEXT_PAGE, pageName ); + return objectModel; + } + + /** + * This method is called before + * the form bean population. + * Has semantics 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. + * + * @param formBean the actual JavaBean which + * will be populated with the request parameters + */ + protected void prepare(Object formBean) + { + // do nothing by default; + return; + } + + + /** + * validates a bean + * + * @param formBean the bean to be validated + * @param phase the validation phase + */ + protected synchronized SortedSet validate( Map objectModel, Form form ) + { + return validate( objectModel, form, null ); + } + + + /** + * validates a bean + * + * @param formBean the bean to be validated + * @param phase the validation phase + */ + protected synchronized SortedSet validate( Map objectModel, Form form, String phase ) + { + if ( phase != null ) + { + validator_.setProperty ( Validator.PROPERTY_PHASE, phase ); + } + + SortedSet violations = validator_.validate( form.getInstance() ); + + // if the validation result is not empty, then + // make the validation result available to the pipeline + // it can be later checked by a <map:selector/> + // or inserted in the SAX stream by a CastorTransformer + // or maybe even both + if (violations != null) + { + form.setViolation( violations ); + //Request request =(Request)objectModel.get(Constants.REQUEST_OBJECT); + } + return violations; + } + + } 1.1 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/Schema.java Index: Schema.java =================================================================== /* * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/Schema.java,v 1.1 2002/04/07 08:58:27 ivelin Exp $ * $Revision: 1.1 $ * $Date: 2002/04/07 08:58:27 $ * * ==================================================================== * 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.validation; /** * * Created on Sat, April 6, 2002 * * @author [EMAIL PROTECTED] */ public interface Schema { public Validator newValidator() throws InstantiationException; } 1.1 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/SchemaFactory.java Index: SchemaFactory.java =================================================================== /* * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/SchemaFactory.java,v 1.1 2002/04/07 08:58:27 ivelin Exp $ * $Revision: 1.1 $ * $Date: 2002/04/07 08:58:27 $ * * ==================================================================== * 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.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.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/scratchpad/src/org/apache/cocoon/validation/Validator.java Index: Validator.java =================================================================== /* * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/Validator.java,v 1.1 2002/04/07 08:58:27 ivelin Exp $ * $Revision: 1.1 $ * $Date: 2002/04/07 08:58:27 $ * * ==================================================================== * 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.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/scratchpad/src/org/apache/cocoon/validation/Violation.java Index: Violation.java =================================================================== /* * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/Violation.java,v 1.1 2002/04/07 08:58:27 ivelin Exp $ * $Revision: 1.1 $ * $Date: 2002/04/07 08:58:27 $ * * ==================================================================== * 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.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 return (getMessage().compareTo( v.getMessage () ) ); } private String xpath_; private String message_; } 1.1 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/ZNestedBean.java Index: ZNestedBean.java =================================================================== package org.apache.cocoon.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/scratchpad/src/org/apache/cocoon/validation/ZTestBean.java Index: ZTestBean.java =================================================================== package org.apache.cocoon.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/scratchpad/src/org/apache/cocoon/validation/ZValidationTest.java Index: ZValidationTest.java =================================================================== /* * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/ZValidationTest.java,v 1.1 2002/04/07 08:58:27 ivelin Exp $ * $Revision: 1.1 $ * $Date: 2002/04/07 08:58:27 $ * * ==================================================================== * 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.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.validation.SchemaFactory; import org.apache.cocoon.validation.Schema; import org.apache.cocoon.validation.Validator; import org.apache.cocoon.validation.Violation; import org.apache.cocoon.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/scratchpad/src/org/apache/cocoon/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.2 +11 -4 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/SchematronSchema.java Index: SchematronSchema.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/SchematronSchema.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SchematronSchema.java 4 Apr 2002 06:21:50 -0000 1.1 +++ SchematronSchema.java 7 Apr 2002 08:58:28 -0000 1.2 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/SchematronSchema.java,v 1.1 2002/04/04 06:21:50 ivelin Exp $ - * $Revision: 1.1 $ - * $Date: 2002/04/04 06:21:50 $ + * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/SchematronSchema.java,v 1.2 2002/04/07 08:58:28 ivelin Exp $ + * $Revision: 1.2 $ + * $Date: 2002/04/07 08:58:28 $ * * ==================================================================== * The Apache Software License, Version 1.1 @@ -66,6 +66,9 @@ import java.util.ArrayList; import java.util.Collection; +import org.apache.cocoon.validation.Schema; +import org.apache.cocoon.validation.Validator; + /** * Represents a Schematron Schema @@ -75,7 +78,7 @@ * * @author Ivelin Ivanov, [EMAIL PROTECTED], [EMAIL PROTECTED] */ -public class SchematronSchema +public class SchematronSchema implements Schema { private String title_; @@ -151,5 +154,9 @@ phases_.add ( p ); } + public Validator newValidator () throws InstantiationException + { + return new SchematronValidator( this ); + } } 1.2 +63 -3 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/ValidationResult.java Index: ValidationResult.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/ValidationResult.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ValidationResult.java 4 Apr 2002 06:21:50 -0000 1.1 +++ ValidationResult.java 7 Apr 2002 08:58:28 -0000 1.2 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/ValidationResult.java,v 1.1 2002/04/04 06:21:50 ivelin Exp $ - * $Revision: 1.1 $ - * $Date: 2002/04/04 06:21:50 $ + * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/ValidationResult.java,v 1.2 2002/04/07 08:58:28 ivelin Exp $ + * $Revision: 1.2 $ + * $Date: 2002/04/07 08:58:28 $ * * ==================================================================== * The Apache Software License, Version 1.1 @@ -62,10 +62,15 @@ package org.apache.cocoon.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.validation.Violation; /** * Represents the result of a Schematron validation process @@ -112,6 +117,61 @@ 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/scratchpad/src/org/apache/cocoon/validation/schematron/SchematronFactory.java Index: SchematronFactory.java =================================================================== /* * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/SchematronFactory.java,v 1.1 2002/04/07 08:58:28 ivelin Exp $ * $Revision: 1.1 $ * $Date: 2002/04/07 08:58:28 $ * * ==================================================================== * 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.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.validation.SchemaFactory; import org.apache.cocoon.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/scratchpad/src/org/apache/cocoon/validation/schematron/SchematronValidator.java Index: SchematronValidator.java =================================================================== /* * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/validation/schematron/SchematronValidator.java,v 1.1 2002/04/07 08:58:28 ivelin Exp $ * $Revision: 1.1 $ * $Date: 2002/04/07 08:58:28 $ * * ==================================================================== * 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.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.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 instanceof String) ) ) { throw new IllegalArgumentException(" Property " + property + " is not supported or value is invalid"); } else phaseProperty_ = (String) value; } } 1.1 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/xmlform/Form.java Index: Form.java =================================================================== /* * $Header: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/xmlform/Form.java,v 1.1 2002/04/07 08:58:28 ivelin Exp $ * $Revision: 1.1 $ * $Date: 2002/04/07 08:58:28 $ * * ==================================================================== * 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.xmlform; import java.util.Collection; /** * <p> * Encapsulates a form bean and the validation result * in a single class. It is created automatically by the * FormValidatingAction * </p> * * * @author Ivelin Ivanov, [EMAIL PROTECTED] * @version $Revision: 1.1 $ $Date: 2002/04/07 08:58:28 $ */ public class Form { public Object getInstance() { return instance_; } public void setInstance( Object newInstance ) { instance_ = newInstance; } public Collection getViolation() { return violations_; } public void setViolation( Collection vs ) { violations_ = vs; } private Collection violations_ = null; private Object instance_ = null; } 1.2 +9 -18 xml-cocoon2/src/scratchpad/webapp/mount/xmlform/formbean2html-Demo2.xsl Index: formbean2html-Demo2.xsl =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/webapp/mount/xmlform/formbean2html-Demo2.xsl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- formbean2html-Demo2.xsl 4 Apr 2002 06:21:51 -0000 1.1 +++ formbean2html-Demo2.xsl 7 Apr 2002 08:58:28 -0000 1.2 @@ -9,7 +9,7 @@ <html> <body> Please edit and submit: <br/> - <xsl:apply-templates select="/xmlform/instance/*"/> + <xsl:apply-templates select="/form/*"/> <hr/> <p> Copy of input document (sorry for the lousy format, view source to see the xml): @@ -21,10 +21,9 @@ </html> </xsl:template> - <xsl:template match = "animal" > + <xsl:template match = "instance" > <form method="post" action="demo2"> - <xsl:variable name="animalName" select="name"/> - Animal name: <input type="text" name="name" value="{$animalName}"/> + Animal name: <input type="text" name="name" value="{name}"/> (hint: try submitting name < 4 or > 10 characters) <xsl:call-template name="showErrors"> <xsl:with-param name="element">/name</xsl:with-param> @@ -33,19 +32,16 @@ Kind: <b><xsl:value-of select="personalInfo/@kind"/></b> <br/> - <xsl:variable name="animalScope" select="scope"/> - Animal scope: <input type="text" name="scope" value="{$animalScope}"/> + Animal scope: <input type="text" name="scope" value="{scope}"/> (hint: try submitting scope != session or request) <xsl:call-template name="showErrors"> <xsl:with-param name="element">/scope</xsl:with-param> </xsl:call-template> <br/> - <xsl:variable name="preference1" select="preferences[1]"/> - First Preference: <input type="text" name="preferences[1]" value="{$preference1}"/> + First Preference: <input type="text" name="preferences[1]" value="{preferences[1]}"/> <br/> - <xsl:variable name="preference2" select="preferences[2]"/> - Second Preference: <input type="text" name="preferences[2]" value="{$preference2}"/> + Second Preference: <input type="text" name="preferences[2]" value="{preferences[2]}"/> <br/> <input type="submit"/> @@ -57,16 +53,10 @@ <xsl:template name = "showErrors"> <xsl:param name = "element" /> - <xsl:for-each select="/xmlform/validationResult/pattern/rule[@context=$element]/assert"> + <xsl:for-each select="/form/violation[path=$element]"> <br/> <font color="red"> - * <xsl:value-of select="."/> - </font> - </xsl:for-each> - <xsl:for-each select="/xmlform/validationResult/pattern/rule[@context=$element]/report"> - <br/> - <font color="red"> - * <xsl:value-of select="."/> + * <xsl:value-of select="message"/> </font> </xsl:for-each> </xsl:template> @@ -75,6 +65,7 @@ <xsl:template match = "*" /> </xsl:stylesheet> + 1.2 +3 -10 xml-cocoon2/src/scratchpad/webapp/mount/xmlform/insertFormBean-Demo2.xml Index: insertFormBean-Demo2.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/webapp/mount/xmlform/insertFormBean-Demo2.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- insertFormBean-Demo2.xml 4 Apr 2002 06:21:51 -0000 1.1 +++ insertFormBean-Demo2.xml 7 Apr 2002 08:58:28 -0000 1.2 @@ -1,11 +1,4 @@ <?xml version="1.0"?> -<xmlform - xmlns:xform="http://xml.apache.cocoon/xmlform" - xmlns:castor="http://castor.exolab.org/cocoontransfomer"> - <instance> - <castor:InsertBean name="xmlForm"/> - </instance> - <castor:InsertBean name="xmlFormValidationResult"/> -</xmlform> - - + <castor:InsertBean name="xmlForm" + xmlns:form="http://xml.apache.cocoon/xmlform" + xmlns:castor="http://castor.exolab.org/cocoontransfomer"/> 1.2 +6 -4 xml-cocoon2/src/scratchpad/webapp/mount/xmlform/sitemap.xmap Index: sitemap.xmap =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/webapp/mount/xmlform/sitemap.xmap,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- sitemap.xmap 4 Apr 2002 06:21:51 -0000 1.1 +++ sitemap.xmap 7 Apr 2002 08:58:28 -0000 1.2 @@ -63,7 +63,7 @@ 3) Schematron stylesheet validates data and adds results to the SAX stream 4) Stylesheet displays form and errors based on the output from 3) --> - <map:match pattern="demo1"> + <map:match pattern="demo1.html"> <map:act type="FormBinderAction"/> <map:generate src="insertFormBean.xml"/> <map:transform type="castor"/> @@ -84,10 +84,10 @@ --> <map:match pattern="demo2"> <map:act type="ValidationFormAction"/> - <map:select type="request-attribute"> - <map:parameter name="attribute-name" value="validationPassed"/> + <map:select type="parameter"> + <map:parameter name="parameter-selector-test" value="{$nextPage}"/> <!-- validation passed, go to next page --> - <map:when test="true"> + <map:when test="success"> <map:call resource="display-success"/> </map:when> <!-- validation failed, go to the same page --> @@ -99,7 +99,9 @@ </map:otherwise> </map:select> </map:match> + </map:pipeline> + </map:pipelines> 1.2 +2 -94 xml-cocoon2/src/scratchpad/webapp/mount/xmlform/castor-mappings/test-mapping.xml Index: test-mapping.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/webapp/mount/xmlform/castor-mappings/test-mapping.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- test-mapping.xml 4 Apr 2002 06:21:51 -0000 1.1 +++ test-mapping.xml 7 Apr 2002 08:58:28 -0000 1.2 @@ -37,102 +37,10 @@ </field> </class> -<!-- mapping for Schematron ValidationResult --> - - <class name="org.apache.cocoon.validation.schematron.ValidationResult"> - <map-to xml="validationResult"/> - - <field name="pattern" type="org.apache.cocoon.validation.schematron.Pattern" - collection="collection"> - <bind-xml name="pattern"/> - </field> - </class> - - - <class name="org.apache.cocoon.validation.schematron.Phase"> - <map-to xml="phase"/> - - <field name="id" type="java.lang.String"> - <bind-xml name="id" node="attribute"/> - </field> - - <field name="active" type="org.apache.cocoon.validation.schematron.ActivePattern" - collection="collection"> - <bind-xml name="active"/> - </field> - </class> - - <class name="org.apache.cocoon.validation.schematron.ActivePattern"> - <map-to xml="active"/> - - <field name="pattern" type="java.lang.String"> - <bind-xml name="id" node="attribute"/> - </field> - </class> - - - <class name="org.apache.cocoon.validation.schematron.Pattern"> - <map-to xml="pattern"/> - - <field name="name" type="java.lang.String"> - <bind-xml name="name" node="attribute"/> - </field> - - <field name="id" type="java.lang.String"> - <bind-xml name="id" node="attribute"/> - </field> - - <field name="rule" type="org.apache.cocoon.validation.schematron.Rule" - collection="collection"> - <bind-xml name="rule"/> - </field> - </class> - - <class name="org.apache.cocoon.validation.schematron.Rule"> - <map-to xml="rule"/> - - <field name="context" type="java.lang.String"> - <bind-xml name="context" node="attribute"/> - </field> - - <field name="assert" type="org.apache.cocoon.validation.schematron.Assert" - collection="collection"> - <bind-xml name="assert"/> - </field> - - <field name="report" type="org.apache.cocoon.validation.schematron.Report" - collection="collection"> - <bind-xml name="report"/> - </field> - - </class> - - <class name="org.apache.cocoon.validation.schematron.Assert"> - <map-to xml="assert"/> - - <field name="test" type="java.lang.String"> - <bind-xml name="test" node="attribute"/> - </field> - - <field name="message" type="java.lang.String"> - <bind-xml node="text"/> - </field> - </class> - - <class name="org.apache.cocoon.validation.schematron.Report"> - <map-to xml="report"/> - - <field name="test" type="java.lang.String"> - <bind-xml name="test" node="attribute"/> - </field> - - <field name="message" type="java.lang.String"> - <bind-xml node="text"/> - </field> - </class> - </mapping> + +
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]