sylvain     01/08/09 03:51:33

  Modified:    .        changes.xml
               webapp   cocoon.xconf
  Added:       src/org/apache/cocoon/acting ServerPagesAction.java
               src/org/apache/cocoon/components/language/markup/xsp/java
                        action.xsl capture.xsl logicsheet-util.xsl
               src/org/apache/cocoon/components/sax
                        XMLByteStreamFragment.java
  Log:
  New ServerPagesAction
  
  Revision  Changes    Path
  1.27      +6 -1      xml-cocoon2/changes.xml
  
  Index: changes.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/changes.xml,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- changes.xml       2001/07/28 22:15:53     1.26
  +++ changes.xml       2001/08/09 10:51:32     1.27
  @@ -4,7 +4,7 @@
   
   <!--
     History of Cocoon changes
  -  $Id: changes.xml,v 1.26 2001/07/28 22:15:53 vgritsenko Exp $
  +  $Id: changes.xml,v 1.27 2001/08/09 10:51:32 sylvain Exp $
   -->
   
   <changes title="History of Changes">
  @@ -26,6 +26,11 @@
    </devs>
   
    <release version="2.1-dev" date="@date@">
  +  <action dev="SW" type="add">
  +   New ServerPagesAction and associated "action" and "capture" logicsheets
  +   that allow actions to be written in XSP and parts of the generated XML
  +   to be captured in XMLFragment or DOM objects.
  +  </action>
     <action dev="VG" type="add">
      Added ability to specify custom 404 error page for pipelines using
      map:handle-errors element with attribute type="404".
  
  
  
  1.1                  xml-cocoon2/src/org/apache/cocoon/acting/ServerPagesAction.java
  
  Index: ServerPagesAction.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included  with this distribution in *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  package org.apache.cocoon.acting;
  
  import java.util.HashMap;
  import java.util.Map;
  
  import org.apache.avalon.framework.parameters.Parameters;
  
  import org.apache.cocoon.Constants;
  import org.apache.cocoon.components.sax.XMLByteStreamCompiler;
  import org.apache.cocoon.components.sax.XMLByteStreamFragment;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.generation.ServerPagesGenerator;
  import org.apache.cocoon.xml.AbstractXMLConsumer;
  
  /**
   * Allows actions to be written in XSP. This allows to use XSP to produce
   * XML fragments that are later reused in generators.<br/>
   *
   * This action works in concert with the "action" logicheet, that offers
   * actions-related services such as redirect or result map access, and the
   * "capture" logicsheet that allows to capture parts of XSP-generated XML
   * either as an <code>XMLFragment</code> containing serialized SAX events,
   * or as a DOM <code>Node</code>.<br/>
   *
   * As for generators, the XSP file name is set using the "src" attribute.<br/>
   *
   * This action accepts a single parameter, "result-attribute", which names
   * the request attribute where the XSP-generated document will be stored
   * (as an <code>XMLFragment</code>). If this parameter is omitted, the
   * XSP result is discarded (often the case when inner fragments are captured
   * with the "capture" logicsheet").<br/>
   *
   * When "result-attribute" is set, the action status defaults to "success",
   * meaning child sitemap statements are executed. This allows to use an
   * existing XSP without modification with this action.<br/>
   *
   * When "result-attribute" isn't set, the action status defaults to "failure".
   * The XSP must then use the "action" logicsheet to set its status.<br/>
   *
   * Example :
   * <pre>
   *   &lt;action type="xsp-action" src="myAction.xsp"&gt;
   *     &lt;map:param name="result-attribute" value="xsp-action-result"/&gt;
   *     ...
   *   &lt;/action&gt;
   * </pre>
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Sylvain Wallez</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/08/09 10:51:32 $
   */
  public class ServerPagesAction extends ComposerAction {
      
      public static final String REDIRECTOR_OBJECT = "xsp-action:redirector";
      public static final String ACTION_RESULT_OBJECT = "xsp-action:result";
      public static final String ACTION_SUCCESS_OBJECT = "xsp-action:success";
      
      public Map act(Redirector redirector, SourceResolver resolver, Map objectModel,
          String source, Parameters parameters)
        throws Exception {
          
          getLogger().debug("serverpage source: " + source);
          
          String outputKey = parameters.getParameter("result-attribute", null);
          Map resultMap = new HashMap();
          Object success = null;
  
          // Create a new ServerPagesGenerator
          // FIXME : generator should be pooled for better performances
          ServerPagesGenerator generator = new ServerPagesGenerator();
          generator.setLogger(getLogger());
          generator.compose(this.manager);        
          generator.setup(resolver, objectModel, source, parameters);
          
          // Setup generator output
          XMLByteStreamCompiler compiler = null;
          if (outputKey == null) {
              // discard output to a "black hole"
              generator.setConsumer(new AbstractXMLConsumer() { } ); // Make the 
abstract class instanciable
          } else {
              // store output in a byte stream
              compiler = new XMLByteStreamCompiler();
              generator.setConsumer(compiler);
          }
          
          // Augment the object model for the "action" logicsheet
          objectModel.put(REDIRECTOR_OBJECT, redirector);
          objectModel.put(ACTION_RESULT_OBJECT, resultMap);
          
          try {
              // Let the XSP do it's stuff
              generator.generate();
              success = objectModel.get(ACTION_SUCCESS_OBJECT);
              
          } catch (Exception e) {
              getLogger().warn("serverpage error", e);
              throw e;
              
          } finally {
              // Clean up object model
              objectModel.remove(REDIRECTOR_OBJECT);
              objectModel.remove(ACTION_RESULT_OBJECT);
              objectModel.remove(ACTION_SUCCESS_OBJECT);
          }
          
          if (outputKey != null) {
              // Success defaults to true when the whole output is captured
              if (success == null) {
                  success = Boolean.TRUE;
              }
              
              if (success == Boolean.TRUE) {
                  // Store the XSP output in the request
                  Request req = (Request)objectModel.get(Constants.REQUEST_OBJECT);
                  req.setAttribute(outputKey, new 
XMLByteStreamFragment(compiler.getSAXFragment()));
              }
          }
          
          return (success == Boolean.TRUE) ? resultMap : null;
      }
  }
  
  
  
  1.1                  
