1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.sys.context;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Map;
21
22 import org.apache.commons.lang.StringUtils;
23 import org.kuali.rice.kns.service.DataDictionaryService;
24
25
26
27
28
29 public class AttributeSchemaValidationBuilder {
30 protected static final String DD_MAP_MAX_LENGTH_KEY = "maxLength";
31 protected static final String DD_MAP_EXACT_LENGTH_KEY = "validationPattern.exactLength";
32 protected static final String DD_MAP_REQUIRED_KEY = "required";
33 protected static final String DD_MAP_EXCLUSIVE_MIN_KEY = "exclusiveMin";
34 protected static final String DD_MAP_EXCLUSIVE_MAX_KEY = "exclusiveMax";
35 protected static final String DD_MAP_VALIDATION_KEY = "validationPattern";
36 protected static final String DD_MAP_VALIDATION_TYPE_KEY = "type";
37 protected static final String DD_ALLOW_WHITESPACE_KEY = "validationPattern.allowWhitespace";
38
39 public static class DD_VALIDATION_TYPES {
40 public static final String DATE = "date";
41 public static final String EMAIL = "emailAddress";
42 public static final String FIXED_POINT = "fixedPoint";
43 public static final String FLOATING_POINT = "floatingPoint";
44 public static final String MONTH = "month";
45 public static final String PHONE_NUMBER = "phoneNumber";
46 public static final String TIMESTAMP = "timestamp";
47 public static final String YEAR = "year";
48 public static final String ZIP_CODE = "zipcode";
49 public static final String ALPHA_NUMBER = "alphaNumeric";
50 public static final String ALPHA = "alpha";
51 public static final String ANY_CHARACTER = "anyCharacter";
52 public static final String CHARSET = "charset";
53 public static final String NUMBERIC = "numeric";
54 public static final String REGEX = "regex";
55 }
56
57 public static final String XSD_SCHEMA_PREFIX = "xsd:";
58
59 public static class SCHEMA_BASE_TYPES {
60 public static final String DATE = "date";
61 public static final String DATE_TIME = "dateTime";
62 public static final String STRING = "normalizedString";
63 public static final String INTEGER = "integer";
64 public static final String DECIMAL = "decimal";
65 }
66
67 protected String attributeKey;
68 protected Map attributeMap;
69
70
71
72
73 public AttributeSchemaValidationBuilder() {
74
75 }
76
77
78
79
80
81
82 public AttributeSchemaValidationBuilder(String attributeKey) {
83 this.attributeKey = attributeKey;
84
85 Map dataDictionaryMap = SpringContext.getBean(DataDictionaryService.class).getDataDictionaryMap();
86 String boClassName = StringUtils.substringBefore(attributeKey, ".");
87 String attributeName = StringUtils.substringAfter(attributeKey, ".");
88
89 Map boMap = (Map) dataDictionaryMap.get(boClassName);
90 if (boMap == null) {
91 throw new RuntimeException("Unable to find bo map for class: " + boClassName);
92 }
93
94 Map attributesMap = (Map) boMap.get("attributes");
95 this.attributeMap = (Map) attributesMap.get(attributeName);
96 if (this.attributeMap == null) {
97 throw new RuntimeException("Unable to find export map for attribute: " + attributeKey);
98 }
99 }
100
101
102
103
104
105
106
107 public Collection toSchemaType() {
108 Collection schemaType = new ArrayList();
109
110 schemaType.add(getTypeTagOpener());
111 schemaType.add(getRestrictionTagOpener());
112 schemaType.addAll(getFurtherRestrictionTags());
113 schemaType.add(getRestrictionTagCloser());
114 schemaType.add(getTypeTagCloser());
115
116 return schemaType;
117 }
118
119
120
121
122
123
124 public String getTypeTagOpener() {
125 return String.format(" <%ssimpleType name=\"%s\">", XSD_SCHEMA_PREFIX, attributeKey);
126 }
127
128
129
130
131
132
133 public String getTypeTagCloser() {
134 return String.format(" </%ssimpleType>", XSD_SCHEMA_PREFIX);
135 }
136
137
138
139
140
141
142 public String getRestrictionTagOpener() {
143 String xsdBase = "";
144 if (isDateType()) {
145 xsdBase = XSD_SCHEMA_PREFIX + SCHEMA_BASE_TYPES.DATE;
146 }
147 else if (isTimestampType()) {
148 xsdBase = XSD_SCHEMA_PREFIX + SCHEMA_BASE_TYPES.DATE_TIME;
149 }
150 else if (isDecimalType() || isFloatingType()) {
151 xsdBase = XSD_SCHEMA_PREFIX + SCHEMA_BASE_TYPES.DECIMAL;
152 }
153 else if (isNumericType()) {
154 xsdBase = XSD_SCHEMA_PREFIX + SCHEMA_BASE_TYPES.INTEGER;
155 }
156 else {
157 xsdBase = XSD_SCHEMA_PREFIX + SCHEMA_BASE_TYPES.STRING;
158 }
159
160 return String.format(" <%srestriction base=\"%s\">", XSD_SCHEMA_PREFIX, xsdBase);
161 }
162
163
164
165
166
167
168 public String getRestrictionTagCloser() {
169 return String.format(" </%srestriction>", XSD_SCHEMA_PREFIX);
170 }
171
172
173
174
175
176
177 public Collection getFurtherRestrictionTags() {
178 Collection restrictions = new ArrayList();
179
180
181 boolean required = getRequiredFromMap();
182 if (required) {
183 if (isStringType()) {
184 restrictions.add(String.format(" <%sminLength value=\"1\"/>", XSD_SCHEMA_PREFIX));
185 }
186 else {
187 restrictions.add(String.format(" <%spattern value=\"[^\\s]+\"/>", XSD_SCHEMA_PREFIX));
188 }
189 }
190
191 if (isDateType() || isTimestampType() || isFloatingType()) {
192 return restrictions;
193 }
194
195 if (isDecimalType()) {
196 restrictions.add(String.format(" <%sfractionDigits value=\"2\"/>", XSD_SCHEMA_PREFIX));
197 return restrictions;
198 }
199
200 if (isNumericType()) {
201 String exclusiveMin = (String) attributeMap.get(DD_MAP_EXCLUSIVE_MIN_KEY);
202 String exclusiveMax = (String) attributeMap.get(DD_MAP_EXCLUSIVE_MAX_KEY);
203 if (StringUtils.isNotBlank(exclusiveMin)) {
204 restrictions.add(String.format(" <%sminExclusive value=\"%s\"/>", XSD_SCHEMA_PREFIX, exclusiveMin));
205 }
206 if (StringUtils.isNotBlank(exclusiveMax)) {
207 restrictions.add(String.format(" <%smaxExclusive value=\"%s\"/>", XSD_SCHEMA_PREFIX, exclusiveMax));
208 }
209
210 int exactLength = getExactLengthFromMap();
211 if (exactLength > 0) {
212 restrictions.add(String.format(" <%stotalDigits value=\"%s\"/>", XSD_SCHEMA_PREFIX, exactLength));
213 }
214
215 return restrictions;
216 }
217
218
219 int maxLength = getMaxLengthFromMap();
220 if (maxLength > 0) {
221 restrictions.add(String.format(" <%smaxLength value=\"%s\"/>", XSD_SCHEMA_PREFIX, maxLength));
222 }
223
224 int exactLength = getExactLengthFromMap();
225 if (exactLength > 0) {
226 restrictions.add(String.format(" <%slength value=\"%s\"/>", XSD_SCHEMA_PREFIX, exactLength));
227 }
228
229 boolean collapseWhitespace = !getAllowWhitespaceFromMap();
230 if (collapseWhitespace) {
231 restrictions.add(String.format(" <%swhiteSpace value=\"replace\"/>", XSD_SCHEMA_PREFIX));
232 }
233
234 return restrictions;
235 }
236
237
238
239
240
241
242 protected int getMaxLengthFromMap() {
243 String maxLengthStr = (String) attributeMap.get(DD_MAP_MAX_LENGTH_KEY);
244 if (StringUtils.isNotBlank(maxLengthStr)) {
245 int maxLength = Integer.parseInt(maxLengthStr);
246
247 return maxLength;
248 }
249
250 return -1;
251 }
252
253
254
255
256
257
258 protected int getExactLengthFromMap() {
259 String exactLengthStr = (String) attributeMap.get(DD_MAP_EXACT_LENGTH_KEY);
260 if (StringUtils.isNotBlank(exactLengthStr)) {
261 int exactLength = Integer.parseInt(exactLengthStr);
262
263 return exactLength;
264 }
265
266 return -1;
267 }
268
269
270
271
272
273
274 protected boolean getRequiredFromMap() {
275 String requiredStr = (String) attributeMap.get(DD_MAP_REQUIRED_KEY);
276 if (StringUtils.isNotBlank(requiredStr)) {
277 boolean required = Boolean.parseBoolean(requiredStr);
278
279 return required;
280 }
281
282 return false;
283 }
284
285
286
287
288
289
290 protected boolean getAllowWhitespaceFromMap() {
291 String whitespaceStr = (String) attributeMap.get(DD_ALLOW_WHITESPACE_KEY);
292 if (StringUtils.isNotBlank(whitespaceStr)) {
293 boolean allowWhitespace = Boolean.parseBoolean(whitespaceStr);
294
295 return allowWhitespace;
296 }
297
298 return false;
299 }
300
301
302
303
304
305
306 protected String getValidationType() {
307 String validationType = "";
308 Map validationMap = (Map) attributeMap.get(DD_MAP_VALIDATION_KEY);
309 if (validationMap != null) {
310 validationType = (String) validationMap.get(DD_MAP_VALIDATION_TYPE_KEY);
311 }
312
313 return validationType;
314 }
315
316
317
318
319
320
321 protected boolean isDateType() {
322 return DD_VALIDATION_TYPES.DATE.equals(getValidationType());
323 }
324
325
326
327
328
329
330 protected boolean isTimestampType() {
331 return DD_VALIDATION_TYPES.TIMESTAMP.equals(getValidationType());
332 }
333
334
335
336
337
338
339 protected boolean isNumericType() {
340 return DD_VALIDATION_TYPES.NUMBERIC.equals(getValidationType());
341 }
342
343
344
345
346
347
348 protected boolean isDecimalType() {
349 return DD_VALIDATION_TYPES.FIXED_POINT.equals(getValidationType());
350 }
351
352
353
354
355
356
357 protected boolean isFloatingType() {
358 return DD_VALIDATION_TYPES.FLOATING_POINT.equals(getValidationType());
359 }
360
361
362
363
364
365
366 protected boolean isStringType() {
367 return !isDateType() && !isTimestampType() && !isNumericType() && !isDecimalType() && !isFloatingType();
368 }
369
370
371
372
373
374
375 public String getAttributeKey() {
376 return attributeKey;
377 }
378
379
380
381
382
383
384 public void setAttributeKey(String attributeKey) {
385 this.attributeKey = attributeKey;
386 }
387
388
389 }