You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by co...@apache.org on 2004/01/04 02:07:53 UTC

cvs commit: cocoon-2.1/src/documentation/xdocs/userdocs/flow jxtemplate.xml

coliver     2004/01/03 17:07:53

  Modified:    src/java/org/apache/cocoon/generation
                        JXTemplateGenerator.java
               src/documentation/xdocs/userdocs/flow jxtemplate.xml
  Log:
  Added evalBody tag to JXTemplateGenerator
  
  Revision  Changes    Path
  1.26      +79 -23    cocoon-2.1/src/java/org/apache/cocoon/generation/JXTemplateGenerator.java
  
  Index: JXTemplateGenerator.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/generation/JXTemplateGenerator.java,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- JXTemplateGenerator.java	29 Dec 2003 21:26:05 -0000	1.25
  +++ JXTemplateGenerator.java	4 Jan 2004 01:07:53 -0000	1.26
  @@ -62,6 +62,7 @@
   import java.text.DecimalFormatSymbols;
   import java.text.NumberFormat;
   import java.text.SimpleDateFormat;
  +import java.util.Enumeration;
   import java.util.HashMap;
   import java.util.Iterator;
   import java.util.LinkedList;
  @@ -691,6 +692,25 @@
           public Iterator getIterator(Object obj, Info i)
               throws Exception {
               if (!(obj instanceof Scriptable)) {
  +                // support Enumeration
  +                if (obj instanceof Enumeration) {
  +                    final Enumeration e = (Enumeration)obj;
  +                    return new Iterator() {
  +
  +                            public boolean hasNext() {
  +                                return e.hasMoreElements();
  +                            }
  +
  +                            public Object next() {
  +                                return e.nextElement();
  +                            }
  +
  +                            public void remove() {
  +                                // no action
  +                            }
  +
  +                        };
  +                }
                   return super.getIterator(obj, i);
               }
               if (obj instanceof NativeArray) {
  @@ -878,6 +898,7 @@
       final static String IMPORT = "import";
       final static String SET = "set";
       final static String MACRO = "macro";
  +    final static String EVALBODY = "evalBody";
       final static String PARAMETER = "parameter";
       final static String FORMAT_NUMBER = "formatNumber";
       final static String FORMAT_DATE = "formatDate";
  @@ -1598,7 +1619,7 @@
   
       static class StartForEach extends StartInstruction {
           StartForEach(StartElement raw,
  -                     Expression items, String var, String varStatus,
  +                     Expression items, Expression var, Expression varStatus,
                        Expression begin, Expression end, Expression step, Boolean lenient) {
               super(raw);
               this.items = items;
  @@ -1610,8 +1631,8 @@
               this.lenient = lenient;
           }
           final Expression items;
  -        final String var;
  -        final String varStatus;
  +        final Expression var;
  +        final Expression varStatus;
           final Expression begin;
           final Expression end;
           final Expression step;
  @@ -1677,6 +1698,12 @@
           }
       }
   
  +    static class StartEvalBody extends StartInstruction {
  +        StartEvalBody(StartElement raw) {
  +            super(raw);
  +        }
  +    }
  +
       static class StartDefine extends StartInstruction {
           StartDefine(StartElement raw, String namespace, String name) {
               super(raw);
  @@ -2358,8 +2385,12 @@
                       Expression step = compileInt(attrs.getValue("step"),
                                                    FOR_EACH,
                                                    locator);
  -                    String var = attrs.getValue("var");
  -                    String varStatus = attrs.getValue("varStatus");
  +                    Expression var =
  +                        compileExpr(attrs.getValue("var"), 
  +                                    null, locator);           
  +                    Expression varStatus =
  +                        compileExpr(attrs.getValue("varStatus"), 
  +                                    null, locator);           
                       if (items == null) {
                           if (select == null && (begin == null || end == null)) {
                               throw new SAXParseException("forEach: \"select\", \"items\", or both \"begin\" and \"end\" must be specified", locator, null);
  @@ -2546,6 +2577,10 @@
                       if (syntaxErr) {
                           throw new SAXParseException("<parameter> not allowed here", locator, null);
                       }
  +                } else if (localName.equals(EVALBODY)) {
  +                    StartEvalBody startEval = 
  +                        new StartEvalBody(startElement);
  +                    newEvent = startEval;
                   } else if (localName.equals(SET)) {
                       String var = attrs.getValue("var");
                       String value = attrs.getValue("value");
  @@ -2654,6 +2689,7 @@
                   gen.execute(gen.getConsumer(),
                               gen.getJexlContext(),
                               gen.getJXPathContext(),
  +                            null,
                               getStartEvent(), null);
               }
   
  @@ -2870,7 +2906,7 @@
               }
           }
           execute(this.xmlConsumer,
  -                globalJexlContext, jxpathContext, 
  +                globalJexlContext, jxpathContext, null,
                   startEvent, null);
       }
   
  @@ -3009,7 +3045,7 @@
      }
   
       private void call(Locator location,
  -                      String messagePrefix,
  +                      StartElement macroCall,
                         final XMLConsumer consumer,
                         MyJexlContext jexlContext,
                         JXPathContext jxpathContext,
  @@ -3017,9 +3053,10 @@
           throws SAXException {
           try {
               execute(consumer, jexlContext,
  -                    jxpathContext, startEvent, endEvent);
  +                    jxpathContext, macroCall,
  +                    startEvent, endEvent);
           } catch (SAXParseException exc) {
  -            throw new SAXParseException(messagePrefix +": " +exc.getMessage(),
  +            throw new SAXParseException(macroCall.localName +": " +exc.getMessage(),
                                           location, 
                                           exc);
           }
  @@ -3064,6 +3101,7 @@
       private void execute(final XMLConsumer consumer,
                            MyJexlContext jexlContext,
                            JXPathContext jxpathContext,
  +                         StartElement macroCall,
                            Event startEvent, Event endEvent) 
       throws SAXException {
           Event ev = startEvent;
  @@ -3191,6 +3229,7 @@
                   final Object items = startForEach.items;
                   Iterator iter = null;
                   int begin, end, step;
  +                String var, varStatus;
                   try {
                       if (items == null) {
                           iter = NULL_ITER;
  @@ -3250,6 +3289,11 @@
                       step = startForEach.step == null ? 1 : 
                           getIntValue(startForEach.step, jexlContext,
                                       jxpathContext);
  +                    var = getStringValue(startForEach.var, jexlContext, 
  +                                            jxpathContext);
  +                    varStatus = getStringValue(startForEach.varStatus, 
  +                                               jexlContext, 
  +                                               jxpathContext);
                   } catch (Exception exc) {
                       throw new SAXParseException(exc.getMessage(),
                                                   ev.location,
  @@ -3269,15 +3313,15 @@
                       iter.next();
                   }
                   LoopTagStatus status = null;
  -                if (startForEach.varStatus != null) {
  +                if (varStatus != null) {
                       status = new LoopTagStatus();
                       status.begin = begin;
                       status.end = end;
                       status.step = step;
                       status.first = true;
  -                    localJexlContext.put(startForEach.varStatus,
  +                    localJexlContext.put(varStatus,
                                            status);
  -                    localJXPathVariables.declareVariable(startForEach.varStatus,
  +                    localJXPathVariables.declareVariable(varStatus,
                                                            status);
                   }
                   for (int count = 1; i <= end && iter.hasNext(); i+=step, count++) {
  @@ -3301,8 +3345,8 @@
                                                               value);
                       }
                       localJXPathContext.setVariables(localJXPathVariables);
  -                    if (startForEach.var != null) {
  -                        localJexlContext.put(startForEach.var, value);
  +                    if (var != null) {
  +                        localJexlContext.put(var, value);
                       }
                       if (status != null) {
                           status.index = i;
  @@ -3314,6 +3358,7 @@
                       execute(consumer,
                               localJexlContext,
                               localJXPathContext,
  +                            macroCall,
                               startForEach.next,
                               startForEach.endInstruction);
                       for (int skip = step-1; 
  @@ -3344,7 +3389,7 @@
                       }
                       if (result) {
                           execute(consumer,
  -                                jexlContext, jxpathContext,
  +                                jexlContext, jxpathContext, macroCall,
                                   startWhen.next, startWhen.endInstruction);
                           break;
                       }
  @@ -3352,7 +3397,7 @@
                   if (startWhen == null) {
                       if (startChoose.otherwise != null) {
                           execute(consumer,
  -                                jexlContext, jxpathContext,
  +                                jexlContext, jxpathContext, macroCall,
                                   startChoose.otherwise.next,
                                   startChoose.otherwise.endInstruction);
                       }
  @@ -3378,9 +3423,8 @@
                                            "set",
                                            "set",
                                            EMPTY_ATTRS);
  -                    execute(builder, jexlContext, jxpathContext,
  -                            startSet.next, 
  -                            startSet.endInstruction);
  +                    execute(builder, jexlContext, jxpathContext, macroCall,
  +                            startSet.next, startSet.endInstruction);
                       builder.endElement(NS,
                                          "set",
                                          "set");
  @@ -3523,7 +3567,7 @@
                           jxpathContextFactory.newContext(null, arr);
                       localJXPathContext.setVariables(vars);
                       call(ev.location,
  -                         startElement.localName,
  +                         startElement,
                            consumer, 
                            localJexlContext, localJXPathContext,
                            def.body, def.endInstruction);
  @@ -3695,6 +3739,18 @@
                                                   e);
                   }
               } else if (ev instanceof StartTemplate) {
  +            } else if (ev instanceof StartEvalBody) {
  +                StartEvalBody startEval = (StartEvalBody)ev;
  +                try {
  +                    execute(consumer, jexlContext,
  +                            jxpathContext, null,
  +                            macroCall.next, macroCall.endElement);
  +                } catch (Exception exc) {
  +                    throw new SAXParseException(exc.getMessage(),
  +                                                ev.location, exc);
  +                }
  +                ev = startEval.endInstruction.next;
  +                continue;
               } else if (ev instanceof StartDefine) {
                   StartDefine startDefine = (StartDefine)ev;
                   definitions.put(startDefine.qname, startDefine);
  @@ -3812,8 +3868,8 @@
                                                       null);
                       }
                   }
  -                execute(consumer, selectJexl, selectJXPath, doc.next, 
  -                        doc.endDocument);
  +                execute(consumer, selectJexl, selectJXPath, macroCall,
  +                        doc.next, doc.endDocument);
                   ev = startImport.endInstruction.next;
                   continue;
               }
  
  
  
  1.28      +39 -1     cocoon-2.1/src/documentation/xdocs/userdocs/flow/jxtemplate.xml
  
  Index: jxtemplate.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/documentation/xdocs/userdocs/flow/jxtemplate.xml,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- jxtemplate.xml	27 Dec 2003 23:55:45 -0000	1.27
  +++ jxtemplate.xml	4 Jan 2004 01:07:53 -0000	1.28
  @@ -456,7 +456,7 @@
     &lt;/jx:forEach&gt;
   &lt;/jx:macro&gt;
   </source>
  -<p>The <code>parameter</code> tags in the macro definition define formal parameters, which are replaced with the actual attribute values of the tag when it is used. The content of the tag is also available as a special variable <code>${content}</code>.</p><p>Assuming you had this code in your flowscript:</p>
  +<p>The <code>parameter</code> tags in the macro definition define formal parameters, which are replaced with the actual attribute values of the tag when it is used.</p><p>Assuming you had this code in your flowscript:</p>
      <source>var greatlakes = ["Superior", "Michigan", "Huron", "Erie", "Ontario"];
      sendPage(uri, {greatlakes: greatlakes});</source>
   <p>and a template like this:</p><source>
  @@ -475,6 +475,44 @@
     &lt;tr&gt;&lt;td bgcolor="blue"&gt;Ontario&lt;/td&gt;&lt;/tr&gt;
   &lt;/table&gt;
   </source>
  +</s2>
  +<s2 title="evalBody"> 
  +<p>Within the body of a macro the <code>evalBody</code> tag treats the content of the macro tag invocation as a <em>JX</em>Template and executes it. For example, the below macro uses this facility to implement the <link href="http://java.sun.com/products/jsp/jstl/">JSTL</link> <code>forTokens</code> tag:
  +</p>
  +<source>
  +<![CDATA[
  +<jx:macro name="forTokens">
  +  <jx:parameter name="var"/>
  +  <jx:parameter name="items"/>
  +  <jx:parameter name="delims"/>
  +  <jx:forEach var="${var}" 
  +         items="${java.util.StringTokenizer(items, delims)}">
  +    <jx:evalBody/>
  +  </jx:forEach>
  +</jx:macro>
  +]]> </source>
  +<p>
  +The tag produced by this macro can be used like this:
  +</p>
  +<source>
  +<![CDATA[
  +<forTokens var="letter" items="a,b,c,d,e,f,g" delims=",">
  +  letter = ${letter} <br/>
  +</forTokens>
  +]]> </source>
  +<p>
  +which would create the following output:
  +</p>
  +<source>
  +<![CDATA[
  +  letter = a  <br/>  
  +  letter = b  <br/>  
  +  letter = c  <br/>  
  +  letter = d  <br/>  
  +  letter = e  <br/>  
  +  letter = f  <br/>  
  +  letter = g  <br/>  
  +]]> </source>
   </s2>
   </s1>
   </body>