xml-cocoon2/src/org/apache/cocoon/components/language/markup/xsp/java/action.xsl
  
  Index: action.xsl
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <!--
   *****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * _________________________________________________________________________ *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included  with this distribution in *
   * the LICENSE file.                                                         *
   *****************************************************************************
  -->
  
  <!--
    Logicsheet for XSP executed in actions using ServerPagesAction.
  
    @author <a href="mailto:[EMAIL PROTECTED]";>Sylvain Wallez</a>
    @version CVS $Revision: 1.1 $ $Date: 2001/08/09 10:51:32 $
  -->
  
  <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:xsp="http://apache.org/xsp";
    xmlns:action="http://apache.org/cocoon/action/1.0";
    exclude-result-prefixes="action"
  >
  <!-- Namespace URI for this logicsheet -->
  <xsl:param name="namespace-uri">http://apache.org/cocoon/action/1.0</xsl:param>
  
  <!-- Include logicsheet common stuff -->
  <xsl:include href="logicsheet-util.xsl"/>
  
  <!--
     Class-level declarations.
  -->
  <xsl:template match="xsp:page">
    <xsp:page>
      <xsl:apply-templates select="@*"/>
      <xsp:structure>
        <xsp:include>org.apache.cocoon.environment.Redirector</xsp:include>
        <xsp:include>org.apache.cocoon.acting.ServerPagesAction</xsp:include>
        <xsp:include>java.util.Map</xsp:include>
      </xsp:structure>
      <xsp:logic>
        private Redirector actionRedirector;
        private Map actionResultMap;
      </xsp:logic>
      <xsl:apply-templates/>
    </xsp:page>
  </xsl:template>
  
  <!--
     Before generation begins, get redirector and result map from the object model.
     If it's not there, we're not in an action, so throw a ProcessingException.
  -->
  <xsl:template match="xsp:page/*[not(self::xsp:*)]">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsp:logic>
        // action prefix is "<xsl:value-of select="$namespace-prefix"/>"
        this.actionRedirector = 
