You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cr...@apache.org on 2002/11/06 16:53:41 UTC

cvs commit: xml-cocoon2/src/java/org/apache/cocoon/transformation JPathTransformer.java

crafterm    2002/11/06 07:53:41

  Modified:    src/java/org/apache/cocoon/components/flow TODO
  Added:       src/java/org/apache/cocoon/transformation
                        JPathTransformer.java
  Log:
  * Initial revision of a JPathTransformer.
  
    Currently the transformer supports the <jpath:value-of/> element
    and a 'jpath:action' attribute on all elements (useful for form
    action elemnts).
  
    More elements to come.
  
  * Updated TODO to reflect work in progress.
  
  Revision  Changes    Path
  1.2       +1 -1      xml-cocoon2/src/java/org/apache/cocoon/components/flow/TODO
  
  Index: TODO
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/flow/TODO,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TODO	29 Oct 2002 05:14:55 -0000	1.1
  +++ TODO	6 Nov 2002 15:53:40 -0000	1.2
  @@ -21,7 +21,7 @@
   - allow the ability to specify the continuation handler function in
   cocoon.xconf, or even better in <map:continue>.
   
  -- implement a transformer for JPath, in addition to the jpath.xsl
  +- [in progress] implement a transformer for JPath, in addition to the jpath.xsl
   logicsheet. This should allow template pages to be created without the
   need for XSP, which requires a Java compiler. This should make
   Schecoon run on MacOS X, which doesn't provide tools.jar with the
  
  
  
  1.1                  xml-cocoon2/src/java/org/apache/cocoon/transformation/JPathTransformer.java
  
  Index: JPathTransformer.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.transformation;
  
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.excalibur.source.Source;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.components.flow.WebContinuation;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.environment.Environment;
  import org.apache.commons.jxpath.JXPathContext;
  import org.apache.regexp.RE;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.helpers.AttributesImpl;
  import org.xml.sax.SAXException;
  
  import java.io.IOException;
  import java.util.HashMap;
  import java.util.Map;
  
  /**
   * JPath Transformer.
   *
   * <p>
   *  Transformer implementation of the JPath XSP tag library.
   * </p>
   *
   * <p>
   *  This transformer (so far) supports the following jpath elements:
   *
   *   <ul>
   *     <li>&lt;jpath:value-of select=".."/&gt; element.
   *     <li>jpath:action attribute on all elements that implicitly replaces any
   *         occurance of the string 'id' with the continuation id (useful when
   *         writing form action attributes). eg:
   *         <pre>&lt;form name="myform" jpath:action="../cont/id"&gt;..&lt;/form&gt;</pre>
   *   </ul>
   * </p>
   *
   * @author <a href="mailto:crafterm@apache.org">Marcus Crafter</a>
   * @version CVS $Id: JPathTransformer.java,v 1.1 2002/11/06 15:53:40 crafterm Exp $
   */
  public class JPathTransformer
  extends AbstractSAXTransformer implements Initializable {
  
      /** namespace constant */
      public static final String JPATH_NAMESPACE_URI  = "http://apache.org/xsp/jpath/1.0";
  
      /** jpath:action attribute constant */
      public static final String JPATH_ACTION         = "jpath:action";
  
      /** jpath:value-of element constant*/
      public static final String JPATH_VALUEOF        = "value-of";
  
      /** jpath:value-of select attribute constant */
      public static final String JPATH_VALUEOF_SELECT = "select";
  
      // web contination
      private WebContinuation m_kont;
  
      // web continuation level
      private int m_level = 0;
  
      // regular expression for matching 'id' strings with jpath:action
      private RE m_re;
  
      // jxpath context
      private JXPathContext m_jxpathContext;
  
      // jpath:value-of variable cache
      private Map m_cache;
  
      /**
       * Initialize this transformer.
       *
       * @exception Exception if an error occurs
       */
      public void initialize()
          throws Exception {
  
          namespaceURI = JPATH_NAMESPACE_URI;
          m_re = new RE("id");
          m_cache = new HashMap();
      }
  
      /**
       * Setup this transformer
       *
       * @param resolver a {@link SourceResolver} instance
       * @param objectModel the objectModel
       * @param src <code>src</code> parameter
       * @param parameters optional parameters
       * @exception ProcessingException if an error occurs
       * @exception SAXException if an error occurs
       * @exception IOException if an error occurs
       */
      public void setup(SourceResolver resolver, Map objectModel,
                        String src, Parameters parameters)
          throws ProcessingException, SAXException, IOException {
  
          super.setup(resolver, objectModel, src, parameters);
  
          // setup the jpath transformer for this thread
          Object bean = ((Environment)resolver).getAttribute("bean-dict");
          m_kont = (WebContinuation)((Environment)resolver).getAttribute("kont");
          m_jxpathContext = JXPathContext.newContext(bean);
      }
  
      /**
       * Intercept startElement to ensure all &lt;jpath:action&gt; attributes
       * are modified.
       *
       * @param uri a <code>String</code> value
       * @param loc a <code>String</code> value
       * @param raw a <code>String</code> value
       * @param a an <code>Attributes</code> value
       * @exception SAXException if an error occurs
       */
      public void startElement(String uri, String loc, String raw, Attributes a)
          throws SAXException {
  
          AttributesImpl impl = new AttributesImpl(a);
          checkJPathAction(impl);
  
          super.startElement(uri, loc, raw, impl);
      }
  
      /**
       * Entry method for all elements in our namespace
       *
       * @param uri a <code>String</code> value
       * @param name a <code>String</code> value
       * @param raw a <code>String</code> value
       * @param attr an <code>Attributes</code> value
       * @exception ProcessingException if an error occurs
       * @exception IOException if an error occurs
       * @exception SAXException if an error occurs
       */
      public void startTransformingElement(
          String uri, String name, String raw, Attributes attr
      )
          throws ProcessingException ,IOException, SAXException {
  
          if (name.equals(JPATH_VALUEOF)) {
              valueOf(attr);
          } else {
              super.startTransformingElement(uri, name, raw, attr);
          }
      }
  
      /**
       * Exit method for all elements in our namespace
       *
       * @param uri a <code>String</code> value
       * @param name a <code>String</code> value
       * @param raw a <code>String</code> value
       * @exception ProcessingException if an error occurs
       * @exception IOException if an error occurs
       * @exception SAXException if an error occurs
       */
      public void endTransformingElement(
          String uri, String name, String raw
      )
          throws ProcessingException, IOException, SAXException {
  
          if (name.equals(JPATH_VALUEOF)) {
              return; // do nothing
          } else {
              super.endTransformingElement(uri, name, raw);
          }
      }
  
      /**
       * Helper method to check for the existance of an attribute named
       * jpath:action. If existing the string 'id' is replaced with the
       * continuation id.
       *
       * @param a an {@link AttributesImpl} instance
       */
      private void checkJPathAction(final AttributesImpl a) {
  
          // check for jpath:action attribute
          int idx = a.getIndex(JPATH_ACTION);
  
          if (idx != -1 && JPATH_NAMESPACE_URI.equals(a.getURI(idx))) {
              if (getLogger().isDebugEnabled()) {
                  getLogger().debug("found jpath:action, adjusting");
              }
  
              String value = a.getValue(idx);
  
              // REVISIT(MC): support for continuation level
              String id = m_kont.getContinuation(m_level).getId();
  
              a.removeAttribute(idx);
              a.addAttribute(
                  "", "action", "action", "CDATA", m_re.subst(value, id)
              );
          }
      }
  
      /**
       * Helper method to process a &lt;jpath:value-of select="."&gt; tag
       *
       * @param a an {@link Attributes} instance
       * @exception SAXException if a SAX error occurs
       * @exception ProcessingException if a processing error occurs
       */
      private void valueOf(final Attributes a)
          throws SAXException, ProcessingException {
  
          String select = a.getValue(JPATH_VALUEOF_SELECT);
          Object value;
  
          if (null != select) {
              if (m_cache.containsKey(select)) {
                  value = m_cache.get(select);
              } else {
                  value = m_jxpathContext.compile(select).getValue(m_jxpathContext);
                  m_cache.put(select, value);
              }
  
              if (value != null) {
                  sendTextEvent((String)value);
              }
              else {
                  throw new ProcessingException(
                      "<jpath:" + JPATH_VALUEOF + " select=\"" + select +
                      "\"/> yields a null value"
                  );
              }
          }
          else {
              throw new ProcessingException(
                  "jpath:" + JPATH_VALUEOF + " specified without a select attribute"
              );
          }
      }
  
      /**
       * Release all held resources.
       */
      public void recycle() {
          super.recycle();
  
          m_cache.clear();
          m_kont = null;
          m_jxpathContext = null;
      }
  }
  
  
  

----------------------------------------------------------------------
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