001/* 002 * SonarQube 003 * Copyright (C) 2009-2016 SonarSource SA 004 * mailto:contact AT sonarsource DOT com 005 * 006 * This program 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 * This program 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 */ 020package org.sonar.api.server.ws; 021 022import com.google.common.base.Splitter; 023import com.google.common.collect.Lists; 024import java.io.InputStream; 025import java.util.ArrayList; 026import java.util.Date; 027import java.util.List; 028import javax.annotation.CheckForNull; 029import org.apache.commons.lang.StringUtils; 030import org.sonar.api.utils.DateUtils; 031import org.sonar.api.utils.SonarException; 032 033/** 034 * @since 4.2 035 */ 036public abstract class Request { 037 038 /** 039 * Returns the name of the HTTP method with which this request was made. Possible 040 * values are GET and POST. Others are not supported. 041 */ 042 public abstract String method(); 043 044 /** 045 * Returns the requested MIME type, or {@code "application/octet-stream"} if not specified. 046 */ 047 public abstract String getMediaType(); 048 049 /** 050 * Return true of the parameter is set. 051 */ 052 public abstract boolean hasParam(String key); 053 054 /** 055 * Returns a non-null value. To be used when parameter is required or has a default value. 056 * 057 * @throws java.lang.IllegalArgumentException is value is null or blank 058 */ 059 public String mandatoryParam(String key) { 060 String value = param(key); 061 if (value == null) { 062 throw new IllegalArgumentException(String.format("The '%s' parameter is missing", key)); 063 } 064 return value; 065 } 066 067 /** 068 * Returns a boolean value. To be used when parameter is required or has a default value. 069 * 070 * @throws java.lang.IllegalArgumentException is value is null or blank 071 */ 072 public boolean mandatoryParamAsBoolean(String key) { 073 String s = mandatoryParam(key); 074 return parseBoolean(key, s); 075 } 076 077 /** 078 * Returns an int value. To be used when parameter is required or has a default value. 079 * 080 * @throws java.lang.IllegalArgumentException is value is null or blank 081 */ 082 public int mandatoryParamAsInt(String key) { 083 String s = mandatoryParam(key); 084 return Integer.parseInt(s); 085 } 086 087 /** 088 * Returns a long value. To be used when parameter is required or has a default value. 089 * 090 * @throws java.lang.IllegalArgumentException is value is null or blank 091 */ 092 public long mandatoryParamAsLong(String key) { 093 String s = mandatoryParam(key); 094 return Long.parseLong(s); 095 } 096 097 public <E extends Enum<E>> E mandatoryParamAsEnum(String key, Class<E> enumClass) { 098 return Enum.valueOf(enumClass, mandatoryParam(key)); 099 } 100 101 public List<String> mandatoryParamAsStrings(String key) { 102 List<String> values = paramAsStrings(key); 103 if (values == null) { 104 throw new IllegalArgumentException(String.format("The '%s' parameter is missing", key)); 105 } 106 return values; 107 } 108 109 @CheckForNull 110 public List<String> paramAsStrings(String key) { 111 String value = param(key); 112 if (value == null) { 113 return null; 114 } 115 return Lists.newArrayList(Splitter.on(',').omitEmptyStrings().trimResults().split(value)); 116 } 117 118 @CheckForNull 119 public abstract String param(String key); 120 121 @CheckForNull 122 public abstract InputStream paramAsInputStream(String key); 123 124 /** 125 * @deprecated to be dropped in 4.4. Default values are declared in ws metadata 126 */ 127 @CheckForNull 128 @Deprecated 129 public String param(String key, @CheckForNull String defaultValue) { 130 return StringUtils.defaultString(param(key), defaultValue); 131 } 132 133 /** 134 * @deprecated to be dropped in 4.4. Default values must be declared in {@link org.sonar.api.server.ws.WebService} then 135 * this method can be replaced by {@link #mandatoryParamAsBoolean(String)}. 136 */ 137 @Deprecated 138 public boolean paramAsBoolean(String key, boolean defaultValue) { 139 String value = param(key); 140 return value == null ? defaultValue : parseBoolean(key, value); 141 } 142 143 /** 144 * @deprecated to be dropped in 4.4. Default values must be declared in {@link org.sonar.api.server.ws.WebService} then 145 * this method can be replaced by {@link #mandatoryParamAsInt(String)}. 146 */ 147 @Deprecated 148 public int paramAsInt(String key, int defaultValue) { 149 String s = param(key); 150 return s == null ? defaultValue : Integer.parseInt(s); 151 } 152 153 /** 154 * @deprecated to be dropped in 4.4. Default values must be declared in {@link org.sonar.api.server.ws.WebService} then 155 * this method can be replaced by {@link #mandatoryParamAsLong(String)}. 156 */ 157 @Deprecated 158 public long paramAsLong(String key, long defaultValue) { 159 String s = param(key); 160 return s == null ? defaultValue : Long.parseLong(s); 161 } 162 163 @CheckForNull 164 public Boolean paramAsBoolean(String key) { 165 String value = param(key); 166 return value == null ? null : parseBoolean(key, value); 167 } 168 169 @CheckForNull 170 public Integer paramAsInt(String key) { 171 String s = param(key); 172 return s == null ? null : Integer.parseInt(s); 173 } 174 175 @CheckForNull 176 public Long paramAsLong(String key) { 177 String s = param(key); 178 return s == null ? null : Long.parseLong(s); 179 } 180 181 @CheckForNull 182 public <E extends Enum<E>> E paramAsEnum(String key, Class<E> enumClass) { 183 String s = param(key); 184 return s == null ? null : Enum.valueOf(enumClass, s); 185 } 186 187 @CheckForNull 188 public <E extends Enum<E>> List<E> paramAsEnums(String key, Class<E> enumClass) { 189 String value = param(key); 190 if (value == null) { 191 return null; 192 } 193 Iterable<String> values = Splitter.on(',').omitEmptyStrings().trimResults().split(value); 194 List<E> result = new ArrayList<>(); 195 for (String s : values) { 196 result.add(Enum.valueOf(enumClass, s)); 197 } 198 return result; 199 } 200 201 @CheckForNull 202 public Date paramAsDateTime(String key) { 203 String s = param(key); 204 if (s != null) { 205 try { 206 return DateUtils.parseDateTime(s); 207 } catch (SonarException notDateTime) { 208 try { 209 return DateUtils.parseDate(s); 210 } catch (SonarException notDateEither) { 211 throw new SonarException(String.format("'%s' cannot be parsed as either a date or date+time", s)); 212 } 213 } 214 } 215 return null; 216 } 217 218 @CheckForNull 219 public Date paramAsDate(String key) { 220 String s = param(key); 221 if (s != null) { 222 return DateUtils.parseDate(s); 223 } 224 return null; 225 } 226 227 private static boolean parseBoolean(String key, String value) { 228 if ("true".equals(value) || "yes".equals(value)) { 229 return true; 230 } 231 if ("false".equals(value) || "no".equals(value)) { 232 return false; 233 } 234 throw new IllegalArgumentException(String.format("Property %s is not a boolean value: %s", key, value)); 235 } 236}