tcurdt      02/03/22 09:46:41

  Added:       src/scratchpad/lib commons-JXPath-20020320.jar
               src/scratchpad/src/org/apache/cocoon/precept Constraint.java
                        Context.java Instance.java InstanceFactory.java
                        InstanceTransformer.java
                        InvalidXPathSyntaxException.java
                        NoSuchNodeException.java Preceptor.java
                        PreceptorViolationException.java
               src/scratchpad/src/org/apache/cocoon/precept/acting
                        AbstractMethodAction.java
                        AbstractPreceptorAction.java
                        PreceptorDemoAction.java
               src/scratchpad/src/org/apache/cocoon/precept/preceptors
                        AbstractPreceptor.java PreceptorBuilder.java
               src/scratchpad/src/org/apache/cocoon/precept/preceptors/easyrelax
                        AbstractPreceptorNode.java
                        AttributePreceptorNode.java ConstraintFactory.java
                        ElementPreceptorNode.java PreceptorBuilderImpl.java
                        PreceptorImpl.java
               
src/scratchpad/src/org/apache/cocoon/precept/preceptors/easyrelax/constraints
                        AbstractConstraint.java ChoiceConstraint.java
                        RegexprConstraint.java
               src/scratchpad/src/org/apache/cocoon/precept/stores
                        AbstractInstance.java
               src/scratchpad/src/org/apache/cocoon/precept/stores/bean
                        InstanceImpl.java
               src/scratchpad/src/org/apache/cocoon/precept/stores/bean/test
                        CocoonInstallationBean.java SystemBean.java
                        UserBean.java
               src/scratchpad/src/org/apache/cocoon/precept/stores/dom/simple
                        AttributeNode.java ElementNode.java
                        InstanceImpl.java Node.java
               src/scratchpad/webapp/mount/precept README sitemap.xmap
                        snippet.roles snippet.xconf
               src/scratchpad/webapp/mount/precept/example1 README
                        error.xml error.xsl thanks.xml thanks.xsl view1.xml
                        view1.xsl view2.xml view2.xsl view3.xml view3.xsl
                        view4.xml view4.xsl
               src/scratchpad/webapp/mount/precept/example2 README
                        i2html.xsl view1.xml
               src/scratchpad/webapp/mount/precept/model easyrelax.xml
  Log:
  first version of the new form handling stuff
  please read scratchpad/webapp/mount/precept/README first
  
  Revision  Changes    Path
  1.1                  