(Redirector)this.objectModel.get(ServerPagesAction.REDIRECTOR_OBJECT);
        this.actionResultMap = 
(Map)this.objectModel.get(ServerPagesAction.ACTION_RESULT_OBJECT);
        if (this.actionRedirector == null) {
          throw new ProcessingException("action logicsheet cannot be used in 
generators");
        }
      </xsp:logic>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
  
  <!--
     Redirects to a given URL.
     @param uri the URI to redirect to (String)
     @param session-mode keep session across redirect (boolean, default = true).
  -->
  <xsl:template match="action:redirect-to">
    <xsl:variable name="uri">
      <xsl:call-template name="get-string-parameter">
        <xsl:with-param name="name">uri</xsl:with-param>
        <xsl:with-param name="required">true</xsl:with-param>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="session-mode">
      <xsl:call-template name="get-parameter">
        <xsl:with-param name="name">session-mode</xsl:with-param>
        <xsl:with-param name="default">true</xsl:with-param>
        <xsl:with-param name="required">false</xsl:with-param>
      </xsl:call-template>
    </xsl:variable>
    <xsp:logic>
      this.actionRedirector.redirect(<xsl:value-of select="$session-mode"/>, 
<xsl:value-of select="$uri"/>);
    </xsp:logic>
  </xsl:template>
  
  <!--
     Adds an entry in the action result map, and implicitly set the action status to 
successful.
  
     @param name the entry name (String)
     @param value the entry value (String)
  -->
  <xsl:template match="action:set-result">
    <xsl:variable name="name">
      <xsl:call-template name="get-string-parameter">
        <xsl:with-param name="name">name</xsl:with-param>
        <xsl:with-param name="required">true</xsl:with-param>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="value">
      <xsl:call-template name="get-string-parameter">
        <xsl:with-param name="name">value</xsl:with-param>
        <xsl:with-param name="required">true</xsl:with-param>
      </xsl:call-template>
    </xsl:variable>
    <xsp:logic>
      this.actionResultMap.put(<xsl:value-of select="$name"/>, <xsl:value-of 
select="$value"/>);
    </xsp:logic>
  </xsl:template>
  
  <!--
     Gets the value of an entry of the Action result map (previously set
     with &lt;action:set-result&gt;)
  
     @param name the entry name (String)
  -->
  <xsl:template match="action:get-result">
    <xsl:variable name="name">
      <xsl:call-template name="get-string-parameter">
        <xsl:with-param name="name">name</xsl:with-param>
        <xsl:with-param name="required">true</xsl:with-param>
      </xsl:call-template>
    </xsl:variable>
    <xsp:expr>this.actionResultMap.get(<xsl:value-of select="$name"/>)</xsp:expr>
  </xsl:template>
  
  <!--
     Sets the action status to successful.
  -->
  
  <xsl:template match="action:set-success">
    <xsp:logic>
      this.objectModel.put(ServerPagesAction.ACTION_SUCCESS_OBJECT, Boolean.TRUE);
    </xsp:logic>
  </xsl:template>
  
  <!--
     Sets the action status to failure (child statements in the sitemap won't be
     executed).
  -->
  
  <xsl:template match="action:set-failure">
    <xsp:logic>
      this.objectModel.put(ServerPagesAction.ACTION_SUCCESS_OBJECT, Boolean.FALSE);
    </xsp:logic>
  </xsl:template>
  
  </xsl:stylesheet>
  
  
  
  1.1                  
xml-cocoon2/src/org/apache/cocoon/components/language/markup/xsp/java/capture.xsl
  
  Index: capture.xsl
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <!--
   *****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * _________________________________________________________________________ *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included  with this distribution in *
   * the LICENSE file.                                                         *
   *****************************************************************************
  -->
  
  <!--
    Logicsheet for capturing parts of the generated XML as SAX XML fragments or
    DOM nodes.
  
    This logicsheet allows to use XSP-generated XML for other purposes than
    content production.
  
    @author <a href="mailto:[EMAIL PROTECTED]";>Sylvain Wallez</a>
    @version CVS $Revision: 1.1 $ $Date: 2001/08/09 10:51:32 $
  -->
  
  <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:xsp="http://apache.org/xsp";
    xmlns:capture="http://apache.org/cocoon/capture/1.0";
  >
  <!-- Namespace URI for this logicsheet -->
  <xsl:param name="namespace-uri">http://apache.org/cocoon/capture/1.0</xsl:param>
  
  <!-- Include logicsheet common stuff -->
  <xsl:include href="logicsheet-util.xsl"/>
  
  <!--
     Class-level declarations
  -->
  <xsl:template match="xsp:page">
    <xsp:page>
      <xsl:apply-templates select="@*"/>
      <xsp:structure>
        
<xsp:include>org.apache.cocoon.components.sax.XMLByteStreamCompiler</xsp:include>
        
<xsp:include>org.apache.cocoon.components.sax.XMLByteStreamFragment</xsp:include>
        <xsp:include>org.apache.cocoon.xml.XMLFragment</xsp:include>
        <xsp:include>org.apache.cocoon.xml.dom.DOMBuilder</xsp:include>
        <xsp:include>org.w3c.dom.DocumentFragment</xsp:include>
        <xsp:include>org.w3c.dom.Node</xsp:include>
        <xsp:include>org.xml.sax.ContentHandler</xsp:include>
        <xsp:include>org.xml.sax.ext.LexicalHandler</xsp:include>
      </xsp:structure>
      <xsl:if test="//capture:dom-variable or //capture:dom-request-attr">
        <xsp:logic>
          private Parser captureParser;
        </xsp:logic>
      </xsl:if>
     <xsl:apply-templates/>
    </xsp:page>
  </xsl:template>
  
  <!--
     Before generation begins, setup a parser if DOM captures are performed.
  -->
  <xsl:template match="xsp:page/*[not(self::xsp:*)]">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:choose>
        <xsl:when test="//capture:dom-variable or //capture:dom-request-attr">
          <xsp:logic>
          try {
            this.captureParser = (Parser)this.manager.lookup(Parser.ROLE);
          } catch(Exception e) {
            throw new ProcessingException("Cannot get parser" , e);
          }
          try {
          </xsp:logic>
          <xsl:apply-templates/>
          <xsp:logic>
          } finally {
            this.manager.release(this.captureParser);
          }
          </xsp:logic>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:copy>
  </xsl:template>
  
  <!--
     Captures its content and store it as an XMLFragment variable.
  
     @param name name of the generated variable holding the fragment
  -->
  <xsl:template match="capture:fragment-variable">
    <xsl:variable name="name">
      <xsl:call-template name="get-parameter">
        <xsl:with-param name="name">name</xsl:with-param>
        <xsl:with-param name="required">true</xsl:with-param>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="id" select="generate-id(.)"/>
    <xsp:logic>
      // Save the current XML consumer
      ContentHandler contentHandler_<xsl:value-of select="$id"/> = this.contentHandler;
      LexicalHandler lexicalHandler_<xsl:value-of select="$id"/> = this.lexicalHandler;
      // Create a new one that will capture all SAX events
      XMLByteStreamCompiler consumer_<xsl:value-of select="$id"/> = new 
XMLByteStreamCompiler();
      try {
        this.contentHandler = consumer_<xsl:value-of select="$id"/>;
        this.lexicalHandler = consumer_<xsl:value-of select="$id"/>;
        this.contentHandler.startDocument(); // XMLByteStream wants documents
        <xsl:apply-templates/>
        this.contentHandler.endDocument();
      } finally {
        // Always restore previous consumer
        this.contentHandler = contentHandler_<xsl:value-of select="$id"/>;
        this.lexicalHandler = lexicalHandler_<xsl:value-of select="$id"/>;
      }
      XMLFragment <xsl:value-of select="$name"/> =
        new XMLByteStreamFragment(consumer_<xsl:value-of 
select="$id"/>.getSAXFragment());
    </xsp:logic>
  </xsl:template>
  
  <!--
     Captures its content and store it as an XMLFragment in a request attribute.
  
     @param name the request attribute name (String)
  -->
  <xsl:template match="capture:fragment-request-attr">
    <xsl:variable name="name">
      <xsl:call-template name="get-string-parameter">
        <xsl:with-param name="name">name</xsl:with-param>
        <xsl:with-param name="required">true</xsl:with-param>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="id" select="generate-id(.)"/>
    <xsp:logic>
      ContentHandler contentHandler_<xsl:value-of select="$id"/> = this.contentHandler;
      LexicalHandler lexicalHandler_<xsl:value-of select="$id"/> = this.lexicalHandler;
      XMLByteStreamCompiler consumer_<xsl:value-of select="$id"/> = new 
XMLByteStreamCompiler();
      try {
        this.contentHandler = consumer_<xsl:value-of select="$id"/>;
        this.lexicalHandler = consumer_<xsl:value-of select="$id"/>;
        this.contentHandler.startDocument(); // XMLByteStream wants documents
        <xsl:apply-templates/>
        this.contentHandler.endDocument();
      } finally {
        this.contentHandler = contentHandler_<xsl:value-of select="$id"/>;
        this.lexicalHandler = lexicalHandler_<xsl:value-of select="$id"/>;
      }
      this.request.setAttribute(<xsl:value-of select="$name"/>,
        new XMLByteStreamFragment(consumer_<xsl:value-of 
select="$id"/>.getSAXFragment()));
    </xsp:logic>
  </xsl:template>
  
  <!--
     Captures its content and store it as a org.w3c.dom.Node variable.
     Note : the node is actually a DocumentFragment.
  
     @param name name of the generated variable holding the DOM node
  -->
  <xsl:template match="capture:dom-variable">
    <xsl:variable name="name">
      <xsl:call-template name="get-parameter">
        <xsl:with-param name="name">name</xsl:with-param>
        <xsl:with-param name="required">true</xsl:with-param>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="id" select="generate-id(.)"/>
    <xsp:logic>
      ContentHandler contentHandler_<xsl:value-of select="$id"/> = this.contentHandler;
      LexicalHandler lexicalHandler_<xsl:value-of select="$id"/> = this.lexicalHandler;
      // Create a DOMBuilder that will feed a DocumentFragment
      DocumentFragment fragment_<xsl:value-of select="$id"/> =
        this.captureParser.newDocument().createDocumentFragment();
      DOMBuilder builder_<xsl:value-of select="$id"/> = new 
DOMBuilder(fragment_<xsl:value-of select="$id"/>);
      try {
        this.contentHandler = builder_<xsl:value-of select="$id"/>;
        this.lexicalHandler = builder_<xsl:value-of select="$id"/>;
        <xsl:apply-templates/>
      } finally {
        this.contentHandler = contentHandler_<xsl:value-of select="$id"/>;
        this.lexicalHandler = lexicalHandler_<xsl:value-of select="$id"/>;
      }
      Node <xsl:value-of select="$name"/> = fragment_<xsl:value-of select="$id"/>;
    </xsp:logic>
  </xsl:template>
  
  <!--
     Captures its content and store it as a org.w3c.dom.Node in a request attribute.
     Note : the node is actually a DocumentFragment.
  
     @param name the request attribute name (String)
  -->
  <xsl:template match="capture:dom-request-attr">
    <xsl:variable name="name">
      <xsl:call-template name="get-string-parameter">
        <xsl:with-param name="name">name</xsl:with-param>
        <xsl:with-param name="required">true</xsl:with-param>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="id" select="generate-id(.)"/>
    <xsp:logic>
      ContentHandler contentHandler_<xsl:value-of select="$id"/> = this.contentHandler;
      LexicalHandler lexicalHandler_<xsl:value-of select="$id"/> = this.lexicalHandler;
      // Create a DOMBuilder that will feed a DocumentFragment
      DocumentFragment fragment_<xsl:value-of select="$id"/> =
        this.captureParser.newDocument().createDocumentFragment();
      DOMBuilder builder_<xsl:value-of select="$id"/> = new 
DOMBuilder(fragment_<xsl:value-of select="$id"/>);
      try {
        this.contentHandler = builder_<xsl:value-of select="$id"/>;
        this.lexicalHandler = builder_<xsl:value-of select="$id"/>;
        <xsl:apply-templates/>
      } finally {
        this.contentHandler = contentHandler_<xsl:value-of select="$id"/>;
        this.lexicalHandler = lexicalHandler_<xsl:value-of select="$id"/>;
      }
      this.request.setAttribute(<xsl:value-of select="$name"/>, fragment_<xsl:value-of 
select="$id"/>);
    </xsp:logic>
  </xsl:template>
  
  </xsl:stylesheet>
  
  
  
  1.1                  
xml-cocoon2/src/org/apache/cocoon/components/language/markup/xsp/java/logicsheet-util.xsl
  
  Index: logicsheet-util.xsl
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <!--
   *****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * _________________________________________________________________________ *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included  with this distribution in *
   * the LICENSE file.                                                         *
   *****************************************************************************
  -->
  
  <!--
    A collection of utility templates to help logicsheet writers, and ensure
    a consistent behaviour of logicsheets using them.
  
    To use them, just add &lt;xsl:include href="logicsheet-util.xsl"/&gt; at the
    top of your logicsheet.
    <br/>
    Note : some templates rely on the <code>$namespace-uri</code> variable which must
    be set in the including logicsheet to its namespace URI.
  
    @author <a href="mailto:[EMAIL PROTECTED]";>Sylvain Wallez</a>
    @version CVS $Revision: 1.1 $ $Date: 2001/08/09 10:51:32 $
  -->
  
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <!--
    Namespace prefix for this logicsheet.
  -->
  <xsl:param name="namespace-prefix">
    <xsl:call-template name="get-namespace-prefix"/>
  </xsl:param>
  
  <!--
    Find the namespace prefix used in the source document for a given namespace URI.
  
    @param uri the namespace URI (default value = $namespace-uri)
    @return the namespace prefix
  -->
  <xsl:template name="get-namespace-prefix">
    <xsl:param name="uri"><xsl:value-of select="$namespace-uri"/></xsl:param>
    <!-- Search it on the root element -->
    <xsl:variable name="ns-attr" select="/*/namespace::*[string(.) = $uri]"/>
    <xsl:choose>
      <xsl:when test="$ns-attr"><xsl:value-of 
select="local-name($ns-attr)"/></xsl:when>
      <xsl:otherwise>
        <!-- Examine all nodes (requires the XSL processor to traverse the DOM) -->
        <xsl:variable name="ns-attr2" select="//*/namespace::*[string(.) = $uri]"/>
        <xsl:choose>
          <xsl:when test="$ns-attr2"><xsl:value-of 
select="local-name($ns-attr2)"/></xsl:when>
          <xsl:otherwise>
            <xsl:call-template name="error">
              <xsl:with-param name="message">Cannot find namespace prefix for 
<xsl:value-of select="$uri"/></xsl:with-param>
            </xsl:call-template>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!--
    Break on error.
    @param message explanation of the error
  -->
  <xsl:template name="error">
    <xsl:param name="message"/>
    <xsl:message terminate="yes"><xsl:value-of select="$message"/></xsl:message>
  </xsl:template>
  
  <!--
    Ignore $namespace-prefix:param elements used in get-parameter and 
get-string-parameter
  -->
  <xsl:template match="*[namespace-uri(.) = $namespace-uri and local-name(.) = 
'param']" priority="-1"/>
  
  <!--
    Break on error on all elements belonging to this logicheet's namespace not
    handled by a template.
  -->
  <xsl:template match="*[namespace-uri(.) = $namespace-uri and local-name(.) != 
