001package org.conqat.engine.service.shared.client; 002 003import java.util.List; 004 005import org.conqat.engine.index.shared.CommitDescriptor; 006import org.conqat.engine.service.shared.ServiceUtils; 007import org.conqat.lib.commons.collections.ListMap; 008import org.conqat.lib.commons.collections.Pair; 009import org.conqat.lib.commons.string.StringUtils; 010import org.conqat.lib.commons.uniformpath.UniformPath; 011 012/** Methods to build Teamscale service URIs. */ 013public class ServiceClientUris { 014 015 /** Prefix used to recognize projects. */ 016 public static final String LEGACY_PROJECT_PREFIX = "p/"; 017 018 /** 019 * Name of the boolean query parameter used to indicate recursive queries. 020 */ 021 public static final String RECURSIVE_PARAMETER = "recursive"; 022 023 /** Baselines parameter for findings service. */ 024 public static final String BASELINE_PARAMETER = "baseline"; 025 026 /** Include changed code findings parameter. */ 027 public static final String INCLUDE_CHANGED_CODE_FINDINGS_PARAMETER = "include-changed-code-findings"; 028 029 /** Principal metric index parameter for metric distribution service */ 030 public static final String PRINCIPAL_METRIC_INDEX_PARAMETER = "principal-metric-index"; 031 032 /** Metric index parameter for metric distribution service */ 033 public static final String METRIC_INDEXES_PARAMETER = "metric-indexes"; 034 035 /** Boundaries parameter for metric distribution service */ 036 public static final String BOUNDARY_PARAMETER = "boundaries"; 037 038 /** Name of the timestamp parameter. */ 039 public static final String TIMESTAMP_PARAMETER_NAME = "t"; 040 041 /** Name of the first timestamp parameter for delta queries. */ 042 public static final String TIMESTAMP_ONE_PARAMETER_NAME = "t1"; 043 044 /** Name of the second timestamp parameter for delta queries. */ 045 public static final String TIMESTAMP_TWO_PARAMETER_NAME = "t2"; 046 047 private ServiceClientUris() { 048 // Utils class should not be instantiated 049 } 050 051 /** Constructs a global service uri for services with api prefix. */ 052 public static String getGlobal(String serviceName, ServerDetails serverDetails, Pair<?, ?>... options) { 053 return getGlobal(serviceName, serverDetails, toOptionsMap(options)); 054 } 055 056 /** Constructs a global service uri for services with api prefix. */ 057 public static String getGlobal(String serviceName, ServerDetails serverDetails, ListMap<String, String> options) { 058 return StringUtils.ensureEndsWith(serverDetails.getUrl(), "/") // 059 + "api/" + serviceName + createOptionString(options); 060 } 061 062 /** Constructs a project service uri for services with api prefix. */ 063 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 064 Pair<?, ?>... options) { 065 return getProject(serviceName, serverDetails, projectName, toOptionsMap(options)); 066 } 067 068 /** Constructs a project service uri for services with api prefix. */ 069 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 070 ListMap<String, String> options) { 071 return getProject(serviceName, serverDetails, projectName, StringUtils.EMPTY_STRING, options); 072 } 073 074 /** Constructs a project service uri for services with api prefix. */ 075 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 076 UniformPath uniformPath, Pair<?, ?>... options) { 077 return getProject(serviceName, serverDetails, projectName, uniformPath.toString(), options); 078 } 079 080 /** Constructs a project service uri for services with api prefix. */ 081 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 082 String uniformPath, Pair<?, ?>... options) { 083 return getProject(serviceName, serverDetails, projectName, uniformPath, toOptionsMap(options)); 084 } 085 086 /** Constructs a project service uri for services with api prefix. */ 087 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 088 UniformPath uniformPath, ListMap<String, String> options) { 089 return getProject(serviceName, serverDetails, projectName, uniformPath.toString(), options); 090 } 091 092 /** Constructs a project service uri for services with api prefix. */ 093 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 094 String uniformPath, ListMap<String, String> options) { 095 return StringUtils.ensureEndsWith(serverDetails.getUrl(), "/") // 096 + "api/projects/" + projectName + "/" // 097 + serviceName + "/" // 098 + ServiceUtils.encodeUniformPath(uniformPath) // 099 + createOptionString(options); 100 } 101 102 /** Class for building URI's for legacy services. */ 103 public static class Legacy { 104 105 /** Constructs a global service uri for services of the legacy framework. */ 106 public static String getGlobal(String serviceName, ServerDetails serverDetails, Pair<?, ?>... options) { 107 return getGlobal(serviceName, serverDetails, toOptionsMap(options)); 108 } 109 110 /** Constructs a global service uri for services of the legacy framework. */ 111 public static String getGlobal(String serviceName, ServerDetails serverDetails, 112 ListMap<String, String> options) { 113 return getServiceUrl(serverDetails, null, serviceName) + createOptionString(options); 114 } 115 116 /** Constructs a project service uri for services of the legacy framework. */ 117 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 118 Pair<?, ?>... options) { 119 return getProject(serviceName, serverDetails, projectName, toOptionsMap(options)); 120 } 121 122 /** Constructs a project service uri for services of the legacy framework. */ 123 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 124 String uniformPath, Pair<?, ?>... options) { 125 return getProject(serviceName, serverDetails, projectName, uniformPath, toOptionsMap(options)); 126 } 127 128 /** Constructs a project service uri for services of the legacy framework. */ 129 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 130 String uniformPath, ListMap<String, String> options) { 131 return getServiceUrl(serverDetails, projectName, serviceName) // 132 + ServiceUtils.encodeUniformPath(uniformPath) // 133 + createOptionString(options); 134 } 135 136 /** Constructs a project service uri for services of the legacy framework. */ 137 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 138 UniformPath uniformPath, Pair<?, ?> options) { 139 return getProject(serviceName, serverDetails, projectName, uniformPath, toOptionsMap(options)); 140 } 141 142 /** Constructs a project service uri for services of the legacy framework. */ 143 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 144 UniformPath uniformPath, ListMap<String, String> options) { 145 return getProject(serviceName, serverDetails, projectName, uniformPath.toString(), options); 146 } 147 148 /** Constructs a project service uri for services of the legacy framework. */ 149 public static String getProject(String serviceName, ServerDetails serverDetails, String projectName, 150 ListMap<String, String> options) { 151 return getServiceUrl(serverDetails, projectName, serviceName) // 152 + createOptionString(options); 153 } 154 155 /** Constructs the URL of a service. */ 156 private static String getServiceUrl(ServerDetails serverDetails, String projectName, String serviceName) { 157 String url = serverDetails.getUrl(); 158 url = StringUtils.ensureEndsWith(url, "/"); 159 160 if (projectName != null) { 161 url += StringUtils.ensureEndsWith(LEGACY_PROJECT_PREFIX + projectName, "/"); 162 } 163 url = StringUtils.ensureEndsWith(url, "/"); 164 165 url += serviceName; 166 url = StringUtils.ensureEndsWith(url, "/"); 167 168 return url; 169 } 170 } 171 172 /** 173 * @return the given options as a {@link ListMap} or {@code null}, if no options 174 * are given. 175 */ 176 private static ListMap<String, String> toOptionsMap(Pair<?, ?>... options) { 177 if (options.length == 0) { 178 return null; 179 } 180 ListMap<String, String> optionsMap = new ListMap<>(); 181 for (Pair<?, ?> option : options) { 182 if (option != null) { 183 optionsMap.add(option.getFirst().toString(), option.getSecond().toString()); 184 } 185 } 186 return optionsMap; 187 } 188 189 /** 190 * Creates an encoded URL options string starting with <code>?</code> from the 191 * given options. The given parameters are interpreted as parameter names and 192 * values, where each odd numbered parameter is a parameter name and each even 193 * one is the corresponding value. 194 */ 195 public static String createOptionString(String... parametersAndValues) { 196 return createOptionString(ListMap.of(parametersAndValues)); 197 } 198 199 /** 200 * Creates an encoded URL options string starting with <code>?</code> from the 201 * given options. 202 */ 203 private static String createOptionString(ListMap<String, String> options) { 204 StringBuilder sb = new StringBuilder(); 205 if (options != null) { 206 String separator = "?"; 207 for (String option : options.getKeys()) { 208 List<String> values = options.getCollection(option); 209 for (String value : values) { 210 value = ServiceUtils.encodeQueryParameter(value); 211 sb.append(separator).append(option).append('=').append(value); 212 separator = "&"; 213 } 214 } 215 } 216 return sb.toString(); 217 } 218 219 /** 220 * Creates a timestamp parameter pair. When the timestamp is null the method 221 * returns <code>null</code>. 222 */ 223 public static Pair<String, String> createCommitDescriptorOption(CommitDescriptor commitDescriptor) { 224 if (commitDescriptor == null) { 225 return null; 226 } 227 return Pair.createPair(TIMESTAMP_PARAMETER_NAME, commitDescriptor.toServiceCallFormat()); 228 } 229 230}