xml-cocoon2/src/scratchpad/lib/commons-JXPath-20020320.jar
  
        <<Binary file>>
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/Constraint.java
  
  Index: Constraint.java
  ===================================================================
  /*
   * @version: Mar 14, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept;
  
  import org.apache.cocoon.precept.Context;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  
  public interface Constraint {
    public boolean isSatisfiedBy( Object value, Context context );
    public String getId();
    public String getType();
    public void toSAX(ContentHandler handler) throws SAXException;
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/Context.java
  
  Index: Context.java
  ===================================================================
  /*
   * @version: Mar 14, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept;
  
  import java.util.Locale;
  
  public class Context {
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/Instance.java
  
  Index: Instance.java
  ===================================================================
  /*
   * @version: Mar 15, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept;
  
  import org.apache.avalon.framework.component.Component;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  
  import java.util.List;
  
  public interface Instance extends Component {
    public String ROLE = "org.apache.cocoon.precept.Instance";
    public void setValue(String xpath, Object value) throws 
PreceptorViolationException, InvalidXPathSyntaxException;
    public void setValue(String xpath, Object value, Context context) throws 
PreceptorViolationException, InvalidXPathSyntaxException;
    public Object getValue(String xpath) throws InvalidXPathSyntaxException, 
NoSuchNodeException;
  
    public void setPreceptor( Preceptor preceptor );
    public List validate(String xpath, Context context) throws 
InvalidXPathSyntaxException, NoSuchNodeException;
    public List validate(Context context) throws InvalidXPathSyntaxException;
  
    public Preceptor getPreceptor();
    public void toSAX( ContentHandler handler, boolean constraints) throws 
SAXException;
    public long getLastModified();
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/InstanceFactory.java
  
  Index: InstanceFactory.java
  ===================================================================
  /*
   * @version: Mar 18, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept;
  
  import org.apache.avalon.framework.logger.AbstractLoggable;
  import org.apache.avalon.framework.logger.Loggable;
  import org.apache.avalon.framework.component.*;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.thread.ThreadSafe;
  
  import java.util.HashMap;
  import java.net.URL;
  import java.net.MalformedURLException;
  
  import org.apache.cocoon.precept.preceptors.PreceptorBuilder;
  
  public class InstanceFactory extends AbstractLoggable implements Component, 
Configurable, Composable, ThreadSafe {
  
    public final static String ROLE = 
"org.apache.cocoon.precept.InstanceFactory";
  
    private ComponentManager manager = null;
    private HashMap instanceConfigurationMap;
  
    public void configure(Configuration conf) throws ConfigurationException {
      instanceConfigurationMap = new HashMap();
      Configuration[] instances = conf.getChildren("instance");
  
      if (instances != null) {
        for (int p = 0; p < instances.length; p++) {
          Configuration instance = instances[p];
          String name = instance.getAttribute("name");
          getLogger().debug("registering instance [name=" + 
String.valueOf(name) + ";impl=" + String.valueOf(instance.getAttribute("impl")) 
+ "]");
          instanceConfigurationMap.put(name, instance);
        }
      }
      else {
        getLogger().warn("no instances are configured");
      }
    }
  
    public void compose(ComponentManager manager) throws ComponentException {
      this.manager = manager;
    }
  
    public Instance createInstance( String name ) {
      getLogger().debug("creating instance [" + String.valueOf(name) + "]");
      Configuration instanceConf = (Configuration) 
instanceConfigurationMap.get(name);
      ComponentSelector instanceSelector = null;
      Instance instance = null;
      try {
        instanceSelector = (ComponentSelector) manager.lookup(Instance.ROLE + 
"Selector");
        instance = (Instance) 
instanceSelector.select(instanceConf.getAttribute("impl"));
  
        Configuration builderConf = instanceConf.getChild("preceptor");
        if (builderConf != null) {
          ComponentSelector preceptorBuilderSelector = null;
          PreceptorBuilder preceptorBuilder = null;
          try {
            preceptorBuilderSelector = (ComponentSelector) 
manager.lookup(PreceptorBuilder.ROLE + "Selector");
            preceptorBuilder = (PreceptorBuilder) 
preceptorBuilderSelector.select(builderConf.getAttribute("impl"));
  
            String uri = builderConf.getAttribute("uri");
  
            getLogger().debug("building preceptor from [" + String.valueOf(uri) 
+ "]");
  
            //FIXME: use a resolver here
            Preceptor newPreceptor = preceptorBuilder.buildPreceptor(new 
URL(uri));
  
            instance.setPreceptor( newPreceptor );
          }
          catch(ComponentException e) {
            if(preceptorBuilderSelector != null) {
              getLogger().error("could not get preceptor builder",e);
            }
            else {
              getLogger().error("could not get preceptor builder selector",e);
            }
          }
          catch(Exception e) {
            getLogger().error("",e);
            e.printStackTrace(System.out);
          }
          finally {
            manager.release(preceptorBuilder);
            manager.release(preceptorBuilderSelector);
          }
        }
      }
      catch(ConfigurationException e) {
        getLogger().error("",e);
      }
      catch(ComponentException e) {
        getLogger().error("could not get instance selector",e);
      }
      finally {
        //manager.release(instance);
        //should be released while session invalidation
        manager.release(instanceSelector);
      }
      return(instance);
    }
  
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/InstanceTransformer.java
  
  Index: InstanceTransformer.java
  ===================================================================
  package org.apache.cocoon.precept;
  
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.caching.CacheValidity;
  import org.apache.cocoon.caching.Cacheable;
  import org.apache.cocoon.caching.NOPCacheValidity;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Session;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.transformation.AbstractTransformer;
  import org.apache.log.Logger;
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  
  import java.io.IOException;
  import java.util.Map;
  
  public class InstanceTransformer extends AbstractTransformer { //implements 
Cacheable {
  
    public final static String NS = "http://www.dff.st/ns/desire/instance/1.0";;
  
    public final static String TAG_INSTANCE = "instance";
    public final static String TAG_INSTANCE_ATTR_ID = "id";
  
    private Logger log;
    private Request request;
    private Session session;
  
    public void setup(SourceResolver resolver, Map objectModel, String source, 
Parameters parameters) throws ProcessingException, SAXException, IOException {
      log = getLogger();
      request = ObjectModelHelper.getRequest(objectModel);
      if (request == null) {
        log.debug("no request object");
        throw new ProcessingException("no request object");
      }
  
      session = request.getSession(false);
    }
  
    public void startElement(String uri, String name, String raw, Attributes 
attributes) throws SAXException {
      if (NS.equals(uri)) {
        if (TAG_INSTANCE.equals(name)) {
          if (session != null) {
            String id = attributes.getValue(TAG_INSTANCE_ATTR_ID);
  
            log.debug("inserting instance [id=" + String.valueOf(id) + "]");
            Instance instance = (Instance) session.getAttribute(id);
            if (instance != null) {
              instance.toSAX(this, true);
            }
            else {
              log.debug("could not find instance [id=" + String.valueOf(id) + 
"]");
            }
          }
          else {
            log.debug("no session - no instance");
          }
        }
        else {
          String ref = attributes.getValue("ref");
  
        }
      }
      else {
        super.startElement(uri, name, raw, attributes);
      }
    }
  
  
    public void endElement(String uri, String name, String raw) throws 
SAXException {
      if (NS.equals(uri)) {
        if (TAG_INSTANCE.equals(name)) {
        }
        else {
        }
      }
      else {
        super.endElement(uri, name, raw);
      }
    }
  
    public void characters(char[] chars, int start, int len) throws 
SAXException {
      super.characters(chars, start, len);
    }
  
    public long generateKey() {
      return (1);
    }
  
    public CacheValidity generateValidity() {
      return (new NOPCacheValidity());
    }
  }
  
  
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/InvalidXPathSyntaxException.java
  
  Index: InvalidXPathSyntaxException.java
  ===================================================================
  /*
   * @version: Mar 14, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept;
  
  import org.apache.avalon.framework.CascadingException;
  
  public class InvalidXPathSyntaxException extends CascadingException {
    public InvalidXPathSyntaxException(String s) {
      super(s);
    }
  
    public InvalidXPathSyntaxException(Throwable t) {
      super("",t);
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/NoSuchNodeException.java
  
  Index: NoSuchNodeException.java
  ===================================================================
  /*
   * @version: Mar 14, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept;
  
  import org.apache.avalon.framework.CascadingException;
  
  public class NoSuchNodeException extends CascadingException {
    public NoSuchNodeException(String s) {
      super(s);
    }
  
    public NoSuchNodeException(Throwable t) {
      super("",t);
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/Preceptor.java
  
  Index: Preceptor.java
  ===================================================================
  /*
   * @version: Mar 14, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept;
  
  import org.apache.avalon.framework.component.Component;
  
  import java.util.List;
  import java.net.URL;
  
  public interface Preceptor extends Component {
    public String ROLE = "org.apache.cocoon.precept.Preceptor";
    public List getConstraitsFor( String xpath ) throws 
InvalidXPathSyntaxException, NoSuchNodeException;
    public boolean isValidNode( String xpath ) throws 
InvalidXPathSyntaxException;
    public void buildInstance( Instance instance );
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/PreceptorViolationException.java
  
  Index: PreceptorViolationException.java
  ===================================================================
  /*
   * @version: Mar 14, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept;
  
  import org.apache.avalon.framework.CascadingException;
  
  public class PreceptorViolationException extends CascadingException {
    public PreceptorViolationException(String s) {
      super(s);
    }
  
    public PreceptorViolationException(Throwable t) {
      super("",t);
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/acting/AbstractMethodAction.java
  
  Index: AbstractMethodAction.java
  ===================================================================
  /*
   * @version: Feb 25, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.acting;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.acting.ConfigurableComposerAction;
  
  import java.util.HashMap;
  import java.util.Map;
  import java.lang.reflect.Method;
  
  
  public abstract class AbstractMethodAction extends ConfigurableComposerAction 
{
  
     private static final String ACTION_METHOD_PREFIX = "do";
     private static final String ACTION_METHOD_PARAMETER = "method";
  
     private HashMap methodIndex = null;
  
     public void configure(Configuration conf) throws ConfigurationException {
       super.configure(conf);
  
       if (methodIndex == null) {
         try {
           Method[] methods = this.getClass().getMethods();
           methodIndex = new HashMap();
  
           int prefixLen = ACTION_METHOD_PREFIX.length();
           for (int i = 0; i < methods.length; i++) {
             String methodName = methods[i].getName();
             if (methodName.startsWith(ACTION_METHOD_PREFIX)) {
               String actionName = methodName.substring(prefixLen, prefixLen + 
1).toLowerCase() +
                       methodName.substring(prefixLen + 1);
               methodIndex.put(actionName, methods[i]);
               if (getLogger().isDebugEnabled()) {
                 getLogger().debug("registered method \"" + methodName + "\" as 
action \"" + actionName + "\"");
               }
             }
           }
         }
         catch (Exception e) {
           throw new ConfigurationException("cannot get methods by reflection", 
e);
         }
       }
     }
  
    public Map introspection( Redirector redirector, SourceResolver resolver, 
Map objectModel, String source, Parameters parameters) throws Exception {
      return(EMPTY_MAP);
    }
  
    public Map act( Redirector redirector, SourceResolver resolver, Map 
objectModel, String source, Parameters parameters) throws Exception {
      String actionMethod = 
parameters.getParameter(ACTION_METHOD_PARAMETER,null);
      if (actionMethod != null) {
        Method method = (Method) methodIndex.get(actionMethod);
        if (method != null) {
          getLogger().debug("calling method ["+ String.valueOf(actionMethod) + 
"]");
          return((Map) method.invoke(this, new Object[]{ 
redirector,resolver,objectModel,source,parameters }));
        }
        else {
          throw new Exception("action has no method \"" + actionMethod + "\"");
        }
      }
      else {
        Request request = ObjectModelHelper.getRequest(objectModel);
        if (request != null && "GET".equalsIgnoreCase(request.getMethod())) {
          // just the first view of the page
          // call introspection
          getLogger().debug("calling introspection");
          
return(introspection(redirector,resolver,objectModel,source,parameters ));
        }
        else {
          getLogger().debug("already in flow - no introspection");
          return(EMPTY_MAP);
        }
      }
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/acting/AbstractPreceptorAction.java
  
  Index: AbstractPreceptorAction.java
  ===================================================================
  /*
   * @version: Feb 25, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.acting;
  
  import org.apache.cocoon.environment.*;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.thread.ThreadSafe;
  
  import java.util.*;
  
  import org.apache.cocoon.precept.*;
  import org.apache.cocoon.precept.acting.AbstractMethodAction;
  
  public abstract class AbstractPreceptorAction extends AbstractMethodAction 
implements ThreadSafe {
  
    protected Session createSession( Map objectModel ) {
      Request request = ObjectModelHelper.getRequest(objectModel);
      return(request.getSession(true));
    }
  
    protected Instance getInstance( Map objectModel, String instanceId ) {
      Request request = ObjectModelHelper.getRequest(objectModel);
      Session session = request.getSession(false);
      return((Instance)session.getAttribute(instanceId));
    }
  
    protected Instance createInstance(String id) throws ComponentException {
      InstanceFactory factory = (InstanceFactory) 
manager.lookup(InstanceFactory.ROLE);
      Instance instance = factory.createInstance(id);
      manager.release(factory);
      return(instance);
    }
  
    protected void populate(Map objectModel, String instanceId, String xpath) 
throws PreceptorViolationException, InvalidXPathSyntaxException {
      Request request = ObjectModelHelper.getRequest(objectModel);
      Session session = request.getSession(false);
      if (session != null) {
        Instance instance = (Instance)session.getAttribute(instanceId);
        if (instance != null) {
          String value = request.getParameter(xpath);
          //String[] values = request.getParameterValues(xpath);
  
          if (value == null) value = "false";
  
          getLogger().debug("populating into " + String.valueOf(xpath) + " = " 
+ String.valueOf(value));
          instance.setValue(xpath,value);
        }
      }
    }
  
    protected void populate(Map objectModel, String instanceId, String[] 
xpaths) throws PreceptorViolationException, InvalidXPathSyntaxException {
      for(int i=0; i < xpaths.length; i++) {
        populate(objectModel,instanceId,xpaths[i]);
      }
    }
  
    protected List validate(Map objectModel, String instanceId) throws 
InvalidXPathSyntaxException, NoSuchNodeException {
      return(getInstance(objectModel,instanceId).validate(null));
    }
  
    protected List validate(Map objectModel, String instanceId, String xpath) 
throws InvalidXPathSyntaxException, NoSuchNodeException {
      return(getInstance(objectModel,instanceId).validate(xpath,null));
    }
  
    protected List validate(Map objectModel, String instanceId, String[] 
xpaths) throws InvalidXPathSyntaxException, NoSuchNodeException {
      Instance instance = getInstance(objectModel,instanceId);
      ArrayList allErrors = null;
      for(int i=0; i < xpaths.length; i++) {
        List errors = instance.validate(xpaths[i],null);
        if (errors != null) {
          if (allErrors == null) allErrors = new ArrayList(1);
          allErrors.addAll(errors);
        }
      }
      return(allErrors);
    }
  
    protected Map page( String id ) {
      Map m = new HashMap(1);
      m.put("page",id);
      return(m);
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/acting/PreceptorDemoAction.java
  
  Index: PreceptorDemoAction.java
  ===================================================================
  /*
   * @version: Feb 25, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.acting;
  
  import org.apache.cocoon.environment.*;
  import org.apache.avalon.framework.parameters.Parameters;
  
  import java.util.Map;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Iterator;
  
  import org.apache.cocoon.precept.Instance;
  import org.apache.cocoon.precept.acting.AbstractPreceptorAction;
  
  public class PreceptorDemoAction extends AbstractPreceptorAction {
  
    private final static String VIEW1 = "view1";
    private final static String VIEW2 = "view2";
    private final static String VIEW3 = "view3";
    private final static String VIEW4 = "view4";
    private final static String VIEW_THANKS = "thanks";
    private final static String VIEW_ERROR = "error";
  
    private final static String[] SET_PERSON = {
      "cocoon-installation/user/firstname",
      "cocoon-installation/user/lastname",
      "cocoon-installation/user/email",
      "cocoon-installation/user/age"
    };
  
    private final static String[] SET_INSTALLATION = {
      "cocoon-installation/number",
      "cocoon-installation/live-url",
      "cocoon-installation/publish"
    };
  
    private final static String[] SET_SYSTEM = {
      "cocoon-installation/system/os",
      "cocoon-installation/system/processor",
      "cocoon-installation/system/ram",
      "cocoon-installation/system/servlet-engine",
      "cocoon-installation/system/java-version"
    };
  
  
    public Map introspection(Redirector redirector, SourceResolver resolver, 
Map objectModel, String src, Parameters par) throws Exception {
      getLogger().debug("start of flow");
  
      Session session = createSession(objectModel);
      Instance instance = createInstance("feedback");
  
      session.setAttribute("form-feedback",instance);
      return(page(VIEW1));
    }
  
    public Map doPrev1(Redirector redirector, SourceResolver resolver, Map 
objectModel, String src, Parameters par) throws Exception {
      populate(objectModel, "form-feedback", SET_INSTALLATION );
      return (page(VIEW1));
    }
    public Map doPrev2(Redirector redirector, SourceResolver resolver, Map 
objectModel, String src, Parameters par) throws Exception {
      populate(objectModel, "form-feedback", SET_SYSTEM );
      return (page(VIEW2));
    }
    public Map doPrev3(Redirector redirector, SourceResolver resolver, Map 
objectModel, String src, Parameters par) throws Exception {
      return (page(VIEW3));
    }
  
    public Map doNext2(Redirector redirector, SourceResolver resolver, Map 
objectModel, String src, Parameters par) throws Exception {
      getLogger().debug("populating");
      populate(objectModel, "form-feedback", SET_PERSON );
  
      List errors = validate(objectModel, "form-feedback", SET_PERSON );
      if(errors != null) {
        getLogger().debug("some constraints FAILED");
        return (page(VIEW1));
      }
      else {
        getLogger().debug("all constraints are ok");
        return (page(VIEW2));
      }
    }
  
    public Map doNext3(Redirector redirector, SourceResolver resolver, Map 
objectModel, String src, Parameters par) throws Exception {
      getLogger().debug("populating");
      populate(objectModel, "form-feedback", SET_INSTALLATION );
  
      List errors = validate(objectModel, "form-feedback", SET_INSTALLATION );
      if(errors != null) {
        getLogger().debug("some constraints FAILED");
        return (page(VIEW2));
      }
      else {
        getLogger().debug("all constraints are ok");
        return (page(VIEW3));
      }
    }
  
    public Map doNext4(Redirector redirector, SourceResolver resolver, Map 
objectModel, String src, Parameters par) throws Exception {
      getLogger().debug("populating");
      populate(objectModel, "form-feedback", SET_SYSTEM );
  
      List errors = validate(objectModel, "form-feedback", SET_SYSTEM );
      if(errors != null) {
        getLogger().debug("some constraints FAILED");
        return (page(VIEW3));
      }
      else {
        getLogger().debug("all constraints are ok");
        return (page(VIEW4));
      }
    }
  
    public Map doSubmit(Redirector redirector, SourceResolver resolver, Map 
objectModel, String src, Parameters par) throws Exception {
      getLogger().debug("submitting");
      List errors = validate(objectModel, "form-feedback");
      if (errors != null) {
        getLogger().debug("some constraints FAILED");
        return (page(VIEW_ERROR));
      }
      else {
        getLogger().debug("instance is valid - submitting");
  
        /*
         * do whatever you want with the instance data
         */
  
        return (page(VIEW_THANKS));
      }
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/preceptors/AbstractPreceptor.java
  
  Index: AbstractPreceptor.java
  ===================================================================
  /*
   * @version: Mar 18, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.preceptors;
  
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.logger.AbstractLoggable;
  import org.apache.cocoon.precept.Preceptor;
  
  
  public abstract class AbstractPreceptor extends AbstractLoggable implements 
Preceptor, Composable {
    protected ComponentManager manager;
  
    public void compose(ComponentManager manager) throws ComponentException {
      this.manager = manager;
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/preceptors/PreceptorBuilder.java
  
  Index: PreceptorBuilder.java
  ===================================================================
  /*
   * @version: Mar 20, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.preceptors;
  
  import org.apache.avalon.framework.component.Component;
  import org.apache.cocoon.precept.Preceptor;
  
  import java.net.URL;
  
  public interface PreceptorBuilder extends Component {
    public String ROLE = "org.apache.cocoon.precept.PreceptorBuilder";
  
    public Preceptor buildPreceptor( URL source ) throws Exception;
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/preceptors/easyrelax/AbstractPreceptorNode.java
  
  Index: AbstractPreceptorNode.java
  ===================================================================
  /*
   * @version: Feb 22, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.preceptors.easyrelax;
  
  import org.apache.cocoon.precept.Preceptor;
  import org.apache.cocoon.precept.Constraint;
  
  import java.util.List;
  import java.util.ArrayList;
  import java.util.Iterator;
  
  public abstract class AbstractPreceptorNode {
    protected String name;
    protected List constraints;
    protected ElementPreceptorNode parent;
    protected Preceptor preceptor;
  
  
    public String getName() {
      return(this.name);
    }
  
    public ElementPreceptorNode getParent() {
      return(this.parent);
    }
  
    public List validate(Object value) {
      if (constraints != null) {
        for (Iterator it = constraints.iterator(); it.hasNext();) {
          Constraint constraint = (Constraint) it.next();
        }
        return(null);
      }
      else {
        return(null);
      }
    }
  
    public List getConstraints() {
      return(constraints);
    }
  
    public AbstractPreceptorNode addConstraints(List constraints) {
      if (constraints != null) {
        if (this.constraints == null) {
          this.constraints = new ArrayList(constraints.size());
        }
        this.constraints.addAll(constraints);
      }
      return(this);
    }
  
    public AbstractPreceptorNode addConstraint(Constraint constraint) {
      if (constraint != null) {
        if (this.constraints == null){
          this.constraints = new ArrayList(1);
        }
        this.constraints.add(constraint);
      }
      return(this);
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/preceptors/easyrelax/AttributePreceptorNode.java
  
  Index: AttributePreceptorNode.java
  ===================================================================
  /*
   * @version: Feb 22, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.preceptors.easyrelax;
  
  import org.apache.cocoon.precept.Preceptor;
  import org.apache.cocoon.precept.Constraint;
  
  import java.util.List;
  import java.util.Iterator;
  
  public class AttributePreceptorNode extends AbstractPreceptorNode {
    private boolean required;
    //private StringBuffer valueObject;
  
    public AttributePreceptorNode( Preceptor preceptor, ElementPreceptorNode 
parent, String name, boolean required ) {
      this.name = name;
      this.required = required;
      this.parent = parent;
      this.preceptor = preceptor;
    }
  
    public boolean isRequired() {
      return(required);
    }
  
    public void toStringBuffer( StringBuffer sb, int depth) {
      sb.append(" ").append(name).append("=");
  
      if (constraints != null) {
        for (Iterator it = constraints.iterator(); it.hasNext();) {
          Constraint constraint = (Constraint) it.next();
          sb.append("{").append(constraint.getType()).append("}");
        }
      }
  
      sb.append("[").append( (required)?"required":"optional"  ).append("]");
    }
  
  /*
    public StringBuffer setValue( String value ) {
      if (valueObject == null){
        valueObject = new StringBuffer(value);
      }
      else {
        valueObject.setLength(0);
        valueObject.append(value);
      }
      return(valueObject);
    }
  
    public StringBuffer getValue() {
      return(valueObject);
    }
    */
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/preceptors/easyrelax/ConstraintFactory.java
  
  Index: ConstraintFactory.java
  ===================================================================
  /*
   * @version: Mar 21, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.preceptors.easyrelax;
  
  import org.apache.cocoon.precept.Constraint;
  import 
org.apache.cocoon.precept.preceptors.easyrelax.constraints.ChoiceConstraint;
  import 
org.apache.cocoon.precept.preceptors.easyrelax.constraints.RegexprConstraint;
  import org.apache.avalon.framework.configuration.Configuration;
  
  public class ConstraintFactory {
    public Constraint createConstraintInstance(String type, String name, Object 
context, Configuration conf) {
      if ("choice".equals(type)) {
        return(new ChoiceConstraint());
      }
      else {
        return(new RegexprConstraint());
      }
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/preceptors/easyrelax/ElementPreceptorNode.java
  
  Index: ElementPreceptorNode.java
  ===================================================================
  /*
   * @version: Feb 22, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.preceptors.easyrelax;
  
  
  import org.apache.cocoon.precept.Preceptor;
  import org.apache.cocoon.precept.Constraint;
  
  import java.util.*;
  
  public class ElementPreceptorNode extends AbstractPreceptorNode {
    public final static int UNBOUND = -1;
  
    private Map childs;
    private Map attributes;
  //  private List values;
    private int minOcc;
    private int maxOcc;
  
    public ElementPreceptorNode( Preceptor preceptor, ElementPreceptorNode 
parent, String name, int minOcc, int maxOcc) {
      this.name = name;
      this.minOcc = minOcc;
      this.maxOcc = maxOcc;
      this.parent = parent;
      this.preceptor = preceptor;
  
    }
  
    public AttributePreceptorNode addAttribute( String name, boolean required, 
List constraints ) {
      if (attributes == null) attributes = new HashMap();
      AttributePreceptorNode a = new AttributePreceptorNode( preceptor, this, 
name, required );
      a.addConstraints(constraints);
      attributes.put(name,a);
      return(a);
    }
  
    public ElementPreceptorNode addElement( String name, int min, int max, List 
constraints ) {
      if (childs == null) childs = new HashMap();
      ElementPreceptorNode e = new ElementPreceptorNode( preceptor, this, name, 
min, max);
      e.addConstraints(constraints);
      childs.put(name,e);
      return(e);
    }
  
    public ElementPreceptorNode getChild( String name ) {
      if (childs != null) {
        return((ElementPreceptorNode)childs.get(name));
      }
      else {
        return(null);
      }
    }
  
    public Collection getChildElements() {
      if (childs != null) {
        return(childs.values());
      }
      else {
        return(null);
      }
    }
  
    public AttributePreceptorNode getAttribute( String name ) {
      if (attributes != null) {
        return((AttributePreceptorNode)attributes.get(name));
      }
      else {
        return(null);
      }
    }
  
    public Collection getAttributes() {
      if (attributes != null) {
        return(attributes.values());
      }
      else {
        return(null);
      }
    }
  
    public int getMinOcc() {
      return(this.minOcc);
    }
  
    public int getMaxOcc() {
      return(this.maxOcc);
    }
  
  /*
    public StringBuffer setValue(int i, String value) throws 
PreceptorViolationException {
      if (values == null) values = new ArrayList(1);
  
      if (i <= values.size()) {
        // already there
        StringBuffer valueObject = (StringBuffer) values.get(i-1);
        valueObject.setLength(0);
        valueObject.append(value);
        return(valueObject);
      }
      else {
        // create a slot
        if (i > maxOcc) {
          // restricted
          throw new PreceptorViolationException( String.valueOf(name) + " is 
out of bound");
        }
        else {
          StringBuffer valueObject = new StringBuffer(value);
          values.add(valueObject);
          return(valueObject);
        }
      }
    }
  
    public StringBuffer getValue(int i) {
      if (values != null && i <= values.size()) {
        // is there
        return((StringBuffer)values.get(i-1));
      }
      else {
        return(null);
      }
    }
  
    public int valueCount() {
      if (values != null) {
        return(values.size());
      }
      else {
        return(0);
      }
    }
    */
  
    public void toStringBuffer( StringBuffer sb, ElementPreceptorNode e, int 
depth) {
      StringBuffer ident = new StringBuffer();
      for(int i=0;i<depth*3;i++) ident.append(" ");
  
      sb.append("\n").append(ident).append("<").append(e.getName());
      
sb.append("[").append(e.getMinOcc()).append(",").append(e.getMaxOcc()).append("]");
  
      Collection attributes = e.getAttributes();
      if (attributes != null) {
        for (Iterator it = attributes.iterator(); it.hasNext();) {
          AttributePreceptorNode attr = (AttributePreceptorNode) it.next();
          attr.toStringBuffer(sb,depth);
        }
      }
  
      sb.append(">");
  
      if (e.getConstraints() != null) {
        for (Iterator it = e.getConstraints().iterator(); it.hasNext();) {
          Constraint constraint = (Constraint) it.next();
          sb.append("{").append(constraint.getType()).append("}");
        }
      }
      else {
        sb.append("{*}");
      }
  
      Collection childs = e.getChildElements();
      if (childs != null) {
        for (Iterator it = childs.iterator(); it.hasNext();) {
          ElementPreceptorNode child = (ElementPreceptorNode) it.next();
          toStringBuffer(sb, child, depth + 1);
        }
      }
      sb.append("</").append(e.getName()).append(">");
    }
  
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/preceptors/easyrelax/PreceptorBuilderImpl.java
  
  Index: PreceptorBuilderImpl.java
  ===================================================================
  /*
   * @version: Feb 23, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.preceptors.easyrelax;
  
  import org.apache.avalon.excalibur.pool.Poolable;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.logger.Loggable;
  import org.apache.cocoon.components.sax.XMLByteStreamInterpreter;
  import org.apache.cocoon.xml.EmbeddedXMLPipe;
  import org.apache.cocoon.xml.AbstractXMLConsumer;
  import org.xml.sax.*;
  import org.xml.sax.helpers.AttributesImpl;
  import org.apache.cocoon.precept.Preceptor;
  import org.apache.cocoon.precept.Constraint;
  import org.apache.cocoon.precept.preceptors.PreceptorBuilder;
  
  import javax.xml.parsers.SAXParserFactory;
  import java.io.BufferedInputStream;
  import java.io.InputStreamReader;
  import java.io.Reader;
  import java.io.StringReader;
  import java.net.URL;
  import java.util.*;
  
  
  public class PreceptorBuilderImpl extends AbstractXMLConsumer implements 
PreceptorBuilder, Composable, Disposable, Poolable {
    //public final static String ROLE = 
"org.apache.cocoon.precept.PreceptorBuilderImpl";
  
    public final static Attributes NOATTR = new AttributesImpl();
  
    public final static String NS = 
"http://www.dff.st/ns/desire/easyrelax/grammar/1.0";;
  
    private ComponentManager manager;
  
    private SAXConfigurationHandler configurationHandler;
    private PreceptorImpl preceptor;
    private Stack environments;
    private Environment environment;
    private List constraints;
    private StringBuffer text;
    private ElementPreceptorNode root;
    private ElementPreceptorNode currentElement;
    private AttributePreceptorNode currentAttribute;
    private String constraintAliasType;
    private String constraintType;
    private String constraintName;
    private String constraintContext;
    private String includeUri;
    private StringBuffer currentPath;
    private Map constraintAliases;
    private XMLByteStreamInterpreter xmli;
    private ConstraintFactory constraintFactory = new ConstraintFactory();
  
    private boolean define;
  
    private ContentHandler redirect;
    private int redirectLevel;
  
    public Preceptor getPreceptor() {
      return (preceptor);
    }
  
    public Preceptor buildPreceptor(URL source) throws Exception {
      parse(source);
      return (preceptor);
    }
  
    public void parse(URL url) throws Exception {
      parse(new InputStreamReader((BufferedInputStream) url.getContent()));
    }
  
    public void parse(String xmlstring) {
      StringReader reader = new StringReader(xmlstring);
      parse(reader);
    }
  
    public void parse(Reader reader) {
      try {
        //FIXME: use parser component
        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setValidating(false);
        spf.setNamespaceAware(true);
        XMLReader parser = spf.newSAXParser().getXMLReader();
        parser.setContentHandler(this);
        //parser.setErrorHandler(this);
        InputSource source = new InputSource(reader);
        parser.parse(source);
      }
      catch (Exception e) {
        e.printStackTrace(System.out);
      }
    }
  
  
    public void startDocument() throws SAXException {
      currentPath = new StringBuffer();
      preceptor = new PreceptorImpl();
      preceptor.setLogger(getLogger());
      text = new StringBuffer();
      environments = new Stack();
      environment = new Environment();
      constraints = new ArrayList();
      constraintAliases = new HashMap();
      redirect = null;
      redirectLevel = 0;
      define = false;
      xmli = new XMLByteStreamInterpreter();
      xmli.setContentHandler(new EmbeddedXMLPipe(this));
    }
  
    public void endDocument() throws SAXException {
      text = null;
      constraints = null;
      environments = null;
      environment = null;
      constraints = null;
      redirect = null;
    }
  
    public void startElement(String ns, String name, String raw, Attributes 
attributes) throws SAXException {
      if (redirect != null) {
        redirectLevel++;
        getLogger().debug("saving [start." + String.valueOf(name) + "] into 
config");
        redirect.startElement(ns, name, raw, attributes);
      }
      else {
        text.setLength(0);
  
        if (NS.equals(ns)) {
          if ("grammar".equals(name)) {
          }
          else if ("include".equals(name)) {
            includeUri = attributes.getValue("uri");
          }
          else if ("define".equals(name)) {
            define = true;
          }
          else if ("start".equals(name)) {
          }
          else if ("occurrs".equals(name)) {
            environments.push(environment);
            environment = new Environment();
  
            try {
              environment.minOcc = 
Integer.parseInt(String.valueOf(attributes.getValue("min")));
              environment.maxOcc = 
Integer.parseInt(String.valueOf(attributes.getValue("max")));
            }
            catch (NumberFormatException e) {
              throw new SAXException("min/max must be a valid number", e);
            }
          }
          else if ("optional".equals(name)) {
            environments.push(environment);
            environment = new Environment();
  
            environment.minOcc = 0;
            environment.maxOcc = 1;
          }
          else if ("element-alias".equals(name)) {
          }
          else if ("element".equals(name)) {
            String nameAttr = attributes.getValue("name");
            if (root != null) {
              currentElement = currentElement.addElement(nameAttr, 
environment.minOcc, environment.maxOcc, null);
              currentPath.append("/");
              environment.len = nameAttr.length() + 1;
            }
            else {
              root = new ElementPreceptorNode(preceptor, null, nameAttr, 1, 1);
              currentElement = root;
              environment.len = nameAttr.length();
            }
            currentPath.append(nameAttr);
            preceptor.index.put(currentPath.toString(), currentElement);
            getLogger().debug("creating index [" + String.valueOf(currentPath) 
+ "]");
  
            environments.push(environment);
            environment = new Environment();
          }
          else if ("attribute".equals(name)) {
            String nameAttr = attributes.getValue("name");
            currentAttribute = currentElement.addAttribute(nameAttr, 
environment.minOcc > 0, null);
  
            String path = currentPath.toString() + "/@" + nameAttr;
            preceptor.index.put(path, currentElement);
  
            getLogger().debug("creating index [" + String.valueOf(path) + "]");
          }
          else if ("constraint-alias".equals(name)) {
            constraintAliasType = attributes.getValue("type");
          }
          else if ("constraint".equals(name)) {
            constraintType = attributes.getValue("type");
            constraintName = attributes.getValue("name");
            constraintContext = attributes.getValue("context");
  
            configurationHandler = new SAXConfigurationHandler();
            configurationHandler.startElement("", "configuration", 
"configuration", NOATTR);
            redirect = configurationHandler;
          }
          else if ("value".equals(name)) {
          }
          else if ("value-of".equals(name)) {
          }
          else {
            throw new SAXException("unknown element " + String.valueOf(name));
          }
        }
        else {
          throw new SAXException("only elements in namespace " + NS + " are 
supported");
        }
      }
    }
  
    public void endElement(String ns, String name, String raw) throws 
SAXException {
      if (redirect != null) {
        if (--redirectLevel < 0) {
          redirect = null;
          redirectLevel = 0;
        }
        else {
          getLogger().debug("saving [end." + String.valueOf(name) + "] into 
config");
          redirect.endElement(ns, name, raw);
        }
      }
  
      if (redirect == null) {
        if (NS.equals(ns)) {
          if ("grammar".equals(name)) {
          }
          else if ("include".equals(name)) {
          }
          else if ("define".equals(name)) {
            define = false;
          }
          else if ("start".equals(name)) {
          }
          else if ("occurrs".equals(name)) {
            environment = (Environment) environments.pop();
          }
          else if ("optional".equals(name)) {
            environment = (Environment) environments.pop();
          }
          else if ("element-alias".equals(name)) {
          }
          else if ("element".equals(name)) {
            if (!constraints.isEmpty()) {
              getLogger().debug("adding " + constraints.size() + " constrain(s) 
to element [" + currentElement.getName() + "]");
              currentElement.addConstraints(constraints);
              constraints.clear();
            }
  
            currentElement = currentElement.getParent();
            environment = (Environment) environments.pop();
            currentPath.setLength(currentPath.length() - environment.len);
          }
          else if ("attribute".equals(name)) {
            if (!constraints.isEmpty()) {
              getLogger().debug("adding " + constraints.size() + " constrain(s) 
to attribute [" + currentAttribute.getName() + "]");
              currentAttribute.addConstraints(constraints);
              constraints.clear();
            }
          }
          else if ("constraint-alias".equals(name)) {
            if (!constraints.isEmpty()) {
              getLogger().debug("registering local constraint alias [" + 
String.valueOf(constraintAliasType) + "] with " + constraints.size() + " 
constraint(s)");
              constraintAliases.put(constraintAliasType, new 
ArrayList(constraints));
              constraints.clear();
            }
          }
          else if ("constraint".equals(name)) {
            configurationHandler.endElement("", "configuration", 
"configuration");
  
            if (constraintAliases.containsKey(constraintType)) {
              List aliasConstraints = (List) 
constraintAliases.get(constraintType);
              int i = 1;
              for (Iterator it = aliasConstraints.iterator(); it.hasNext(); 
i++) {
                Constraint constraint = (Constraint) it.next();
                getLogger().debug("new alias constraint " + (constraints.size() 
+ i) + ". " + String.valueOf(constraint.getType()) + "[" + 
String.valueOf(constraint) + "]");
              }
              constraints.addAll(aliasConstraints);
            }
            else {
              Constraint constraint = 
constraintFactory.createConstraintInstance(constraintType, constraintName, 
constraintContext, configurationHandler.getConfiguration());
  
              if (constraint instanceof Loggable) {
                ((Loggable)constraint).setLogger(getLogger());
              }
  
              if (constraint instanceof Configurable) {
                try {
                
((Configurable)constraint).configure(configurationHandler.getConfiguration());
                }
                catch(Throwable t) {};
              }
  
              if (constraint != null) {
                getLogger().debug("new simple constraint " + 
(constraints.size() + 1) + ". " + String.valueOf(constraint.getType()) + "[" + 
String.valueOf(constraint) + "]");
                constraints.add(constraint);
              }
              else {
                throw new SAXException("could not create constraint " + 
String.valueOf(constraintType));
              }
            }
            configurationHandler = null;
          }
          else if ("value".equals(name)) {
          }
          else if ("value-of".equals(name)) {
          }
        }
        else {
          throw new SAXException("only elements in namespace " + NS + " are 
supported");
        }
      }
    }
  
    public void characters(char[] chars, int start, int len) throws 
SAXException {
      if (redirect != null) {
        getLogger().debug("saving [" + new String(chars, start, len) + "] into 
config");
        redirect.characters(chars, start, len);
      }
      else {
        text.append(chars, start, len);
      }
    }
  
    private class Environment {
      int minOcc = 1;
      int maxOcc = 1;
      int len = 0;
    }
  
    public void compose(ComponentManager manager) throws ComponentException {
      this.manager = manager;
      //this.constraintFactory = (ConstraintFactory) 
manager.lookup(ConstraintFactory.ROLE);
      //this.preceptorRepository = (PreceptorRepository) 
manager.lookup(PreceptorRepository.ROLE);
    }
  
    public void dispose() {
      //this.manager.release(preceptorRepository);
      //this.manager.release(constraintFactory);
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/preceptors/easyrelax/PreceptorImpl.java
  
  Index: PreceptorImpl.java
  ===================================================================
  /*
   * @version: Mar 14, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.preceptors.easyrelax;
  
  import org.apache.cocoon.precept.Instance;
  import org.apache.cocoon.precept.InvalidXPathSyntaxException;
  import org.apache.cocoon.precept.NoSuchNodeException;
  import org.apache.cocoon.precept.PreceptorViolationException;
  import org.apache.cocoon.precept.preceptors.AbstractPreceptor;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.StringTokenizer;
  
  public class PreceptorImpl extends AbstractPreceptor {
    HashMap index = new HashMap();
  
    public List getConstraitsFor(String xpath) throws NoSuchNodeException {
      AbstractPreceptorNode node = (AbstractPreceptorNode) index.get(xpath);
      if (node != null) {
        List constraints = node.getConstraints();
        if (constraints != null) {
          getLogger().debug(constraints.size() + " constraints for [" + 
String.valueOf(xpath) + "]");
          return (constraints);
        }
        else {
          getLogger().debug("no constraints for [" + String.valueOf(xpath) + 
"]");
          return (null);
        }
      }
      else {
        throw new NoSuchNodeException(xpath);
      }
    }
  
    public void buildInstance(Instance instance) {
      try {
        for (Iterator it = index.keySet().iterator(); it.hasNext();) {
          String xpath = (String) it.next();
          AbstractPreceptorNode node = (AbstractPreceptorNode) index.get(xpath);
          if (node instanceof ElementPreceptorNode) {
            for (int i = 0; i < ((ElementPreceptorNode) node).getMinOcc(); i++) 
{
              String s = xpath;
              if (i != 0) {
                s += "[" + (i + 1) + "]";
              }
              getLogger().debug("building node [" + String.valueOf(s) + "]");
              instance.setValue(s, "");
            }
          }
          else {
            getLogger().debug("building node [" + String.valueOf(xpath) + "]");
            instance.setValue(xpath, "");
          }
        }
      }
      catch (InvalidXPathSyntaxException e) {
        getLogger().error("hm.. the preceptor should know how to build the 
instance!");
      }
      catch (PreceptorViolationException e) {
        getLogger().error("hm.. the preceptor should know how to build the 
instance!");
      }
    }
  
    public boolean isValidNode(String xpath) throws InvalidXPathSyntaxException 
{
      StringBuffer currentPath = new StringBuffer();
      StringTokenizer tok = new StringTokenizer(xpath, "/", false);
      boolean first = true;
      while (tok.hasMoreTokens()) {
        String level = tok.nextToken();
        if (!first) {
          currentPath.append("/");
        }
        else {
          first = false;
        }
  
        if (level.startsWith("@")) {
          currentPath.append(level);
          AbstractPreceptorNode node = (AbstractPreceptorNode) 
index.get(currentPath.toString());
          if (node != null) {
            getLogger().debug("found attribute node [" + 
String.valueOf(currentPath) + "] in index");
            return (true);
          }
          else {
            getLogger().debug("could not find attribute [" + 
String.valueOf(currentPath) + "] in index");
            return (false);
          }
        }
        else {
          String levelName;
          int levelInt = 1;
          int open = level.indexOf("[");
          if (open > 0) {
            int close = level.indexOf("]", open);
            if (close > 0) {
              try {
                levelInt = Integer.parseInt(level.substring(open + 1, close));
                levelName = level.substring(0, open);
              }
              catch (NumberFormatException e) {
                getLogger().debug("invalid syntax [" + String.valueOf(level) + 
"]");
                throw new InvalidXPathSyntaxException(level);
              }
            }
            else {
              getLogger().debug("invalid syntax [" + String.valueOf(level) + 
"]");
              throw new InvalidXPathSyntaxException(level);
            }
          }
          else {
            levelName = level;
          }
  
          currentPath.append(levelName);
          AbstractPreceptorNode node = (AbstractPreceptorNode) 
index.get(currentPath.toString());
          if (node != null) {
            getLogger().debug("found node [" + String.valueOf(currentPath) + "] 
in index");
  
            if (node instanceof ElementPreceptorNode) {
              if (((ElementPreceptorNode)node).getMaxOcc() != 
ElementPreceptorNode.UNBOUND && levelInt > 
((ElementPreceptorNode)node).getMaxOcc()) {
                getLogger().debug(String.valueOf(levelName) + "[" + levelInt + 
"] exceeds maximal occurrences [" + ((ElementPreceptorNode)node).getMaxOcc() + 
"]");
                return (false);
              }
            }
  
            if (!tok.hasMoreTokens()) return (true);
          }
          else {
            getLogger().debug("could not find [" + String.valueOf(currentPath) 
+ "] in index");
            return (false);
          }
        }
      }
      return (false);
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/preceptors/easyrelax/constraints/AbstractConstraint.java
  
  Index: AbstractConstraint.java
  ===================================================================
  /*
   * @version: Mar 21, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.preceptors.easyrelax.constraints;
  
  import org.apache.cocoon.precept.Constraint;
  import org.apache.avalon.framework.logger.AbstractLoggable;
  import org.apache.avalon.framework.component.Component;
  
  public abstract class AbstractConstraint extends AbstractLoggable implements 
Constraint, Component {
  
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/preceptors/easyrelax/constraints/ChoiceConstraint.java
  
  Index: ChoiceConstraint.java
  ===================================================================
  /*
   * @version: Mar 21, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.preceptors.easyrelax.constraints;
  
  import org.apache.cocoon.precept.Context;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.thread.SingleThreaded;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  
  import java.util.Collection;
  import java.util.ArrayList;
  import java.util.Map;
  import java.util.HashMap;
  
  public class ChoiceConstraint extends AbstractConstraint implements 
Configurable, SingleThreaded {
    public Collection validValues = new ArrayList();
    public Map validValuesDescription = new HashMap();
  
    public void configure(Configuration configuration) throws 
ConfigurationException {
      if (validValues.size() == 0) {
        validValues.add("linux"); validValuesDescription.put("linux","Linux");
        validValues.add("w2k"); validValuesDescription.put("w2k","Windows 
2000");
      }
    }
  
    public boolean isSatisfiedBy(Object value, Context context ) {
      System.out.println("checking choice [" + String.valueOf(value) + "] 
contains [" + String.valueOf(validValues) + "]");
      return(validValues.contains(value));
    }
  
    public String getId() {
      return("os");
    }
  
    public String getType() {
      return("choice");
    }
  
    public String toString() {
      return( String.valueOf(getType()) + "[" + String.valueOf(getId()) + "] -> 
[" + String.valueOf(validValues) + "]");
    }
  
    public void toSAX(ContentHandler handler) throws SAXException {
    }
  
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/preceptors/easyrelax/constraints/RegexprConstraint.java
  
  Index: RegexprConstraint.java
  ===================================================================
  /*
   * @version: Mar 21, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.preceptors.easyrelax.constraints;
  
  import org.apache.cocoon.precept.Context;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.thread.SingleThreaded;
  import org.apache.regexp.RE;
  import org.apache.regexp.RESyntaxException;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  
  public class RegexprConstraint extends AbstractConstraint implements 
Configurable, SingleThreaded {
  
    private String expressionString;
    private RE expression;
  
    public void configure(Configuration configuration) throws 
ConfigurationException {
      expressionString = "[EMAIL PROTECTED](\\.[a-zA-Z0-9-]+)+$";
      try {
        expression = new RE(expressionString);
      }
      catch (RESyntaxException e) {
        throw new ConfigurationException("",e);
      }
    }
  
    public boolean isSatisfiedBy(Object value, Context context ) {
      System.out.println("checking regexpr [" + String.valueOf(value) + "] 
matches [" + String.valueOf(expressionString) + "]");
      return(expression.match(String.valueOf(value)));
    }
  
    public String getId() {
      return("email");
    }
  
    public String getType() {
      return("regexpr");
    }
  
    public String toString() {
      return( String.valueOf(getType()) + "[" + String.valueOf(getId()) + "] -> 
[" + String.valueOf(expression) + "]");
    }
  
    public void toSAX(ContentHandler handler) throws SAXException {
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/stores/AbstractInstance.java
  
  Index: AbstractInstance.java
  ===================================================================
  /*
   * @version: Mar 18, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.stores;
  
  import org.apache.avalon.framework.logger.AbstractLoggable;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.cocoon.precept.Instance;
  
  import javax.servlet.http.HttpSessionBindingListener;
  import javax.servlet.http.HttpSessionBindingEvent;
  
  public abstract class AbstractInstance extends AbstractLoggable implements 
Instance, Composable, Disposable, HttpSessionBindingListener {
    protected ComponentManager manager;
  
    public void compose(ComponentManager manager) throws ComponentException {
      this.manager = manager;
    }
  
    public void valueBound(HttpSessionBindingEvent event) {
    }
  
    public void valueUnbound(HttpSessionBindingEvent event) {
      getLogger().debug("releasing instance in session");
      manager.release(this);
    }
  
    public void dispose() {
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/stores/bean/InstanceImpl.java
  
  Index: InstanceImpl.java
  ===================================================================
  /*
   * @version: Mar 15, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.stores.bean;
  
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.cocoon.components.classloader.ClassLoaderManager;
  import org.apache.cocoon.xml.DocumentHandlerAdapter;
  import org.apache.commons.jxpath.JXPathContext;
  import org.exolab.castor.mapping.Mapping;
  import org.exolab.castor.mapping.MappingException;
  import org.exolab.castor.xml.MarshalException;
  import org.exolab.castor.xml.Marshaller;
  import org.exolab.castor.xml.ValidationException;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  import org.apache.cocoon.precept.*;
  import org.apache.cocoon.precept.stores.AbstractInstance;
  
  import java.util.List;
  
  public class InstanceImpl extends AbstractInstance implements Configurable {
    private Preceptor preceptor;
    private Mapping mapping;
    private Object bean;
    private JXPathContext beanContext;
  
    public void setBean(Object bean) {
      this.bean = bean;
      this.beanContext = JXPathContext.newContext(bean);
    }
  
    public void configure(Configuration configuration) throws 
ConfigurationException {
      Configuration clazzConf = configuration.getChild("class");
      if (clazzConf != null) {
        ClassLoaderManager clazzLoader = null;
        try {
          String clazzName = clazzConf.getValue();
          String mappingURI = clazzConf.getAttribute("mapping");
  
          if (mappingURI != null) {
            mapping = new Mapping();
            // resolve
            //mapping.loadMapping(getFile(resolver,mappingURI));
            getLogger().debug("bean class = [" + String.valueOf(clazzName) + "] 
mapping [" + String.valueOf(mappingURI) + "]");
          }
          else {
            getLogger().debug("bean class = [" + String.valueOf(clazzName) + "] 
using default mapping");
          }
  
          clazzLoader = (ClassLoaderManager) 
manager.lookup(ClassLoaderManager.ROLE);
          Class clazz = clazzLoader.loadClass(clazzName);
          setBean(clazz.newInstance());
        }
        catch (ComponentException e) {
          throw new ConfigurationException("", e);
        }
        catch (ClassNotFoundException e) {
          throw new ConfigurationException("", e);
        }
        catch (InstantiationException e) {
          throw new ConfigurationException("", e);
        }
        catch (IllegalAccessException e) {
          throw new ConfigurationException("", e);
        }
        finally {
          manager.release(clazzLoader);
        }
      }
    }
  
    public void setValue(String xpath, Object value) throws 
PreceptorViolationException, InvalidXPathSyntaxException {
      setValue(xpath, value, null);
    }
  
    public void setValue(String xpath, Object value, Context context) throws 
PreceptorViolationException, InvalidXPathSyntaxException {
      try {
        beanContext.setValue(xpath, value);
      }
      catch (Exception e) {
        throw new PreceptorViolationException(e);
      }
    }
  
    public Object getValue(String xpath) throws InvalidXPathSyntaxException {
      try {
        return (beanContext.getValue(xpath));
      }
      catch (Exception e) {
        throw new InvalidXPathSyntaxException(e);
      }
    }
  
    public void setPreceptor(Preceptor preceptor) {
      this.preceptor = preceptor;
      preceptor.buildInstance(this);
    }
  
    public List validate(String xpath, Context context) throws 
InvalidXPathSyntaxException, NoSuchNodeException {
  
      //NYI
      return null;
    }
  
    public List validate(Context context) throws InvalidXPathSyntaxException {
  
      //NYI
      return null;
    }
  
    public Preceptor getPreceptor() {
      return (preceptor);
    }
  
    public long getLastModified() {
      //NYI
      return 0;
    }
  
    public void toSAX(ContentHandler handler, boolean withConstraints) throws 
SAXException {
      try {
        Marshaller marshaller = new Marshaller(new 
DocumentHandlerAdapter(handler));
        if (mapping != null) {
          marshaller.setMapping(mapping);
        }
        marshaller.marshal(bean);
      }
      catch (ValidationException e) {
        throw new SAXException(e);
      }
      catch (MappingException e) {
        throw new SAXException(e);
      }
      catch (MarshalException e) {
        throw new SAXException(e);
      }
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/stores/bean/test/CocoonInstallationBean.java
  
  Index: CocoonInstallationBean.java
  ===================================================================
  /*
   * @version: Mar 20, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.stores.bean.test;
  
  public class CocoonInstallationBean {
    private UserBean user;
    private SystemBean system;
    private int number;
    private String live_url;
    private boolean publish;
  
    public CocoonInstallationBean() {
      user = new UserBean();
      system = new SystemBean();
    }
  
    public UserBean getUser() {
      return user;
    }
  
    public void setUser(UserBean user) {
      this.user = user;
    }
  
    public SystemBean getSystem() {
      return system;
    }
  
    public void setSystem(SystemBean system) {
      this.system = system;
    }
  
    public int getNumber() {
      return number;
    }
  
    public void setNumber(int number) {
      this.number = number;
    }
  
    public String getLive_url() {
      return live_url;
    }
  
    public void setLive_url(String live_url) {
      this.live_url = live_url;
    }
  
    public boolean isPublish() {
      return publish;
    }
  
    public void setPublish(boolean publish) {
      this.publish = publish;
    }
  
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/stores/bean/test/SystemBean.java
  
  Index: SystemBean.java
  ===================================================================
  /*
   * @version: Mar 20, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.stores.bean.test;
  
  public class SystemBean {
    private String os;
    private String processor;
    private int ram;
    private String servlet_engine;
    private String java_version;
  
    public SystemBean() {
    }
  
    public String getOs() {
      return os;
    }
  
    public void setOs(String os) {
      this.os = os;
    }
  
    public String getProcessor() {
      return processor;
    }
  
    public void setProcessor(String processor) {
      this.processor = processor;
    }
  
    public int getRam() {
      return ram;
    }
  
    public void setRam(int ram) {
      this.ram = ram;
    }
  
    public String getServlet_engine() {
      return servlet_engine;
    }
  
    public void setServlet_engine(String servlet_engine) {
      this.servlet_engine = servlet_engine;
    }
  
    public String getJava_version() {
      return java_version;
    }
  
    public void setJava_version(String java_version) {
      this.java_version = java_version;
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/stores/bean/test/UserBean.java
  
  Index: UserBean.java
  ===================================================================
  /*
   * @version: Mar 20, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.stores.bean.test;
  
  public class UserBean {
    private String firstname;
    private String lastname;
    private String email;
  
    public UserBean() {
    }
  
    public String getFirstname() {
      return firstname;
    }
  
    public void setFirstname(String firstname) {
      this.firstname = firstname;
    }
  
    public String getLastname() {
      return lastname;
    }
  
    public void setLastname(String lastname) {
      this.lastname = lastname;
    }
  
    public String getEmail() {
      return email;
    }
  
    public void setEmail(String email) {
      this.email = email;
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/stores/dom/simple/AttributeNode.java
  
  Index: AttributeNode.java
  ===================================================================
  /*
   * Created by IntelliJ IDEA.
   * User: tcurdt
   * Date: 15.03.2002
   * Time: 23:55:52
   * To change template for new class use
   * Code Style | Class Templates options (Tools | IDE Options).
   */
  package org.apache.cocoon.precept.stores.dom.simple;
  
  import java.util.Iterator;
  import java.util.List;
  
  public class AttributeNode extends Node {
  
    public AttributeNode( String name, List constraints) {
      super(name,constraints);
    }
  
    public void toStringBuffer( StringBuffer sb, int depth) {
      sb.append(" ").append(name).append("=");
  
      sb.append("\"").append(String.valueOf(getValue())).append("\"");
  
    }
  
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/stores/dom/simple/ElementNode.java
  
  Index: ElementNode.java
  ===================================================================
  /*
   * Created by IntelliJ IDEA.
   * User: tcurdt
   * Date: 15.03.2002
   * Time: 23:56:03
   * To change template for new class use
   * Code Style | Class Templates options (Tools | IDE Options).
   */
  package org.apache.cocoon.precept.stores.dom.simple;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.AttributesImpl;
  import org.apache.cocoon.precept.Constraint;
  
  import java.util.*;
  
  public class ElementNode extends Node {
    private final static Attributes NOATTR = new AttributesImpl();
  
    private ArrayList childs;
    private ArrayList attributes;
    private HashMap attributeIndex;
  
  
    public ElementNode(String name, List constraints) {
      super(name, constraints);
    }
  
    public void addAttribute(Node node) {
      if (attributes == null) attributes = new ArrayList();
      if (attributeIndex == null) attributeIndex = new HashMap();
      attributes.add(node);
      attributeIndex.put(node.getValue(), node);
    }
  
    //public Node getAttribute( String name ) {
    //}
  
    public List getAttributes() {
      return (attributes);
    }
  
  
    public void addChild(Node node) {
      if (childs == null) childs = new ArrayList();
      childs.add(node);
    }
  
    public List getChilds() {
      return (childs);
    }
  
    //public List getChilds( String name ) {
    //}
  
    public void toStringBuffer(StringBuffer sb, ElementNode e, int depth) {
      StringBuffer ident = new StringBuffer();
      for (int i = 0; i < depth * 3; i++) ident.append(" ");
  
      sb.append("\n").append(ident).append("<").append(e.getName());
  
  
      Collection attributes = e.getAttributes();
      if (attributes != null) {
        for (Iterator it = attributes.iterator(); it.hasNext();) {
          AttributeNode attr = (AttributeNode) it.next();
          attr.toStringBuffer(sb, depth);
        }
      }
  
      sb.append(">").append("\n").append(ident).append(" ");
  
      sb.append(String.valueOf(e.getValue()));
  
      Collection childs = e.getChilds();
      if (childs != null) {
        for (Iterator it = childs.iterator(); it.hasNext();) {
          ElementNode child = (ElementNode) it.next();
          toStringBuffer(sb, child, depth + 1);
        }
      }
      sb.append("\n").append(ident);
      sb.append("</").append(e.getName()).append(">");
    }
  
  
    public void toSAX(ContentHandler handler, ElementNode e, boolean 
withConstraints) throws SAXException {
  
      handler.startElement("", e.getName(), e.getName(), NOATTR);
  
      if (e.getValue() != null) 
handler.characters(e.getValue().toString().toCharArray(), 0, 
e.getValue().length());
  
      if (withConstraints) {
        List constraints = e.getConstraints();
        if (constraints != null) {
          for (Iterator it = constraints.iterator(); it.hasNext();) {
            Constraint constraint = (Constraint) it.next();
  
            handler.startElement("", "constraint", "constraint", NOATTR);
            String s = String.valueOf(constraint.getId()) +
                    " of type " + String.valueOf(constraint.getType()) +
                    " is " + constraint.isSatisfiedBy(e.getValue(), null);
            handler.characters(s.toString().toCharArray(), 0, s.length());
            handler.endElement("", "constraint", "constraint");
          }
        }
      }
  
      Collection childs = e.getChilds();
      if (childs != null) {
        for (Iterator it = childs.iterator(); it.hasNext();) {
          ElementNode child = (ElementNode) it.next();
          toSAX(handler, child, withConstraints);
        }
      }
      handler.endElement("", getName(), e.getName());
    }
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/stores/dom/simple/InstanceImpl.java
  
  Index: InstanceImpl.java
  ===================================================================
  /*
   * @version: Mar 14, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.stores.dom.simple;
  
  
  import org.apache.cocoon.precept.*;
  import org.apache.cocoon.precept.Constraint;
  import org.apache.cocoon.precept.stores.dom.simple.Node;
  import org.apache.cocoon.precept.stores.AbstractInstance;
  
  import java.util.*;
  
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.ComponentException;
  
  public class InstanceImpl extends AbstractInstance {
    private HashMap index = new HashMap();
    private Preceptor preceptor;
    private ElementNode root;
  
    public void setPreceptor(Preceptor preceptor) {
      this.preceptor = preceptor;
      preceptor.buildInstance(this);
    }
  
    private Node createNode(String xpath) throws InvalidXPathSyntaxException {
      try {
        StringBuffer currentPath = new StringBuffer();
        StringTokenizer tok = new StringTokenizer(xpath, "/", false);
        Node currentParent = root;
        boolean first = true;
        while (tok.hasMoreTokens()) {
          String level = tok.nextToken();
          if (!first) {
            currentPath.append("/");
          }
          else {
            first = false;
          }
          if (level.endsWith("[1]")) {
            level = level.substring(0, level.length() - 3);
          }
          currentPath.append(level);
          Node node = (Node) index.get(currentPath.toString());
          if (node != null) {
            getLogger().debug("found node [" + String.valueOf(currentPath) + "] 
in index");
            currentParent = node;
          }
          else {
            if (currentParent != null) {
              if (level.startsWith("@")) {
                if (level.indexOf("[") >= 0 || level.indexOf("]") >= 0) {
                  throw new InvalidXPathSyntaxException(level);
                }
                if (preceptor != null) {
                  node = new AttributeNode(level.substring(1), 
preceptor.getConstraitsFor(currentPath.toString()));
                }
                else {
                  node = new AttributeNode(level.substring(1), null);
                }
                getLogger().debug("creating attribute [" + 
String.valueOf(currentPath) + "]");
                ((ElementNode) currentParent).addAttribute(node);
                index.put(currentPath.toString(), node);
                return (node);
              }
              else {
                if (preceptor != null) {
                  node = new ElementNode(level, 
preceptor.getConstraitsFor(currentPath.toString()));
                }
                else {
                  node = new ElementNode(level, null);
                }
                getLogger().debug("creating node [" + 
String.valueOf(currentPath) + "]");
                ((ElementNode) currentParent).addChild(node);
                index.put(currentPath.toString(), node);
                index.put(currentPath.toString() + "[1]", node);
              }
            }
            else {
              getLogger().debug("creating root node [" + 
String.valueOf(currentPath) + "]");
              if (preceptor != null) {
                node = root = new ElementNode(level, 
preceptor.getConstraitsFor(currentPath.toString()));
              }
              else {
                node = root = new ElementNode(level, null);
              }
              index.put(currentPath.toString(), node);
              index.put(currentPath.toString() + "[1]", node);
            }
          }
          currentParent = node;
        }
        return (currentParent);
      }
      catch (NoSuchNodeException e) {
        getLogger().error("hm.. this should not happen!");
        return (null);
      }
    }
  
    public void setValue(String xpath, Object value) throws 
PreceptorViolationException, InvalidXPathSyntaxException {
      setValue(xpath, value, null);
    }
  
    public void setValue(String xpath, Object value, Context context) throws 
PreceptorViolationException, InvalidXPathSyntaxException {
      Node node = (Node) index.get(xpath);
      if (node != null) {
        node.setValue((String) value);
      }
      else {
        if (preceptor != null) {
          getLogger().debug("checking preceptor for [" + String.valueOf(xpath) 
+ "]");
          if (preceptor.isValidNode(xpath)) {
            node = createNode(xpath);
            node.setValue((String) value);
          }
          else {
            throw new PreceptorViolationException("[" + String.valueOf(xpath) + 
"] is prohibited by preceptor");
          }
        }
        else {
          getLogger().debug("no preceptor");
          node = createNode(xpath);
          node.setValue((String) value);
        }
      }
    }
  
    public Object getValue(String xpath) throws InvalidXPathSyntaxException, 
NoSuchNodeException {
      Node node = (Node) index.get(xpath);
      if (node != null) {
        return (node.getValue());
      }
      else {
        throw new NoSuchNodeException(xpath);
      }
    }
  
    public List validate(Context context) throws InvalidXPathSyntaxException {
      ArrayList all = null;
      for (Iterator it = index.keySet().iterator(); it.hasNext();) {
        String xpath = (String) it.next();
        if (!xpath.endsWith("[1]")) {
          try {
            List result = validate(xpath, context);
            if (result != null) {
              getLogger().debug("constraint violations for [" + 
String.valueOf(xpath) + "]");
              if (all == null) all = new ArrayList();
              all.addAll(result);
            }
            else {
              getLogger().debug("[" + String.valueOf(xpath) + "] is valid");
            }
          }
          catch (NoSuchNodeException e) {
            getLogger().error("hm... this should not happen!");
          }
        }
      }
      return (all);
    }
  
    public List validate(String xpath, Context context) throws 
InvalidXPathSyntaxException, NoSuchNodeException {
      Node node = (Node) index.get(xpath);
      if (node != null) {
        ArrayList result = null;
        List constraints = node.getConstraints();
        if (constraints != null) {
          for (Iterator it = constraints.iterator(); it.hasNext();) {
            Constraint constraint = (Constraint) it.next();
            if (constraint.isSatisfiedBy(getValue(xpath), context )) {
              getLogger().debug("[" + String.valueOf(xpath) + "] constraint [" 
+ String.valueOf(constraint) + "] is satisfied");
            }
            else {
              getLogger().debug("[" + String.valueOf(xpath) + "] constraint [" 
+ String.valueOf(constraint) + "] FAILED!");
              if (result == null) result = new ArrayList();
              result.add(constraint);
            }
          }
        }
        return (result);
      }
      else {
        getLogger().error("could not find node [" + String.valueOf(xpath) + 
"]");
        throw new NoSuchNodeException(xpath);
      }
    }
  
    public Preceptor getPreceptor() {
      return (preceptor);
    }
  
    public long getLastModified() {
      //NYI
      return 0;
    }
  
    public void toSAX(ContentHandler handler, boolean constraints) throws 
SAXException {
      if (root != null) {
        root.toSAX(handler, root, constraints);
      }
    }
  
    public String toString() {
      if (root != null) {
        StringBuffer sb = new StringBuffer();
        root.toStringBuffer(sb, root, 0);
        return (sb.toString());
      }
      else {
        return ("");
      }
    }
  
  }
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/precept/stores/dom/simple/Node.java
  
  Index: Node.java
  ===================================================================
  /*
   * @version: Mar 14, 2002
   * @author: Torsten Curdt <[EMAIL PROTECTED]>
   */
  package org.apache.cocoon.precept.stores.dom.simple;
  
  import org.apache.cocoon.precept.Context;
  
  import java.util.List;
  import java.util.ArrayList;
  import java.util.HashMap;
  
  public abstract class Node {
  
    protected String name;
    protected String value;
    protected List constraints;
  
    public Node( String name, List constraints) {
      this.name = name;
      this.constraints = constraints;
    }
  
    public String getName() {
      return(name);
    }
  
    public String getValue() {
      return(value);
    }
  
    public void setValue( String value ) {
      this.value = value;
    }
  
    public List getConstraints() {
      return(constraints);
    }
  }
  
  
  
  1.1                  xml-cocoon2/src/scratchpad/webapp/mount/precept/README
  
  Index: README
  ===================================================================
  The Precept Stuff
  -----------------
  
  This is all still far from being ready for prime time but in order to share 
efforts I think
  it makes sense to have it in scratchpad. I'll give a short indroduction about 
the idea, the
  terms I am using, what is still missing, what should change and how I see its 
future.
  
  Installation
  ------------
  
  Add the roles and xconf snippet to you installation, set your precptor path 
(it's not yet
  resolved) mount the sitemap and access the url "app/demo.html" relative to 
the sitemap mount.
  
  
  Introduction
  ------------ 
  
  Form processing is always about collecting data of a specific structure. When 
this data
  selection process is finished the data will be used for some kind of purpose. 
Seeing this
  from a more concrete XMLish point of view one could say we are building some 
kind of XML
  instance which needs to conform to a schema description. That's exactly the 
major goal of
  this approach.
  
  
  The model
  ---------
  
  At the start of the flow we create some kind of instance that can hold our 
values. This
  instance will be held inside the users session until the end of form 
processing. In order to
  specify the structure and validation of the form data we need some kind of 
schema. Since
  "schema" is widely used as the short form for the w3.org XML Schema language 
I have chosen to
  use a different term that means schemas in general (XML Schema, relax-ng, 
etc.): "preceptors".
  In the first place the preceptor defines the structure of the instance but 
also holds 
  information about the value constraints. That's our model.
  
  
  The view
  --------
  
  Especially for multipage forms (sometimes called "wizards") it is quite 
obvious that only parts 
  of an instance are supposed to be displayed.
  
    [-----------------instance---------------]
    [---view1---][----view2----][----view3---]
  
  So we have different views of the instance. There are 2 different ways of 
achieving this. 
  (see webapp example1 and example2 for more details)
  
  
  The controller
  --------------
  
  The controller needs to populate request parameters into the instance and 
depending on the
  validation result select the correct following view. At the beginning I was 
quite optimistic
  this could all happen automagically - now I know better. I experienced two 
problems that are 
  not to solve automagically:
  
  1. checkboxes - Arrggh! This is the most stupid behavior I have ever seen... 
Anyway we have
     to deal with it. The only really working solution is that the controller 
"knows" when a 
     checkbox value is supposed to be in the request. Otherwise you cannot turn 
off your 
     checkboxes because a turned off checkbox will not appear in the request.
  
  2. partial validation - It's not true that you always want to validate a 
complete view.
     Never thought this would be necessary until some people showed me a real 
world example.
  
  The current approach is to bind methods to the form submit buttons. So you 
can define
  explicitly what should happen (populated, validated, which view is supposed 
to be shown) on a 
  specific button. So you are free to do whatever you want on a button click...
  
  
  This usually will happen inside an multiaction (maybe also within Ovidiu's 
schecoon?)
  
   ...
   public Map introspection(Redirector redirector, Sou...
      getLogger().debug("start of flow");
      // start of flow create session
      Session session = createSession(objectModel);
      // create instance
      Instance instance = createInstance("feedback");
      // save instance into session
      session.setAttribute("form-feedback",instance);
      // select first view
      return(page(VIEW1));
    }                                                                           
                     
   ...
   public Map doNext(Redirector redirector, Sou...
      getLogger().debug("populating");
      // populate a set of data into the instace
      populate(objectModel, "form-feedback", SET_INSTALLATION );
      // check if there are errors in those fields
      List errors = validate(objectModel, "form-feedback", SET_INSTALLATION );
      if(errors != null) {
        // errors - go back to last view
        getLogger().debug("some constraints FAILED");
        return (page(VIEW1));
      }
      else {
        // errors - go to next view
        getLogger().debug("all constraints are ok");
        return (page(VIEW2));
      }
    }                     
   ...
  
  
  The Instance
  ------------
  
  You can drop in any instance implementation that conforms to the following 
interface:
  
  public interface Instance extends Component {
    public void setValue(String xpath, Object value);
    public void setValue(String xpath, Object value, Context context);
  
    public Object getValue(String xpath);
  
    public List validate(String xpath, Context context);
    public List validate(Context context);
  
    public void setPreceptor( Preceptor preceptor );
    public Preceptor getPreceptor();
   
    public void toSAX( ContentHandler handler, boolean withConstraints);
    public long getLastModified();
  }                                       
  
  Note: I removed the Exceptions for this README. Please use the Instance.java 
as reference.
  
  Currently I have written a (very) simple dom implementation. (without 
namespace support or 
  any other features. More a simple tree. But should be quite fast)
  And the first step towards a BeanInstance. (Validation is missing and needs 
some more 
  discussion)
  
    ...
    <instance-impl>
      <component-instance name="dom" class="...">
      <component-instance name="bean" class="...">
        <class mapping="...">somwhere.my.bean</class>
      </component-instance>
    </instance-impl> 
    ...
  
  
  The Preceptor
  -------------
  
  A preceptor is usually some kind of wrapper around or interface to one of the 
well known
  validators. If you write a preceptor e.g. for XML Schema you can easily drop 
it in and 
  design your form within an XSD.
  
  public interface Preceptor extends Component {
    public List getConstraitsFor( String xpath );
    public boolean isValidNode( String xpath );
    public void buildInstance( Instance instance );
  } 
  
  Note: I removed the Exceptions for this README. Please use the Instance.java 
as reference.
  
  The mapping between the instance and the preceptor looks like this:
  
    <instances logger="webapp.validation">
      <!-- dom instance without validation -->
      <instance name="empty" impl="dom"/>
  
      <!-- dom instance with an easyrelax preceptor -->
      <instance name="feedback" impl="dom">
        <preceptor impl="easyrelax" uri="file:/D:/...../model/easyrelax.xml"/>
      </instance>
  
      <!--
      <instance name="form1" impl="dom">
        <preceptor impl="xsd" uri="..."/>
      </instance>
      <instance name="form2" impl="bean">
        <preceptor impl="relax-ng" uri="..."/>
      </instance>
      -->
    </instances>  
  
  
  The Constraint
  --------------
  
  A constraint restricts valid values of nodes inside the instance for a given 
context.  If we
  don't want to write our own constraints (and this should be the goal) we need 
to wrap
  existing ones into the Constraint Interface.
  
  public interface Constraint {
    public boolean isSatisfiedBy( Object value, Context context );
    public String getId();
    public String getType();
    public void toSAX(ContentHandler handler) throws SAXException;
  } 
  
  
  TODOs
  -----
  
  * make the easyrelax PreceptorBuilder use the parser component
  * put the easyrelax ConstraintFactory under CM control
  * use the real configuration values in the easyrelax constraints
  * implement the getLastModified in the simple dom instance
  * use the resolver to lookup the mapping for the bean instance
  * implement the validation for the bean instance
  * implement the getLastModified in the bean instance
  * maybe pass the validation result as request attribute to the
    instance transformer
  * discuss the selectMany instance representation
  * discuss schematron integration
  * implement the following tags in the instance transformer
      <textbox ref="xpath">
      <password ref="xpath">
      <selectOne ref="xpath">
      <selectMany ref="xpath">
      <selectBoolean ref="xpath">
      <output ref="xpath">
  
  
  
  The future
  ----------
  
  1) What I like to see in the future is a way to define simple form 
controllers not in java
     but in XML. This should be quite easy to achieve by writing an action 
taking an XML
     desciptor as configuration.
  
  2) A better multiaction integration in the sitemap. So those ugly action-set 
