Author: bruno
Date: Mon Nov 22 06:16:31 2004
New Revision: 106182

Modified:
   cocoon/trunk/src/java/org/apache/cocoon/i18n/XMLResourceBundle.java
   cocoon/trunk/src/java/org/apache/cocoon/xml/ParamSaxBuffer.java
Log:
Concerning {..} params spanning multiple character events: replaced my
earlier post-processing solution with an altered version of the one
provided by bugzilla 31887 (by Neil Bacon).


Modified: cocoon/trunk/src/java/org/apache/cocoon/i18n/XMLResourceBundle.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/i18n/XMLResourceBundle.java?view=diff&rev=106182&p1=cocoon/trunk/src/java/org/apache/cocoon/i18n/XMLResourceBundle.java&r1=106181&p2=cocoon/trunk/src/java/org/apache/cocoon/i18n/XMLResourceBundle.java&r2=106182
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/i18n/XMLResourceBundle.java 
(original)
+++ cocoon/trunk/src/java/org/apache/cocoon/i18n/XMLResourceBundle.java Mon Nov 
22 06:16:31 2004
@@ -198,7 +198,6 @@
                 case 2:
                     if (this.namespace.equals(ns) && 
EL_MESSAGE.equals(localName)) {
                         // </i18n:message>
-                        this.buffer.processParams();
                         this.buffer = null;
                         state --;
                     } else {

Modified: cocoon/trunk/src/java/org/apache/cocoon/xml/ParamSaxBuffer.java
Url: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/xml/ParamSaxBuffer.java?view=diff&rev=106182&p1=cocoon/trunk/src/java/org/apache/cocoon/xml/ParamSaxBuffer.java&r1=106181&p2=cocoon/trunk/src/java/org/apache/cocoon/xml/ParamSaxBuffer.java&r2=106182
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/xml/ParamSaxBuffer.java     
(original)
+++ cocoon/trunk/src/java/org/apache/cocoon/xml/ParamSaxBuffer.java     Mon Nov 
22 06:16:31 2004
@@ -17,29 +17,33 @@
 
 import java.util.Iterator;
 import java.util.Map;
-import java.util.List;
-import java.util.ArrayList;
 import java.io.Writer;
 import java.io.IOException;
 
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
+import org.xml.sax.Attributes;
 
 /**
  * Modification of the SAX buffer with parameterization capabilities.
  *
- * <p>Any <code>{name}</code> expression inside of the character events can be
+ * Any <code>{name}</code> expression inside of the character events can be
  * replaced by the content of another SaxBuffer if it is present in the map
  * passed to the [EMAIL PROTECTED] #toSAX(ContentHandler, Map)} method.
  *
- * <p>Once all events have been pushed into this buffer, you need to call
- * [EMAIL PROTECTED] #processParams()}.</p>
- *
  * @author <a href="mailto:[EMAIL PROTECTED]">Vadim Gritsenko</a>
  * @version CVS $Id$
  */
 public class ParamSaxBuffer extends SaxBuffer {
 
+   /**
+    * If ch (in characters()) contains an unmatched '{' then
+    * we save the chars from '{' onward in previous_ch.
+    * Next call to characters() prepends the saved chars to ch before 
processing
+    * (and sets previous_ch to null).
+    */
+    private char[] previous_ch = null;
+
     /**
      * Creates empty SaxBuffer
      */
@@ -54,102 +58,113 @@
     }
 
     /**
-     * Parses text in character events and extracts <code>{name}</code> 
parameters for later
+     * Parses text and extracts <code>{name}</code> parameters for later
      * substitution.
      */
-    public void processParams() throws SAXException {
-        // what we do here is running over all sax bits and copying them over
-        // into a new list, and meanwhile processing all Character bits
-
-        int initialSize;
-        if (saxbits.size() <= 3)
-            initialSize = 6;
-        else
-            initialSize = (int)((double)saxbits.size() * 1.35d);
-
-        List newSaxBits = new ArrayList(initialSize);
-
-        int i = 0;
-        while (i < saxbits.size()) {
-            Object bit = saxbits.get(i);
-            if (bit instanceof Characters) {
-                char[] chars = ((Characters)bit).ch;
-
-                // check if there are more character events immediately 
following this one,
-                // if so merge all data into one big array
-                int consecutiveCharacterEventCount = 0;
-                int totalLength = chars.length;
-                for (int k = i + 1; k < saxbits.size(); k++) {
-                    Object otherbit = saxbits.get(k);
-                    if (otherbit instanceof Characters) {
-                        consecutiveCharacterEventCount++;
-                        totalLength += ((Characters)otherbit).ch.length;
-                    } else {
-                        break;
-                    }
-                }
+    public void characters(char ch[], int start, int length) throws 
SAXException {
 
-                if (consecutiveCharacterEventCount > 0) {
-                    char[] newchars = new char[totalLength];
-                    System.arraycopy(chars, 0, newchars, 0, chars.length);
-                    int newCharPos = chars.length;
-                    for (int k = 0; k < consecutiveCharacterEventCount; k++) {
-                        Object otherbit = saxbits.get(i + 1 + k);
-                        char[] otherchars = ((Characters)otherbit).ch;
-                        System.arraycopy(otherchars, 0, newchars, newCharPos, 
otherchars.length);
-                        newCharPos += otherchars.length;
-                    }
-                    chars = newchars;
-                    i += consecutiveCharacterEventCount + 1;
-                } else {
-                    i++;
+        if (previous_ch != null) {
+            // prepend char's from previous_ch to ch
+            char[] buf = new char[length + previous_ch.length];
+            System.arraycopy(previous_ch, 0, buf, 0, previous_ch.length);
+            System.arraycopy(ch, start, buf, previous_ch.length, length);
+            ch = buf;
+            start = 0;
+            length += previous_ch.length;
+            previous_ch = null;
+        }
+
+        final int end = start + length;
+        for (int i = start; i < end; i++) {
+            if (ch[i] == '{') {
+                // Send any collected characters so far
+                if (i > start) {
+                    addBit(new Characters(ch, start, i - start));
                 }
 
-                // now process the actual {...}
-                int start = 0;
-                final int end = chars.length;
-                for (int r = 0; r < end; r++) {
-                    if (chars[r] == '{') {
-                        // Send any collected characters so far
-                        if (r > start) {
-                            newSaxBits.add(new Characters(chars, start, r - 
start));
-                        }
-
-                        // Find closing brace, and construct parameter name
-                        StringBuffer name = new StringBuffer();
-                        int j = r + 1;
-                        for (; j < end; j++) {
-                            if (chars[j] == '}') {
-                                break;
-                            }
-                            name.append(chars[j]);
-                        }
-                        if (j == end) {
-                            throw new SAXException("Unclosed '}'");
-                        }
-                        newSaxBits.add(new Parameter(name.toString()));
-
-                        // Continue processing
-                        r = j;
-                        start = j + 1;
-                        continue;
+                // Find closing brace, and construct parameter name
+                StringBuffer name = new StringBuffer();
+                int j = i + 1;
+                for (; j < end; j++) {
+                    if (ch[j] == '}') {
+                        break;
                     }
+                    name.append(ch[j]);
                 }
-
-                // Send any tailing characters
-                if (start < end) {
-                    newSaxBits.add(new Characters(chars, start, end - start));
+                if (j == end) {
+                    // '{' without a closing '}'
+                    // save char's from '{' in previous_ch in case the 
following call to characters()
+                    // provides the '}'
+                    previous_ch = new char[end - i];
+                    System.arraycopy(ch, i, previous_ch, 0, end - i);
+                    break;
                 }
-            } else {
-                newSaxBits.add(bit);
-                i++;
+                addBit(new Parameter(name.toString()));
+
+                // Continue processing
+                i = j;
+                start = j + 1;
+                continue;
             }
         }
-        this.saxbits = newSaxBits;
+
+        // Send any tailing characters
+        if (start < end) {
+            addBit(new Characters(ch, start, end - start));
+        }
     }
 
-    public void characters(char ch[], int start, int length) throws 
SAXException {
-        addBit(new Characters(ch, start, length));
+    public void endElement(String namespaceURI, String localName, String 
qName) throws SAXException {
+        flushChars();
+        super.endElement(namespaceURI, localName, qName);
+    }
+
+    public void ignorableWhitespace(char ch[], int start, int length) throws 
SAXException {
+        flushChars();
+        super.ignorableWhitespace(ch, start, length);
+    }
+
+    public void processingInstruction(String target, String data) throws 
SAXException {
+        flushChars();
+        super.processingInstruction(target, data);
+    }
+
+    public void startDocument() throws SAXException {
+        flushChars();
+        super.startDocument();
+    }
+
+    public void startElement(String namespaceURI, String localName, String 
qName, Attributes atts) throws SAXException {
+        flushChars();
+        super.startElement(namespaceURI, localName, qName, atts);
+    }
+
+    public void endDocument() throws SAXException {
+        flushChars();
+        super.endDocument();
+    }
+
+    public void comment(char ch[], int start, int length) throws SAXException {
+        flushChars();
+        super.comment(ch, start, length);
+    }
+
+    public void endDTD() throws SAXException {
+        flushChars();
+        super.endDTD();
+    }
+
+    public void startDTD(String name, String publicId, String systemId) throws 
SAXException {
+        flushChars();
+        super.startDTD(name, publicId, systemId);
+    }
+
+    private void flushChars() {
+        // Handle saved chars (in case we had a '{' with no matching '}').
+        if (previous_ch != null) {
+            addBit(new Characters(previous_ch, 0, previous_ch.length));
+            previous_ch = null;
+        }
     }
 
     /**

Reply via email to