001/*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2012 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar 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 * Sonar 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
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019 */
020package org.sonar.wsclient.services;
021
022import java.util.Date;
023
024/**
025 * @since 2.2
026 */
027public abstract class AbstractQuery<M extends Model> {
028
029  /**
030   * Default timeout for waiting data, in milliseconds.
031   *
032   * @since 2.10
033   */
034  public static final int DEFAULT_TIMEOUT_MILLISECONDS = 30 * 1000;
035
036  private int timeoutMilliseconds = DEFAULT_TIMEOUT_MILLISECONDS;
037
038  // accepted-language as defined in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
039  private String locale;
040
041  /**
042   * Must start with a slash, for example: /api/metrics
043   * <p>
044   * IMPORTANT: In implementations of this method we must use helper methods to construct URL.
045   * </p>
046   *
047   * @see #encode(String)
048   * @see #appendUrlParameter(StringBuilder, String, Object)
049   * @see #appendUrlParameter(StringBuilder, String, Object[])
050   * @see #appendUrlParameter(StringBuilder, String, Date, boolean)
051   */
052  public abstract String getUrl();
053
054  /**
055   * Request body. By default it is empty but it can be overridden.
056   */
057  public String getBody() {
058    return null;
059  }
060
061  /**
062   * Get the timeout for waiting data, in milliseconds. A value of zero is interpreted as an infinite timeout.
063   *
064   * @since 2.10
065   */
066  public final int getTimeoutMilliseconds() {
067    return timeoutMilliseconds;
068  }
069
070  /**
071   * Set the timeout for waiting data, in milliseconds. Avalue of zero is interpreted as an infinite timeout.
072   *
073   * @since 2.10
074   */
075  public final AbstractQuery<M> setTimeoutMilliseconds(int i) {
076    this.timeoutMilliseconds = (i < 0 ? 0 : i);
077    return this;
078  }
079
080  /**
081   * Accepted-language, as defined in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
082   *
083   * @since 2.10
084   */
085  public final String getLocale() {
086    return locale;
087  }
088
089  /**
090   * Set the Accepted-language HTTP parameter
091   *
092   * @since 2.10
093   */
094  public final AbstractQuery<M> setLocale(String locale) {
095    this.locale = locale;
096    return this;
097  }
098
099  /**
100   * Encodes single parameter value.
101   */
102  protected static String encode(String value) {
103    return WSUtils.getINSTANCE().encodeUrl(value);
104  }
105
106  protected static void appendUrlParameter(StringBuilder url, String paramKey, int paramValue) {
107    url.append(paramKey)
108      .append('=')
109      .append(paramValue)
110      .append("&");
111  }
112
113  protected static void appendUrlParameter(StringBuilder url, String paramKey, Object paramValue) {
114    if (paramValue != null) {
115      url.append(paramKey)
116        .append('=')
117        .append(encode(paramValue.toString()))
118        .append('&');
119    }
120  }
121
122  protected static void appendUrlParameter(StringBuilder url, String paramKey, Object[] paramValues) {
123    if (paramValues != null) {
124      url.append(paramKey).append('=');
125      for (int index = 0; index < paramValues.length; index++) {
126        if (index > 0) {
127          url.append(',');
128        }
129        if (paramValues[index] != null) {
130          url.append(encode(paramValues[index].toString()));
131        }
132      }
133      url.append('&');
134    }
135  }
136
137  protected static void appendUrlParameter(StringBuilder url, String paramKey, Date paramValue, boolean includeTime) {
138    if (paramValue != null) {
139      String format = (includeTime ? "yyyy-MM-dd'T'HH:mm:ssZ" : "yyyy-MM-dd");
140      url.append(paramKey)
141        .append('=')
142        .append(encode(WSUtils.getINSTANCE().format(paramValue, format)))
143        .append('&');
144    }
145  }
146}