definitions go
     away.
  
  3) A tight integration with Schecoon
  
  4) Talk with with guys from Xerces2 (xsd) about the Preceptor stuff. IIRC 
they are about to
     rewrite some of the validation stuff anyway.
  
  5) Talk with the guys from Jing (relax-ng) about the Preceptor stuff. AFAICS 
they currently
     only have per document validation.
  
  6) add a toJavaScript() method to the Constraint interface so we can even 
generate JavaScript
     validation from the Constraints
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/sitemap.xmap
  
  Index: sitemap.xmap
  ===================================================================
  <?xml version="1.0"?>
  
  <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0";>
  
    <map:components>
      <map:generators default="file"/>
      <map:transformers default="xslt">
        <map:transformer name="instance" 
src="org.apache.cocoon.precept.InstanceTransformer" logger="webapp.validation"/>
      </map:transformers>
      <map:actions>
        <map:action name="demoflow" 
src="org.apache.cocoon.precept.acting.PreceptorDemoAction" 
logger="webapp.validation"/>
      </map:actions>
      <map:readers default="resource"/>
      <map:serializers default="html"/>
      <map:selectors default="browser"/>
      <map:matchers default="wildcard"/>    
    </map:components>
  
    <map:action-sets>
      <map:action-set name="demo">
         <map:act type="demoflow"/>
         <map:act type="demoflow" action="prev1">
           <map:parameter name="method" value="prev1"/>
         </map:act>
         <map:act type="demoflow" action="prev2">
           <map:parameter name="method" value="prev2"/>
         </map:act>
         <map:act type="demoflow" action="prev3">
           <map:parameter name="method" value="prev3"/>
         </map:act>
         <map:act type="demoflow" action="prev4">
           <map:parameter name="method" value="prev4"/>
         </map:act>
         <map:act type="demoflow" action="next2">
           <map:parameter name="method" value="next2"/>
         </map:act>
         <map:act type="demoflow" action="next3">
           <map:parameter name="method" value="next3"/>
         </map:act>
         <map:act type="demoflow" action="next4">
           <map:parameter name="method" value="next4"/>
         </map:act>
         <map:act type="demoflow" action="submit">
           <map:parameter name="method" value="submit"/>
         </map:act>
      </map:action-set>
    </map:action-sets>
  
    <map:pipelines>
      <map:pipeline>
  
        <map:match pattern="**.html">
          <map:act type="request">
  
            <map:match pattern="app/**">
              <map:match pattern="**/demo.*">
                <map:act set="demo">
                  <map:generate src="example1/{page}.xml"/>
                  <map:transform type="instance"/>
                  <map:transform src="example1/{page}.xsl"/>
                  <map:serialize/>
                </map:act>
  
              </map:match>
            </map:match>
  
          </map:act>
        </map:match>
      </map:pipeline>
  
    </map:pipelines>
  </map:sitemap>
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/snippet.roles
  
  Index: snippet.roles
  ===================================================================
  <?xml version="1.0" ?>
  <role-list>
    <role name="org.apache.cocoon.precept.InstanceFactory"
         shorthand="instances"
         default-class="org.apache.cocoon.precept.InstanceFactory"/>
   
    <role name="org.apache.cocoon.precept.InstanceSelector"
         shorthand="instance-impl"
         
