You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by tc...@apache.org on 2002/03/22 18:46:41 UTC

cvs commit: xml-cocoon2/src/scratchpad/webapp/mount/precept/model easyrelax.xml

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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 = "^[a-zA-Z0-9]+[a-zA-Z0-9-_.]*@[a-zA-Z0-9-]+(\\.[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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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 <tc...@dff.st>
   */
  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:     webmaster@xml.apache.org
To unsubscribe, e-mail:          cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org