001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2016 ForgeRock AS. 015 */ 016 017package org.forgerock.api.models; 018 019import static org.forgerock.api.util.ValidationUtil.isEmpty; 020 021import java.util.Arrays; 022import java.util.Objects; 023 024import com.fasterxml.jackson.annotation.JsonInclude; 025import com.fasterxml.jackson.annotation.JsonProperty; 026import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 027import org.forgerock.api.ApiValidationException; 028import org.forgerock.api.enums.ParameterSource; 029import org.forgerock.util.i18n.LocalizableString; 030 031/** 032 * Class that represents the Parameter type in API descriptor. 033 */ 034@JsonDeserialize(builder = Parameter.Builder.class) 035@JsonInclude(JsonInclude.Include.NON_EMPTY) 036public final class Parameter { 037 038 private final String name; 039 private final String type; 040 private final String defaultValue; //Todo String? 041 private final LocalizableString description; 042 private final ParameterSource source; 043 private final Boolean required; 044 private final String[] enumValues; 045 private final String[] enumTitles; 046 047 // TODO "Other appropriate fields as described in the JSON Schema Validation spec may also be used." 048 049 /** 050 * Private Parameter constructor called by the builder. 051 * 052 * @param builder Builder that holds the values for setting the parameter properties 053 */ 054 private Parameter(Builder builder) { 055 this.name = builder.name; 056 this.type = builder.type; 057 this.defaultValue = builder.defaultValue; 058 this.description = builder.description; 059 this.source = builder.source; 060 this.required = builder.required; 061 this.enumValues = builder.enumValues; 062 this.enumTitles = builder.enumTitles; 063 064 if (isEmpty(name) || isEmpty(type) || source == null) { 065 throw new ApiValidationException("name, type, and source are required"); 066 } 067 if (enumTitles != null) { 068 if (enumValues == null) { 069 throw new ApiValidationException("enum[] required when enum_values[] is defined"); 070 } 071 if (enumTitles.length != enumValues.length) { 072 throw new ApiValidationException("enum[] and enum_values[] must be the same length"); 073 } 074 } 075 } 076 077 /** 078 * Getter of the name of the parameter. 079 * 080 * @return Parameter name 081 */ 082 public String getName() { 083 return name; 084 } 085 086 /** 087 * Getter of the parameter type. 088 * 089 * @return Parameter type 090 */ 091 public String getType() { 092 return type; 093 } 094 095 /** 096 * Getter of the parameter's default value. 097 * 098 * @return Parameter default value 099 */ 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}