default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector"
         default-hint="dom">
         <hint shorthand="dom" 
class="org.apache.cocoon.precept.stores.dom.simple.InstanceImpl"/>
         <hint shorthand="bean" 
class="org.apache.cocoon.precept.stores.bean.InstanceImpl"/>
    </role>
   
    <role name="org.apache.cocoon.precept.PreceptorBuilderSelector"
         shorthand="preceptor-impl"
         
default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector"
         default-hint="easyrelax">
         <hint shorthand="easyrelax" 
class="org.apache.cocoon.precept.preceptors.easyrelax.PreceptorBuilderImpl"/>
    </role>
  </role-list>
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/snippet.xconf
  
  Index: snippet.xconf
  ===================================================================
  
    <instance-impl>
      <component-instance name="dom" 
class="org.apache.cocoon.precept.stores.dom.simple.InstanceImpl" 
logger="webapp.validation"/>
      <component-instance name="bean" 
class="org.apache.cocoon.precept.stores.bean.InstanceImpl" 
logger="webapp.validation">
        <class mapping="file:/...">somwhere.my.bean</class>
      </component-instance>
    </instance-impl>
  
    <preceptor-impl>
      <component-instance name="easyrelax" 
class="org.apache.cocoon.precept.preceptors.easyrelax.PreceptorBuilderImpl" 
logger="webapp.validation"/>
      <!--
      <component-instance name="relax-ng" class="..." 
