]> source.dussan.org Git - sonarqube.git/commitdiff
New WS api/rules/list for batch
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Wed, 29 Jul 2015 06:34:35 +0000 (08:34 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 30 Jul 2015 09:43:12 +0000 (11:43 +0200)
15 files changed:
server/sonar-server/src/main/gen-java/org/sonarqube/ws/Rules.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/main/java/org/sonar/server/rule/ws/ListAction.java [new file with mode: 0644]
server/sonar-server/src/main/protobuf/ws-rules.proto [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/rule/ws/ListActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWsMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/ws/DumbResponse.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/ws/TestRequest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/ws/TestResponse.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/ws/WsActionTester.java [new file with mode: 0644]
sonar-core/src/test/java/org/sonar/core/util/ProtobufJsonFormatTest.java
sonar-db/src/main/java/org/sonar/db/rule/RuleDao.java
sonar-db/src/main/java/org/sonar/db/rule/RuleMapper.java
sonar-db/src/test/java/org/sonar/db/rule/RuleDaoTest.java
sonar-db/src/test/resources/org/sonar/db/rule/RuleDaoTest/selectEnabledAndNonManual.xml [new file with mode: 0644]

diff --git a/server/sonar-server/src/main/gen-java/org/sonarqube/ws/Rules.java b/server/sonar-server/src/main/gen-java/org/sonarqube/ws/Rules.java
new file mode 100644 (file)
index 0000000..346793f
--- /dev/null
@@ -0,0 +1,1537 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: ws-rules.proto
+
+package org.sonarqube.ws;
+
+public final class Rules {
+  private Rules() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface ListResponseOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:sonarqube.ws.rules.ListResponse)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+     */
+    java.util.List<org.sonarqube.ws.Rules.ListResponse.Rule> 
+        getRulesList();
+    /**
+     * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+     */
+    org.sonarqube.ws.Rules.ListResponse.Rule getRules(int index);
+    /**
+     * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+     */
+    int getRulesCount();
+    /**
+     * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+     */
+    java.util.List<? extends org.sonarqube.ws.Rules.ListResponse.RuleOrBuilder> 
+        getRulesOrBuilderList();
+    /**
+     * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+     */
+    org.sonarqube.ws.Rules.ListResponse.RuleOrBuilder getRulesOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code sonarqube.ws.rules.ListResponse}
+   *
+   * <pre>
+   * WS api/rules/list for internal use only
+   * </pre>
+   */
+  public static final class ListResponse extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:sonarqube.ws.rules.ListResponse)
+      ListResponseOrBuilder {
+    // Use ListResponse.newBuilder() to construct.
+    private ListResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private ListResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final ListResponse defaultInstance;
+    public static ListResponse getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public ListResponse getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private ListResponse(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                rules_ = new java.util.ArrayList<org.sonarqube.ws.Rules.ListResponse.Rule>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              rules_.add(input.readMessage(org.sonarqube.ws.Rules.ListResponse.Rule.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          rules_ = java.util.Collections.unmodifiableList(rules_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.sonarqube.ws.Rules.internal_static_sonarqube_ws_rules_ListResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.sonarqube.ws.Rules.internal_static_sonarqube_ws_rules_ListResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.sonarqube.ws.Rules.ListResponse.class, org.sonarqube.ws.Rules.ListResponse.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<ListResponse> PARSER =
+        new com.google.protobuf.AbstractParser<ListResponse>() {
+      public ListResponse parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new ListResponse(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<ListResponse> getParserForType() {
+      return PARSER;
+    }
+
+    public interface RuleOrBuilder extends
+        // @@protoc_insertion_point(interface_extends:sonarqube.ws.rules.ListResponse.Rule)
+        com.google.protobuf.MessageOrBuilder {
+
+      /**
+       * <code>optional string repository = 1;</code>
+       */
+      boolean hasRepository();
+      /**
+       * <code>optional string repository = 1;</code>
+       */
+      java.lang.String getRepository();
+      /**
+       * <code>optional string repository = 1;</code>
+       */
+      com.google.protobuf.ByteString
+          getRepositoryBytes();
+
+      /**
+       * <code>optional string key = 2;</code>
+       */
+      boolean hasKey();
+      /**
+       * <code>optional string key = 2;</code>
+       */
+      java.lang.String getKey();
+      /**
+       * <code>optional string key = 2;</code>
+       */
+      com.google.protobuf.ByteString
+          getKeyBytes();
+
+      /**
+       * <code>optional string internal_key = 3;</code>
+       */
+      boolean hasInternalKey();
+      /**
+       * <code>optional string internal_key = 3;</code>
+       */
+      java.lang.String getInternalKey();
+      /**
+       * <code>optional string internal_key = 3;</code>
+       */
+      com.google.protobuf.ByteString
+          getInternalKeyBytes();
+    }
+    /**
+     * Protobuf type {@code sonarqube.ws.rules.ListResponse.Rule}
+     */
+    public static final class Rule extends
+        com.google.protobuf.GeneratedMessage implements
+        // @@protoc_insertion_point(message_implements:sonarqube.ws.rules.ListResponse.Rule)
+        RuleOrBuilder {
+      // Use Rule.newBuilder() to construct.
+      private Rule(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+        super(builder);
+        this.unknownFields = builder.getUnknownFields();
+      }
+      private Rule(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+      private static final Rule defaultInstance;
+      public static Rule getDefaultInstance() {
+        return defaultInstance;
+      }
+
+      public Rule getDefaultInstanceForType() {
+        return defaultInstance;
+      }
+
+      private final com.google.protobuf.UnknownFieldSet unknownFields;
+      @java.lang.Override
+      public final com.google.protobuf.UnknownFieldSet
+          getUnknownFields() {
+        return this.unknownFields;
+      }
+      private Rule(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        initFields();
+        int mutable_bitField0_ = 0;
+        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+            com.google.protobuf.UnknownFieldSet.newBuilder();
+        try {
+          boolean done = false;
+          while (!done) {
+            int tag = input.readTag();
+            switch (tag) {
+              case 0:
+                done = true;
+                break;
+              default: {
+                if (!parseUnknownField(input, unknownFields,
+                                       extensionRegistry, tag)) {
+                  done = true;
+                }
+                break;
+              }
+              case 10: {
+                com.google.protobuf.ByteString bs = input.readBytes();
+                bitField0_ |= 0x00000001;
+                repository_ = bs;
+                break;
+              }
+              case 18: {
+                com.google.protobuf.ByteString bs = input.readBytes();
+                bitField0_ |= 0x00000002;
+                key_ = bs;
+                break;
+              }
+              case 26: {
+                com.google.protobuf.ByteString bs = input.readBytes();
+                bitField0_ |= 0x00000004;
+                internalKey_ = bs;
+                break;
+              }
+            }
+          }
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          throw e.setUnfinishedMessage(this);
+        } catch (java.io.IOException e) {
+          throw new com.google.protobuf.InvalidProtocolBufferException(
+              e.getMessage()).setUnfinishedMessage(this);
+        } finally {
+          this.unknownFields = unknownFields.build();
+          makeExtensionsImmutable();
+        }
+      }
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.sonarqube.ws.Rules.internal_static_sonarqube_ws_rules_ListResponse_Rule_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.sonarqube.ws.Rules.internal_static_sonarqube_ws_rules_ListResponse_Rule_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.sonarqube.ws.Rules.ListResponse.Rule.class, org.sonarqube.ws.Rules.ListResponse.Rule.Builder.class);
+      }
+
+      public static com.google.protobuf.Parser<Rule> PARSER =
+          new com.google.protobuf.AbstractParser<Rule>() {
+        public Rule parsePartialFrom(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws com.google.protobuf.InvalidProtocolBufferException {
+          return new Rule(input, extensionRegistry);
+        }
+      };
+
+      @java.lang.Override
+      public com.google.protobuf.Parser<Rule> getParserForType() {
+        return PARSER;
+      }
+
+      private int bitField0_;
+      public static final int REPOSITORY_FIELD_NUMBER = 1;
+      private java.lang.Object repository_;
+      /**
+       * <code>optional string repository = 1;</code>
+       */
+      public boolean hasRepository() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional string repository = 1;</code>
+       */
+      public java.lang.String getRepository() {
+        java.lang.Object ref = repository_;
+        if (ref instanceof java.lang.String) {
+          return (java.lang.String) ref;
+        } else {
+          com.google.protobuf.ByteString bs = 
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            repository_ = s;
+          }
+          return s;
+        }
+      }
+      /**
+       * <code>optional string repository = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getRepositoryBytes() {
+        java.lang.Object ref = repository_;
+        if (ref instanceof java.lang.String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          repository_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+
+      public static final int KEY_FIELD_NUMBER = 2;
+      private java.lang.Object key_;
+      /**
+       * <code>optional string key = 2;</code>
+       */
+      public boolean hasKey() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional string key = 2;</code>
+       */
+      public java.lang.String getKey() {
+        java.lang.Object ref = key_;
+        if (ref instanceof java.lang.String) {
+          return (java.lang.String) ref;
+        } else {
+          com.google.protobuf.ByteString bs = 
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            key_ = s;
+          }
+          return s;
+        }
+      }
+      /**
+       * <code>optional string key = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getKeyBytes() {
+        java.lang.Object ref = key_;
+        if (ref instanceof java.lang.String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          key_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+
+      public static final int INTERNAL_KEY_FIELD_NUMBER = 3;
+      private java.lang.Object internalKey_;
+      /**
+       * <code>optional string internal_key = 3;</code>
+       */
+      public boolean hasInternalKey() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional string internal_key = 3;</code>
+       */
+      public java.lang.String getInternalKey() {
+        java.lang.Object ref = internalKey_;
+        if (ref instanceof java.lang.String) {
+          return (java.lang.String) ref;
+        } else {
+          com.google.protobuf.ByteString bs = 
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            internalKey_ = s;
+          }
+          return s;
+        }
+      }
+      /**
+       * <code>optional string internal_key = 3;</code>
+       */
+      public com.google.protobuf.ByteString
+          getInternalKeyBytes() {
+        java.lang.Object ref = internalKey_;
+        if (ref instanceof java.lang.String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          internalKey_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+
+      private void initFields() {
+        repository_ = "";
+        key_ = "";
+        internalKey_ = "";
+      }
+      private byte memoizedIsInitialized = -1;
+      public final boolean isInitialized() {
+        byte isInitialized = memoizedIsInitialized;
+        if (isInitialized == 1) return true;
+        if (isInitialized == 0) return false;
+
+        memoizedIsInitialized = 1;
+        return true;
+      }
+
+      public void writeTo(com.google.protobuf.CodedOutputStream output)
+                          throws java.io.IOException {
+        getSerializedSize();
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          output.writeBytes(1, getRepositoryBytes());
+        }
+        if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          output.writeBytes(2, getKeyBytes());
+        }
+        if (((bitField0_ & 0x00000004) == 0x00000004)) {
+          output.writeBytes(3, getInternalKeyBytes());
+        }
+        getUnknownFields().writeTo(output);
+      }
+
+      private int memoizedSerializedSize = -1;
+      public int getSerializedSize() {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+
+        size = 0;
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          size += com.google.protobuf.CodedOutputStream
+            .computeBytesSize(1, getRepositoryBytes());
+        }
+        if (((bitField0_ & 0x00000002) == 0x00000002)) {
+          size += com.google.protobuf.CodedOutputStream
+            .computeBytesSize(2, getKeyBytes());
+        }
+        if (((bitField0_ & 0x00000004) == 0x00000004)) {
+          size += com.google.protobuf.CodedOutputStream
+            .computeBytesSize(3, getInternalKeyBytes());
+        }
+        size += getUnknownFields().getSerializedSize();
+        memoizedSerializedSize = size;
+        return size;
+      }
+
+      private static final long serialVersionUID = 0L;
+      @java.lang.Override
+      protected java.lang.Object writeReplace()
+          throws java.io.ObjectStreamException {
+        return super.writeReplace();
+      }
+
+      public static org.sonarqube.ws.Rules.ListResponse.Rule parseFrom(
+          com.google.protobuf.ByteString data)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data);
+      }
+      public static org.sonarqube.ws.Rules.ListResponse.Rule parseFrom(
+          com.google.protobuf.ByteString data,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data, extensionRegistry);
+      }
+      public static org.sonarqube.ws.Rules.ListResponse.Rule parseFrom(byte[] data)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data);
+      }
+      public static org.sonarqube.ws.Rules.ListResponse.Rule parseFrom(
+          byte[] data,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return PARSER.parseFrom(data, extensionRegistry);
+      }
+      public static org.sonarqube.ws.Rules.ListResponse.Rule parseFrom(java.io.InputStream input)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input);
+      }
+      public static org.sonarqube.ws.Rules.ListResponse.Rule parseFrom(
+          java.io.InputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input, extensionRegistry);
+      }
+      public static org.sonarqube.ws.Rules.ListResponse.Rule parseDelimitedFrom(java.io.InputStream input)
+          throws java.io.IOException {
+        return PARSER.parseDelimitedFrom(input);
+      }
+      public static org.sonarqube.ws.Rules.ListResponse.Rule parseDelimitedFrom(
+          java.io.InputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      }
+      public static org.sonarqube.ws.Rules.ListResponse.Rule parseFrom(
+          com.google.protobuf.CodedInputStream input)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input);
+      }
+      public static org.sonarqube.ws.Rules.ListResponse.Rule parseFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        return PARSER.parseFrom(input, extensionRegistry);
+      }
+
+      public static Builder newBuilder() { return Builder.create(); }
+      public Builder newBuilderForType() { return newBuilder(); }
+      public static Builder newBuilder(org.sonarqube.ws.Rules.ListResponse.Rule prototype) {
+        return newBuilder().mergeFrom(prototype);
+      }
+      public Builder toBuilder() { return newBuilder(this); }
+
+      @java.lang.Override
+      protected Builder newBuilderForType(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        Builder builder = new Builder(parent);
+        return builder;
+      }
+      /**
+       * Protobuf type {@code sonarqube.ws.rules.ListResponse.Rule}
+       */
+      public static final class Builder extends
+          com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+          // @@protoc_insertion_point(builder_implements:sonarqube.ws.rules.ListResponse.Rule)
+          org.sonarqube.ws.Rules.ListResponse.RuleOrBuilder {
+        public static final com.google.protobuf.Descriptors.Descriptor
+            getDescriptor() {
+          return org.sonarqube.ws.Rules.internal_static_sonarqube_ws_rules_ListResponse_Rule_descriptor;
+        }
+
+        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+            internalGetFieldAccessorTable() {
+          return org.sonarqube.ws.Rules.internal_static_sonarqube_ws_rules_ListResponse_Rule_fieldAccessorTable
+              .ensureFieldAccessorsInitialized(
+                  org.sonarqube.ws.Rules.ListResponse.Rule.class, org.sonarqube.ws.Rules.ListResponse.Rule.Builder.class);
+        }
+
+        // Construct using org.sonarqube.ws.Rules.ListResponse.Rule.newBuilder()
+        private Builder() {
+          maybeForceBuilderInitialization();
+        }
+
+        private Builder(
+            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          super(parent);
+          maybeForceBuilderInitialization();
+        }
+        private void maybeForceBuilderInitialization() {
+          if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          }
+        }
+        private static Builder create() {
+          return new Builder();
+        }
+
+        public Builder clear() {
+          super.clear();
+          repository_ = "";
+          bitField0_ = (bitField0_ & ~0x00000001);
+          key_ = "";
+          bitField0_ = (bitField0_ & ~0x00000002);
+          internalKey_ = "";
+          bitField0_ = (bitField0_ & ~0x00000004);
+          return this;
+        }
+
+        public Builder clone() {
+          return create().mergeFrom(buildPartial());
+        }
+
+        public com.google.protobuf.Descriptors.Descriptor
+            getDescriptorForType() {
+          return org.sonarqube.ws.Rules.internal_static_sonarqube_ws_rules_ListResponse_Rule_descriptor;
+        }
+
+        public org.sonarqube.ws.Rules.ListResponse.Rule getDefaultInstanceForType() {
+          return org.sonarqube.ws.Rules.ListResponse.Rule.getDefaultInstance();
+        }
+
+        public org.sonarqube.ws.Rules.ListResponse.Rule build() {
+          org.sonarqube.ws.Rules.ListResponse.Rule result = buildPartial();
+          if (!result.isInitialized()) {
+            throw newUninitializedMessageException(result);
+          }
+          return result;
+        }
+
+        public org.sonarqube.ws.Rules.ListResponse.Rule buildPartial() {
+          org.sonarqube.ws.Rules.ListResponse.Rule result = new org.sonarqube.ws.Rules.ListResponse.Rule(this);
+          int from_bitField0_ = bitField0_;
+          int to_bitField0_ = 0;
+          if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+            to_bitField0_ |= 0x00000001;
+          }
+          result.repository_ = repository_;
+          if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+            to_bitField0_ |= 0x00000002;
+          }
+          result.key_ = key_;
+          if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+            to_bitField0_ |= 0x00000004;
+          }
+          result.internalKey_ = internalKey_;
+          result.bitField0_ = to_bitField0_;
+          onBuilt();
+          return result;
+        }
+
+        public Builder mergeFrom(com.google.protobuf.Message other) {
+          if (other instanceof org.sonarqube.ws.Rules.ListResponse.Rule) {
+            return mergeFrom((org.sonarqube.ws.Rules.ListResponse.Rule)other);
+          } else {
+            super.mergeFrom(other);
+            return this;
+          }
+        }
+
+        public Builder mergeFrom(org.sonarqube.ws.Rules.ListResponse.Rule other) {
+          if (other == org.sonarqube.ws.Rules.ListResponse.Rule.getDefaultInstance()) return this;
+          if (other.hasRepository()) {
+            bitField0_ |= 0x00000001;
+            repository_ = other.repository_;
+            onChanged();
+          }
+          if (other.hasKey()) {
+            bitField0_ |= 0x00000002;
+            key_ = other.key_;
+            onChanged();
+          }
+          if (other.hasInternalKey()) {
+            bitField0_ |= 0x00000004;
+            internalKey_ = other.internalKey_;
+            onChanged();
+          }
+          this.mergeUnknownFields(other.getUnknownFields());
+          return this;
+        }
+
+        public final boolean isInitialized() {
+          return true;
+        }
+
+        public Builder mergeFrom(
+            com.google.protobuf.CodedInputStream input,
+            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+            throws java.io.IOException {
+          org.sonarqube.ws.Rules.ListResponse.Rule parsedMessage = null;
+          try {
+            parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+            parsedMessage = (org.sonarqube.ws.Rules.ListResponse.Rule) e.getUnfinishedMessage();
+            throw e;
+          } finally {
+            if (parsedMessage != null) {
+              mergeFrom(parsedMessage);
+            }
+          }
+          return this;
+        }
+        private int bitField0_;
+
+        private java.lang.Object repository_ = "";
+        /**
+         * <code>optional string repository = 1;</code>
+         */
+        public boolean hasRepository() {
+          return ((bitField0_ & 0x00000001) == 0x00000001);
+        }
+        /**
+         * <code>optional string repository = 1;</code>
+         */
+        public java.lang.String getRepository() {
+          java.lang.Object ref = repository_;
+          if (!(ref instanceof java.lang.String)) {
+            com.google.protobuf.ByteString bs =
+                (com.google.protobuf.ByteString) ref;
+            java.lang.String s = bs.toStringUtf8();
+            if (bs.isValidUtf8()) {
+              repository_ = s;
+            }
+            return s;
+          } else {
+            return (java.lang.String) ref;
+          }
+        }
+        /**
+         * <code>optional string repository = 1;</code>
+         */
+        public com.google.protobuf.ByteString
+            getRepositoryBytes() {
+          java.lang.Object ref = repository_;
+          if (ref instanceof String) {
+            com.google.protobuf.ByteString b = 
+                com.google.protobuf.ByteString.copyFromUtf8(
+                    (java.lang.String) ref);
+            repository_ = b;
+            return b;
+          } else {
+            return (com.google.protobuf.ByteString) ref;
+          }
+        }
+        /**
+         * <code>optional string repository = 1;</code>
+         */
+        public Builder setRepository(
+            java.lang.String value) {
+          if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+          repository_ = value;
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional string repository = 1;</code>
+         */
+        public Builder clearRepository() {
+          bitField0_ = (bitField0_ & ~0x00000001);
+          repository_ = getDefaultInstance().getRepository();
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional string repository = 1;</code>
+         */
+        public Builder setRepositoryBytes(
+            com.google.protobuf.ByteString value) {
+          if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+          repository_ = value;
+          onChanged();
+          return this;
+        }
+
+        private java.lang.Object key_ = "";
+        /**
+         * <code>optional string key = 2;</code>
+         */
+        public boolean hasKey() {
+          return ((bitField0_ & 0x00000002) == 0x00000002);
+        }
+        /**
+         * <code>optional string key = 2;</code>
+         */
+        public java.lang.String getKey() {
+          java.lang.Object ref = key_;
+          if (!(ref instanceof java.lang.String)) {
+            com.google.protobuf.ByteString bs =
+                (com.google.protobuf.ByteString) ref;
+            java.lang.String s = bs.toStringUtf8();
+            if (bs.isValidUtf8()) {
+              key_ = s;
+            }
+            return s;
+          } else {
+            return (java.lang.String) ref;
+          }
+        }
+        /**
+         * <code>optional string key = 2;</code>
+         */
+        public com.google.protobuf.ByteString
+            getKeyBytes() {
+          java.lang.Object ref = key_;
+          if (ref instanceof String) {
+            com.google.protobuf.ByteString b = 
+                com.google.protobuf.ByteString.copyFromUtf8(
+                    (java.lang.String) ref);
+            key_ = b;
+            return b;
+          } else {
+            return (com.google.protobuf.ByteString) ref;
+          }
+        }
+        /**
+         * <code>optional string key = 2;</code>
+         */
+        public Builder setKey(
+            java.lang.String value) {
+          if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+          key_ = value;
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional string key = 2;</code>
+         */
+        public Builder clearKey() {
+          bitField0_ = (bitField0_ & ~0x00000002);
+          key_ = getDefaultInstance().getKey();
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional string key = 2;</code>
+         */
+        public Builder setKeyBytes(
+            com.google.protobuf.ByteString value) {
+          if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+          key_ = value;
+          onChanged();
+          return this;
+        }
+
+        private java.lang.Object internalKey_ = "";
+        /**
+         * <code>optional string internal_key = 3;</code>
+         */
+        public boolean hasInternalKey() {
+          return ((bitField0_ & 0x00000004) == 0x00000004);
+        }
+        /**
+         * <code>optional string internal_key = 3;</code>
+         */
+        public java.lang.String getInternalKey() {
+          java.lang.Object ref = internalKey_;
+          if (!(ref instanceof java.lang.String)) {
+            com.google.protobuf.ByteString bs =
+                (com.google.protobuf.ByteString) ref;
+            java.lang.String s = bs.toStringUtf8();
+            if (bs.isValidUtf8()) {
+              internalKey_ = s;
+            }
+            return s;
+          } else {
+            return (java.lang.String) ref;
+          }
+        }
+        /**
+         * <code>optional string internal_key = 3;</code>
+         */
+        public com.google.protobuf.ByteString
+            getInternalKeyBytes() {
+          java.lang.Object ref = internalKey_;
+          if (ref instanceof String) {
+            com.google.protobuf.ByteString b = 
+                com.google.protobuf.ByteString.copyFromUtf8(
+                    (java.lang.String) ref);
+            internalKey_ = b;
+            return b;
+          } else {
+            return (com.google.protobuf.ByteString) ref;
+          }
+        }
+        /**
+         * <code>optional string internal_key = 3;</code>
+         */
+        public Builder setInternalKey(
+            java.lang.String value) {
+          if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+          internalKey_ = value;
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional string internal_key = 3;</code>
+         */
+        public Builder clearInternalKey() {
+          bitField0_ = (bitField0_ & ~0x00000004);
+          internalKey_ = getDefaultInstance().getInternalKey();
+          onChanged();
+          return this;
+        }
+        /**
+         * <code>optional string internal_key = 3;</code>
+         */
+        public Builder setInternalKeyBytes(
+            com.google.protobuf.ByteString value) {
+          if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+          internalKey_ = value;
+          onChanged();
+          return this;
+        }
+
+        // @@protoc_insertion_point(builder_scope:sonarqube.ws.rules.ListResponse.Rule)
+      }
+
+      static {
+        defaultInstance = new Rule(true);
+        defaultInstance.initFields();
+      }
+
+      // @@protoc_insertion_point(class_scope:sonarqube.ws.rules.ListResponse.Rule)
+    }
+
+    public static final int RULES_FIELD_NUMBER = 1;
+    private java.util.List<org.sonarqube.ws.Rules.ListResponse.Rule> rules_;
+    /**
+     * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+     */
+    public java.util.List<org.sonarqube.ws.Rules.ListResponse.Rule> getRulesList() {
+      return rules_;
+    }
+    /**
+     * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+     */
+    public java.util.List<? extends org.sonarqube.ws.Rules.ListResponse.RuleOrBuilder> 
+        getRulesOrBuilderList() {
+      return rules_;
+    }
+    /**
+     * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+     */
+    public int getRulesCount() {
+      return rules_.size();
+    }
+    /**
+     * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+     */
+    public org.sonarqube.ws.Rules.ListResponse.Rule getRules(int index) {
+      return rules_.get(index);
+    }
+    /**
+     * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+     */
+    public org.sonarqube.ws.Rules.ListResponse.RuleOrBuilder getRulesOrBuilder(
+        int index) {
+      return rules_.get(index);
+    }
+
+    private void initFields() {
+      rules_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < rules_.size(); i++) {
+        output.writeMessage(1, rules_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < rules_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, rules_.get(i));
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static org.sonarqube.ws.Rules.ListResponse parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.sonarqube.ws.Rules.ListResponse parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.sonarqube.ws.Rules.ListResponse parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.sonarqube.ws.Rules.ListResponse parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.sonarqube.ws.Rules.ListResponse parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.sonarqube.ws.Rules.ListResponse parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.sonarqube.ws.Rules.ListResponse parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.sonarqube.ws.Rules.ListResponse parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.sonarqube.ws.Rules.ListResponse parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.sonarqube.ws.Rules.ListResponse parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.sonarqube.ws.Rules.ListResponse prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code sonarqube.ws.rules.ListResponse}
+     *
+     * <pre>
+     * WS api/rules/list for internal use only
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:sonarqube.ws.rules.ListResponse)
+        org.sonarqube.ws.Rules.ListResponseOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.sonarqube.ws.Rules.internal_static_sonarqube_ws_rules_ListResponse_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.sonarqube.ws.Rules.internal_static_sonarqube_ws_rules_ListResponse_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.sonarqube.ws.Rules.ListResponse.class, org.sonarqube.ws.Rules.ListResponse.Builder.class);
+      }
+
+      // Construct using org.sonarqube.ws.Rules.ListResponse.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getRulesFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (rulesBuilder_ == null) {
+          rules_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          rulesBuilder_.clear();
+        }
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.sonarqube.ws.Rules.internal_static_sonarqube_ws_rules_ListResponse_descriptor;
+      }
+
+      public org.sonarqube.ws.Rules.ListResponse getDefaultInstanceForType() {
+        return org.sonarqube.ws.Rules.ListResponse.getDefaultInstance();
+      }
+
+      public org.sonarqube.ws.Rules.ListResponse build() {
+        org.sonarqube.ws.Rules.ListResponse result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.sonarqube.ws.Rules.ListResponse buildPartial() {
+        org.sonarqube.ws.Rules.ListResponse result = new org.sonarqube.ws.Rules.ListResponse(this);
+        int from_bitField0_ = bitField0_;
+        if (rulesBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            rules_ = java.util.Collections.unmodifiableList(rules_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.rules_ = rules_;
+        } else {
+          result.rules_ = rulesBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.sonarqube.ws.Rules.ListResponse) {
+          return mergeFrom((org.sonarqube.ws.Rules.ListResponse)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.sonarqube.ws.Rules.ListResponse other) {
+        if (other == org.sonarqube.ws.Rules.ListResponse.getDefaultInstance()) return this;
+        if (rulesBuilder_ == null) {
+          if (!other.rules_.isEmpty()) {
+            if (rules_.isEmpty()) {
+              rules_ = other.rules_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureRulesIsMutable();
+              rules_.addAll(other.rules_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.rules_.isEmpty()) {
+            if (rulesBuilder_.isEmpty()) {
+              rulesBuilder_.dispose();
+              rulesBuilder_ = null;
+              rules_ = other.rules_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              rulesBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getRulesFieldBuilder() : null;
+            } else {
+              rulesBuilder_.addAllMessages(other.rules_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.sonarqube.ws.Rules.ListResponse parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.sonarqube.ws.Rules.ListResponse) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.util.List<org.sonarqube.ws.Rules.ListResponse.Rule> rules_ =
+        java.util.Collections.emptyList();
+      private void ensureRulesIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          rules_ = new java.util.ArrayList<org.sonarqube.ws.Rules.ListResponse.Rule>(rules_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.sonarqube.ws.Rules.ListResponse.Rule, org.sonarqube.ws.Rules.ListResponse.Rule.Builder, org.sonarqube.ws.Rules.ListResponse.RuleOrBuilder> rulesBuilder_;
+
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public java.util.List<org.sonarqube.ws.Rules.ListResponse.Rule> getRulesList() {
+        if (rulesBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(rules_);
+        } else {
+          return rulesBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public int getRulesCount() {
+        if (rulesBuilder_ == null) {
+          return rules_.size();
+        } else {
+          return rulesBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public org.sonarqube.ws.Rules.ListResponse.Rule getRules(int index) {
+        if (rulesBuilder_ == null) {
+          return rules_.get(index);
+        } else {
+          return rulesBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public Builder setRules(
+          int index, org.sonarqube.ws.Rules.ListResponse.Rule value) {
+        if (rulesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureRulesIsMutable();
+          rules_.set(index, value);
+          onChanged();
+        } else {
+          rulesBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public Builder setRules(
+          int index, org.sonarqube.ws.Rules.ListResponse.Rule.Builder builderForValue) {
+        if (rulesBuilder_ == null) {
+          ensureRulesIsMutable();
+          rules_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          rulesBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public Builder addRules(org.sonarqube.ws.Rules.ListResponse.Rule value) {
+        if (rulesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureRulesIsMutable();
+          rules_.add(value);
+          onChanged();
+        } else {
+          rulesBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public Builder addRules(
+          int index, org.sonarqube.ws.Rules.ListResponse.Rule value) {
+        if (rulesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureRulesIsMutable();
+          rules_.add(index, value);
+          onChanged();
+        } else {
+          rulesBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public Builder addRules(
+          org.sonarqube.ws.Rules.ListResponse.Rule.Builder builderForValue) {
+        if (rulesBuilder_ == null) {
+          ensureRulesIsMutable();
+          rules_.add(builderForValue.build());
+          onChanged();
+        } else {
+          rulesBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public Builder addRules(
+          int index, org.sonarqube.ws.Rules.ListResponse.Rule.Builder builderForValue) {
+        if (rulesBuilder_ == null) {
+          ensureRulesIsMutable();
+          rules_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          rulesBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public Builder addAllRules(
+          java.lang.Iterable<? extends org.sonarqube.ws.Rules.ListResponse.Rule> values) {
+        if (rulesBuilder_ == null) {
+          ensureRulesIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, rules_);
+          onChanged();
+        } else {
+          rulesBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public Builder clearRules() {
+        if (rulesBuilder_ == null) {
+          rules_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          rulesBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public Builder removeRules(int index) {
+        if (rulesBuilder_ == null) {
+          ensureRulesIsMutable();
+          rules_.remove(index);
+          onChanged();
+        } else {
+          rulesBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public org.sonarqube.ws.Rules.ListResponse.Rule.Builder getRulesBuilder(
+          int index) {
+        return getRulesFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public org.sonarqube.ws.Rules.ListResponse.RuleOrBuilder getRulesOrBuilder(
+          int index) {
+        if (rulesBuilder_ == null) {
+          return rules_.get(index);  } else {
+          return rulesBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public java.util.List<? extends org.sonarqube.ws.Rules.ListResponse.RuleOrBuilder> 
+           getRulesOrBuilderList() {
+        if (rulesBuilder_ != null) {
+          return rulesBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(rules_);
+        }
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public org.sonarqube.ws.Rules.ListResponse.Rule.Builder addRulesBuilder() {
+        return getRulesFieldBuilder().addBuilder(
+            org.sonarqube.ws.Rules.ListResponse.Rule.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public org.sonarqube.ws.Rules.ListResponse.Rule.Builder addRulesBuilder(
+          int index) {
+        return getRulesFieldBuilder().addBuilder(
+            index, org.sonarqube.ws.Rules.ListResponse.Rule.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .sonarqube.ws.rules.ListResponse.Rule rules = 1;</code>
+       */
+      public java.util.List<org.sonarqube.ws.Rules.ListResponse.Rule.Builder> 
+           getRulesBuilderList() {
+        return getRulesFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.sonarqube.ws.Rules.ListResponse.Rule, org.sonarqube.ws.Rules.ListResponse.Rule.Builder, org.sonarqube.ws.Rules.ListResponse.RuleOrBuilder> 
+          getRulesFieldBuilder() {
+        if (rulesBuilder_ == null) {
+          rulesBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.sonarqube.ws.Rules.ListResponse.Rule, org.sonarqube.ws.Rules.ListResponse.Rule.Builder, org.sonarqube.ws.Rules.ListResponse.RuleOrBuilder>(
+                  rules_,
+                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  getParentForChildren(),
+                  isClean());
+          rules_ = null;
+        }
+        return rulesBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:sonarqube.ws.rules.ListResponse)
+    }
+
+    static {
+      defaultInstance = new ListResponse(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:sonarqube.ws.rules.ListResponse)
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_sonarqube_ws_rules_ListResponse_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_sonarqube_ws_rules_ListResponse_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_sonarqube_ws_rules_ListResponse_Rule_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_sonarqube_ws_rules_ListResponse_Rule_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\016ws-rules.proto\022\022sonarqube.ws.rules\"\203\001\n" +
+      "\014ListResponse\0224\n\005rules\030\001 \003(\0132%.sonarqube" +
+      ".ws.rules.ListResponse.Rule\032=\n\004Rule\022\022\n\nr" +
+      "epository\030\001 \001(\t\022\013\n\003key\030\002 \001(\t\022\024\n\014internal" +
+      "_key\030\003 \001(\tB\033\n\020org.sonarqube.wsB\005RulesH\001"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+    internal_static_sonarqube_ws_rules_ListResponse_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_sonarqube_ws_rules_ListResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_sonarqube_ws_rules_ListResponse_descriptor,
+        new java.lang.String[] { "Rules", });
+    internal_static_sonarqube_ws_rules_ListResponse_Rule_descriptor =
+      internal_static_sonarqube_ws_rules_ListResponse_descriptor.getNestedTypes().get(0);
+    internal_static_sonarqube_ws_rules_ListResponse_Rule_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_sonarqube_ws_rules_ListResponse_Rule_descriptor,
+        new java.lang.String[] { "Repository", "Key", "InternalKey", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
index c7159655879df0588331cf08a879cf87b347cae3..3e942619cdda98fc97486d1ca349ccf8d0e9443e 100644 (file)
@@ -463,6 +463,7 @@ public class PlatformLevel4 extends PlatformLevel {
       org.sonar.server.rule.ws.ShowAction.class,
       org.sonar.server.rule.ws.CreateAction.class,
       org.sonar.server.rule.ws.DeleteAction.class,
+      org.sonar.server.rule.ws.ListAction.class,
       TagsAction.class,
       RuleMapping.class,
       ActiveRuleCompleter.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/ListAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/ListAction.java
new file mode 100644 (file)
index 0000000..52be58c
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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.server.rule.ws;
+
+import com.google.common.base.Strings;
+import org.apache.ibatis.session.ResultContext;
+import org.apache.ibatis.session.ResultHandler;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.rule.RuleDto;
+import org.sonar.server.plugins.MimeTypes;
+import org.sonarqube.ws.Rules.ListResponse;
+
+public class ListAction implements RulesWsAction {
+
+  private final DbClient dbClient;
+
+  public ListAction(DbClient dbClient) {
+    this.dbClient = dbClient;
+  }
+
+  @Override
+  public void define(WebService.NewController controller) {
+    controller
+      .createAction("list")
+      .setDescription("List of rules, excluding the manual rules and the rules with status REMOVED. JSON format is not supported for response.")
+      .setSince("5.2")
+      .setInternal(true)
+      .setHandler(this);
+  }
+
+  @Override
+  public void handle(Request wsRequest, Response wsResponse) throws Exception {
+    DbSession dbSession = dbClient.openSession(false);
+    final ListResponse.Builder listResponseBuilder = ListResponse.newBuilder();
+    final ListResponse.Rule.Builder ruleBuilder = ListResponse.Rule.newBuilder();
+    try {
+      dbClient.ruleDao().selectEnabledAndNonManual(dbSession, new ResultHandler() {
+        @Override
+        public void handleResult(ResultContext resultContext) {
+          RuleDto dto = (RuleDto) resultContext.getResultObject();
+          ruleBuilder
+            .clear()
+            .setRepository(dto.getRepositoryKey())
+            .setKey(dto.getRuleKey());
+          String internalKey = dto.getConfigKey();
+          if (!Strings.isNullOrEmpty(internalKey)) {
+            ruleBuilder.setInternalKey(internalKey);
+          }
+          listResponseBuilder.addRules(ruleBuilder.build());
+        }
+      });
+    } finally {
+      dbClient.closeSession(dbSession);
+    }
+
+    // JSON response is voluntarily not supported. This WS is for internal use.
+    wsResponse.stream().setMediaType(MimeTypes.PROTOBUF);
+    listResponseBuilder.build().writeTo(wsResponse.stream().output());
+  }
+
+}
diff --git a/server/sonar-server/src/main/protobuf/ws-rules.proto b/server/sonar-server/src/main/protobuf/ws-rules.proto
new file mode 100644 (file)
index 0000000..264137d
--- /dev/null
@@ -0,0 +1,38 @@
+// SonarQube, open source software quality management tool.
+// Copyright (C) 2008-2015 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.
+
+syntax = "proto2";
+
+package sonarqube.ws.rules;
+
+option java_package = "org.sonarqube.ws";
+option java_outer_classname = "Rules";
+option optimize_for = SPEED;
+
+// WS api/rules/list for internal use only
+message ListResponse {
+
+  message Rule {
+    optional string repository = 1;
+    optional string key = 2;
+    optional string internal_key = 3;
+  }
+
+  repeated Rule rules = 1;
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/ListActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/ListActionTest.java
new file mode 100644 (file)
index 0000000..fd9aea6
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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.server.rule.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.rule.RuleTesting;
+import org.sonar.server.plugins.MimeTypes;
+import org.sonar.server.ws.TestResponse;
+import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.Rules;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ListActionTest {
+
+  @Rule
+  public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+  ListAction underTest = new ListAction(dbTester.getDbClient());
+
+  WsActionTester tester = new WsActionTester(underTest);
+
+  @Test
+  public void define() throws Exception {
+    WebService.Action def = tester.getDef();
+    assertThat(def.params()).isEmpty();
+  }
+
+  @Test
+  public void return_rules_in_protobuf() throws Exception {
+    dbTester.getDbClient().ruleDao().insert(dbTester.getSession(), RuleTesting.newDto(RuleKey.of("java", "S001")).setConfigKey(null));
+    dbTester.getDbClient().ruleDao().insert(dbTester.getSession(), RuleTesting.newDto(RuleKey.of("java", "S002")).setConfigKey("I002"));
+    dbTester.getSession().commit();
+
+    TestResponse response = tester.newRequest()
+      .setMimeType(MimeTypes.PROTOBUF)
+      .execute();
+
+    assertThat(response.getMediaType()).isEqualTo(MimeTypes.PROTOBUF);
+    Rules.ListResponse listResponse = Rules.ListResponse.parseFrom(response.getInputStream());
+    assertThat(listResponse.getRulesCount()).isEqualTo(2);
+
+    assertThat(listResponse.getRules(0).getKey()).isEqualTo("S001");
+    assertThat(listResponse.getRules(0).hasInternalKey()).isFalse();
+    assertThat(listResponse.getRules(1).getKey()).isEqualTo("S002");
+    assertThat(listResponse.getRules(1).getInternalKey()).isEqualTo("I002");
+  }
+}
index 80a4784197f364efdd9e3b6a5a51b5928faf4f7e..17ba3f9495d56769debed184a24e4f8150d11563 100644 (file)
@@ -97,7 +97,7 @@ public class RulesWsMediumTest {
     WebService.Controller controller = context.controller(API_ENDPOINT);
 
     assertThat(controller).isNotNull();
-    assertThat(controller.actions()).hasSize(8);
+    assertThat(controller.actions()).hasSize(9);
     assertThat(controller.action(API_SEARCH_METHOD)).isNotNull();
     assertThat(controller.action(API_SHOW_METHOD)).isNotNull();
     assertThat(controller.action(API_TAGS_METHOD)).isNotNull();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ws/DumbResponse.java b/server/sonar-server/src/test/java/org/sonar/server/ws/DumbResponse.java
new file mode 100644 (file)
index 0000000..76bc143
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * 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.server.ws;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.Maps;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.Map;
+import javax.annotation.CheckForNull;
+import org.apache.commons.io.IOUtils;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.api.utils.text.XmlWriter;
+
+public class DumbResponse implements Response {
+  private InMemoryStream stream;
+
+  private final ByteArrayOutputStream output = new ByteArrayOutputStream();
+
+  private Map<String, String> headers = Maps.newHashMap();
+
+  public class InMemoryStream implements Response.Stream {
+    private String mediaType;
+
+    private int status;
+
+    @CheckForNull
+    public String mediaType() {
+      return mediaType;
+    }
+
+    public int status() {
+      return status;
+    }
+
+    @Override
+    public Response.Stream setMediaType(String s) {
+      this.mediaType = s;
+      return this;
+    }
+
+    @Override
+    public Response.Stream setStatus(int i) {
+      this.status = i;
+      return this;
+    }
+    @Override
+    public OutputStream output() {
+      return output;
+    }
+
+  }
+
+  @Override
+  public JsonWriter newJsonWriter() {
+    return JsonWriter.of(new OutputStreamWriter(output, StandardCharsets.UTF_8));
+  }
+
+  @Override
+  public XmlWriter newXmlWriter() {
+    return XmlWriter.of(new OutputStreamWriter(output, StandardCharsets.UTF_8));
+  }
+
+  @Override
+  public InMemoryStream stream() {
+    if (stream == null) {
+      stream = new InMemoryStream();
+    }
+    return stream;
+  }
+
+  @Override
+  public Response noContent() {
+    stream().setStatus(HttpURLConnection.HTTP_NO_CONTENT);
+    IOUtils.closeQuietly(output);
+    return this;
+  }
+
+  public String outputAsString() {
+    return new String(output.toByteArray(), StandardCharsets.UTF_8);
+  }
+
+  @Override
+  public Response setHeader(String name, String value) {
+    headers.put(name, value);
+    return this;
+  }
+
+  @Override
+  public Collection<String> getHeaderNames() {
+    return headers.keySet();
+  }
+
+  @Override
+  public String getHeader(String name) {
+    return headers.get(name);
+  }
+
+  public byte[] getFlushedOutput() {
+    try {
+      output.flush();
+      return output.toByteArray();
+    } catch (IOException e) {
+      throw Throwables.propagate(e);
+    }
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ws/TestRequest.java b/server/sonar-server/src/test/java/org/sonar/server/ws/TestRequest.java
new file mode 100644 (file)
index 0000000..06c7362
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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.server.ws;
+
+import com.google.common.base.Throwables;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import org.sonar.api.server.ws.internal.ValidatingRequest;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class TestRequest extends ValidatingRequest {
+
+  private final Map<String, String> params = new HashMap<>();
+  private String method = "GET";
+  private String mimeType = "application/octet-stream";
+
+  @Override
+  protected String readParam(String key) {
+    return params.get(key);
+  }
+
+  @Override
+  protected InputStream readInputStreamParam(String key) {
+    throw new UnsupportedOperationException("Not supported in test yet");
+  }
+
+  @Override
+  public String method() {
+    return method;
+  }
+
+  @Override
+  public boolean hasParam(String key) {
+    return params.containsKey(key);
+  }
+
+  public TestRequest setMethod(String method) {
+    checkNotNull(method);
+    this.method = method;
+    return this;
+  }
+
+  public String getMimeType() {
+    return mimeType;
+  }
+
+  public TestRequest setMimeType(String type) {
+    checkNotNull(type);
+    this.mimeType = type;
+    return this;
+  }
+
+  public TestRequest setParam(String key, String value) {
+    checkNotNull(key);
+    checkNotNull(value);
+    this.params.put(key, value);
+    return this;
+  }
+
+  public TestResponse execute() {
+    try {
+      DumbResponse response = new DumbResponse();
+      action().handler().handle(this, response);
+      return new TestResponse(response);
+    } catch (Exception e) {
+      throw Throwables.propagate(e);
+    }
+  }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ws/TestResponse.java b/server/sonar-server/src/test/java/org/sonar/server/ws/TestResponse.java
new file mode 100644 (file)
index 0000000..e764804
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.server.ws;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+public class TestResponse {
+
+  private final DumbResponse dumbResponse;
+
+  TestResponse(DumbResponse dumbResponse) {
+    this.dumbResponse = dumbResponse;
+  }
+
+  public InputStream getInputStream() {
+    return new ByteArrayInputStream(dumbResponse.getFlushedOutput());
+  }
+
+  public String getInput() {
+    return new String(dumbResponse.getFlushedOutput(), StandardCharsets.UTF_8);
+  }
+
+  public String getMediaType() {
+    return dumbResponse.stream().mediaType();
+  }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ws/WsActionTester.java b/server/sonar-server/src/test/java/org/sonar/server/ws/WsActionTester.java
new file mode 100644 (file)
index 0000000..667be2c
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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.server.ws;
+
+import com.google.common.collect.Iterables;
+import org.sonar.api.server.ws.WebService;
+
+public class WsActionTester {
+
+  public static final String CONTROLLER_KEY = "test";
+  private final WebService.Action action;
+
+  public WsActionTester(WsAction wsAction) {
+    WebService.Context context = new WebService.Context();
+    WebService.NewController newController = context.createController(CONTROLLER_KEY);
+    wsAction.define(newController);
+    newController.done();
+    action = Iterables.get(context.controller(CONTROLLER_KEY).actions(), 0);
+  }
+
+  public WebService.Action getDef() {
+    return action;
+  }
+
+  public TestRequest newRequest() {
+    TestRequest request = new TestRequest();
+    request.setAction(action);
+    return request;
+  }
+}
index ee036208c9e481e29065526c66cf0dc77199e9f9..d81033e5fd869f121c659a46517edf587dc198b6 100644 (file)
@@ -66,4 +66,18 @@ public class ProtobufJsonFormatTest {
 
     ProtobufJsonFormat.write(protobuf, JsonWriter.of(new StringWriter()));
   }
+
+  @Test
+  public void protobuf_empty_strings_are_not_output() throws Exception {
+    org.sonar.core.test.Test.Fake protobuf = org.sonar.core.test.Test.Fake.newBuilder().build();
+
+    // field is not set but value is "", not null
+    assertThat(protobuf.hasAString()).isFalse();
+    assertThat(protobuf.getAString()).isEqualTo("");
+
+    StringWriter json = new StringWriter();
+    JsonWriter jsonWriter = JsonWriter.of(json);
+    ProtobufJsonFormat.write(protobuf, jsonWriter);
+    assertThat(json.toString()).isEqualTo("{}");
+  }
 }
index c58859013854c4a479f21fa188011dd21046ceb5..a2e028988916105f68e1cc00fe44d1aa7cc83ed1 100644 (file)
@@ -23,6 +23,7 @@ import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import java.util.List;
 import javax.annotation.Nonnull;
+import org.apache.ibatis.session.ResultHandler;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.db.Dao;
 import org.sonar.db.DbSession;
@@ -56,6 +57,14 @@ public class RuleDao implements Dao {
     return mapper(session).selectEnabledAndNonManual();
   }
 
+  public void selectEnabledAndNonManual(DbSession session, ResultHandler resultHandler) {
+    mapper(session).selectEnabledAndNonManual(resultHandler);
+  }
+
+  public void insert(DbSession session, RuleDto dto) {
+    mapper(session).insert(dto);
+  }
+
   private RuleMapper mapper(DbSession session) {
     return session.getMapper(RuleMapper.class);
   }
index 9e957944c2be612fa185a0edea09d695b7c297fc..84d2859b9114bf081ca8739cfd9a3c55654babad 100644 (file)
@@ -23,6 +23,7 @@ import java.sql.Timestamp;
 import java.util.List;
 import javax.annotation.Nullable;
 import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.session.ResultHandler;
 import org.sonar.api.rule.RuleKey;
 
 public interface RuleMapper {
@@ -31,6 +32,8 @@ public interface RuleMapper {
 
   List<RuleDto> selectEnabledAndNonManual();
 
+  void selectEnabledAndNonManual(ResultHandler resultHandler);
+
   List<RuleDto> selectNonManual();
 
   List<RuleDto> selectBySubCharacteristicId(int characteristicId);
index c6265510d7620fae40921f88fb9e7d78c5bf5e2a..96bd40611b9d8ca89e855348a5f6f03477e87f73 100644 (file)
 package org.sonar.db.rule;
 
 import com.google.common.base.Optional;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import org.apache.ibatis.session.ResultContext;
+import org.apache.ibatis.session.ResultHandler;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
@@ -113,4 +117,34 @@ public class RuleDaoTest {
     assertThat(ruleDto.getEffortToFixDescription()).isEqualTo("squid.S115.effortToFix");
   }
 
+  @Test
+  public void insert() throws Exception {
+    dbTester.getDbClient().ruleDao().insert(dbTester.getSession(), RuleTesting.newDto(RuleKey.of("java", "S001")).setConfigKey(null));
+    dbTester.getDbClient().ruleDao().insert(dbTester.getSession(), RuleTesting.newDto(RuleKey.of("java", "S002")).setConfigKey("I002"));
+    dbTester.getSession().commit();
+
+    List<Map<String, Object>> rows = dbTester.select("select plugin_rule_key as \"ruleKey\" from rules order by plugin_rule_key");
+    assertThat(rows).hasSize(2);
+    assertThat(rows.get(0).get("ruleKey")).isEqualTo("S001");
+    assertThat(rows.get(1).get("ruleKey")).isEqualTo("S002");
+
+  }
+
+  @Test
+  public void selectEnabledAndNonManual_with_ResultHandler() {
+    dbTester.prepareDbUnit(getClass(), "selectEnabledAndNonManual.xml");
+
+    final List<RuleDto> rules = new ArrayList<>();
+    ResultHandler resultHandler = new ResultHandler() {
+      @Override
+      public void handleResult(ResultContext resultContext) {
+        rules.add((RuleDto) resultContext.getResultObject());
+      }
+    };
+    underTest.selectEnabledAndNonManual(dbTester.getSession(), resultHandler);
+
+    assertThat(rules.size()).isEqualTo(1);
+    RuleDto ruleDto = rules.get(0);
+    assertThat(ruleDto.getId()).isEqualTo(1);
+  }
 }
diff --git a/sonar-db/src/test/resources/org/sonar/db/rule/RuleDaoTest/selectEnabledAndNonManual.xml b/sonar-db/src/test/resources/org/sonar/db/rule/RuleDaoTest/selectEnabledAndNonManual.xml
new file mode 100644 (file)
index 0000000..fe85e59
--- /dev/null
@@ -0,0 +1,27 @@
+<dataset>
+
+  <rules tags="[null]" system_tags="[null]" id="1" plugin_rule_key="AvoidNull" plugin_name="checkstyle" name="Avoid Null" description="Should avoid NULL" status="READY"
+         note_data="Rule note with accents éèà" note_user_login="polop.palap" note_created_at="2013-12-25" description_format="HTML"
+         characteristic_id="100" default_characteristic_id="101"
+         remediation_function="LINEAR" default_remediation_function="LINEAR_OFFSET"
+         remediation_coeff="1h" default_remediation_coeff="5d"
+         remediation_offset="5min" default_remediation_offset="10h"
+         effort_to_fix_description="squid.S115.effortToFix"/>
+
+  <rules tags="[null]" system_tags="[null]" id="2" plugin_rule_key="AvoidNull" plugin_name="squid" name="Avoid Null" description="Should avoid NULL" status="REMOVED"
+         note_data="[null]" note_user_login="[null]" note_created_at="[null]" description_format="HTML"
+         characteristic_id="[null]" default_characteristic_id="[null]"
+         remediation_function="[null]" default_remediation_function="[null]"
+         remediation_coeff="[null]" default_remediation_coeff="[null]"
+         remediation_offset="[null]" default_remediation_offset="[null]"
+         effort_to_fix_description="[null]"/>
+
+  <rules tags="[null]" system_tags="[null]" id="3" plugin_rule_key="AvoidNull" plugin_name="manual" name="Manual Rule" description="Should not appear" status="READY"
+         note_data="[null]" note_user_login="[null]" note_created_at="[null]" description_format="HTML"
+         characteristic_id="[null]" default_characteristic_id="[null]"
+         remediation_function="[null]" default_remediation_function="[null]"
+         remediation_coeff="[null]" default_remediation_coeff="[null]"
+         remediation_offset="[null]" default_remediation_offset="[null]"
+         effort_to_fix_description="[null]"/>
+
+</dataset>