1 /* 2 * Copyright 2011 Vincent Behar 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.rundeck.api; 17 18 import java.io.InputStream; 19 import java.util.Date; 20 import java.util.HashMap; 21 import java.util.Map; 22 import java.util.Properties; 23 import org.apache.commons.lang.StringUtils; 24 import org.rundeck.api.util.ParametersUtil; 25 26 /** 27 * Builder for API paths 28 * 29 * @author Vincent Behar 30 */ 31 class ApiPathBuilder { 32 33 /** Internally, we store everything in a {@link StringBuilder} */ 34 private final StringBuilder apiPath; 35 36 /** When POSTing, we can add attachments */ 37 private final Map<String, InputStream> attachments; 38 39 /** Marker for using the right separator between parameters ("?" or "&") */ 40 private boolean firstParamDone = false; 41 42 /** 43 * Build a new instance, for the given "path" (the "path" is the part before the parameters. The path and the 44 * parameters are separated by a "?") 45 * 46 * @param paths elements of the path 47 */ 48 public ApiPathBuilder(String... paths) { 49 apiPath = new StringBuilder(); 50 attachments = new HashMap<String, InputStream>(); 51 if (paths != null) { 52 for (String path : paths) { 53 if (StringUtils.isNotBlank(path)) { 54 append(path); 55 } 56 } 57 } 58 } 59 60 /** 61 * Append the given parameter (key and value). This will only append the parameter if it is not blank (null, empty 62 * or whitespace), and make sure to add the right separator ("?" or "&") before. The key and value will be separated 63 * by the "=" character. Also, the value will be url-encoded. 64 * 65 * @param key of the parameter. Must not be null or empty 66 * @param value of the parameter. May be null/empty/blank. Will be url-encoded. 67 * @return this, for method chaining 68 */ 69 public ApiPathBuilder param(String key, String value) { 70 if (StringUtils.isNotBlank(value)) { 71 appendSeparator(); 72 append(key); 73 append("="); 74 append(ParametersUtil.urlEncode(value)); 75 } 76 return this; 77 } 78 79 /** 80 * Append the given parameter (key and value). This will only append the parameter if it is not null, and make sure 81 * to add the right separator ("?" or "&") before. The key and value will be separated by the "=" character. Also, 82 * the value will be converted to lower-case. 83 * 84 * @param key of the parameter. Must not be null or empty 85 * @param value of the parameter. May be null 86 * @return this, for method chaining 87 */ 88 public ApiPathBuilder param(String key, Enum<?> value) { 89 if (value != null) { 90 param(key, StringUtils.lowerCase(value.toString())); 91 } 92 return this; 93 } 94 95 /** 96 * Append the given parameter (key and value). This will only append the parameter if it is not null, and make sure 97 * to add the right separator ("?" or "&") before. The key and value will be separated by the "=" character. 98 * 99 * @param key of the parameter. Must not be null or empty 100 * @param value of the parameter. May be null 101 * @return this, for method chaining 102 */ 103 public ApiPathBuilder param(String key, Date value) { 104 if (value != null) { 105 param(key, value.getTime()); 106 } 107 return this; 108 } 109 110 /** 111 * Append the given parameter (key and value). This will only append the parameter if it is not null, and make sure 112 * to add the right separator ("?" or "&") before. The key and value will be separated by the "=" character. 113 * 114 * @param key of the parameter. Must not be null or empty 115 * @param value of the parameter. May be null 116 * @return this, for method chaining 117 */ 118 public ApiPathBuilder param(String key, Long value) { 119 if (value != null) { 120 param(key, value.toString()); 121 } 122 return this; 123 } 124 125 /** 126 * Append the given parameter (key and value). This will only append the parameter if it is not null, and make sure 127 * to add the right separator ("?" or "&") before. The key and value will be separated by the "=" character. 128 * 129 * @param key of the parameter. Must not be null or empty 130 * @param value of the parameter. May be null 131 * @return this, for method chaining 132 */ 133 public ApiPathBuilder param(String key, Integer value) { 134 if (value != null) { 135 param(key, value.toString()); 136 } 137 return this; 138 } 139 140 /** 141 * Append the given parameter (key and value). This will only append the parameter if it is not null, and make sure 142 * to add the right separator ("?" or "&") before. The key and value will be separated by the "=" character. 143 * 144 * @param key of the parameter. Must not be null or empty 145 * @param value of the parameter. May be null 146 * @return this, for method chaining 147 */ 148 public ApiPathBuilder param(String key, Boolean value) { 149 if (value != null) { 150 param(key, value.toString()); 151 } 152 return this; 153 } 154 155 /** 156 * Append the given node filters, only if it is not null/empty 157 * 158 * @param nodeFilters may be null/empty 159 * @return this, for method chaining 160 * @see ParametersUtil#generateNodeFiltersString(Properties) 161 */ 162 public ApiPathBuilder nodeFilters(Properties nodeFilters) { 163 String filters = ParametersUtil.generateNodeFiltersString(nodeFilters); 164 if (StringUtils.isNotBlank(filters)) { 165 appendSeparator(); 166 append(filters); 167 } 168 return this; 169 } 170 171 /** 172 * When POSTing a request, add the given {@link InputStream} as an attachment to the content of the request. This 173 * will only add the stream if it is not null. 174 * 175 * @param name of the attachment. Must not be null or empty 176 * @param stream. May be null 177 * @return this, for method chaining 178 */ 179 public ApiPathBuilder attach(String name, InputStream stream) { 180 if (stream != null) { 181 attachments.put(name, stream); 182 } 183 return this; 184 } 185 186 /** 187 * @return all attachments to be POSTed, with their names 188 */ 189 public Map<String, InputStream> getAttachments() { 190 return attachments; 191 } 192 193 @Override 194 public String toString() { 195 return apiPath.toString(); 196 } 197 198 /** 199 * Append the given string 200 * 201 * @param str to append 202 */ 203 private void append(String str) { 204 apiPath.append(str); 205 } 206 207 /** 208 * Append the right separator "?" or "&" between 2 parameters 209 */ 210 private void appendSeparator() { 211 if (firstParamDone) { 212 append("&"); 213 } else { 214 append("?"); 215 firstParamDone = true; 216 } 217 } 218 219 }