logger="webapp.validation"/>
      <component-instance name="xsd" class="..." logger="webapp.validation"/>
      -->
    </preceptor-impl>
    
    <instances logger="webapp.validation">
      <instance name="empty" impl="dom"/>
      <instance name="feedback" impl="dom">
        <preceptor impl="easyrelax" uri="file:/D:/...../model/easyrelax.xml"/>
      </instance>
      <!--
      <instance name="form1" impl="dom">
        <preceptor impl="xsd" uri="..."/>
      </instance>
      <instance name="form2" impl="dom">
        <preceptor impl="relax-ng" uri="..."/>
      </instance>
      -->
    </instances>
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/README
  
  Index: README
  ===================================================================
  This example always inserts the full instance into the SAX stream and uses
  the different stylesheets to display only parts of it.
  
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/error.xml
  
  Index: error.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <root xmlns:f="http://www.dff.st/dform";
        xmlns:r="http://www.dff.st/drender";
        xmlns:i="http://www.dff.st/ns/desire/instance/1.0";
        >
  
     Sorry, submit failed
     
  </root>
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/error.xsl
  
  Index: error.xsl
  ===================================================================
  <?xml version="1.0"?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                                
xmlns:i="http://www.dff.st/ns/desire/instance/1.0";>
  
  
     <xsl:template match="root">
       <html><body><xsl:apply-templates/></body></html>
     </xsl:template>
        
     <xsl:template match="/|*">
        <xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates /></xsl:copy>
     </xsl:template>
  
     <xsl:template match="text()">
        <xsl:value-of select="." />
     </xsl:template>
  </xsl:stylesheet>
  
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/thanks.xml
  
  Index: thanks.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <root xmlns:f="http://www.dff.st/dform";
        xmlns:r="http://www.dff.st/drender";
        xmlns:i="http://www.dff.st/ns/desire/instance/1.0";
        >
  
     Successfully submitted your data!
     
  </root>
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/thanks.xsl
  
  Index: thanks.xsl
  ===================================================================
  <?xml version="1.0"?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                                