'param']" priority="-1">
    <xsl:call-template name="error">
      <xsl:with-param name="message">Unknown logicsheet tag : <xsl:value-of 
select="name(.)"/></xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  
  <!--
    Copy all nodes that were not handled by a dedicated template.
  -->
  <xsl:template match="@*|node()" priority="-2">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
  <!--
    Get the value of a logicsheet tag parameter as a String (borrowed from ESQL).
  
    @name the name of the parameter
    @default the default value (String expression)
    @required true if the parameter is required
  -->
    <xsl:template name="get-string-parameter">
      <xsl:param name="name"/>
      <xsl:param name="default"/>
      <xsl:param name="required">false</xsl:param>
  
      <xsl:variable name="qname">
        <xsl:value-of select="concat($namespace-prefix, ':param')"/>
      </xsl:variable>
  
      <xsl:choose>
        <xsl:when test="@*[name(.) = $name]">"<xsl:value-of select="@*[name(.) = 
$name]"/>"</xsl:when>
        <xsl:when test="(*[name(.) = $qname])[@name = $name]">
          <xsl:call-template name="get-nested-string">
            <xsl:with-param name="content" select="(*[name(.) = $qname])[@name = 
$name]"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:choose>
            <xsl:when test="string-length($default) = 0">
              <xsl:choose>
                <xsl:when test="$required = 'true'">
                  <xsl:call-template name="error">
                    <xsl:with-param name="message">[Logicsheet processor]
  Parameter '<xsl:value-of select="$name"/>' missing in dynamic tag &lt;<xsl:value-of 
