aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-channel
diff options
context:
space:
mode:
authorbellingard <bellingard@gmail.com>2010-10-18 15:25:51 +0000
committerbellingard <bellingard@gmail.com>2010-10-18 15:25:51 +0000
commit7877c79af7a38c21655b1ed07e226fce80d78969 (patch)
treec297bd403aacc2205caffae9792e57aaa0558a6b /sonar-channel
parent7e212fe31cf53def323428e7c7ac35938f4ca691 (diff)
downloadsonarqube-7877c79af7a38c21655b1ed07e226fce80d78969.tar.gz
sonarqube-7877c79af7a38c21655b1ed07e226fce80d78969.zip
[SONAR-1875] Improve CodeReaderFilter with channel capabilities
http://jira.codehaus.org/browse/SONAR-1875
Diffstat (limited to 'sonar-channel')
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/ChannelCodeReaderFilter.java88
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java6
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java44
-rw-r--r--sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java57
4 files changed, 186 insertions, 9 deletions
diff --git a/sonar-channel/src/main/java/org/sonar/channel/ChannelCodeReaderFilter.java b/sonar-channel/src/main/java/org/sonar/channel/ChannelCodeReaderFilter.java
new file mode 100644
index 00000000000..0834a52850e
--- /dev/null
+++ b/sonar-channel/src/main/java/org/sonar/channel/ChannelCodeReaderFilter.java
@@ -0,0 +1,88 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.channel;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * This class is a special CodeReaderFilter that uses Channels to filter the character stream before it is passed to the main channels
+ * declared for the CodeReader.
+ *
+ */
+public final class ChannelCodeReaderFilter<OUTPUT> extends CodeReaderFilter {
+
+ @SuppressWarnings("unchecked")
+ private Channel<OUTPUT>[] channels = new Channel[0];
+
+ private CodeReader internalCodeReader;
+
+ private OUTPUT output;
+
+ /**
+ * Creates a CodeReaderFilter that will use the provided Channels to filter the character stream it gets from its reader. And optionaly,
+ * it can push token to the provided output object.
+ *
+ * @param output
+ * the object that may accept tokens
+ * @param channels
+ * the different channels
+ */
+ public ChannelCodeReaderFilter(OUTPUT output, Channel<OUTPUT>... channels) {
+ super();
+ this.channels = channels;
+ this.output = output;
+ }
+
+ /**
+ * ${@inheritDoc}
+ */
+ @Override
+ public void setReader(Reader reader) {
+ super.setReader(reader);
+ internalCodeReader = new CodeReader(reader);
+ }
+
+ /**
+ * ${@inheritDoc}
+ */
+ @Override
+ public int read(char[] filteredBuffer, int offset, int lenght) throws IOException {
+ int initialOffset = offset;
+ while (offset < filteredBuffer.length) {
+ if (internalCodeReader.peek() == -1) {
+ break;
+ }
+ boolean consumed = false;
+ for (Channel<OUTPUT> channel : channels) {
+ if (channel.consume(internalCodeReader, output)) {
+ consumed = true;
+ break;
+ }
+ }
+ if ( !consumed) {
+ int charRead = internalCodeReader.pop();
+ filteredBuffer[offset++] = (char) charRead;
+ }
+ }
+ return offset - initialOffset;
+ }
+
+}
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 b4288bad3ce..fcddb8d827f 100644
--- a/sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java
+++ b/sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java
@@ -253,6 +253,9 @@ public class CodeBuffer implements CharSequence {
}
}
+ /**
+ * Bridge class between CodeBuffer and CodeReaderFilter
+ */
final class Filter extends FilterReader {
private CodeReaderFilter codeReaderFilter;
@@ -260,6 +263,7 @@ public class CodeBuffer implements CharSequence {
public Filter(Reader in, CodeReaderFilter codeReaderFilter) {
super(in);
this.codeReaderFilter = codeReaderFilter;
+ this.codeReaderFilter.setReader(in);
}
@Override
@@ -269,7 +273,7 @@ public class CodeBuffer implements CharSequence {
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
- return codeReaderFilter.read(in, cbuf, off, len);
+ return codeReaderFilter.read(cbuf, off, len);
}
@Override
diff --git a/sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java b/sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java
index 4c63bcd9f90..da5a1dcb4f3 100644
--- a/sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java
+++ b/sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java
@@ -1,3 +1,22 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
package org.sonar.channel;
import java.io.IOException;
@@ -16,6 +35,27 @@ import java.io.Reader;
*/
public abstract class CodeReaderFilter {
+ private Reader reader;
+
+ /**
+ * Returns the reader from which this class reads the character stream.
+ *
+ * @return the reader
+ */
+ public Reader getReader() {
+ return reader;
+ }
+
+ /**
+ * Sets the reader from which this class will read the character stream.
+ *
+ * @param reader
+ * the reader
+ */
+ public void setReader(Reader reader) {
+ this.reader = reader;
+ }
+
/**
* This method implements the filtering logic, that is:
* <ul>
@@ -27,8 +67,6 @@ public abstract class CodeReaderFilter {
* and fill the given buffer to its full capacity with the filtered data.</li>
* </ul>
*
- * @param reader
- * the input character flow
* @param filteredBuffer
* the output buffer that must contain the filtered data
* @param offset
@@ -39,6 +77,6 @@ public abstract class CodeReaderFilter {
* @throws IOException
* If an I/O error occurs
*/
- public abstract int read(Reader reader, char[] filteredBuffer, int offset, int lenght) throws IOException;
+ public abstract int read(char[] filteredBuffer, int offset, int lenght) 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 05ac7704804..3807951eee0 100644
--- a/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java
+++ b/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java
@@ -24,7 +24,6 @@ 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;
@@ -175,14 +174,45 @@ public class CodeBufferTest {
assertThat((char) code.pop(), is('-'));
}
+ @Test
+ public void testChannelCodeReaderFilter() throws Exception {
+ // create a windowing channel that drops the 2 first characters, keeps 6 characters and drops the rest of the line
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ CodeBuffer code = new CodeBuffer("0123456789\nABCDEFGHIJ", new ChannelCodeReaderFilter(null, new WindowingChannel()));
+ // test #charAt
+ assertEquals('2', code.charAt(0));
+ assertEquals('7', code.charAt(5));
+ assertEquals('\n', code.charAt(6));
+ assertEquals('C', code.charAt(7));
+ assertEquals('H', code.charAt(12));
+ assertEquals( -1, code.intAt(13));
+ // test peek and pop
+ assertThat((char) code.peek(), is('2'));
+ assertThat((char) code.pop(), is('2'));
+ assertThat((char) code.pop(), is('3'));
+ assertThat((char) code.pop(), is('4'));
+ assertThat((char) code.pop(), is('5'));
+ assertThat((char) code.pop(), is('6'));
+ assertThat((char) code.pop(), is('7'));// and 8 shouldn't show up
+ assertThat((char) code.pop(), is('\n'));
+ assertThat((char) code.peek(), is('C'));
+ assertThat((char) code.pop(), is('C'));
+ assertThat((char) code.pop(), is('D'));
+ 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(code.pop(), is( -1));
+ }
+
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 {
+ public int read(char[] cbuf, int off, int len) throws IOException {
char[] tempBuffer = new char[cbuf.length];
- int charCount = in.read(tempBuffer, off, len);
+ int charCount = getReader().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);
@@ -196,9 +226,9 @@ public class CodeBufferTest {
private Pattern pattern = Pattern.compile("[a-zA-Z]");
private String REPLACEMENT = "*";
- public int read(Reader in, char[] cbuf, int off, int len) throws IOException {
+ public int read(char[] cbuf, int off, int len) throws IOException {
char[] tempBuffer = new char[cbuf.length];
- int charCount = in.read(tempBuffer, off, len);
+ int charCount = getReader().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);
@@ -207,4 +237,21 @@ public class CodeBufferTest {
}
}
+ @SuppressWarnings("rawtypes")
+ class WindowingChannel extends Channel {
+
+ @Override
+ public boolean consume(CodeReader code, Object output) {
+ int columnPosition = code.getColumnPosition();
+ if (code.peek() == '\n') {
+ return false;
+ }
+ if (columnPosition < 2 || columnPosition > 7) {
+ code.pop();
+ return true;
+ }
+ return false;
+ }
+ }
+
}