xmlns:i="http://www.dff.st/ns/desire/instance/1.0";>
  
  
     <xsl:template match="root">
       <html><body><xsl:apply-templates/></body></html>
     </xsl:template>
        
     <xsl:template match="/|*">
        <xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates /></xsl:copy>
     </xsl:template>
  
     <xsl:template match="text()">
        <xsl:value-of select="." />
     </xsl:template>
  </xsl:stylesheet>
  
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/view1.xml
  
  Index: view1.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <root xmlns:f="http://www.dff.st/dform";
        xmlns:r="http://www.dff.st/drender";
        xmlns:i="http://www.dff.st/ns/desire/instance/1.0";
        >
  
     <i:instance id="form-feedback"/>
     
     <!--
     <r:render>
        <f:label r:x="108" r:y="77" r:w="181" r:h="108">Name</f:label>
        <f:textbox ref="cocoon-user/name" r:x="108" r:y="77" r:w="181" 
r:h="108"/>
        <f:textbox ref="cocoon-user/surname" r:x="108" r:y="77" r:w="181" 
r:h="108"/>
        <f:textbox ref="cocoon-user/email" r:x="108" r:y="77" r:w="181" 
r:h="108"/>
        <f:textbox ref="cocoon-user/age" r:x="108" r:y="77" r:w="181" 