select="name(.)"/>&gt;
                    </xsl:with-param>
                  </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>""</xsl:otherwise>
              </xsl:choose>
            </xsl:when>
            <xsl:otherwise><xsl:copy-of select="$default"/></xsl:otherwise>
          </xsl:choose>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
  
    <xsl:template name="get-nested-string">
      <xsl:param name="content"/>
        <xsl:choose>
          <!-- if $content has sub-elements, concatenate them -->
          <xsl:when test="$content/*">
            ""
            <xsl:for-each select="$content/node()">
              <xsl:choose>
                <xsl:when test="name(.)">
                  <!-- element -->
                  <xsl:choose>
                    <xsl:when test="namespace-uri(.)='http://apache.org/xsp' and 
local-name(.)='text'">
                      <!-- xsp:text element -->
                      + "<xsl:value-of select="."/>"
                    </xsl:when>
                    <xsl:otherwise>
                      <!-- other elements -->
                      + <xsl:apply-templates select="."/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:when>
                <xsl:otherwise>
                  <!-- text node -->
                  + "<xsl:value-of select="translate(.,'&#9;&#10;&#13;','   ')"/>"
                </xsl:otherwise>
              </xsl:choose>
            </xsl:for-each>
          </xsl:when>
          <!-- else return the text value of $content -->
          <xsl:otherwise>"<xsl:value-of 
