]> source.dussan.org Git - sonarqube.git/commitdiff
Provide a builder to the ChannelDispatcher class and depreciate all constructors
authorFreddy Mallet <freddy.mallet@gmail.com>
Tue, 24 May 2011 14:15:25 +0000 (16:15 +0200)
committerFreddy Mallet <freddy.mallet@gmail.com>
Tue, 24 May 2011 14:15:25 +0000 (16:15 +0200)
sonar-channel/src/main/java/org/sonar/channel/ChannelDispatcher.java
sonar-channel/src/test/java/org/sonar/channel/ChannelDispatcherTest.java [new file with mode: 0644]

index dcbd5c56a7476a8cbd323012010e64fd695d2839..58b8c95afba198aa2e215a7ad09dc7ef7b78aa34 100644 (file)
@@ -20,6 +20,7 @@
 
 package org.sonar.channel;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -34,43 +35,96 @@ public class ChannelDispatcher<OUTPUT> extends Channel<OUTPUT> {
   @SuppressWarnings("rawtypes")
   private final Channel[] channels;
 
+  /**
+   * @deprecated please use the builder() method
+   */
   @SuppressWarnings("rawtypes")
+  @Deprecated
   public ChannelDispatcher(List<Channel> channels) {
     this(channels, false);
   }
 
+  /**
+   * @deprecated please use the builder() method
+   */
   @SuppressWarnings("rawtypes")
+  @Deprecated
   public ChannelDispatcher(Channel... channels) {
     this(Arrays.asList(channels), false);
   }
 
+  /**
+   * @deprecated 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;
+  }
+
   public boolean consume(CodeReader code, OUTPUT output) {
     int nextChar = code.peek();
     while (nextChar != -1) {
-      boolean channelConsumed = false;
+      boolean characterConsumed = false;
       for (Channel<OUTPUT> channel : channels) {
         if (channel.consume(code, output)) {
-          channelConsumed = true;
+          characterConsumed = true;
           break;
         }
       }
-      if ( !channelConsumed) {
-        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);
+      if ( !characterConsumed) {
+        if (logger.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);
+          }
+          logger.debug(message);
         }
-        logger.debug(message);
         code.pop();
       }
       nextChar = code.peek();
     }
     return true;
   }
+
+  /**
+   * 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;
+    }
+
+    /**
+     * 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 <OUTPUT> ChannelDispatcher<OUTPUT> build() {
+      return new ChannelDispatcher<OUTPUT>(this);
+    }
+
+  }
 }
\ No newline at end of file
diff --git a/sonar-channel/src/test/java/org/sonar/channel/ChannelDispatcherTest.java b/sonar-channel/src/test/java/org/sonar/channel/ChannelDispatcherTest.java
new file mode 100644 (file)
index 0000000..030d82f
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * 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 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(expected = IllegalStateException.class)
+  public void shouldThrowExceptionWhenNoChannelToConsumeNextCharacter() {
+    ChannelDispatcher<StringBuilder> dispatcher = ChannelDispatcher.builder().failIfNoChannelToConsumeOneCharacter().build();
+    dispatcher.consume(new CodeReader("two words"), new StringBuilder());
+  }
+
+  private 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;
+    }
+
+  }
+}