View Javadoc

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 }