View Javadoc
1   /*
2    * The contents of this file are subject to the terms of the Common Development and
3    * Distribution License (the License). You may not use this file except in compliance with the
4    * License.
5    *
6    * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7    * specific language governing permission and limitations under the License.
8    *
9    * When distributing Covered Software, include this CDDL Header Notice in each file and include
10   * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11   * Header, with the fields enclosed by brackets [] replaced by your own identifying
12   * information: "Portions copyright [year] [name of copyright owner]".
13   *
14   * Copyright 2016 ForgeRock AS.
15   */
16  
17  package org.forgerock.api.models;
18  
19  import static org.forgerock.api.util.ValidationUtil.isEmpty;
20  
21  import java.util.Arrays;
22  import java.util.Objects;
23  
24  import com.fasterxml.jackson.annotation.JsonInclude;
25  import com.fasterxml.jackson.annotation.JsonProperty;
26  import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
27  import org.forgerock.api.ApiValidationException;
28  import org.forgerock.api.enums.ParameterSource;
29  import org.forgerock.util.i18n.LocalizableString;
30  
31  /**
32   * Class that represents the Parameter type in API descriptor.
33   */
34  @JsonDeserialize(builder = Parameter.Builder.class)
35  @JsonInclude(JsonInclude.Include.NON_EMPTY)
36  public final class Parameter {
37  
38      private final String name;
39      private final String type;
40      private final String defaultValue; //Todo String?
41      private final LocalizableString description;
42      private final ParameterSource source;
43      private final Boolean required;
44      private final String[] enumValues;
45      private final String[] enumTitles;
46  
47      // TODO "Other appropriate fields as described in the JSON Schema Validation spec may also be used."
48  
49      /**
50       * Private Parameter constructor called by the builder.
51       *
52       * @param builder Builder that holds the values for setting the parameter properties
53       */
54      private Parameter(Builder builder) {
55          this.name = builder.name;
56          this.type = builder.type;
57          this.defaultValue = builder.defaultValue;
58          this.description = builder.description;
59          this.source = builder.source;
60          this.required = builder.required;
61          this.enumValues = builder.enumValues;
62          this.enumTitles = builder.enumTitles;
63  
64          if (isEmpty(name) || isEmpty(type) || source == null) {
65              throw new ApiValidationException("name, type, and source are required");
66          }
67          if (enumTitles != null) {
68              if (enumValues == null) {
69                  throw new ApiValidationException("enum[] required when enum_values[] is defined");
70              }
71              if (enumTitles.length != enumValues.length) {
72                  throw new ApiValidationException("enum[] and enum_values[] must be the same length");
73              }
74          }
75      }
76  
77      /**
78       * Getter of the name of the parameter.
79       *
80       * @return Parameter name
81       */
82      public String getName() {
83          return name;
84      }
85  
86      /**
87       * Getter of the parameter type.
88       *
89       * @return Parameter type
90       */
91      public String getType() {
92          return type;
93      }
94  
95      /**
96       * Getter of the parameter's default value.
97       *
98       * @return Parameter default value
99       */
100     public String getDefaultValue() {
101         return defaultValue;
102     }
103 
104     /**
105      * Getter of the parameter description.
106      *
107      * @return Parameter description
108      */
109     public LocalizableString getDescription() {
110         return description;
111     }
112 
113     /**
114      * Getter of the parameter source.
115      *
116      * @return Parameter source enum
117      */
118     public ParameterSource getSource() {
119         return source;
120     }
121 
122     /**
123      * Getter of the required property.
124      *
125      * @return Required
126      */
127     public Boolean isRequired() {
128         return required;
129     }
130 
131     /**
132      * Getter of required enum-values.
133      *
134      * @return Required enum-values or {@code null}
135      */
136     @JsonProperty("enum")
137     public String[] getEnumValues() {
138         return enumValues;
139     }
140 
141     /**
142      * Getter of enum-titles.
143      *
144      * @return Enum-titles or {@code null}
145      */
146     @JsonProperty("options/enum_titles")
147     public String[] getEnumTitles() {
148         return enumTitles;
149     }
150 
151     @Override
152     public boolean equals(Object o) {
153         if (this == o) {
154             return true;
155         }
156         if (o == null || getClass() != o.getClass()) {
157             return false;
158         }
159         Parameter parameter = (Parameter) o;
160         return required == parameter.required
161                 && Objects.equals(name, parameter.name)
162                 && Objects.equals(type, parameter.type)
163                 && Objects.equals(defaultValue, parameter.defaultValue)
164                 && Objects.equals(description, parameter.description)
165                 && source == parameter.source
166                 && Arrays.equals(enumValues, parameter.enumValues)
167                 && Arrays.equals(enumTitles, parameter.enumTitles);
168     }
169 
170     @Override
171     public int hashCode() {
172         return Objects.hash(name, type, defaultValue, description, source, required, enumValues, enumTitles);
173     }
174 
175     /**
176      * New parameter builder.
177      *
178      * @return Builder
179      */
180     public static Builder parameter() {
181         return new Builder();
182     }
183 
184     /**
185      * Builds a Parameter object from the data in the annotation.
186      * @param type The type to resolve {@link LocalizableString}s from.
187      * @param parameter The annotation that holds the data
188      * @return Parameter instance
189      */
190     public static Parameter fromAnnotation(Class<?> type, org.forgerock.api.annotations.Parameter parameter) {
191         return parameter()
192                 .description(new LocalizableString(parameter.description(), type))
193                 .defaultValue(parameter.defaultValue())
194                 .enumValues(parameter.enumValues())
195                 .enumTitles(parameter.enumTitles())
196                 .required(parameter.required())
197                 .name(parameter.name())
198                 .source(parameter.source())
199                 .type(parameter.type())
200                 .build();
201     }
202 
203     /**
204      * Builder to construct Parameter object.
205      */
206     public static final class Builder {
207 
208         private String name;
209         private String type;
210         private String defaultValue;
211         private LocalizableString description;
212         private ParameterSource source;
213         private Boolean required;
214         private String[] enumValues;
215         private String[] enumTitles;
216 
217         private Builder() {
218         }
219 
220         /**
221          * Set the parameter name.
222          *
223          * @param name Parameter name
224          * @return Builder
225          */
226         @JsonProperty("name")
227         public Builder name(String name) {
228             this.name = name;
229             return this;
230         }
231 
232         /**
233          * Sets enum-values that must match.
234          *
235          * @param enumValues Enum-values
236          * @return Builder
237          */
238         @JsonProperty("enum")
239         public Builder enumValues(String... enumValues) {
240             this.enumValues = enumValues;
241             return this;
242         }
243 
244         /**
245          * Sets enum-titles that <b>must</b> be the same length as {@link #enumValues(String[])}, if provided.
246          *
247          * @param enumTitles Enum-titles
248          * @return Builder
249          */
250         @JsonProperty("options/enum_titles")
251         public Builder enumTitles(String... enumTitles) {
252             this.enumTitles = enumTitles;
253             return this;
254         }
255 
256         /**
257          * Set the parameter type.
258          *
259          * @param type Parameter type
260          * @return Builder
261          */
262         @JsonProperty("type")
263         public Builder type(String type) {
264             this.type = type;
265             return this;
266         }
267 
268         /**
269          * Set the parameter default value.
270          *
271          * @param defaultValue If exists, the default value
272          * @return builder
273          */
274         @JsonProperty("defaultValue")
275         public Builder defaultValue(String defaultValue) {
276             this.defaultValue = defaultValue;
277             return this;
278         }
279 
280         /**
281          * Set the parameter description.
282          *
283          * @param description The description of the parameter
284          * @return builder
285          */
286         public Builder description(LocalizableString description) {
287             this.description = description;
288             return this;
289         }
290 
291         /**
292          * Set the parameter description.
293          *
294          * @param description The description of the parameter
295          * @return builder
296          */
297         @JsonProperty("description")
298         public Builder description(String description) {
299             this.description = new LocalizableString(description);
300             return this;
301         }
302 
303         /**
304          * Set the parameter source.
305          *
306          * @param source Where the parameter comes from. May be: PATH or ADDITIONAL
307          * @return builder
308          */
309         @JsonProperty("source")
310         public Builder source(ParameterSource source) {
311             this.source = source;
312             return this;
313         }
314 
315         /**
316          * Set the required property.
317          *
318          * @param required Whether the parameter is required
319          * @return builder
320          */
321         @JsonProperty("required")
322         public Builder required(Boolean required) {
323             this.required = required;
324             return this;
325         }
326 
327         /**
328          * Builds the Parameter.
329          *
330          * @return The parameter instance
331          */
332         public Parameter build() {
333             return new Parameter(this);
334         }
335     }
336 
337 }