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.jackson;
18  
19  import static org.forgerock.api.jackson.JacksonUtils.*;
20  import static org.forgerock.api.util.ValidationUtil.isEmpty;
21  
22  import java.math.BigDecimal;
23  import java.util.Collections;
24  import java.util.List;
25  import java.util.Map;
26  
27  import javax.validation.ValidationException;
28  
29  import org.forgerock.api.enums.ReadPolicy;
30  import org.forgerock.json.JsonValue;
31  
32  import com.fasterxml.jackson.annotation.JsonProperty;
33  import com.fasterxml.jackson.module.jsonSchema.types.NumberSchema;
34  import org.forgerock.api.enums.WritePolicy;
35  
36  /**
37   * An extension to the Jackson {@code NumberSchema} that includes the custom CREST JSON Schema attributes.
38   */
39  class CrestNumberSchema extends NumberSchema implements CrestReadWritePoliciesSchema, OrderedFieldSchema, EnumSchema,
40          ValidatableSchema, MultipleOfSchema, PropertyFormatSchema, MinimumMaximumSchema, WithExampleSchema<BigDecimal> {
41      private WritePolicy writePolicy;
42      private ReadPolicy readPolicy;
43      private Boolean errorOnWritePolicyFailure;
44      private Boolean returnOnDemand;
45      private Integer propertyOrder;
46      private Double multipleOf;
47      private String propertyFormat;
48      private BigDecimal propertyMinimum;
49      private BigDecimal propertyMaximum;
50      @JsonProperty
51      private Map<String, List<String>> options;
52      private BigDecimal example;
53  
54      @Override
55      public WritePolicy getWritePolicy() {
56          return writePolicy;
57      }
58  
59      @Override
60      public void setWritePolicy(WritePolicy policy) {
61          this.writePolicy = policy;
62      }
63  
64      @Override
65      public ReadPolicy getReadPolicy() {
66          return readPolicy;
67      }
68  
69      @Override
70      public void setReadPolicy(ReadPolicy readPolicy) {
71          this.readPolicy = readPolicy;
72      }
73  
74      @Override
75      public Boolean getErrorOnWritePolicyFailure() {
76          return errorOnWritePolicyFailure;
77      }
78  
79      @Override
80      public void setErrorOnWritePolicyFailure(Boolean errorOnWritePolicyFailure) {
81          this.errorOnWritePolicyFailure = errorOnWritePolicyFailure;
82      }
83  
84      @Override
85      public Boolean getReturnOnDemand() {
86          return returnOnDemand;
87      }
88  
89      @Override
90      public void setReturnOnDemand(Boolean returnOnDemand) {
91          this.returnOnDemand = returnOnDemand;
92      }
93  
94      @Override
95      public Integer getPropertyOrder() {
96          return propertyOrder;
97      }
98  
99      @Override
100     public void setPropertyOrder(Integer order) {
101         this.propertyOrder = order;
102     }
103 
104     @Override
105     public List<String> getEnumTitles() {
106         return options == null ? null : options.get(ENUM_TITLES);
107     }
108 
109     @Override
110     public void setEnumTitles(List<String> titles) {
111         this.options = Collections.singletonMap(ENUM_TITLES, titles);
112     }
113 
114     @Override
115     public void validate(JsonValue object) throws ValidationException {
116         if (!object.isNumber()) {
117             throw new ValidationException("Expected number, but got " + object.getObject());
118         }
119         Number number = object.asNumber();
120         validateMaximumAndMinimum(number, getMaximum(), getExclusiveMaximum(), getMinimum(), getExclusiveMinimum());
121         validateFormatForNumber(format);
122         validateEnum(enums, number.toString());
123     }
124 
125     @Override
126     public Double getMultipleOf() {
127         return multipleOf;
128     }
129 
130     @Override
131     public void setMultipleOf(Double multipleOf) {
132         this.multipleOf = multipleOf;
133     }
134 
135     /**
136      * Gets read-only property. This method overrides the superclass' definition of "readOnly" being all lower-case,
137      * via the {@code JsonProperty} annotation.
138      *
139      * @return {@code true} if property is read-only, otherwise {@code false} or {@code null}
140      */
141     @JsonProperty("readOnly")
142     @Override
143     public Boolean getReadonly() {
144         return super.getReadonly();
145     }
146 
147     // This method overrides the superclass' definition of "format" via JsonProperty annotation
148     @JsonProperty("format")
149     @Override
150     public String getPropertyFormat() {
151         if (!isEmpty(propertyFormat)) {
152             return propertyFormat;
153         }
154         // fallback to old behavior
155         return format == null ? null : format.toString();
156     }
157 
158     @Override
159     public void setPropertyFormat(String propertyFormat) {
160         this.propertyFormat = propertyFormat;
161     }
162 
163     // This method overrides the superclass' definition of "minimum" via JsonProperty annotation
164     @JsonProperty("minimum")
165     @Override
166     public BigDecimal getPropertyMinimum() {
167         return propertyMinimum;
168     }
169 
170     @Override
171     public void setPropertyMinimum(BigDecimal propertyMinimum) {
172         this.propertyMinimum = propertyMinimum;
173     }
174 
175     // This method overrides the superclass' definition of "maximum" via JsonProperty annotation
176     @JsonProperty("maximum")
177     @Override
178     public BigDecimal getPropertyMaximum() {
179         return propertyMaximum;
180     }
181 
182     @Override
183     public void setPropertyMaximum(BigDecimal propertyMaximum) {
184         this.propertyMaximum = propertyMaximum;
185     }
186 
187     @Override
188     public BigDecimal getExample() {
189         return example;
190     }
191 
192     @Override
193     public void setExample(String example) {
194         this.example = new BigDecimal(example);
195     }
196 }