select="normalize-space($content)"/>"</xsl:otherwise>
        </xsl:choose>
    </xsl:template>
  
  <!--
    Get the value of a logicsheet tag parameter either as a primitive value or an 
object.
    @name the name of the parameter
    @default the default value
    @required true if the parameter is required
  -->
    <xsl:template name="get-parameter">
      <xsl:param name="name"/>
      <xsl:param name="default"/>
      <xsl:param name="required">false</xsl:param>
  
      <xsl:variable name="qname">
        <xsl:value-of select="concat($namespace-prefix, ':param')"/>
      </xsl:variable>
  
      <xsl:choose>
        <xsl:when test="@*[name(.) = $name]"><xsl:value-of select="@*[name(.) = 
$name]"/></xsl:when>
        <xsl:when test="(*[name(.) = $qname])[@name = $name]">
          <xsl:call-template name="get-nested-content">
            <xsl:with-param name="content" select="(*[name(.) = $qname])[@name = 
$name]"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:choose>
            <xsl:when test="string-length($default) = 0">
              <xsl:choose>
                <xsl:when test="$required = 'true'">
                  <xsl:call-template name="error">
                    <xsl:with-param name="message">[Logicsheet processor]
  Parameter '<xsl:value-of select="$name"/>' missing in dynamic tag &lt;<xsl:value-of 
