1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.net.URI;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Map;
26
27 import javax.mail.internet.AddressException;
28 import javax.mail.internet.InternetAddress;
29 import javax.validation.ValidationException;
30 import javax.xml.bind.DatatypeConverter;
31
32 import org.forgerock.api.enums.ReadPolicy;
33 import org.wrensecurity.guava.common.net.InetAddresses;
34 import org.wrensecurity.guava.common.net.InternetDomainName;
35 import org.forgerock.json.JsonValue;
36
37 import com.fasterxml.jackson.annotation.JsonProperty;
38 import com.fasterxml.jackson.module.jsonSchema.types.StringSchema;
39 import org.forgerock.api.enums.WritePolicy;
40
41
42
43
44 class CrestStringSchema extends StringSchema implements CrestReadWritePoliciesSchema, OrderedFieldSchema, EnumSchema,
45 ValidatableSchema, PropertyFormatSchema, WithExampleSchema<String> {
46 private WritePolicy writePolicy;
47 private ReadPolicy readPolicy;
48 private Boolean errorOnWritePolicyFailure;
49 private Boolean returnOnDemand;
50 private Integer propertyOrder;
51 private String propertyFormat;
52 @JsonProperty
53 private Map<String, List<String>> options;
54 private String example;
55
56 @Override
57 public WritePolicy getWritePolicy() {
58 return writePolicy;
59 }
60
61 @Override
62 public void setWritePolicy(WritePolicy policy) {
63 this.writePolicy = policy;
64 }
65
66 @Override
67 public ReadPolicy getReadPolicy() {
68 return readPolicy;
69 }
70
71 @Override
72 public void setReadPolicy(ReadPolicy readPolicy) {
73 this.readPolicy = readPolicy;
74 }
75
76 @Override
77 public Boolean getErrorOnWritePolicyFailure() {
78 return errorOnWritePolicyFailure;
79 }
80
81 @Override
82 public void setErrorOnWritePolicyFailure(Boolean errorOnWritePolicyFailure) {
83 this.errorOnWritePolicyFailure = errorOnWritePolicyFailure;
84 }
85
86 @Override
87 public Boolean getReturnOnDemand() {
88 return returnOnDemand;
89 }
90
91 @Override
92 public void setReturnOnDemand(Boolean returnOnDemand) {
93 this.returnOnDemand = returnOnDemand;
94 }
95
96 @Override
97 public Integer getPropertyOrder() {
98 return propertyOrder;
99 }
100
101 @Override
102 public void setPropertyOrder(Integer order) {
103 this.propertyOrder = order;
104 }
105
106 @Override
107 public List<String> getEnumTitles() {
108 return options == null ? null : options.get(ENUM_TITLES);
109 }
110
111 @Override
112 public void setEnumTitles(List<String> titles) {
113 this.options = Collections.singletonMap(ENUM_TITLES, titles);
114 }
115
116 @Override
117 public void validate(JsonValue object) throws ValidationException {
118 if (!object.isString()) {
119 throw new ValidationException("Expected string but got: " + object.getObject());
120 }
121 String s = object.asString();
122 validateEnum(enums, s);
123 if (!isEmpty(propertyFormat)) {
124 validateFormat(s);
125 }
126 }
127
128
129
130
131
132
133
134
135 private void validateFormat(final String s) throws ValidationException {
136 switch (propertyFormat) {
137 case "date-time":
138
139 try {
140 DatatypeConverter.parseDateTime(s);
141 } catch (IllegalArgumentException e) {
142 throw new ValidationException("Expected date-time format, but got " + s, e);
143 }
144 return;
145 case "date":
146 case "full-date":
147
148
149 try {
150 DatatypeConverter.parseDate(s);
151 } catch (IllegalArgumentException e) {
152 throw new ValidationException("Expected date/full-date format, but got " + s, e);
153 }
154 return;
155 case "email":
156
157 try {
158 new InternetAddress(s).validate();
159 } catch (AddressException e) {
160 throw new ValidationException("Expected email, but got " + s, e);
161 }
162 return;
163 case "hostname":
164
165 if (!InternetDomainName.isValid(s)) {
166 throw new ValidationException("Expected host-name, but got " + s);
167 }
168 return;
169 case "ipv4":
170
171 if (!InetAddresses.isInetAddress(s) || s.indexOf(':') != -1) {
172 throw new ValidationException("Expected ipv4, but got " + s);
173 }
174 return;
175 case "ipv6":
176
177 if (!InetAddresses.isInetAddress(s) || s.indexOf(':') == -1) {
178 throw new ValidationException("Expected ipv6, but got " + s);
179 }
180 return;
181 case "uri":
182
183 try {
184 URI.create(s);
185 } catch (IllegalArgumentException e) {
186 throw new ValidationException("Expected URI format, but got " + s, e);
187 }
188 return;
189 }
190 }
191
192
193 @JsonProperty("format")
194 @Override
195 public String getPropertyFormat() {
196 if (!isEmpty(propertyFormat)) {
197 return propertyFormat;
198 }
199
200 return format == null ? null : format.toString();
201 }
202
203 @Override
204 public void setPropertyFormat(String propertyFormat) {
205 this.propertyFormat = propertyFormat;
206 }
207
208 @Override
209 public String getExample() {
210 return example;
211 }
212
213 @Override
214 public void setExample(String example) {
215 this.example = example;
216 }
217 }