Author: henrib Date: Fri Oct 21 16:49:41 2011 New Revision: 1187462 URL: http://svn.apache.org/viewvc?rev=1187462&view=rev Log: Utility classes to ease UJEXL template capabilities
Added: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/CharSequenceReader.java (with props) Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/StringParser.java commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/parser/ParserTest.java Added: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/CharSequenceReader.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/CharSequenceReader.java?rev=1187462&view=auto ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/CharSequenceReader.java (added) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/CharSequenceReader.java Fri Oct 21 16:49:41 2011 @@ -0,0 +1,207 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.jexl2.parser; + +import java.io.Reader; +import java.io.Serializable; + +/** + * {@link Reader} implementation that can read from String, StringBuffer, + * StringBuilder or CharBuffer. + * <p> + * <strong>Note:</strong> Supports {@link #mark(int)} and {@link #reset()}. + * Extracted from Commons IO. + */ +public class CharSequenceReader extends Reader implements Serializable { + private final CharSequence charSequence; + private int idx; + private int mark; + + /** + * Construct a new instance with the specified character sequence. + * + * @param charSequence The character sequence, may be <code>null</code> + */ + public CharSequenceReader(CharSequence charSequence) { + this.charSequence = (charSequence != null ? charSequence : ""); + } + + /** + * Close resets the file back to the start and removes any marked position. + */ + @Override + public void close() { + idx = 0; + mark = 0; + } + + /** + * Mark the current position. + * + * @param readAheadLimit ignored + */ + @Override + public void mark(int readAheadLimit) { + mark = idx; + } + + /** + * Get the current position. + * @return the position + */ + public int position() { + return idx; + } + + /** + * Mark is supported (returns true). + * + * @return <code>true</code> + */ + @Override + public boolean markSupported() { + return true; + } + + /** + * Read a single character. + * + * @return the next character from the character sequence + * or -1 if the end has been reached. + */ + @Override + public int read() { + if (idx >= charSequence.length()) { + return -1; + } else { + return charSequence.charAt(idx++); + } + } + + /** + * Read the sepcified number of characters into the array. + * + * @param array The array to store the characters in + * @param offset The starting position in the array to store + * @param length The maximum number of characters to read + * @return The number of characters read or -1 if there are + * no more + */ + @Override + public int read(char[] array, int offset, int length) { + if (idx >= charSequence.length()) { + return -1; + } + if (array == null) { + throw new NullPointerException("Character array is missing"); + } + if (length < 0 || (offset + length) > array.length) { + throw new IndexOutOfBoundsException("Array Size=" + array.length + + ", offset=" + offset + ", length=" + length); + } + int count = 0; + for (int i = 0; i < length; i++) { + int c = read(); + if (c == -1) { + return count; + } + array[offset + i] = (char) c; + count++; + } + return count; + } + + /** + * Reset the reader to the last marked position (or the beginning if + * mark has not been called). + */ + @Override + public void reset() { + idx = mark; + } + + /** + * Skip the specified number of characters. + * + * @param n The number of characters to skip + * @return The actual number of characters skipped + */ + @Override + public long skip(long n) { + if (n < 0) { + throw new IllegalArgumentException( + "Number of characters to skip is less than zero: " + n); + } + if (idx >= charSequence.length()) { + return -1; + } + int dest = (int) Math.min(charSequence.length(), (idx + n)); + int count = dest - idx; + idx = dest; + return count; + } + + /** + * Return a String representation of the underlying + * character sequence. + * + * @return The contents of the character sequence + */ + @Override + public String toString() { + return charSequence.toString(); + } + + /** + * Read a line of text. + * A line is considered to be terminated by any sequence of line feed + * ('\n'), carriage return ('\r') or form feed ('\f'). + * @return A String containing the contents of the line, not including any line-termination characters, + * or null if the end of the stream has been reached + */ + public CharSequence readLine() { + final int start = idx; + int end = idx; + read: + while (true) { + int c = read(); + if (c < 0) { + break read; + } else if (c == '\n' || c == '\f' || c == '\r') { + // skip the sequence of line terminators + while (true) { + c = read(); + if (c == '\n' || c == '\f' || c == '\r') { + continue; + } else { + if (c >= 0) { + idx -= 1; + } + break read; + } + } + } else { + end = idx; + } + } + if (end > start) { + return charSequence.subSequence(start, end); + } else { + return null; + } + } +} \ No newline at end of file Propchange: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/CharSequenceReader.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/StringParser.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/StringParser.java?rev=1187462&r1=1187461&r2=1187462&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/StringParser.java (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/StringParser.java Fri Oct 21 16:49:41 2011 @@ -54,6 +54,28 @@ public class StringParser { } /** + * Reads lines beginning with a given prefix and append them to a StringBuilder without the prefix. + * @param strb the string builder to append to + * @param str the input char sequence + * @param index the beginning offset in the input char sequence + * @param prefix the prefix to use + * @return the number of characters read from the input sequence + */ + public static int readLines(StringBuilder strb, CharSequence str, int index, String prefix) { + CharSequenceReader csr = new CharSequenceReader(str.subSequence(index, str.length())); + while (true) { + CharSequence line = csr.readLine(); + if (line != null && (prefix == null || line.toString().startsWith(prefix))) { + strb.append(prefix == null? line.toString() : line.subSequence(prefix.length(), line.length())); + strb.append(' '); + } else { + break; + } + } + return csr.position(); + } + + /** * Read the remainder of a string till a given separator, * handles escaping through '\' syntax. * @param strb the destination buffer to copy characters into Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/parser/ParserTest.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/parser/ParserTest.java?rev=1187462&r1=1187461&r2=1187462&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/parser/ParserTest.java (original) +++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/parser/ParserTest.java Fri Oct 21 16:49:41 2011 @@ -24,28 +24,22 @@ import junit.framework.TestCase; * @since 1.0 * */ -public class ParserTest extends TestCase -{ - public ParserTest(String testName) - { +public class ParserTest extends TestCase { + public ParserTest(String testName) { super(testName); } /** - * parse test : see if we can parse a little script - */ - public void testParse1() - throws Exception - { - Parser parser = new Parser(new StringReader(";")); - - SimpleNode sn = parser.parse(new StringReader("foo = 1;"), null); - assertNotNull("parsed node is null", sn); - } - - public void testParse2() - throws Exception - { + * parse test : see if we can parse a little script + */ + public void testParse1() throws Exception { + Parser parser = new Parser(new StringReader(";")); + + SimpleNode sn = parser.parse(new StringReader("foo = 1;"), null); + assertNotNull("parsed node is null", sn); + } + + public void testParse2() throws Exception { Parser parser = new Parser(new StringReader(";")); SimpleNode sn = parser.parse(new StringReader("foo = \"bar\";"), null); @@ -54,4 +48,22 @@ public class ParserTest extends TestCase sn = parser.parse(new StringReader("foo = 'bar';"), null); assertNotNull("parsed node is null", sn); } + + public void testReadLines() throws Exception { + String input = "foo bar\n\rquux\n\r\npizza"; + StringBuilder output = new StringBuilder(32); + int read = StringParser.readLines(output, input, 0, null); + assertEquals(input.length(), read); + String outstr = output.toString(); + assertEquals("foo bar quux pizza ", outstr); + } + + public void testReadLines$$() throws Exception { + String input = "$$foo bar\n\r$$quux\n\r\n$$pizza"; + StringBuilder output = new StringBuilder(32); + int read = StringParser.readLines(output, input, 0, "$$"); + assertEquals(input.length(), read); + String outstr = output.toString(); + assertEquals("foo bar quux pizza ", outstr); + } }