select="name(.)"/>&gt;
                    </xsl:with-param>
                  </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>null</xsl:otherwise>
              </xsl:choose>
            </xsl:when>
            <xsl:otherwise><xsl:copy-of select="$default"/></xsl:otherwise>
          </xsl:choose>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
  
  
    <xsl:template name="get-nested-content">
      <xsl:param name="content"/>
      <xsl:choose>
        <xsl:when test="$content/*">
          <xsl:apply-templates select="$content/*"/>
        </xsl:when>
        <xsl:otherwise><xsl:value-of select="$content"/></xsl:otherwise>
      </xsl:choose>
    </xsl:template>
  
  </xsl:stylesheet>
  
  
  
  1.1                  
xml-cocoon2/src/org/apache/cocoon/components/sax/XMLByteStreamFragment.java
  
  Index: XMLByteStreamFragment.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included  with this distribution in *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  package org.apache.cocoon.components.sax;
  
  import org.apache.cocoon.xml.AbstractSAXFragment;
  import org.apache.cocoon.xml.EmbeddedXMLPipe;
  import org.apache.cocoon.xml.XMLConsumer;
  
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  
  /**
   * An XMLByteStream wrapped by an XMLFragment implementation. This allows to
   * store SAX events and insert them in an XSP result using &lt;xsp:expr&gt;.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Sylvain Wallez</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/08/09 10:51:33 $
   */
  
  public class XMLByteStreamFragment extends AbstractSAXFragment {
      
      /** The XML byte stream */
      private Object xmlBytes;
      
      /**
       * Creates a new <code>XMLByteStreamFragment</code> defined by the given
       * XML byte stream.
       *
       * @param bytes the XML byte stream representing the document fragment
       */
      public XMLByteStreamFragment(Object bytes) {
          xmlBytes = bytes;
      }
      
      /**
       * Output the fragment. If the fragment is a document, start/endDocument
       * events are discarded.
       */
      public void toSAX(ContentHandler ch)
        throws SAXException {
          
          // Stream bytes and discard start/endDocument
          XMLByteStreamInterpreter interp = new XMLByteStreamInterpreter();
          EmbeddedXMLPipe pipe = new EmbeddedXMLPipe(ch);
  
          // If ch is an XMLConsumer, set it as such so that XML comments are
          // also deserialized.
          if (ch instanceof XMLConsumer)
              pipe.setConsumer((XMLConsumer) ch);
          
          interp.setContentHandler(pipe);
          
          interp.deserialize(xmlBytes);
      }
  }
  
  
  
  1.27      +12 -0     xml-cocoon2/webapp/cocoon.xconf
  
  Index: cocoon.xconf
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/webapp/cocoon.xconf,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- cocoon.xconf      2001/08/03 11:10:13     1.26
  +++ cocoon.xconf      2001/08/09 10:51:33     1.27
  @@ -188,6 +188,18 @@
             <parameter name="href" 
value="resource://org/apache/cocoon/components/language/markup/xsp/java/sel.xsl"/>
           </builtin-logicsheet>
   
  +        <builtin-logicsheet>
  +          <parameter name="prefix" value="action"/>
  +          <parameter name="uri" value="http://apache.org/cocoon/action/1.0"/>
  +          <parameter name="href" 
value="resource://org/apache/cocoon/components/language/markup/xsp/java/action.xsl"/>
  +        </builtin-logicsheet>
  +
  +        <builtin-logicsheet>
  +          <parameter name="prefix" value="capture"/>
  +          <parameter name="uri" value="http://apache.org/cocoon/capture/1.0"/>
  +          <parameter name="href" 
value="resource://org/apache/cocoon/components/language/markup/xsp/java/capture.xsl"/>
  +        </builtin-logicsheet>
  +
         </target-language>
       </xsp-language>
   
  
  
  

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

Reply via email to