r:h="108"/>
        <f:textbox ref="cocoon-user/city" r:x="108" r:y="77" r:w="181" 
r:h="108"/>
        <f:textbox ref="cocoon-user/zip" r:x="108" r:y="77" r:w="181" 
r:h="108"/>
        <f:textbox ref="cocoon-user/number-of-projects" r:x="108" r:y="77" 
r:w="181" r:h="108"/>
  
        <f:selectOne ref="cocoon-user/position" 
preferred-presentation="combobox" r:x="108" r:y="77" r:w="181" r:h="108"/>
  
        <f:selectMany ref="cocoon-user/os" preferred-presentation="listbox" 
r:x="108" r:y="77" r:w="181" r:h="108"/>
  
        <f:selectBoolean ref="cocoon-user/like-it" 
preferred-presentation="checkbox" r:x="108" r:y="77" r:w="181" r:h="108"/>
  
        <f:button method="next" r:x="108" r:y="77" r:w="181" r:h="108">
           <f:caption>Next Page</f:caption>
           <f:hint>Click here to get to next page</f:hint>
        </f:button>
  
     </r:render>
     -->
  </root>
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/view1.xsl
  
  Index: view1.xsl
  ===================================================================
  <?xml version="1.0"?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                                
xmlns:i="http://www.dff.st/ns/desire/instance/1.0";>
  
  
     <xsl:template match="root">
       <html><body><form 
