aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbellingard <bellingard@gmail.com>2010-10-14 13:45:29 +0000
committerbellingard <bellingard@gmail.com>2010-10-14 13:45:29 +0000
commit7b0cb741b188abd0be71b5dfacbe5f3a0a5cda9f (patch)
tree5fab661c104408d8dab61dba80ecc1775aecca37
parent4ccf48f4e76bfe9a1783aa9b17e3d4d1c5c278aa (diff)
downloadsonarqube-7b0cb741b188abd0be71b5dfacbe5f3a0a5cda9f.tar.gz
sonarqube-7b0cb741b188abd0be71b5dfacbe5f3a0a5cda9f.zip
[SONAR-1853] Create a new CodeReaderFilter mechanism to prevent logic duplications between Channel(s)
http://jira.codehaus.org/browse/SONAR-1853
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java50
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/CodeReader.java12
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java10
-rw-r--r--sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java101
4 files changed, 152 insertions, 21 deletions
diff --git a/sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java b/sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java
index f726f0a9645..b4288bad3ce 100644
--- a/sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java
+++ b/sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java
@@ -19,6 +19,7 @@
*/
package org.sonar.channel;
+import java.io.FilterReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
@@ -26,8 +27,7 @@ import java.io.StringReader;
import org.apache.commons.io.IOUtils;
/**
- * The CodeBuffer class provides all the basic features required to manipulate a source code character stream.
- * Those features are :
+ * The CodeBuffer class provides all the basic features required to manipulate a source code character stream. Those features are :
* <ul>
* <li>Read and consume next source code character : pop()</li>
* <li>Retrieve last consumed character : lastChar()</li>
@@ -51,25 +51,29 @@ public class CodeBuffer implements CharSequence {
private boolean recordingMode = false;
private StringBuilder recordedCharacters = new StringBuilder();
- public CodeBuffer(Reader code) {
- this(code, DEFAULT_BUFFER_CAPACITY);
+ public CodeBuffer(Reader code, CodeReaderFilter... codeReaderFilters) {
+ this(code, DEFAULT_BUFFER_CAPACITY, codeReaderFilters);
}
- private CodeBuffer(Reader code, int bufferCapacity) {
- this.code = code;
+ private CodeBuffer(Reader initialCodeReader, int bufferCapacity, CodeReaderFilter... codeReaderFilters) {
lastChar = -1;
cursor = new Cursor();
this.bufferCapacity = bufferCapacity;
buffer = new char[bufferCapacity];
+ Reader reader = initialCodeReader;
+ for (CodeReaderFilter codeReaderFilter : codeReaderFilters) {
+ reader = new Filter(reader, codeReaderFilter);
+ }
+ this.code = reader;
fillBuffer();
}
- public CodeBuffer(String code) {
- this(new StringReader(code));
+ public CodeBuffer(String code, CodeReaderFilter... codeReaderFilters) {
+ this(new StringReader(code), codeReaderFilters);
}
- protected CodeBuffer(String code, int bufferCapacity) {
- this(new StringReader(code), bufferCapacity);
+ protected CodeBuffer(String code, int bufferCapacity, CodeReaderFilter... codeReaderFilters) {
+ this(new StringReader(code), bufferCapacity, codeReaderFilters);
}
/**
@@ -248,4 +252,30 @@ public class CodeBuffer implements CharSequence {
return clone;
}
}
+
+ final class Filter extends FilterReader {
+
+ private CodeReaderFilter codeReaderFilter;
+
+ public Filter(Reader in, CodeReaderFilter codeReaderFilter) {
+ super(in);
+ this.codeReaderFilter = codeReaderFilter;
+ }
+
+ @Override
+ public int read() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ return codeReaderFilter.read(in, cbuf, off, len);
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ }
}
diff --git a/sonar-channel/src/main/java/org/sonar/channel/CodeReader.java b/sonar-channel/src/main/java/org/sonar/channel/CodeReader.java
index f894ca7fd15..e597385d387 100644
--- a/sonar-channel/src/main/java/org/sonar/channel/CodeReader.java
+++ b/sonar-channel/src/main/java/org/sonar/channel/CodeReader.java
@@ -34,16 +34,16 @@ public class CodeReader extends CodeBuffer {
private Cursor previousCursor;
- public CodeReader(Reader code) {
- super(code);
+ public CodeReader(Reader code, CodeReaderFilter... codeReaderFilters) {
+ super(code, codeReaderFilters);
}
- public CodeReader(String code) {
- super(code);
+ public CodeReader(String code, CodeReaderFilter... codeReaderFilters) {
+ super(code, codeReaderFilters);
}
- protected CodeReader(String code, int bufferCapacity) {
- super(code, bufferCapacity);
+ protected CodeReader(String code, int bufferCapacity, CodeReaderFilter... codeReaderFilters) {
+ super(code, bufferCapacity, codeReaderFilters);
}
/**
diff --git a/sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java b/sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java
new file mode 100644
index 00000000000..e65136106b6
--- /dev/null
+++ b/sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java
@@ -0,0 +1,10 @@
+package org.sonar.channel;
+
+import java.io.IOException;
+import java.io.Reader;
+
+public abstract class CodeReaderFilter {
+
+ public abstract int read(Reader in, char[] cbuf, int off, int len) throws IOException;
+
+}
diff --git a/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java b/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java
index eedf28ae0ad..05ac7704804 100644
--- a/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java
+++ b/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java
@@ -23,6 +23,10 @@ import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.regex.Pattern;
+
import org.junit.Test;
public class CodeBufferTest {
@@ -48,7 +52,7 @@ public class CodeBufferTest {
@Test
public void testLastCharacter() {
- CodeReader reader = new CodeReader("bar");
+ CodeBuffer reader = new CodeBuffer("bar");
assertThat(reader.lastChar(), is( -1));
reader.pop();
assertThat((char) reader.lastChar(), is('b'));
@@ -56,7 +60,7 @@ public class CodeBufferTest {
@Test
public void testGetColumnAndLinePosition() {
- CodeReader reader = new CodeReader("pa\nc\r\ns\r\n\r\n");
+ CodeBuffer reader = new CodeBuffer("pa\nc\r\ns\r\n\r\n");
assertThat(reader.getColumnPosition(), is(0));
assertThat(reader.getLinePosition(), is(1));
reader.pop(); // p
@@ -92,7 +96,7 @@ public class CodeBufferTest {
@Test
public void testStartAndStopRecording() {
- CodeReader reader = new CodeReader("123456");
+ CodeBuffer reader = new CodeBuffer("123456");
reader.pop();
assertEquals("", reader.stopRecording().toString());
@@ -106,14 +110,101 @@ public class CodeBufferTest {
@Test
public void testCharAt() {
- CodeReader reader = new CodeReader("123456");
+ CodeBuffer reader = new CodeBuffer("123456");
assertEquals('1', reader.charAt(0));
assertEquals('6', reader.charAt(5));
}
@Test
public void testCharAtIndexOutOfBoundsException() {
- CodeReader reader = new CodeReader("12345");
+ CodeBuffer reader = new CodeBuffer("12345");
assertEquals(reader.charAt(5), (char) -1);
}
+
+ @Test
+ public void testCodeReaderFilter() throws Exception {
+ CodeBuffer code = new CodeBuffer("abcd12efgh34", new ReplaceNumbersFilter());
+ // test #charAt
+ assertEquals('a', code.charAt(0));
+ assertEquals('-', code.charAt(4));
+ assertEquals('-', code.charAt(5));
+ assertEquals('e', code.charAt(6));
+ assertEquals('-', code.charAt(10));
+ assertEquals('-', code.charAt(11));
+ // test peek and pop
+ assertThat((char) code.peek(), is('a'));
+ assertThat((char) code.pop(), is('a'));
+ assertThat((char) code.pop(), is('b'));
+ assertThat((char) code.pop(), is('c'));
+ assertThat((char) code.pop(), is('d'));
+ assertThat((char) code.peek(), is('-'));
+ assertThat((char) code.pop(), is('-'));
+ assertThat((char) code.pop(), is('-'));
+ assertThat((char) code.pop(), is('e'));
+ assertThat((char) code.pop(), is('f'));
+ assertThat((char) code.pop(), is('g'));
+ assertThat((char) code.pop(), is('h'));
+ assertThat((char) code.pop(), is('-'));
+ assertThat((char) code.pop(), is('-'));
+ }
+
+ @Test
+ public void testSeveralCodeReaderFilter() throws Exception {
+ CodeBuffer code = new CodeBuffer("abcd12efgh34", new ReplaceNumbersFilter(), new ReplaceCharFilter());
+ // test #charAt
+ assertEquals('*', code.charAt(0));
+ assertEquals('-', code.charAt(4));
+ assertEquals('-', code.charAt(5));
+ assertEquals('*', code.charAt(6));
+ assertEquals('-', code.charAt(10));
+ assertEquals('-', code.charAt(11));
+ // test peek and pop
+ assertThat((char) code.peek(), is('*'));
+ assertThat((char) code.pop(), is('*'));
+ assertThat((char) code.pop(), is('*'));
+ assertThat((char) code.pop(), is('*'));
+ assertThat((char) code.pop(), is('*'));
+ assertThat((char) code.peek(), is('-'));
+ assertThat((char) code.pop(), is('-'));
+ assertThat((char) code.pop(), is('-'));
+ assertThat((char) code.pop(), is('*'));
+ assertThat((char) code.pop(), is('*'));
+ assertThat((char) code.pop(), is('*'));
+ assertThat((char) code.pop(), is('*'));
+ assertThat((char) code.pop(), is('-'));
+ assertThat((char) code.pop(), is('-'));
+ }
+
+ class ReplaceNumbersFilter extends CodeReaderFilter {
+
+ private Pattern pattern = Pattern.compile("\\d");
+ private String REPLACEMENT = "-";
+
+ public int read(Reader in, char[] cbuf, int off, int len) throws IOException {
+ char[] tempBuffer = new char[cbuf.length];
+ int charCount = in.read(tempBuffer, off, len);
+ if (charCount != -1) {
+ String filteredString = pattern.matcher(new String(tempBuffer)).replaceAll(REPLACEMENT);
+ System.arraycopy(filteredString.toCharArray(), 0, cbuf, 0, tempBuffer.length);
+ }
+ return charCount;
+ }
+ }
+
+ class ReplaceCharFilter extends CodeReaderFilter {
+
+ private Pattern pattern = Pattern.compile("[a-zA-Z]");
+ private String REPLACEMENT = "*";
+
+ public int read(Reader in, char[] cbuf, int off, int len) throws IOException {
+ char[] tempBuffer = new char[cbuf.length];
+ int charCount = in.read(tempBuffer, off, len);
+ if (charCount != -1) {
+ String filteredString = pattern.matcher(new String(tempBuffer)).replaceAll(REPLACEMENT);
+ System.arraycopy(filteredString.toCharArray(), 0, cbuf, 0, tempBuffer.length);
+ }
+ return charCount;
+ }
+ }
+
}