001    /*
002     * SonarQube, open source software quality management tool.
003     * Copyright (C) 2008-2013 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * SonarQube is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * SonarQube is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public License
017     * along with this program; if not, write to the Free Software Foundation,
018     * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019     */
020    package org.sonar.wsclient;
021    
022    import org.sonar.wsclient.internal.HttpRequestFactory;
023    import org.sonar.wsclient.issue.ActionPlanClient;
024    import org.sonar.wsclient.issue.internal.DefaultActionPlanClient;
025    import org.sonar.wsclient.issue.internal.DefaultIssueClient;
026    import org.sonar.wsclient.issue.IssueClient;
027    import org.sonar.wsclient.user.DefaultUserClient;
028    import org.sonar.wsclient.user.UserClient;
029    
030    import javax.annotation.Nullable;
031    
032    /**
033     * Entry point of the Java Client for Sonar Web Services. It does not support all web services yet.
034     * <p/>
035     * Example:
036     * <pre>
037     *   SonarClient client = SonarClient.create("http://localhost:9000");
038     *   IssueClient issueClient = client.issueClient();
039     * </pre>
040     *
041     * @since 3.6
042     */
043    public class SonarClient {
044    
045      public static final int DEFAULT_CONNECT_TIMEOUT_MILLISECONDS = 30000;
046      public static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = 60000;
047    
048      /**
049       * Visibility relaxed for unit tests
050       */
051      final HttpRequestFactory requestFactory;
052    
053      private SonarClient(Builder builder) {
054        requestFactory = new HttpRequestFactory(builder.url)
055          .setLogin(builder.login)
056          .setPassword(builder.password)
057          .setProxyHost(builder.proxyHost)
058          .setProxyPort(builder.proxyPort)
059          .setProxyLogin(builder.proxyLogin)
060          .setProxyPassword(builder.proxyPassword)
061          .setConnectTimeoutInMilliseconds(builder.connectTimeoutMs)
062          .setReadTimeoutInMilliseconds(builder.readTimeoutMs);
063      }
064    
065      /**
066       * New client to interact with web services related to issues
067       */
068      public IssueClient issueClient() {
069        return new DefaultIssueClient(requestFactory);
070      }
071    
072      /**
073       * New client to interact with web services related to issue action plans
074       */
075      public ActionPlanClient actionPlanClient() {
076        return new DefaultActionPlanClient(requestFactory);
077      }
078    
079      /**
080       * New client to interact with web services related to users
081       */
082      public UserClient userClient() {
083        return new DefaultUserClient(requestFactory);
084      }
085    
086      /**
087       * Create a builder of {@link SonarClient}s.
088       */
089      public static Builder builder() {
090        return new Builder();
091      }
092    
093      /**
094       * Create a client with default configuration. Use {@link #builder()} to define
095       * a custom configuration (credentials, HTTP proxy, HTTP timeouts).
096       */
097      public static SonarClient create(String serverUrl) {
098        return builder().url(serverUrl).build();
099      }
100    
101      public static class Builder {
102        private String login, password, url, proxyHost, proxyLogin, proxyPassword;
103        private int proxyPort = 0;
104        private int connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MILLISECONDS, readTimeoutMs = DEFAULT_READ_TIMEOUT_MILLISECONDS;
105    
106        private Builder() {
107        }
108    
109        /**
110         * Mandatory HTTP server URL, eg "http://localhost:9000"
111         */
112        public Builder url(String url) {
113          this.url = url;
114          return this;
115        }
116    
117        /**
118         * Optional login, for example "admin"
119         */
120        public Builder login(@Nullable String login) {
121          this.login = login;
122          return this;
123        }
124    
125        /**
126         * Optional password related to {@link #login(String)}, for example "admin"
127         */
128        public Builder password(@Nullable String password) {
129          this.password = password;
130          return this;
131        }
132    
133        /**
134         * Host and port of the optional HTTP proxy
135         */
136        public Builder proxy(@Nullable String proxyHost, int proxyPort) {
137          this.proxyHost = proxyHost;
138          this.proxyPort = proxyPort;
139          return this;
140        }
141    
142        public Builder proxyLogin(@Nullable String proxyLogin) {
143          this.proxyLogin = proxyLogin;
144          return this;
145        }
146    
147        public Builder proxyPassword(@Nullable String proxyPassword) {
148          this.proxyPassword = proxyPassword;
149          return this;
150        }
151    
152        /**
153         * Sets a specified timeout value, in milliseconds, to be used when opening HTTP connection.
154         * A timeout of zero is interpreted as an infinite timeout. Default value is {@link SonarClient#DEFAULT_CONNECT_TIMEOUT_MILLISECONDS}
155         */
156        public Builder connectTimeoutMilliseconds(int i) {
157          this.connectTimeoutMs = i;
158          return this;
159        }
160    
161        /**
162         * Sets the read timeout to a specified timeout, in milliseconds.
163         * A timeout of zero is interpreted as an infinite timeout. Default value is {@link SonarClient#DEFAULT_READ_TIMEOUT_MILLISECONDS}
164         */
165        public Builder readTimeoutMilliseconds(int i) {
166          this.readTimeoutMs = i;
167          return this;
168        }
169    
170        /**
171         * Build a new client
172         */
173        public SonarClient build() {
174          if (url == null || "".equals(url)) {
175            throw new IllegalStateException("Server URL must be set");
176          }
177          return new SonarClient(this);
178        }
179      }
180    }