From 3936e0031f18ee570e284c9115eeddb33cc83e09 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Mon, 13 Jan 2014 18:27:12 +0400 Subject: [PATCH] Add a couple of new methods in NewBaseRepositoryImpl, update Gitlab connector accordingly --- .../tasks/gitlab/GitlabRepository.java | 16 ++++---- .../httpclient/NewBaseRepositoryImpl.java | 39 ++++++++++++++++++- .../src/com/intellij/tasks/impl/TaskUtil.java | 18 +++++++++ 3 files changed, 65 insertions(+), 8 deletions(-) diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/gitlab/GitlabRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/gitlab/GitlabRepository.java index 2d0978462228..7a07878de709 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/gitlab/GitlabRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/gitlab/GitlabRepository.java @@ -134,7 +134,7 @@ public class GitlabRepository extends NewBaseRepositoryImpl { @NotNull List fetchProjects() throws Exception { - HttpGet request = new HttpGet(getRestApiBaseUrl() + "projects"); + HttpGet request = new HttpGet(getRestApiUrl("projects")); ResponseHandler> handler = new GsonMultipleObjectsDeserializer(GSON, LIST_OF_PROJECTS_TYPE); return getHttpClient().execute(request, handler); } @@ -142,7 +142,7 @@ public class GitlabRepository extends NewBaseRepositoryImpl { @SuppressWarnings("UnusedDeclaration") @NotNull GitlabProject fetchProject(int id) throws Exception { - HttpGet request = new HttpGet(getRestApiBaseUrl() + "project/" + id); + HttpGet request = new HttpGet(getRestApiUrl("project", id)); return getHttpClient().execute(request, new GsonSingleObjectDeserializer(GSON, GitlabProject.class)); } @@ -154,14 +154,14 @@ public class GitlabRepository extends NewBaseRepositoryImpl { private String getIssuesUrl() { if (myCurrentProject != null && myCurrentProject != UNSPECIFIED_PROJECT) { - return getRestApiBaseUrl() + "projects/" + myCurrentProject.getId() + "/issues"; + return getRestApiUrl("projects", myCurrentProject.getId(), "issues"); } - return getRestApiBaseUrl() + "issues"; + return getRestApiUrl("issues"); } @NotNull GitlabIssue fetchIssue(int id) throws Exception { - HttpGet request = new HttpGet(getRestApiBaseUrl() + "issues/" + id); + HttpGet request = new HttpGet(getRestApiUrl("issues", id)); ResponseHandler handler = new GsonSingleObjectDeserializer(GSON, GitlabIssue.class); return getHttpClient().execute(request, handler); } @@ -171,8 +171,10 @@ public class GitlabRepository extends NewBaseRepositoryImpl { return super.isConfigured() && !myPassword.isEmpty(); } - private String getRestApiBaseUrl() { - return getUrl() + REST_API_PATH_PREFIX; + @NotNull + @Override + public String getRestApiPathPrefix() { + return REST_API_PATH_PREFIX; } @Nullable diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/httpclient/NewBaseRepositoryImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/httpclient/NewBaseRepositoryImpl.java index 38739e50917d..45aff814d200 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/httpclient/NewBaseRepositoryImpl.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/httpclient/NewBaseRepositoryImpl.java @@ -4,6 +4,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.tasks.TaskRepositoryType; import com.intellij.tasks.config.TaskSettings; import com.intellij.tasks.impl.BaseRepository; +import com.intellij.tasks.impl.TaskUtil; import com.intellij.util.net.CertificatesManager; import com.intellij.util.net.HttpConfigurable; import org.apache.http.HttpHost; @@ -49,7 +50,7 @@ public abstract class NewBaseRepositoryImpl extends BaseRepository { HttpClientBuilder builder = HttpClients.custom() .setDefaultRequestConfig(createRequestConfig()) .setSslcontext(CertificatesManager.getInstance().getSslContext()) - // TODO: use custom one for additional certificate check + // TODO: use custom one for additional certificate check .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) .setDefaultCredentialsProvider(createCredentialsProvider()); HttpRequestInterceptor interceptor = createRequestInterceptor(); @@ -98,4 +99,40 @@ public abstract class NewBaseRepositoryImpl extends BaseRepository { } return builder.build(); } + + /** + * Return server's REST API path prefix, e.g. {@code /rest/api/latest} for JIRA or {@code /api/v3/} for Gitlab. + * This value will be used in {@link #getRestApiUrl(Object...)} + * + * @return server's REST API path prefix + */ + @NotNull + public String getRestApiPathPrefix() { + return ""; + } + + /** + * Build URL using {@link #getUrl()}, {@link #getRestApiPathPrefix()}} and specified path components. + *

+ * Individual path components will should not contain leading or trailing slashes. Empty or null components + * will be omitted. Each components is converted to string using its {@link Object#toString()} method and url encoded, so + * numeric IDs can be used as well. Returned URL doesn't contain trailing '/', because it's not compatible with some services. + * + * @return described URL + */ + @NotNull + public String getRestApiUrl(@NotNull Object... parts) { + StringBuilder builder = new StringBuilder(getUrl()); + builder.append(getRestApiPathPrefix()); + if (builder.charAt(builder.length() - 1) == '/') { + builder.deleteCharAt(builder.length() - 1); + } + for (Object part : parts) { + if (part == null || part.equals("")) { + continue; + } + builder.append('/').append(TaskUtil.encodeUrl(String.valueOf(part))); + } + return builder.toString(); + } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUtil.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUtil.java index 7e6ac533e464..87dbd6250953 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUtil.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUtil.java @@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.tasks.Task; import com.intellij.tasks.TaskRepository; import org.jdom.Element; @@ -28,7 +29,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.lang.reflect.Type; +import java.net.URLEncoder; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -220,4 +223,19 @@ public class TaskUtil { public static GsonBuilder installDateDeserializer(GsonBuilder builder) { return builder.registerTypeAdapter(Date.class, DATE_DESERIALIZER); } + + /** + * Perform standard {@code application/x-www-urlencoded} translation for string {@code s}. + * + * @return urlencoded string + */ + @NotNull + public static String encodeUrl(@NotNull String s) { + try { + return URLEncoder.encode(s, CharsetToolkit.UTF8); + } + catch (UnsupportedEncodingException e) { + throw new AssertionError("UTF-8 is not supported"); + } + } }