cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anathan...@apache.org
Subject svn commit: r226827 - in /cocoon/branches/BRANCH_2_1_X: src/blocks/xsp/java/org/apache/cocoon/components/language/markup/xsp/XSPExpressionParser.java src/blocks/xsp/samples/java/interpolation.xsp status.xml
Date Mon, 01 Aug 2005 15:50:13 GMT
Author: anathaniel
Date: Mon Aug  1 08:50:07 2005
New Revision: 226827

URL: http://svn.apache.org/viewcvs?rev=226827&view=rev
Log:
XSP block: Extend {#expr} interpolation parser to understand {}, "}", '}'
as not being the closing brace.
The previously implemented mechanism #} to escape braces within the
statement is no longer supported.

Modified:
    cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/xsp/XSPExpressionParser.java
    cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/interpolation.xsp
    cocoon/branches/BRANCH_2_1_X/status.xml

Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/xsp/XSPExpressionParser.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/xsp/XSPExpressionParser.java?rev=226827&r1=226826&r2=226827&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/xsp/XSPExpressionParser.java
(original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/xsp/XSPExpressionParser.java
Mon Aug  1 08:50:07 2005
@@ -24,7 +24,12 @@
  * expanded by the
  * {@link org.apache.cocoon.components.language.markup.xsp.XSPMarkupLanguage.PreProcessFilter
PreProcessFilter}
  * and have the form {#expression}. To prevent interpolation, use {##quote}, which results
in the
- * text {#quote}. Inside expressions, to quote '}' write "#}" and to quote '#' write "##".
+ * text {#quote}.
+ * An exception is thrown if the closing brace is missing.
+ * <p>
+ * The parser has a rudimentary understanding of expressions concerning
+ * nested braces and braces inside quoted strings and character constants.
+ * All valid Java, Javascript, and Python expressions can be used.
  * <p>
  * Example: &lt;h1&gt;Hello {#user.getName()}&lt;/h1&gt; &lt;img or
  * src=&quot;image_{#image.getId()}&quot;/&gt;
@@ -63,14 +68,47 @@
          * @throws SAXException It is illegal to finish processing in this state.
          */
         public void done(XSPExpressionParser parser) throws SAXException {
-            throw new SAXException("Illegal XSP expression.");
+            throw new SAXException("Incomplete XSP expression {#"+parser.getExpression());
+        }
+    }
+
+    /**
+     * Parser state in a quoted string.
+     */
+    protected static class QuotedState extends State {
+        private final char quote;
+
+        /**
+         * Create state to process quotes strings.
+         *
+         * @param quote The quote character to delimit strings
+         */
+        public QuotedState(char quote) {
+            this.quote = quote;
+        }
+
+        /**
+         * Consume the next character
+         * 
+         * @param parser The parser
+         * @param ch The character to consume
+         * @throws SAXException If there is an error in the expression
+         */
+        public void consume(XSPExpressionParser parser, char ch) throws SAXException {
+            parser.append(ch);
+            if (ch == quote && !parser.isEscaped())
+                parser.setState(EXPRESSION_STATE);
+            else if (ch == '\\')
+                parser.setEscaped(!parser.isEscaped());
+            else
+                parser.setEscaped(false);
         }
     }
 
     /**
      * The parser is parsing text.
      */
-    protected static State TEXT_STATE = new State() {
+    protected static final State TEXT_STATE = new State() {
         public void consume(XSPExpressionParser parser, char ch) throws SAXException {
             switch (ch) {
                 case '{':
@@ -95,7 +133,7 @@
     /**
      * The parser has encountered '{' in <code>{@link TEXT_STATE}</code>.
      */
-    protected static State LBRACE_STATE = new State() {
+    protected static final State LBRACE_STATE = new State() {
         public void consume(XSPExpressionParser parser, char ch) throws SAXException {
             switch (ch) {
                 case '#':
@@ -124,7 +162,7 @@
     /**
      * The parser has encountered '#' in <code>{@link LBRACE_STATE}</code>.
      */
-    protected static State TEXT_HASH_STATE = new State() {
+    protected static final State TEXT_HASH_STATE = new State() {
         public void consume(XSPExpressionParser parser, char ch) throws SAXException {
             switch (ch) {
                 case '#':
@@ -135,8 +173,9 @@
 
                 default:
                     parser.handleText();
-                    parser.append(ch);
+                    parser.initExpression();
                     parser.setState(EXPRESSION_STATE);
+                    EXPRESSION_STATE.consume(parser, ch);
             }
         }
     };
@@ -144,16 +183,37 @@
     /**
      * The parser is parsing an expression.
      */
-    protected static State EXPRESSION_STATE = new State() {
+    protected static final State EXPRESSION_STATE = new State() {
         public void consume(XSPExpressionParser parser, char ch) throws SAXException {
             switch (ch) {
+                case '{':
+                    parser.incrNesting();
+                    parser.append(ch);
+                    break;
+
                 case '}':
-                    parser.handleExpression();
-                    parser.setState(TEXT_STATE);
+                    if (parser.decrNesting() > 0) {
+                        parser.append(ch);
+                    }
+                    else {
+                        parser.handleExpression();
+                        parser.setState(TEXT_STATE);
+                    }
                     break;
 
-                case '#':
-                    parser.setState(EXPRESSION_HASH_STATE);
+                case '"':
+                    parser.append(ch);
+                    parser.setState(EXPRESSION_STRING_STATE);
+                    break;
+
+                case '\'':
+                    parser.append(ch);
+                    parser.setState(EXPRESSION_CHAR_STATE);
+                    break;
+
+                case '´':
+                    parser.append(ch);
+                    parser.setState(EXPRESSION_SHELL_STATE);
                     break;
 
                 default:
@@ -163,26 +223,22 @@
     };
 
     /**
-     * The parser has encountered '#' in <code>{@link EXPRESSION_STATE}</code>.
+     * The parser has encountered '"' in <code>{@link EXPRESSION_STATE}</code>
+     * to start a string constant.
      */
-    protected static State EXPRESSION_HASH_STATE = new State() {
-        public void consume(XSPExpressionParser parser, char ch) throws SAXException {
-            switch (ch) {
-                case '}':
-                    parser.append('}');
-                    parser.setState(EXPRESSION_STATE);
-                    break;
+    protected static final State EXPRESSION_STRING_STATE = new QuotedState('"');
 
-                case '#':
-                    parser.append('#');
-                    parser.setState(EXPRESSION_STATE);
-                    break;
+    /**
+     * The parser has encountered '\'' in <code>{@link EXPRESSION_STATE}</code>
+     * to start a character constant.
+     */
+    protected static final State EXPRESSION_CHAR_STATE = new QuotedState('\'');
 
-                default:
-                    throw new SAXException("Illegal character '" + ch + "' after '#' in expression.");
-            }
-        }
-    };
+    /**
+     * The parser has encountered '´' in <code>{@link EXPRESSION_STATE}</code>
+     * to start a Python string constant.
+     */
+    protected static final State EXPRESSION_SHELL_STATE = new QuotedState('´');
 
     /**
      * The parser state
@@ -190,6 +246,16 @@
     private State state = TEXT_STATE;
 
     /**
+     * The nesting level of braces.
+     */
+    private int nesting = 0;
+
+    /**
+     * Flag whether previous character was a backslash to escape quotes.
+     */
+    private boolean escaped = false;
+
+    /**
      * The handler for parsed text and expression fragments.
      */
     private Handler handler;
@@ -268,6 +334,31 @@
 
     protected void setState(State state) {
         this.state = state;
+    }
+
+    protected void initExpression() {
+        nesting = 1;
+        escaped = false;
+    }
+
+    protected void incrNesting() {
+        nesting++;
+    }
+
+    protected int decrNesting() {
+        return --nesting;
+    }
+
+    protected void setEscaped(boolean escaped) {
+        this.escaped = escaped;
+    }
+
+    protected boolean isEscaped() {
+        return escaped;
+    }
+
+    protected String getExpression() {
+        return new String(buf, 0, bufSize);
     }
 
     protected void handleText() throws SAXException {

Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/interpolation.xsp
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/interpolation.xsp?rev=226827&r1=226826&r2=226827&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/interpolation.xsp (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/interpolation.xsp Mon Aug  1
08:50:07 2005
@@ -75,6 +75,52 @@
         Interpolation can also be used in logicsheets:
       </p>
       <xsp-interpolation:greeting/>
+
+      <p>
+        The XSP expression parser understands nested braces,
+        single and double quoted strings, and backslash-escaped
+        quotes and apostrophes.
+      </p>
+      <table border="1">
+        <tr>
+          <th>Expression</th>
+          <th>Result</th>
+          <th>Expected</th>
+        </tr>
+        <tr>
+          <td xsp:text-interpolation="false">
+            {#new String[]{}.length}
+          </td>
+          <td>
+            {#new String[]{}.length}
+          </td>
+          <td>
+            0
+          </td>
+        </tr>
+        <tr>
+          <td xsp:text-interpolation="false">
+            {#new String[]{"}"}.length}
+          </td>
+          <td>
+            {#new String[]{"}"}.length}
+          </td>
+          <td>
+            1
+          </td>
+        </tr>
+        <tr>
+          <td xsp:text-interpolation="false">
+            {#"'\"}".indexOf('}')}
+          </td>
+          <td>
+            {#"'\"}".indexOf('}')}
+          </td>
+          <td>
+            2
+          </td>
+        </tr>
+      </table>
     </content>
   </page>
 

Modified: cocoon/branches/BRANCH_2_1_X/status.xml
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/status.xml?rev=226827&r1=226826&r2=226827&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/status.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/status.xml Mon Aug  1 08:50:07 2005
@@ -196,6 +196,12 @@
 
   <changes>
   <release version="@version@" date="@date@">
+    <action dev="AN" type="add">
+      XSP block: Extend {#expr} interpolation parser to understand {}, "}", '}'
+      as not being the closing brace.
+      The previously implemented mechanism #} to escape braces within the
+      statement is no longer supported.
+    </action>
     <action dev="SW" type="add">
       Added Cocoon stacktraces. This is based on location classes in the new org.apache.cocoon.util.location
package
       and a refactoring of the exception management to attach locations to exceptions.



Mime
View raw message