method="POST"><xsl:apply-templates/></form></body></html>
     </xsl:template>
     
     <xsl:template match="cocoon-installation">
       <table border="1">
       <tr>
         <td>Firstname</td>
         <td><input type="textbox" name="cocoon-installation/user/firstname" 
value="{user/firstname/text()}"/></td>
         <td><xsl:apply-templates select="user/firstname/constraint"/></td>
       </tr>
       <tr>
         <td>Lastname</td>
         <td><input type="textbox" name="cocoon-installation/user/lastname" 
value="{user/lastname/text()}"/></td>
         <td><xsl:apply-templates select="user/lastname/constraint"/></td>
       </tr>
       <tr>
         <td>Email</td>
         <td><input type="textbox" name="cocoon-installation/user/email" 
value="{user/email/text()}"/></td>
         <td><xsl:apply-templates select="user/email/constraint"/></td>
       </tr>
       <tr>
         <td>Age</td>
         <td><input type="textbox" name="cocoon-installation/user/age" 
value="{user/age/text()}"/></td>
         <td><xsl:apply-templates select="user/age/constraint"/></td>
       </tr>
       </table>
       <input type="submit" name="cocoon-action-next2" value="Next Page"/>     
     </xsl:template>
     
     <xsl:template match="/|*">
        <xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates /></xsl:copy>
     </xsl:template>
  
     <xsl:template match="text()">
        <xsl:value-of select="." />
     </xsl:template>
  </xsl:stylesheet>
  
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/view2.xml
  
  Index: view2.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <root xmlns:f="http://www.dff.st/dform";
        xmlns:r="http://www.dff.st/drender";
        xmlns:i="http://www.dff.st/ns/desire/instance/1.0";
        >
  
     <i:instance id="form-feedback"/>
     
  </root>
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/view2.xsl
  
  Index: view2.xsl
  ===================================================================
  <?xml version="1.0"?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                                
xmlns:i="http://www.dff.st/ns/desire/instance/1.0";>
  
  
     <xsl:template match="root">
       <html><body><form 
method="POST"><xsl:apply-templates/></form></body></html>
     </xsl:template>
     
     <xsl:template match="cocoon-installation">
       <table border="1">
       <tr>
         <td>Installation number</td>
         <td><input type="textbox" name="cocoon-installation/number" 
value="{number/text()}"/></td>
       </tr>
       <tr>
         <td>Live URL</td>
         <td><input type="textbox" name="cocoon-installation/live-url" 
value="{live-url/text()}"/></td>
       </tr>
       <tr>
         <td>Publish this URL</td>
         <td><input type="checkbox" name="cocoon-installation/publish" 
value="true">
                <xsl:if test="publish/text() = 'true'">
                  <xsl:attribute name="checked"/>
                </xsl:if>
             </input>
         </td>
       </tr>
       </table>
       <input type="submit" name="cocoon-action-prev1" value="Prev Page"/>     
       <input type="submit" name="cocoon-action-next3" value="Next Page"/>     
     </xsl:template>
     
     <xsl:template match="/|*">
        <xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates /></xsl:copy>
     </xsl:template>
  
     <xsl:template match="text()">
        <xsl:value-of select="." />
     </xsl:template>
  </xsl:stylesheet>
  
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/view3.xml
  
  Index: view3.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <root xmlns:f="http://www.dff.st/dform";
        xmlns:r="http://www.dff.st/drender";
        xmlns:i="http://www.dff.st/ns/desire/instance/1.0";
        >
  
     <i:instance id="form-feedback"/>
     
  </root>
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/view3.xsl
  
  Index: view3.xsl
  ===================================================================
  <?xml version="1.0"?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                                
xmlns:i="http://www.dff.st/ns/desire/instance/1.0";>
  
  
     <xsl:template match="root">
       <html><body><form 
method="POST"><xsl:apply-templates/></form></body></html>
     </xsl:template>
     
     <xsl:template match="cocoon-installation">
       <table border="1">
       <tr>
         <td>os</td>
         <td>
            <select name="cocoon-installation/system/os"> 
              <option value="linux">
                <xsl:if test="system/os = 'linux'">
                  <xsl:attribute name="selected"/>
                </xsl:if>
                Linux
              </option>
              <option value="w2k">
                <xsl:if test="system/os = 'w2k'">
                  <xsl:attribute name="selected"/>
                </xsl:if>
                Windows 2k
              </option>
            </select>          
         </td>
         <td><xsl:apply-templates select="system/os/constraint"/></td>
       </tr>
       <tr>
         <td>processor</td>
         <td><input type="textbox" name="cocoon-installation/system/processor" 
value="{system/processor/text()}"/></td>
         <td><xsl:apply-templates select="system/processor/constraint"/></td>
       </tr>
       <tr>
         <td>ram</td>
         <td><input type="textbox" name="cocoon-installation/system/ram" 
value="{system/ram/text()}"/></td>
         <td><xsl:apply-templates select="system/ram/constraint"/></td>
       </tr>
       <tr>
         <td>servlet engine</td>
         <td><input type="textbox" 
name="cocoon-installation/system/servlet-engine" 
value="{system/servlet-engine/text()}"/></td>
         <td><xsl:apply-templates 
select="system/servlet-engine/constraint"/></td>
       </tr>
       <tr>
         <td>java version</td>
         <td><input type="textbox" 
name="cocoon-installation/system/java-version" 
value="{system/java-version/text()}"/></td>
         <td><xsl:apply-templates select="system/java-version/constraint"/></td>
       </tr>
  
       </table>
       <input type="submit" name="cocoon-action-prev2" value="Prev Page"/>     
       <input type="submit" name="cocoon-action-next4" value="Next Page"/>     
     </xsl:template>
     
     <xsl:template match="/|*">
        <xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates /></xsl:copy>
     </xsl:template>
  
     <xsl:template match="text()">
        <xsl:value-of select="." />
     </xsl:template>
  </xsl:stylesheet>
  
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/view4.xml
  
  Index: view4.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <root xmlns:f="http://www.dff.st/dform";
        xmlns:r="http://www.dff.st/drender";
        xmlns:i="http://www.dff.st/ns/desire/instance/1.0";
        >
  
     <i:instance id="form-feedback"/>
     
  </root>
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example1/view4.xsl
  
  Index: view4.xsl
  ===================================================================
  <?xml version="1.0"?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                                
xmlns:i="http://www.dff.st/ns/desire/instance/1.0";>
  
  
     <xsl:template match="root">
       <html><body><form 
method="POST"><xsl:apply-templates/></form></body></html>
     </xsl:template>
     
     <xsl:template match="cocoon-installation">
       <table border="1">
  
       <tr>
         <td>Firstname</td>
         <td><xsl:value-of select="user/firstname/text()"/></td>
       </tr>
       <tr>
         <td>Lastname</td>
         <td><xsl:value-of select="user/lastname/text()"/></td>
       </tr>
       <tr>
         <td>Email</td>
         <td><xsl:value-of select="user/email/text()"/></td>
       </tr>
       <tr>
         <td>Age</td>
         <td><xsl:value-of select="user/age/text()"/></td>
       </tr>
  
       <tr>
         <td>Installation number</td>
         <td><xsl:value-of select="number/text()"/></td>
       </tr>
       <tr>
         <td>Live URL</td>
         <td><xsl:value-of select="live-url/text()"/></td>
       </tr>
       <tr>
         <td>Please publish it as cocoon live-site example</td>
         <td><xsl:value-of select="publish/text()"/></td>
       </tr>
  
       <tr>
         <td>os</td>
         <td><xsl:value-of select="system/os/text()"/></td>
       </tr>
       <tr>
         <td>processor</td>
         <td><xsl:value-of select="system/processor/text()"/></td>
       </tr>
       <tr>
         <td>ram</td>
         <td><xsl:value-of select="system/ram/text()"/></td>
       </tr>
       <tr>
         <td>servlet engine</td>
         <td><xsl:value-of select="system/servlet-engine/text()"/></td>
       </tr>
       <tr>
         <td>java version</td>
         <td><xsl:value-of select="system/java-version/text()"/></td>
       </tr>
  
  
       </table>
       <input type="submit" name="cocoon-action-prev3" value="Prev Page"/>     
       <input type="submit" name="cocoon-action-submit" value="Submit"/>     
     </xsl:template>
     
     <xsl:template match="/|*">
        <xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates /></xsl:copy>
     </xsl:template>
  
     <xsl:template match="text()">
        <xsl:value-of select="." />
     </xsl:template>
  </xsl:stylesheet>
  
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example2/README
  
  Index: README
  ===================================================================
  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/scratchpad/webapp/mount/precept/example2/i2html.xsl
  
  Index: i2html.xsl
  ===================================================================
  <?xml version="1.0" ?>
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/example2/view1.xml
  
  Index: view1.xml
  ===================================================================
  <?xml version="1.0" ?>
  <root>
    <i:instance id="form-feedback">
      <i:textbox ref="cocoon-installation/user/firstname"/>
      <i:textbox ref="cocoon-installation/user/lastname"/>
      <i:textbox ref="cocoon-installation/user/email"/>
      <i:textbox ref="cocoon-installation/user/age"/>
    </i:instance>
  
    <i:button method="next2">
      <i:caption>Next Page<i:caption>
    </i:button>
  </root>
  
  
  
  1.1                  
xml-cocoon2/src/scratchpad/webapp/mount/precept/model/easyrelax.xml
  
  Index: easyrelax.xml
  ===================================================================
  <?xml version="1.0"?>
  <grammar xmlns="http://www.dff.st/ns/desire/easyrelax/grammar/1.0";>
    <start>
      <element name="cocoon-installation">
  
        <!-- the user who installed cocoon -->
        <element name="user">
          <element name="firstname"/>
          <element name="lastname"/>
          <element name="email">
            <constraint type="regexpr">bla</constraint>
          </element>
          <optional>
            <element name="age"/>
            <element name="gender"/>
          </optional>
        </element>
  
        <!-- serial number of cocoon installation -->
        <element name="number"/>
  
        <!-- an optional live url -->
        <optional>
          <element name="live-url"/>
          <element name="publish"/>
        </optional>
  
        <!-- the system cocoon is running on -->
        <element name="system">
          <element name="os">
            <constraint type="choice" name="E_OS">
              <choice value="linux">Linux</choice>
              <choice value="w2k">Windows 2000</choice>
            </constraint>
          </element>
          <element name="processor">
            <!--
            <constraint type="choice">
              <choice value="intel">Intel</choice>
              <choice value="powerpc">PowerPC</choice>
            </constraint>
            -->
          </element>
          <element name="ram"/>
          <element name="servlet-engine">
            <!--
            <constraint type="choice">
              <choice value="tc4">Tomcat 4</choice>
              <choice value="tc3">Tomcat 3</choice>
              <choice value="resin">Resin</choice>
            </constraint>
            -->
          </element>
          <element name="java-version"/>
        </element>
      </element>
    </start>
  </grammar>
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     [EMAIL PROTECTED]
To unsubscribe, e-mail:          [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to