Author: bayard Date: Wed Feb 3 07:31:10 2010 New Revision: 905919 URL: http://svn.apache.org/viewvc?rev=905919&view=rev Log: Adding Vincent Ricard's patch to CharRange.java providing an iterator that lets you walk the chars in the range. LANG-454
Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/CharRange.java commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/CharRangeTest.java Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/CharRange.java URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/CharRange.java?rev=905919&r1=905918&r2=905919&view=diff ============================================================================== --- commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/CharRange.java (original) +++ commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/CharRange.java Wed Feb 3 07:31:10 2010 @@ -17,6 +17,8 @@ package org.apache.commons.lang3; import java.io.Serializable; +import java.util.Iterator; +import java.util.NoSuchElementException; /** * <p>A contiguous range of characters, optionally negated.</p> @@ -241,5 +243,96 @@ } return iToString; } - + + // Expansions + //----------------------------------------------------------------------- + /** + * <p>Returns an iterator which can be used to walk through the characters described by this range.</p> + * + * @return an iterator to the chars represented by this range + */ + public Iterator iterator() { + return new CharacterIterator(this); + } + + static class CharacterIterator implements Iterator { + /** The currect character */ + private char current; + + private CharRange range; + private boolean hasNext; + + public CharacterIterator(CharRange r) { + range = r; + hasNext = true; + + if (range.negated) { + if (range.start == 0) { + if (range.end == Character.MAX_VALUE) { + // This range is an empty set + hasNext = false; + } else { + current = (char) (range.end + 1); + } + } else { + current = 0; + } + } else { + current = range.start; + } + } + + private void prepareNext() { + if (range.negated) { + if (current == Character.MAX_VALUE) { + hasNext = false; + } else if (current + 1 == range.start) { + if (range.end == Character.MAX_VALUE) { + hasNext = false; + } else { + current = (char) (range.end + 1); + } + } else { + current = (char) (current + 1); + } + } else if (current < range.end) { + current = (char) (current + 1); + } else { + hasNext = false; + } + } + + /** + * Has the iterator not reached the end character yet? + * + * @return <code>true</code> if the iterator has yet to reach the character date + */ + public boolean hasNext() { + return hasNext; + } + + /** + * Return the next character in the iteration + * + * @return <code>Character</code> for the next character + */ + public Object next() { + if (hasNext == false) { + throw new NoSuchElementException(); + } + char cur = current; + prepareNext(); + return Character.valueOf(cur); + } + + /** + * Always throws UnsupportedOperationException. + * + * @throws UnsupportedOperationException + * @see java.util.Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + } } Modified: commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/CharRangeTest.java URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/CharRangeTest.java?rev=905919&r1=905918&r2=905919&view=diff ============================================================================== --- commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/CharRangeTest.java (original) +++ commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/CharRangeTest.java Wed Feb 3 07:31:10 2010 @@ -19,6 +19,8 @@ package org.apache.commons.lang3; import java.lang.reflect.Modifier; +import java.util.Iterator; +import java.util.NoSuchElementException; import junit.framework.TestCase; @@ -301,7 +303,73 @@ assertEquals("The Range must not be null", e.getMessage()); } } - + + public void testIterator() { + CharRange a = CharRange.is('a'); + CharRange ad = CharRange.isIn('a', 'd'); + CharRange nota = CharRange.isNot('a'); + CharRange emptySet = CharRange.isNotIn((char) 0, Character.MAX_VALUE); + CharRange notFirst = CharRange.isNotIn((char) 1, Character.MAX_VALUE); + CharRange notLast = CharRange.isNotIn((char) 0, (char) (Character.MAX_VALUE - 1)); + + Iterator aIt = a.iterator(); + assertNotNull(aIt); + assertTrue(aIt.hasNext()); + assertEquals(Character.valueOf('a'), aIt.next()); + assertFalse(aIt.hasNext()); + + Iterator adIt = ad.iterator(); + assertNotNull(adIt); + assertTrue(adIt.hasNext()); + assertEquals(Character.valueOf('a'), adIt.next()); + assertEquals(Character.valueOf('b'), adIt.next()); + assertEquals(Character.valueOf('c'), adIt.next()); + assertEquals(Character.valueOf('d'), adIt.next()); + assertFalse(adIt.hasNext()); + + Iterator notaIt = nota.iterator(); + assertNotNull(notaIt); + assertTrue(notaIt.hasNext()); + while (notaIt.hasNext()) { + Character c = (Character) notaIt.next(); + assertFalse('a' == c.charValue()); + } + + Iterator emptySetIt = emptySet.iterator(); + assertNotNull(emptySetIt); + assertFalse(emptySetIt.hasNext()); + try { + emptySetIt.next(); + fail("Should throw NoSuchElementException"); + } catch (NoSuchElementException e) { + assertTrue(true); + } + + Iterator notFirstIt = notFirst.iterator(); + assertNotNull(notFirstIt); + assertTrue(notFirstIt.hasNext()); + assertEquals(Character.valueOf((char) 0), notFirstIt.next()); + assertFalse(notFirstIt.hasNext()); + try { + notFirstIt.next(); + fail("Should throw NoSuchElementException"); + } catch (NoSuchElementException e) { + assertTrue(true); + } + + Iterator notLastIt = notLast.iterator(); + assertNotNull(notLastIt); + assertTrue(notLastIt.hasNext()); + assertEquals(Character.valueOf(Character.MAX_VALUE), notLastIt.next()); + assertFalse(notLastIt.hasNext()); + try { + notLastIt.next(); + fail("Should throw NoSuchElementException"); + } catch (NoSuchElementException e) { + assertTrue(true); + } + } + //----------------------------------------------------------------------- public void testSerialization() { CharRange range = CharRange.is('a');