aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2014-03-14 22:13:57 +0100
committerSimon Brandhof <simon.brandhof@gmail.com>2014-03-14 22:13:57 +0100
commitbeaaed4bc33977b4c61013a553563758eeff35c4 (patch)
treec59a8b972c34bde84a69895acde9d34fda73949a
parent9509868d743145761211e1ce74c26f01057cc67f (diff)
downloadsonarqube-beaaed4bc33977b4c61013a553563758eeff35c4.tar.gz
sonarqube-beaaed4bc33977b4c61013a553563758eeff35c4.zip
SONAR-5128 Package a release version of sonar-channel
-rw-r--r--pom.xml3
-rw-r--r--sonar-channel/pom.xml38
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/Channel.java35
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/ChannelCodeReaderFilter.java99
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/ChannelDispatcher.java141
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/ChannelException.java36
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java267
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/CodeReader.java209
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/CodeReaderConfiguration.java108
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java131
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/EndMatcher.java25
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/RegexChannel.java64
-rw-r--r--sonar-channel/src/main/java/org/sonar/channel/package-info.java41
-rw-r--r--sonar-channel/src/test/java/org/sonar/channel/ChannelDispatcherTest.java71
-rw-r--r--sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java327
-rw-r--r--sonar-channel/src/test/java/org/sonar/channel/CodeReaderTest.java131
-rw-r--r--sonar-channel/src/test/java/org/sonar/channel/RegexChannelTest.java85
-rw-r--r--sonar-testing-harness/pom.xml1
-rw-r--r--sonar-testing-harness/src/test/java/org/sonar/test/channel/ChannelMatchersTest.java63
19 files changed, 1 insertions, 1874 deletions
diff --git a/pom.xml b/pom.xml
index eaa1ab0a8d6..70ef07f750b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,7 +16,6 @@
<module>sonar-application</module>
<module>sonar-batch</module>
<module>sonar-batch-maven-compat</module>
- <module>sonar-channel</module>
<module>sonar-check-api</module>
<module>sonar-colorizer</module>
<module>sonar-core</module>
@@ -528,7 +527,7 @@
<dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-channel</artifactId>
- <version>${project.version}</version>
+ <version>4.2-RC3</version>
</dependency>
<dependency>
<groupId>org.codehaus.sonar</groupId>
diff --git a/sonar-channel/pom.xml b/sonar-channel/pom.xml
deleted file mode 100644
index 8b25ca1e341..00000000000
--- a/sonar-channel/pom.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.codehaus.sonar</groupId>
- <artifactId>sonar</artifactId>
- <version>4.3-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
-
- <artifactId>sonar-channel</artifactId>
-
- <name>SonarQube :: Channel</name>
- <description>Code Channel</description>
-
- <dependencies>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-all</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/sonar-channel/src/main/java/org/sonar/channel/Channel.java b/sonar-channel/src/main/java/org/sonar/channel/Channel.java
deleted file mode 100644
index a88a55130f4..00000000000
--- a/sonar-channel/src/main/java/org/sonar/channel/Channel.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-public abstract class Channel<O> {
-
- /**
- * Tries to consume the character stream at the current reading cursor position (provided by the {@link org.sonar.channel.CodeReader}). If
- * the character stream is consumed the method must return true and the OUTPUT object can be fed.
- *
- * @param code
- * the handle on the input character stream
- * @param output
- * the OUTPUT that can be optionally fed by the Channel
- * @return false if the Channel doesn't want to consume the character stream, true otherwise.
- */
- public abstract boolean consume(CodeReader code, O output);
-}
diff --git a/sonar-channel/src/main/java/org/sonar/channel/ChannelCodeReaderFilter.java b/sonar-channel/src/main/java/org/sonar/channel/ChannelCodeReaderFilter.java
deleted file mode 100644
index 8db1236b6ca..00000000000
--- a/sonar-channel/src/main/java/org/sonar/channel/ChannelCodeReaderFilter.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-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<O> extends CodeReaderFilter<O> {
-
- @SuppressWarnings("unchecked")
- private Channel<O>[] channels = new Channel[0];
-
- private CodeReader internalCodeReader;
-
- /**
- * Creates a CodeReaderFilter that will use the provided Channels to filter the character stream it gets from its reader.
- *
- * @param channels
- * the different channels
- */
- public ChannelCodeReaderFilter(Channel<O>... channels) {
- super();
- this.channels = channels;
- }
-
- /**
- * Creates a CodeReaderFilter that will use the provided Channels to filter the character stream it gets from its reader. And optionally,
- * it can push token to the provided output object.
- *
- * @param output
- * the object that may accept tokens
- * @param channels
- * the different channels
- */
- public ChannelCodeReaderFilter(O output, Channel<O>... channels) {
- super(output);
- this.channels = channels;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setReader(Reader reader) {
- super.setReader(reader);
- internalCodeReader = new CodeReader(reader, getConfiguration());
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int read(char[] filteredBuffer, int offset, int length) throws IOException {
- if (internalCodeReader.peek() == -1) {
- return -1;
- }
- int initialOffset = offset;
- while (offset < filteredBuffer.length) {
- if (internalCodeReader.peek() == -1) {
- break;
- }
- boolean consumed = false;
- for (Channel<O> channel : channels) {
- if (channel.consume(internalCodeReader, getOutput())) {
- 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/ChannelDispatcher.java b/sonar-channel/src/main/java/org/sonar/channel/ChannelDispatcher.java
deleted file mode 100644
index ebb1f218b58..00000000000
--- a/sonar-channel/src/main/java/org/sonar/channel/ChannelDispatcher.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.channel;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ChannelDispatcher<O> extends Channel<O> {
-
- private static final Logger LOG = LoggerFactory.getLogger(ChannelDispatcher.class);
- private final boolean failIfNoChannelToConsumeOneCharacter;
-
- private final Channel<O>[] channels;
-
- /**
- * @deprecated in version 2.9. Please use the builder() method
- */
- @SuppressWarnings("rawtypes")
- @Deprecated
- public ChannelDispatcher(List<Channel> channels) {
- this(channels, false);
- }
-
- /**
- * @deprecated in version 2.9. Please use the builder() method
- */
- @SuppressWarnings("rawtypes")
- @Deprecated
- public ChannelDispatcher(Channel... channels) {
- this(Arrays.asList(channels), false);
- }
-
- /**
- * @deprecated in version 2.9. Please use the builder() method
- */
- @SuppressWarnings("rawtypes")
- @Deprecated
- public ChannelDispatcher(List<Channel> channels, boolean failIfNoChannelToConsumeOneCharacter) {
- this.channels = channels.toArray(new Channel[channels.size()]);
- this.failIfNoChannelToConsumeOneCharacter = failIfNoChannelToConsumeOneCharacter;
- }
-
- private ChannelDispatcher(Builder builder) {
- this.channels = builder.channels.toArray(new Channel[builder.channels.size()]);
- this.failIfNoChannelToConsumeOneCharacter = builder.failIfNoChannelToConsumeOneCharacter;
- }
-
- @Override
- public boolean consume(CodeReader code, O output) {
- int nextChar = code.peek();
- while (nextChar != -1) {
- boolean characterConsumed = false;
- for (Channel<O> channel : channels) {
- if (channel.consume(code, output)) {
- characterConsumed = true;
- break;
- }
- }
- if ( !characterConsumed) {
- if (LOG.isDebugEnabled() || failIfNoChannelToConsumeOneCharacter) {
- String message = "None of the channel has been able to handle character '" + (char) code.peek() + "' (decimal value "
- + code.peek() + ") at line " + code.getLinePosition() + ", column " + code.getColumnPosition();
- if (failIfNoChannelToConsumeOneCharacter) {
- throw new IllegalStateException(message);
- }
- LOG.debug(message);
- }
- code.pop();
- }
- nextChar = code.peek();
- }
- return true;
- }
-
- Channel[] getChannels() {
- return channels;
- }
-
- /**
- * Get a Builder instance to build a new ChannelDispatcher
- */
- public static Builder builder() {
- return new Builder();
- }
-
- public static final class Builder {
-
- private List<Channel> channels = new ArrayList<Channel>();
- private boolean failIfNoChannelToConsumeOneCharacter = false;
-
- private Builder() {
- }
-
- public Builder addChannel(Channel channel) {
- channels.add(channel);
- return this;
- }
-
- public Builder addChannels(Channel... c) {
- for (Channel channel : c) {
- addChannel(channel);
- }
- return this;
- }
-
- /**
- * If this option is activated, an IllegalStateException will be thrown as soon as a character won't be consumed by any channel.
- */
- public Builder failIfNoChannelToConsumeOneCharacter() {
- failIfNoChannelToConsumeOneCharacter = true;
- return this;
- }
-
- public <O> ChannelDispatcher<O> build() {
- return new ChannelDispatcher<O>(this);
- }
-
- }
-}
diff --git a/sonar-channel/src/main/java/org/sonar/channel/ChannelException.java b/sonar-channel/src/main/java/org/sonar/channel/ChannelException.java
deleted file mode 100644
index 67293e02435..00000000000
--- a/sonar-channel/src/main/java/org/sonar/channel/ChannelException.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-public class ChannelException extends RuntimeException {
-
- public ChannelException(String message, Exception cause) {
- super(message, cause);
- }
-
- public ChannelException(String message) {
- super(message);
- }
-
- public ChannelException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
diff --git a/sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java b/sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java
deleted file mode 100644
index a4ff4ba3a51..00000000000
--- a/sonar-channel/src/main/java/org/sonar/channel/CodeBuffer.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-import java.io.FilterReader;
-import java.io.IOException;
-import java.io.Reader;
-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 :
- * <ul>
- * <li>Read and consume next source code character : pop()</li>
- * <li>Retrieve last consumed character : lastChar()</li>
- * <li>Read without consuming next source code character : peek()</li>
- * <li>Read without consuming character at the specified index after the cursor</li>
- * <li>Position of the pending cursor : line and column</li>
- * </ul>
- */
-public class CodeBuffer implements CharSequence {
-
- private int lastChar = -1;
- private Cursor cursor;
- private char[] buffer;
- private int bufferPosition = 0;
- private static final char LF = '\n';
- private static final char CR = '\r';
- private int tabWidth;
-
- private boolean recordingMode = false;
- private StringBuilder recordedCharacters = new StringBuilder();
-
- protected CodeBuffer(String code, CodeReaderConfiguration configuration) {
- this(new StringReader(code), configuration);
- }
-
- /**
- * Note that this constructor will read everything from reader and will close it.
- */
- protected CodeBuffer(Reader initialCodeReader, CodeReaderConfiguration configuration) {
- Reader reader = null;
-
- try {
- lastChar = -1;
- cursor = new Cursor();
- tabWidth = configuration.getTabWidth();
-
- /* Setup the filters on the reader */
- reader = initialCodeReader;
- for (CodeReaderFilter<?> codeReaderFilter : configuration.getCodeReaderFilters()) {
- reader = new Filter(reader, codeReaderFilter, configuration);
- }
-
- buffer = IOUtils.toCharArray(reader);
- } catch (IOException e) {
- throw new ChannelException(e.getMessage(), e);
- } finally {
- IOUtils.closeQuietly(reader);
- }
- }
-
- /**
- * Read and consume the next character
- *
- * @return the next character or -1 if the end of the stream is reached
- */
- public final int pop() {
- if (bufferPosition >= buffer.length) {
- return -1;
- }
- int character = buffer[bufferPosition++];
- updateCursorPosition(character);
- if (recordingMode) {
- recordedCharacters.append((char)character);
- }
- lastChar = character;
- return character;
- }
-
- private void updateCursorPosition(int character) {
- // see Java Language Specification : http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.4
- if (character == LF || (character == CR && peek() != LF)) {
- cursor.line++;
- cursor.column = 0;
- } else if (character == '\t') {
- cursor.column += tabWidth;
- } else {
- cursor.column++;
- }
- }
-
- /**
- * Looks at the last consumed character
- *
- * @return the last character or -1 if the no character has been yet consumed
- */
- public final int lastChar() {
- return lastChar;
- }
-
- /**
- * Looks at the next character without consuming it
- *
- * @return the next character or -1 if the end of the stream has been reached
- */
- public final int peek() {
- return intAt(0);
- }
-
- /**
- * @return the current line of the cursor
- */
- public final int getLinePosition() {
- return cursor.line;
- }
-
- public final Cursor getCursor() {
- return cursor;
- }
-
- /**
- * @return the current column of the cursor
- */
- public final int getColumnPosition() {
- return cursor.column;
- }
-
- /**
- * Overrides the current column position
- */
- public final CodeBuffer setColumnPosition(int cp) {
- this.cursor.column = cp;
- return this;
- }
-
- /**
- * Overrides the current line position
- */
- public final void setLinePosition(int lp) {
- this.cursor.line = lp;
- }
-
- public final void startRecording() {
- recordingMode = true;
- }
-
- public final CharSequence stopRecording() {
- recordingMode = false;
- CharSequence result = recordedCharacters;
- recordedCharacters = new StringBuilder();
- return result;
- }
-
- /**
- * Returns the character at the specified index after the cursor without consuming it
- *
- * @param index
- * the relative index of the character to be returned
- * @return the desired character
- * @see java.lang.CharSequence#charAt(int)
- */
- public final char charAt(int index) {
- return (char)intAt(index);
- }
-
- protected final int intAt(int index) {
- if (bufferPosition + index >= buffer.length) {
- return -1;
- }
- return buffer[bufferPosition + index];
- }
-
- /**
- * Returns the relative length of the string (i.e. excluding the popped chars)
- */
- public final int length() {
- return buffer.length - bufferPosition;
- }
-
- public final CharSequence subSequence(int start, int end) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public final String toString() {
- StringBuilder result = new StringBuilder();
- result.append("CodeReader(");
- result.append("line:").append(cursor.line);
- result.append("|column:").append(cursor.column);
- result.append("|cursor value:'").append((char) peek()).append("'");
- result.append(")");
- return result.toString();
- }
-
- public final class Cursor implements Cloneable {
-
- private int line = 1;
- private int column = 0;
-
- public int getLine() {
- return line;
- }
-
- public int getColumn() {
- return column;
- }
-
- @Override
- public Cursor clone() {
- Cursor clone = new Cursor();
- clone.column = column;
- clone.line = line;
- return clone;
- }
- }
-
- /**
- * Bridge class between CodeBuffer and CodeReaderFilter
- */
- static final class Filter extends FilterReader {
-
- private CodeReaderFilter<?> codeReaderFilter;
-
- public Filter(Reader in, CodeReaderFilter<?> codeReaderFilter, CodeReaderConfiguration configuration) {
- super(in);
- this.codeReaderFilter = codeReaderFilter;
- this.codeReaderFilter.setConfiguration(configuration.cloneWithoutCodeReaderFilters());
- this.codeReaderFilter.setReader(in);
- }
-
- @Override
- public int read() throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int read(char[] cbuf, int off, int len) throws IOException {
- int read = codeReaderFilter.read(cbuf, off, len);
- return read == 0 ? -1 : read;
- }
-
- @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
deleted file mode 100644
index 5fdf1ee0a55..00000000000
--- a/sonar-channel/src/main/java/org/sonar/channel/CodeReader.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.util.regex.Matcher;
-
-/**
- * The CodeReader class provides some advanced features to read a source code. The most important one is the ability to try consuming the
- * next characters in the stream according to a regular expression.
- */
-public class CodeReader extends CodeBuffer {
-
- private Cursor previousCursor;
-
- /*
- * Constructor needed to be backward compatible (before using CodeReaderFilter)
- */
- public CodeReader(Reader code) {
- super(code, new CodeReaderConfiguration());
- }
-
- /*
- * Constructor needed to be backward compatible (before using CodeReaderFilter)
- */
- public CodeReader(String code) {
- super(code, new CodeReaderConfiguration());
- }
-
- /**
- * Creates a code reader with specific configuration parameters.
- * Note that this constructor will read everything from reader and will close it.
- *
- * @param code
- * the Reader to read code from
- * @param configuration
- * the configuration parameters
- */
- public CodeReader(Reader code, CodeReaderConfiguration configuration) {
- super(code, configuration);
- }
-
- /**
- * Creates a code reader with specific configuration parameters.
- *
- * @param code
- * the code itself
- * @param configuration
- * the configuration parameters
- */
- public CodeReader(String code, CodeReaderConfiguration configuration) {
- super(code, configuration);
- }
-
- /**
- * Read and consume the next character
- *
- * @param appendable
- * the read character is appended to appendable
- */
- public final void pop(Appendable appendable) {
- try {
- appendable.append((char) pop());
- } catch (IOException e) {
- throw new ChannelException(e.getMessage(), e);
- }
- }
-
- /**
- * Read without consuming the next characters
- *
- * @param length
- * number of character to read
- * @return array of characters
- */
- public final char[] peek(int length) {
- char[] result = new char[length];
- int index = 0;
- int nextChar = intAt(index);
- while (nextChar != -1 && index < length) {
- result[index] = (char) nextChar;
- nextChar = intAt(++index);
- }
- return result;
- }
-
- /**
- * Read without consuming the next characters until a condition is reached (EndMatcher)
- *
- * @param matcher
- * the EndMatcher used to stop the reading
- * @param appendable
- * the read characters is appended to appendable
- */
- public final void peekTo(EndMatcher matcher, Appendable appendable) {
- int index = 0;
- char nextChar = charAt(index);
- try {
- while (!matcher.match(nextChar) && nextChar != -1) {
- appendable.append(nextChar);
- nextChar = charAt(++index);
- }
- } catch (IOException e) {
- throw new ChannelException(e.getMessage(), e);
- }
- }
-
- /**
- * @deprecated in 2.2, use {@link #peekTo(EndMatcher matcher, Appendable appendable)} instead
- */
- @Deprecated
- public final String peekTo(EndMatcher matcher) {
- StringBuilder sb = new StringBuilder();
- peekTo(matcher, sb);
- return sb.toString();
- }
-
- /**
- * @deprecated in 2.2, use {@link #popTo(Matcher matcher, Appendable appendable)} instead
- */
- @Deprecated
- public final void popTo(EndMatcher matcher, Appendable appendable) {
- previousCursor = getCursor().clone();
- try {
- do {
- appendable.append((char) pop());
- } while (!matcher.match(peek()) && peek() != -1);
- } catch (IOException e) {
- throw new ChannelException(e.getMessage(), e);
- }
- }
-
- /**
- * Read and consume the next characters according to a given regular expression
- *
- * @param matcher
- * the regular expression matcher
- * @param appendable
- * the consumed characters are appended to this appendable
- * @return number of consumed characters or -1 if the next input sequence doesn't match this matcher's pattern
- */
- public final int popTo(Matcher matcher, Appendable appendable) {
- return popTo(matcher, null, appendable);
- }
-
- /**
- * Read and consume the next characters according to a given regular expression. Moreover the character sequence immediately following the
- * desired characters must also match a given regular expression.
- *
- * @param matcher
- * the Matcher used to try consuming next characters
- * @param afterMatcher
- * the Matcher used to check character sequence immediately following the consumed characters
- * @param appendable
- * the consumed characters are appended to this appendable
- * @return number of consumed characters or -1 if one of the two Matchers doesn't match
- */
- public final int popTo(Matcher matcher, Matcher afterMatcher, Appendable appendable) {
- try {
- matcher.reset(this);
- if (matcher.lookingAt()) {
- if (afterMatcher != null) {
- afterMatcher.reset(this);
- afterMatcher.region(matcher.end(), length());
- if (!afterMatcher.lookingAt()) {
- return -1;
- }
- }
- previousCursor = getCursor().clone();
- for (int i = 0; i < matcher.end(); i++) {
- appendable.append((char) pop());
- }
- return matcher.end();
- }
- } catch (StackOverflowError e) {
- throw new ChannelException("Unable to apply regular expression '" + matcher.pattern().pattern()
- + "' at line " + getCursor().getLine() + " and column " + getCursor().getColumn()
- + ", because it led to a stack overflow error."
- + " This error may be due to an inefficient use of alternations - see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507", e);
- } catch (IndexOutOfBoundsException e) {
- return -1;
- } catch (IOException e) {
- throw new ChannelException(e.getMessage(), e);
- }
- return -1;
- }
-
- public final Cursor getPreviousCursor() {
- return previousCursor;
- }
-}
diff --git a/sonar-channel/src/main/java/org/sonar/channel/CodeReaderConfiguration.java b/sonar-channel/src/main/java/org/sonar/channel/CodeReaderConfiguration.java
deleted file mode 100644
index 25fbff974b9..00000000000
--- a/sonar-channel/src/main/java/org/sonar/channel/CodeReaderConfiguration.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Configuration parameters used by a CodeReader to handle some specificities.
- */
-public class CodeReaderConfiguration {
-
- /**
- * @deprecated in 2.12, do not use anymore.
- */
- @Deprecated
- public static final int DEFAULT_BUFFER_CAPACITY = 8000;
-
- public static final int DEFAULT_TAB_WIDTH = 1;
-
- private int tabWidth = DEFAULT_TAB_WIDTH;
-
- private List<CodeReaderFilter<?>> codeReaderFilters = new ArrayList<CodeReaderFilter<?>>();
-
- /**
- * @deprecated in 2.12, do not use anymore.
- * @return the constant Integer.MAX_VALUE
- */
- @Deprecated
- public int getBufferCapacity() {
- return Integer.MAX_VALUE;
- }
-
- /**
- * @deprecated in 2.12, do not use anymore.
- * @param bufferCapacity
- * the bufferCapacity to set
- */
- @Deprecated
- public void setBufferCapacity(int bufferCapacity) {
- }
-
- /**
- * @return the tabWidth
- */
- public int getTabWidth() {
- return tabWidth;
- }
-
- /**
- * @param tabWidth
- * the tabWidth to set
- */
- public void setTabWidth(int tabWidth) {
- this.tabWidth = tabWidth;
- }
-
- /**
- * @return the codeReaderFilters
- */
- @SuppressWarnings("rawtypes")
- public CodeReaderFilter[] getCodeReaderFilters() {
- return codeReaderFilters.toArray(new CodeReaderFilter[codeReaderFilters.size()]);
- }
-
- /**
- * @param codeReaderFilters
- * the codeReaderFilters to set
- */
- public void setCodeReaderFilters(CodeReaderFilter<?>... codeReaderFilters) {
- this.codeReaderFilters = new ArrayList<CodeReaderFilter<?>>(Arrays.asList(codeReaderFilters));
- }
-
- /**
- * Adds a code reader filter
- *
- * @param codeReaderFilter
- * the codeReaderFilter to add
- */
- public void addCodeReaderFilters(CodeReaderFilter<?> codeReaderFilter) {
- this.codeReaderFilters.add(codeReaderFilter);
- }
-
- public CodeReaderConfiguration cloneWithoutCodeReaderFilters() {
- CodeReaderConfiguration clone = new CodeReaderConfiguration();
- clone.setTabWidth(tabWidth);
- return clone;
- }
-
-}
diff --git a/sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java b/sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java
deleted file mode 100644
index 676f2814606..00000000000
--- a/sonar-channel/src/main/java/org/sonar/channel/CodeReaderFilter.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-import java.io.IOException;
-import java.io.Reader;
-
-/**
- * This class can be extended to provide filtering capabilities for the CodeReader class. <br>
- * The purpose is to filter the character flow before the CodeReader class passes it to the different channels. It is possible to give
- * several filters to a CodeReader: they will be called one after another, following the declaration order in the CodeReader constructor, to
- * sequentially filter the character flow.
- *
- * @see CodeReader
- * @see CodeBufferTest#testCodeReaderFilter()
- * @see CodeBufferTest#testSeveralCodeReaderFilter()
- *
- */
-public abstract class CodeReaderFilter<O> {
-
- private Reader reader;
-
- private O output;
-
- private CodeReaderConfiguration configuration;
-
- public CodeReaderFilter() {
- }
-
- public CodeReaderFilter(O output) {
- this.output = output;
- }
-
- /**
- * 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;
- }
-
- /**
- * Returns the output object.
- *
- * @return the output
- */
- public O getOutput() {
- return output;
- }
-
- /**
- * Sets the output object
- *
- * @param output
- * the output to set
- */
- public void setOutput(O output) {
- this.output = output;
- }
-
- /**
- * Returns the configuration used for the CodeReader
- *
- * @return the configuration
- */
- public CodeReaderConfiguration getConfiguration() {
- return configuration;
- }
-
- /**
- * Sets the configuration that must be used by the CodeReader
- *
- * @param configuration
- * the configuration to set
- */
- public void setConfiguration(CodeReaderConfiguration configuration) {
- this.configuration = configuration;
- }
-
- /**
- * This method implements the filtering logic, that is:
- * <ul>
- * <li>
- * get the characters from the reader,</li>
- * <li>
- * filter the character flow (and grab more characters from the reader if the filtering removes some),</li>
- * <li>
- * and fill the given buffer to its full capacity with the filtered data.</li>
- * </ul>
- *
- * @param filteredBuffer
- * the output buffer that must contain the filtered data
- * @param offset
- * the offset to start reading from the reader
- * @param length
- * the number of characters to read from the reader
- * @return The number of characters read, or -1 if the end of the stream has been reached
- * @throws IOException
- * If an I/O error occurs
- */
- public abstract int read(char[] filteredBuffer, int offset, int length) throws IOException;
-
-}
diff --git a/sonar-channel/src/main/java/org/sonar/channel/EndMatcher.java b/sonar-channel/src/main/java/org/sonar/channel/EndMatcher.java
deleted file mode 100644
index 708da323e3b..00000000000
--- a/sonar-channel/src/main/java/org/sonar/channel/EndMatcher.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-public interface EndMatcher {
-
- boolean match(int toMatch);
-}
diff --git a/sonar-channel/src/main/java/org/sonar/channel/RegexChannel.java b/sonar-channel/src/main/java/org/sonar/channel/RegexChannel.java
deleted file mode 100644
index 8d1f80bc7ea..00000000000
--- a/sonar-channel/src/main/java/org/sonar/channel/RegexChannel.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The RegexChannel can be used to be called each time the next characters in the character stream match a regular expression
- */
-public abstract class RegexChannel<O> extends Channel<O> {
-
- private final StringBuilder tmpBuilder = new StringBuilder();
- private final Matcher matcher;
-
- /**
- * Create a RegexChannel object with the required regular expression
- *
- * @param regex
- * regular expression to be used to try matching the next characters in the stream
- */
- public RegexChannel(String regex) {
- matcher = Pattern.compile(regex).matcher("");
- }
-
- @Override
- public final boolean consume(CodeReader code, O output) {
- if (code.popTo(matcher, tmpBuilder) > 0) {
- consume(tmpBuilder, output);
- tmpBuilder.delete(0, tmpBuilder.length());
- return true;
- }
- return false;
- }
-
- /**
- * The consume method is called each time the regular expression used to create the RegexChannel object matches the next characters in the
- * character streams.
- *
- * @param token
- * the token consumed in the character stream and matching the regular expression
- * @param the
- * OUPUT object which can be optionally fed
- */
- protected abstract void consume(CharSequence token, O output);
-
-}
diff --git a/sonar-channel/src/main/java/org/sonar/channel/package-info.java b/sonar-channel/src/main/java/org/sonar/channel/package-info.java
deleted file mode 100644
index 3ce372d79b4..00000000000
--- a/sonar-channel/src/main/java/org/sonar/channel/package-info.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * Provides a basic framework to sequentially read any kind of character stream in order to feed a generic OUTPUT.
- *
- * This framework can used for instance in order to :
- * <ul>
- * <li>Create a lexer in charge to generate a list of tokens from a character stream</li>
- * <li>Create a source code syntax highligther in charge to decorate a source code with HTML tags</li>
- * <li>Create a javadoc generator</li>
- * <li>...</li>
- * </ul>
- *
- * The entry point of this framework is the {@link org.sonar.channel.ChannelDispatcher} class.
- * This class must be initialized with a {@link org.sonar.channel.CodeReader} and a list of {@link org.sonar.channel.Channel}.
- *
- * The {@link org.sonar.channel.CodeReader} encapsulates any character stream in order to provide all mechanisms to Channels
- * in order to look ahead and look behind the current reading cursor position.
- *
- * A {@link org.sonar.channel.Channel} is in charge to consume the character stream through the CodeReader in order to feed
- * the OUTPUT.
- */
-package org.sonar.channel;
-
diff --git a/sonar-channel/src/test/java/org/sonar/channel/ChannelDispatcherTest.java b/sonar-channel/src/test/java/org/sonar/channel/ChannelDispatcherTest.java
deleted file mode 100644
index 329c09841b4..00000000000
--- a/sonar-channel/src/test/java/org/sonar/channel/ChannelDispatcherTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-
-public class ChannelDispatcherTest {
-
- @Test
- public void shouldRemoveSpacesFromString() {
- ChannelDispatcher<StringBuilder> dispatcher = ChannelDispatcher.builder().addChannel(new SpaceDeletionChannel()).build();
- StringBuilder output = new StringBuilder();
- dispatcher.consume(new CodeReader("two words"), output);
- assertThat(output.toString(), is("twowords"));
- }
-
- @Test
- public void shouldAddChannels() {
- ChannelDispatcher<StringBuilder> dispatcher = ChannelDispatcher.builder().addChannels(new SpaceDeletionChannel(), new FakeChannel()).build();
- assertThat(dispatcher.getChannels().length, is(2));
- assertThat(dispatcher.getChannels()[0], is(SpaceDeletionChannel.class));
- assertThat(dispatcher.getChannels()[1], is(FakeChannel.class));
- }
-
- @Test(expected = IllegalStateException.class)
- public void shouldThrowExceptionWhenNoChannelToConsumeNextCharacter() {
- ChannelDispatcher<StringBuilder> dispatcher = ChannelDispatcher.builder().failIfNoChannelToConsumeOneCharacter().build();
- dispatcher.consume(new CodeReader("two words"), new StringBuilder());
- }
-
- private static class SpaceDeletionChannel extends Channel<StringBuilder> {
- @Override
- public boolean consume(CodeReader code, StringBuilder output) {
- if (code.peek() == ' ') {
- code.pop();
- } else {
- output.append((char) code.pop());
- }
- return true;
- }
- }
-
- private static class FakeChannel extends Channel<StringBuilder> {
- @Override
- public boolean consume(CodeReader code, StringBuilder output) {
- boolean b = true;
- return b;
- }
- }
-
-}
diff --git a/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java b/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java
deleted file mode 100644
index 4077fbad02c..00000000000
--- a/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-import static junit.framework.Assert.assertEquals;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-import java.io.IOException;
-import java.util.regex.Pattern;
-
-import org.junit.Test;
-
-public class CodeBufferTest {
-
- private CodeReaderConfiguration defaulConfiguration = new CodeReaderConfiguration();
-
- @Test
- public void testPop() {
- CodeBuffer code = new CodeBuffer("pa", defaulConfiguration);
- assertThat((char) code.pop(), is('p'));
- assertThat((char) code.pop(), is('a'));
- assertThat(code.pop(), is( -1));
- }
-
- @Test
- public void testPeek() {
- CodeBuffer code = new CodeBuffer("pa", defaulConfiguration);
- assertThat((char) code.peek(), is('p'));
- assertThat((char) code.peek(), is('p'));
- code.pop();
- assertThat((char) code.peek(), is('a'));
- code.pop();
- assertThat(code.peek(), is( -1));
- }
-
- @Test
- public void testLastCharacter() {
- CodeBuffer reader = new CodeBuffer("bar", defaulConfiguration);
- assertThat(reader.lastChar(), is( -1));
- reader.pop();
- assertThat((char) reader.lastChar(), is('b'));
- }
-
- @Test
- public void testGetColumnAndLinePosition() {
- CodeBuffer reader = new CodeBuffer("pa\nc\r\ns\r\n\r\n", defaulConfiguration);
- assertThat(reader.getColumnPosition(), is(0));
- assertThat(reader.getLinePosition(), is(1));
- reader.pop(); // p
- reader.pop(); // a
- assertThat(reader.getColumnPosition(), is(2));
- assertThat(reader.getLinePosition(), is(1));
- reader.peek(); // \n
- reader.lastChar(); // a
- assertThat(reader.getColumnPosition(), is(2));
- assertThat(reader.getLinePosition(), is(1));
- reader.pop(); // \n
- assertThat(reader.getColumnPosition(), is(0));
- assertThat(reader.getLinePosition(), is(2));
- reader.pop(); // c
- assertThat(reader.getColumnPosition(), is(1));
- assertThat(reader.getLinePosition(), is(2));
- reader.pop(); // \r
- reader.pop(); // \n
- assertThat(reader.getColumnPosition(), is(0));
- assertThat(reader.getLinePosition(), is(3));
- assertThat((char) reader.pop(), is('s'));
- reader.pop(); // \r
- assertThat(reader.getColumnPosition(), is(2));
- assertThat(reader.getLinePosition(), is(3));
- reader.pop(); // \n
- assertThat(reader.getColumnPosition(), is(0));
- assertThat(reader.getLinePosition(), is(4));
- reader.pop(); // \r
- reader.pop(); // \n
- assertThat(reader.getColumnPosition(), is(0));
- assertThat(reader.getLinePosition(), is(5));
- }
-
- @Test
- public void testStartAndStopRecording() {
- CodeBuffer reader = new CodeBuffer("123456", defaulConfiguration);
- reader.pop();
- assertEquals("", reader.stopRecording().toString());
-
- reader.startRecording();
- reader.pop();
- reader.pop();
- reader.peek();
- assertEquals("23", reader.stopRecording().toString());
- assertEquals("", reader.stopRecording().toString());
- }
-
- @Test
- public void testCharAt() {
- CodeBuffer reader = new CodeBuffer("123456", defaulConfiguration);
- assertEquals('1', reader.charAt(0));
- assertEquals('6', reader.charAt(5));
- }
-
- @Test
- public void testCharAtIndexOutOfBoundsException() {
- CodeBuffer reader = new CodeBuffer("12345", defaulConfiguration);
- assertEquals(reader.charAt(5), (char) -1);
- }
-
- @Test
- public void testReadWithSpecificTabWidth() {
- CodeReaderConfiguration configuration = new CodeReaderConfiguration();
- configuration.setTabWidth(4);
- CodeBuffer reader = new CodeBuffer("pa\n\tc", configuration);
- assertEquals('\n', reader.charAt(2));
- assertEquals('\t', reader.charAt(3));
- assertEquals('c', reader.charAt(4));
- assertThat(reader.getColumnPosition(), is(0));
- assertThat(reader.getLinePosition(), is(1));
- reader.pop(); // p
- reader.pop(); // a
- assertThat(reader.getColumnPosition(), is(2));
- assertThat(reader.getLinePosition(), is(1));
- reader.peek(); // \n
- reader.lastChar(); // a
- assertThat(reader.getColumnPosition(), is(2));
- assertThat(reader.getLinePosition(), is(1));
- reader.pop(); // \n
- assertThat(reader.getColumnPosition(), is(0));
- assertThat(reader.getLinePosition(), is(2));
- reader.pop(); // \t
- assertThat(reader.getColumnPosition(), is(4));
- assertThat(reader.getLinePosition(), is(2));
- reader.pop(); // c
- assertThat(reader.getColumnPosition(), is(5));
- assertThat(reader.getLinePosition(), is(2));
- }
-
- @Test
- public void testCodeReaderFilter() throws Exception {
- CodeReaderConfiguration configuration = new CodeReaderConfiguration();
- configuration.setCodeReaderFilters(new ReplaceNumbersFilter());
- CodeBuffer code = new CodeBuffer("abcd12efgh34", configuration);
- // 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 theLengthShouldBeTheSameThanTheStringLength() {
- String myCode = "myCode";
- assertThat(new CodeBuffer(myCode, new CodeReaderConfiguration()).length(), is(6));
- }
-
- @Test
- public void theLengthShouldDecreaseEachTimeTheInputStreamIsConsumed() {
- String myCode = "myCode";
- CodeBuffer codeBuffer = new CodeBuffer(myCode, new CodeReaderConfiguration());
- codeBuffer.pop();
- codeBuffer.pop();
- assertThat(codeBuffer.length(), is(4));
- }
-
- @Test
- public void testSeveralCodeReaderFilter() throws Exception {
- CodeReaderConfiguration configuration = new CodeReaderConfiguration();
- configuration.setCodeReaderFilters(new ReplaceNumbersFilter(), new ReplaceCharFilter());
- CodeBuffer code = new CodeBuffer("abcd12efgh34", configuration);
- // 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('-'));
- }
-
- @Test
- @SuppressWarnings({ "unchecked", "rawtypes" })
- 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
- CodeReaderConfiguration configuration = new CodeReaderConfiguration();
- configuration.setCodeReaderFilters(new ChannelCodeReaderFilter(new Object(), new WindowingChannel()));
- CodeBuffer code = new CodeBuffer("0123456789\nABCDEFGHIJ", configuration);
- // 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));
- }
-
- /**
- * Backward compatibility with a COBOL plugin: filter returns 0 instead of -1, when end of the stream has been reached.
- */
- @Test(timeout = 1000)
- public void testWrongEndOfStreamFilter() {
- CodeReaderConfiguration configuration = new CodeReaderConfiguration();
- configuration.setCodeReaderFilters(new WrongEndOfStreamFilter());
- new CodeBuffer("foo", configuration);
- }
-
- class WrongEndOfStreamFilter extends CodeReaderFilter<Object> {
- @Override
- public int read(char[] filteredBuffer, int offset, int length) throws IOException {
- return 0;
- }
- }
-
- class ReplaceNumbersFilter extends CodeReaderFilter<Object> {
-
- private Pattern pattern = Pattern.compile("\\d");
- private String REPLACEMENT = "-";
-
- @Override
- public int read(char[] cbuf, int off, int len) throws IOException {
- char[] tempBuffer = new char[cbuf.length];
- 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);
- }
- return charCount;
- }
- }
-
- class ReplaceCharFilter extends CodeReaderFilter<Object> {
-
- private Pattern pattern = Pattern.compile("[a-zA-Z]");
- private String REPLACEMENT = "*";
-
- @Override
- public int read(char[] cbuf, int off, int len) throws IOException {
- char[] tempBuffer = new char[cbuf.length];
- 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);
- }
- return charCount;
- }
- }
-
- @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;
- }
- }
-}
diff --git a/sonar-channel/src/test/java/org/sonar/channel/CodeReaderTest.java b/sonar-channel/src/test/java/org/sonar/channel/CodeReaderTest.java
deleted file mode 100644
index 21c5394961c..00000000000
--- a/sonar-channel/src/test/java/org/sonar/channel/CodeReaderTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import java.io.StringReader;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-
-public class CodeReaderTest {
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @Test
- public void testPopWithAppendable() {
- CodeReader reader = new CodeReader("package org.sonar;");
-
- StringBuilder sw = new StringBuilder();
- reader.pop(sw);
- assertEquals("p", sw.toString());
- reader.pop(sw);
- assertEquals("pa", sw.toString());
-
- }
-
- @Test
- public void testPeekACharArray() {
- CodeReader reader = new CodeReader(new StringReader("bar"));
- char[] chars = reader.peek(2);
- assertThat(chars.length, is(2));
- assertThat(chars[0], is('b'));
- assertThat(chars[1], is('a'));
- }
-
- @Test
- public void testPeekTo() {
- CodeReader reader = new CodeReader(new StringReader("package org.sonar;"));
- StringBuilder result = new StringBuilder();
- reader.peekTo(new EndMatcher() {
-
- public boolean match(int endFlag) {
- return 'r' == (char) endFlag;
- }
- }, result);
- assertEquals("package o", result.toString());
- assertThat(reader.peek(), is((int) 'p')); // never called pop()
- }
-
- @Test
- public void testPopTo() {
- CodeReader reader = new CodeReader(new StringReader("package org.sonar;"));
- StringBuilder result = new StringBuilder();
- reader.popTo(new EndMatcher() {
-
- public boolean match(int endFlag) {
- return 'r' == (char) endFlag;
- }
- }, result);
- assertThat(result.toString(), is("package o"));
- assertThat(reader.peek(), is((int) 'r'));
- CodeReader.Cursor previousCursor = reader.getPreviousCursor();
- assertThat(previousCursor.getColumn(), is(0));
- assertThat(previousCursor.getLine(), is(1));
- }
-
- @Test
- public void testPopToWithRegex() {
- CodeReader reader = new CodeReader(new StringReader("123ABC"));
- StringBuilder token = new StringBuilder();
- assertEquals(3, reader.popTo(Pattern.compile("\\d+").matcher(new String()), token));
- assertEquals("123", token.toString());
- assertEquals( -1, reader.popTo(Pattern.compile("\\d+").matcher(new String()), token));
- assertEquals(3, reader.popTo(Pattern.compile("\\w+").matcher(new String()), token));
- assertEquals("123ABC", token.toString());
- assertEquals( -1, reader.popTo(Pattern.compile("\\w+").matcher(new String()), token));
- }
-
- @Test
- public void testStackOverflowError() {
- StringBuilder sb = new StringBuilder();
- sb.append("\n");
- for (int i = 0; i < 10000; i++) {
- sb.append(Integer.toHexString(i));
- }
- CodeReader reader = new CodeReader(sb.toString());
- reader.pop();
- reader.pop();
-
- thrown.expect(ChannelException.class);
- thrown.expectMessage("Unable to apply regular expression '([a-fA-F]|\\d)+' at line 2 and column 1," +
- " because it led to a stack overflow error." +
- " This error may be due to an inefficient use of alternations - see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507");
- reader.popTo(Pattern.compile("([a-fA-F]|\\d)+").matcher(""), new StringBuilder());
- }
-
- @Test
- public void testPopToWithRegexAndFollowingMatcher() {
- Matcher digitMatcher = Pattern.compile("\\d+").matcher(new String());
- Matcher alphabeticMatcher = Pattern.compile("[a-zA-Z]").matcher(new String());
- StringBuilder token = new StringBuilder();
- assertEquals( -1, new CodeReader(new StringReader("123 ABC")).popTo(digitMatcher, alphabeticMatcher, token));
- assertEquals("", token.toString());
- assertEquals(3, new CodeReader(new StringReader("123ABC")).popTo(digitMatcher, alphabeticMatcher, token));
- assertEquals("123", token.toString());
- }
-}
diff --git a/sonar-channel/src/test/java/org/sonar/channel/RegexChannelTest.java b/sonar-channel/src/test/java/org/sonar/channel/RegexChannelTest.java
deleted file mode 100644
index 77c184e53e9..00000000000
--- a/sonar-channel/src/test/java/org/sonar/channel/RegexChannelTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.channel;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-
-public class RegexChannelTest {
-
- @Test
- public void shouldMatch() {
- ChannelDispatcher<StringBuilder> dispatcher = ChannelDispatcher.builder().addChannel(new MyWordChannel()).addChannel(new BlackholeChannel()).build();
- StringBuilder output = new StringBuilder();
- dispatcher.consume(new CodeReader("my word"), output);
- assertThat(output.toString(), is("<w>my</w> <w>word</w>"));
- }
-
- @Test
- public void shouldMatchTokenLongerThanBuffer() {
- ChannelDispatcher<StringBuilder> dispatcher = ChannelDispatcher.builder().addChannel(new MyLiteralChannel()).build();
- StringBuilder output = new StringBuilder();
-
- CodeReaderConfiguration codeReaderConfiguration = new CodeReaderConfiguration();
-
- int literalLength = 100000;
- String veryLongLiteral = String.format(String.format("%%0%dd", literalLength), 0).replace("0", "a");
-
- assertThat(veryLongLiteral.length(), is(100000));
- dispatcher.consume(new CodeReader("\">" + veryLongLiteral + "<\"", codeReaderConfiguration), output);
- assertThat(output.toString(), is("<literal>\">" + veryLongLiteral + "<\"</literal>"));
- }
-
- private static class MyLiteralChannel extends RegexChannel<StringBuilder> {
-
- public MyLiteralChannel() {
- super("\"[^\"]*+\"");
- }
-
- @Override
- protected void consume(CharSequence token, StringBuilder output) {
- output.append("<literal>" + token + "</literal>");
- }
- }
-
- private static class MyWordChannel extends RegexChannel<StringBuilder> {
-
- public MyWordChannel() {
- super("\\w++");
- }
-
- @Override
- protected void consume(CharSequence token, StringBuilder output) {
- output.append("<w>" + token + "</w>");
- }
- }
-
- private static class BlackholeChannel extends Channel<StringBuilder> {
-
- @Override
- public boolean consume(CodeReader code, StringBuilder output) {
- output.append((char) code.pop());
- return true;
- }
- }
-
-}
diff --git a/sonar-testing-harness/pom.xml b/sonar-testing-harness/pom.xml
index 5dccfccba8d..61daf832f03 100644
--- a/sonar-testing-harness/pom.xml
+++ b/sonar-testing-harness/pom.xml
@@ -36,7 +36,6 @@
<!-- used only for org.sonar.test.channel classes -->
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-channel</artifactId>
- <version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
diff --git a/sonar-testing-harness/src/test/java/org/sonar/test/channel/ChannelMatchersTest.java b/sonar-testing-harness/src/test/java/org/sonar/test/channel/ChannelMatchersTest.java
deleted file mode 100644
index d7a0a374952..00000000000
--- a/sonar-testing-harness/src/test/java/org/sonar/test/channel/ChannelMatchersTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.test.channel;
-
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.sonar.test.channel.ChannelMatchers.consume;
-import static org.sonar.test.channel.ChannelMatchers.hasNextChar;
-
-import org.junit.Test;
-import org.sonar.channel.Channel;
-import org.sonar.channel.CodeReader;
-
-public class ChannelMatchersTest {
-
- @Test
- public void testConsumeMatcher() {
- Channel<StringBuilder> numberChannel = new Channel<StringBuilder>() {
-
- @Override
- public boolean consume(CodeReader code, StringBuilder output) {
- if (Character.isDigit(code.peek())) {
- output.append((char) code.pop());
- return true;
- }
- return false;
- }
- };
- StringBuilder output = new StringBuilder();
- assertThat(numberChannel, consume("3", output));
- assertThat(output.toString(), is("3"));
- assertThat(numberChannel, consume(new CodeReader("333333"), output));
-
- output = new StringBuilder();
- assertThat(numberChannel, not(consume("n", output)));
- assertThat(output.toString(), is(""));
- assertThat(numberChannel, not(consume(new CodeReader("n"), output)));
- }
-
- @Test
- public void testHasNextChar() {
- assertThat(new CodeReader("123"), hasNextChar('1'));
- assertThat(new CodeReader("123"), not(hasNextChar('n')));
- }
-}