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