1
2
3
4
5
6
7
8
9 package org.kuali.student.r1.common.assembly.dictionary;
10
11 import org.apache.log4j.Logger;
12 import org.kuali.student.r1.common.assembly.data.ConstraintMetadata;
13 import org.kuali.student.r1.common.assembly.data.Data;
14 import org.kuali.student.r1.common.assembly.data.Data.DataType;
15 import org.kuali.student.r1.common.assembly.data.Data.Value;
16 import org.kuali.student.r1.common.assembly.data.LookupMetadata;
17 import org.kuali.student.r1.common.assembly.data.LookupMetadata.WidgetOption;
18 import org.kuali.student.r1.common.assembly.data.LookupParamMetadata;
19 import org.kuali.student.r1.common.assembly.data.Metadata;
20 import org.kuali.student.r1.common.assembly.data.Metadata.WriteAccess;
21 import org.kuali.student.r1.common.assembly.data.UILookupConfig;
22 import org.kuali.student.r1.common.assembly.data.UILookupData;
23 import org.kuali.student.r1.common.dictionary.dto.CaseConstraint;
24 import org.kuali.student.r1.common.dictionary.dto.CommonLookupParam;
25 import org.kuali.student.r1.common.dictionary.dto.Constraint;
26 import org.kuali.student.r1.common.dictionary.dto.FieldDefinition;
27 import org.kuali.student.r1.common.dictionary.dto.ObjectStructureDefinition;
28 import org.kuali.student.r1.common.dictionary.dto.WhenConstraint;
29 import org.kuali.student.r1.common.dictionary.service.DictionaryService;
30 import org.kuali.student.r2.common.dto.DtoConstants;
31 import org.kuali.student.r2.common.dto.DtoConstants.DtoState;
32 import org.kuali.student.r2.common.infc.ValidationResult.ErrorLevel;
33 import org.kuali.student.r2.common.util.date.DateFormatters;
34 import org.springframework.beans.BeanUtils;
35 import org.springframework.context.ApplicationContext;
36 import org.springframework.context.support.ClassPathXmlApplicationContext;
37
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Map;
43
44
45
46
47
48
49
50 public class MetadataServiceImpl {
51 final Logger LOG = Logger.getLogger(MetadataServiceImpl.class);
52
53
54 private List<DictionaryService> dictionaryServices;
55 private List<UILookupConfig> lookupObjectStructures;
56 private String uiLookupContext;
57
58 private static class RecursionCounter {
59 public static final int MAX_DEPTH = 4;
60
61 private Map<String, Integer> recursions = new HashMap<String, Integer>();
62
63 public int increment(String objectName) {
64 Integer hits = recursions.get(objectName);
65
66 if (hits == null) {
67 hits = new Integer(1);
68 } else {
69 hits++;
70 }
71 recursions.put(objectName, hits);
72 return hits;
73 }
74
75 public int decrement(String objectName) {
76 Integer hits = recursions.get(objectName);
77 if (hits >= 1) {
78 hits--;
79 }
80
81 recursions.put(objectName, hits);
82 return hits;
83 }
84 }
85
86 public MetadataServiceImpl() {
87 super();
88 }
89
90
91
92
93
94
95 public MetadataServiceImpl(DictionaryService... dictionaryServices) {
96 setDictionaryServices(Arrays.asList(dictionaryServices));
97 }
98
99 public synchronized void setDictionaryServices(List<DictionaryService> dictionaryServices) {
100 this.dictionaryServices = dictionaryServices;
101
102
103
104
105
106
107
108
109
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123 public Metadata getMetadata(String objectKey, String type, String state, String nextState, String documentTypeName) {
124 nextState = (nextState == null || nextState.length() <=0 ? DtoState.getNextStateAsString(state):nextState);
125 state = state==null?null:state.toUpperCase();
126 nextState = nextState==null?null:nextState.toUpperCase();
127
128 return getMetadataFromDictionaryService(objectKey, type, state, nextState, null, documentTypeName);
129 }
130
131
132
133
134
135
136 public Metadata getMetadataByWorkflowNode(String objectKey, String workflowNode, String documentTypeName) {
137
138 return getMetadataFromDictionaryService(objectKey, null, DtoState.DRAFT.toString(), null, workflowNode, documentTypeName);
139 }
140
141
142
143
144
145
146
147
148
149 public Metadata getMetadata(String objectKey, String type, String state) {
150 state = (state == null ? DtoState.DRAFT.toString():state);
151 String nextState = DtoState.getNextStateAsString(state);
152
153 return getMetadata(objectKey, type, state.toUpperCase(), nextState, null);
154 }
155
156
157
158
159
160
161
162
163
164 public Metadata getMetadata(String objectKey, String state) {
165 return getMetadata(objectKey, null, state);
166 }
167
168
169
170
171
172
173
174
175 public Metadata getMetadata(String objectKey) {
176 return getMetadata(objectKey, null, null);
177 }
178
179
180
181
182
183
184
185
186
187
188
189 protected Metadata getMetadataFromDictionaryService(String objectKey, String type, String state, String nextState, String workflowNode, String documentTypeName) {
190
191 Metadata metadata = new Metadata();
192
193 ObjectStructureDefinition objectStructure = getObjectStructure(objectKey);
194
195 metadata.setProperties(getProperties(objectStructure, type, state, nextState, workflowNode, new RecursionCounter(), documentTypeName));
196
197 metadata.setWriteAccess(WriteAccess.ALWAYS);
198 metadata.setDataType(DataType.DATA);
199 addLookupstoMetadata(objectKey, metadata, type);
200 return metadata;
201 }
202
203
204
205
206
207
208
209
210
211
212
213
214
215 private Map<String, Metadata> getProperties(ObjectStructureDefinition objectStructure, String type, String state, String nextState, String workflowNode, RecursionCounter counter, String documentTypeName) {
216 String objectName = objectStructure.getName();
217 int hits = counter.increment(objectName);
218
219 Map<String, Metadata> properties = null;
220
221 if (hits < RecursionCounter.MAX_DEPTH) {
222 properties = new HashMap<String, Metadata>();
223
224 List<FieldDefinition> attributes = objectStructure.getAttributes();
225 for (FieldDefinition fd : attributes) {
226
227 Metadata metadata = new Metadata();
228
229
230 metadata.setWriteAccess(WriteAccess.ALWAYS);
231 metadata.setDataType(convertDictionaryDataType(fd.getDataType()));
232
233 metadata.setConstraints(getConstraints(fd, type, state, nextState, workflowNode, documentTypeName));
234 metadata.setCanEdit(!fd.isReadOnly());
235 metadata.setCanUnmask(!fd.isMask());
236 metadata.setCanView(!fd.isHide());
237 metadata.setDynamic(fd.isDynamic());
238 metadata.setLabelKey(fd.getLabelKey());
239 metadata.setDefaultValue(convertDefaultValue(metadata.getDataType(), fd.getDefaultValue()));
240 metadata.setDefaultValuePath(fd.getDefaultValuePath());
241
242 if (fd.isPartialMask()){
243 metadata.setPartialMaskFormatter(fd.getPartialMaskFormatter());
244 }
245
246 if (fd.isMask()){
247 metadata.setMaskFormatter(fd.getMaskFormatter());
248 }
249
250
251 Map<String, Metadata> nestedProperties = null;
252 if (fd.getDataType() == org.kuali.student.r1.common.dictionary.dto.DataType.COMPLEX && fd.getDataObjectStructure() != null) {
253 nestedProperties = getProperties(fd.getDataObjectStructure(), type, state, nextState, workflowNode, counter, documentTypeName);
254 }
255
256
257 if (isRepeating(fd)) {
258 Metadata repeatingMetadata = new Metadata();
259 metadata.setDataType(DataType.LIST);
260
261 repeatingMetadata.setWriteAccess(WriteAccess.ALWAYS);
262 repeatingMetadata.setOnChangeRefreshMetadata(false);
263 repeatingMetadata.setDataType(convertDictionaryDataType(fd.getDataType()));
264
265 if (nestedProperties != null) {
266 repeatingMetadata.setProperties(nestedProperties);
267 }
268
269 Map<String, Metadata> repeatingProperty = new HashMap<String, Metadata>();
270 repeatingProperty.put("*", repeatingMetadata);
271 metadata.setProperties(repeatingProperty);
272 } else if (nestedProperties != null) {
273 metadata.setProperties(nestedProperties);
274 }
275
276 properties.put(fd.getName(), metadata);
277
278 }
279 }
280
281 counter.decrement(objectName);
282 return properties;
283 }
284
285
286
287
288
289
290
291 protected boolean isRepeating(FieldDefinition fd) {
292 boolean isRepeating = false;
293 try {
294 int maxOccurs = Integer.parseInt(fd.getMaxOccurs());
295 isRepeating = maxOccurs > 1;
296 } catch (NumberFormatException nfe) {
297 isRepeating = FieldDefinition.UNBOUNDED.equals(fd.getMaxOccurs());
298 }
299
300 return isRepeating;
301 }
302
303
304
305
306
307
308
309 protected ObjectStructureDefinition getObjectStructure(String objectKey) {
310
311
312 DictionaryService dictionaryService = null;
313 for (DictionaryService service : this.dictionaryServices){
314 List<String> objectTypes = service.getObjectTypes();
315 for (String objectType : objectTypes) {
316 if (objectType.equals(objectKey)){
317 dictionaryService = service;
318 }
319 }
320 }
321
322 if (dictionaryService == null) {
323 throw new RuntimeException("Dictionary service not provided for objectKey=[" + objectKey + "].");
324 }
325
326 return dictionaryService.getObjectStructure(objectKey);
327 }
328
329
330 protected List<ConstraintMetadata> getConstraints(FieldDefinition fd, String type, String state, String nextState, String workflowNode, String documentTypeName) {
331 List<ConstraintMetadata> constraints = new ArrayList<ConstraintMetadata>();
332
333 ConstraintMetadata constraintMetadata = new ConstraintMetadata();
334
335 updateConstraintMetadata(constraintMetadata, (Constraint) fd, type, state, nextState, workflowNode);
336 constraints.add(constraintMetadata);
337
338 return constraints;
339 }
340
341
342
343
344
345
346
347 protected void updateConstraintMetadata(ConstraintMetadata constraintMetadata, Constraint constraint, String type, String state, String nextState, String workflowNode) {
348
349
350
351
352 if (constraint.getMinLength() != null) {
353 constraintMetadata.setMinLength(constraint.getMinLength());
354 }
355
356
357 try {
358 if (constraint.getMaxLength() != null) {
359 constraintMetadata.setMaxLength(Integer.parseInt(constraint.getMaxLength()));
360 }
361
362 } catch (NumberFormatException nfe) {
363
364
365 constraintMetadata.setMaxLength(9999);
366 }
367
368
369 if (constraint.getMinOccurs() != null) {
370 constraintMetadata.setMinOccurs(constraint.getMinOccurs());
371 }
372
373
374 String maxOccurs = constraint.getMaxOccurs();
375 if (maxOccurs != null) {
376 try {
377 constraintMetadata.setMaxOccurs(Integer.parseInt(maxOccurs));
378 if (!FieldDefinition.SINGLE.equals(maxOccurs)) {
379 constraintMetadata.setId("repeating");
380 }
381 } catch (NumberFormatException nfe) {
382
383 if (FieldDefinition.UNBOUNDED.equals(maxOccurs)) {
384 constraintMetadata.setId("repeating");
385 constraintMetadata.setMaxOccurs(9999);
386 }
387 }
388 }
389
390
391 if (constraint.getExclusiveMin() != null) {
392 constraintMetadata.setMinValue(constraint.getExclusiveMin());
393 }
394
395
396 if (constraint.getInclusiveMax() != null) {
397 constraintMetadata.setMaxValue(constraint.getInclusiveMax());
398 }
399
400 if (constraint.getValidChars() != null) {
401 constraintMetadata.setValidChars(constraint.getValidChars().getValue());
402 constraintMetadata.setValidCharsMessageId(constraint.getValidChars().getLabelKey());
403 }
404
405
406 if (constraint.getCaseConstraint() != null) {
407 processCaseConstraint(constraintMetadata, constraint.getCaseConstraint(), type, state, nextState, workflowNode);
408 }
409 }
410
411
412
413
414
415
416 protected void processCaseConstraint(ConstraintMetadata constraintMetadata, CaseConstraint caseConstraint, String type, String state, String nextState, String workflowNode) {
417 String fieldPath = caseConstraint.getFieldPath();
418 fieldPath = (fieldPath != null ? fieldPath.toUpperCase() : fieldPath);
419
420 if (workflowNode != null && fieldPath != null && fieldPath.startsWith("PROPOSAL/WORKFLOWNODE")){
421 processRequiredByNodeCaseConstraint(constraintMetadata, caseConstraint, workflowNode);
422
423 } else if ("STATEKEY".equals(fieldPath) || "STATE".equals(fieldPath)) {
424 processStateCaseConstraint(constraintMetadata, caseConstraint, type, state, nextState, workflowNode);
425
426 } else if ("TYPEKEY".equals(fieldPath) || "TYPE".equals(fieldPath)) {
427 processTypeCaseConstraint(constraintMetadata, caseConstraint, type, state, nextState, workflowNode);
428 }
429 }
430
431
432
433
434
435
436
437
438
439 private void processRequiredByNodeCaseConstraint(ConstraintMetadata constraintMetadata, CaseConstraint caseConstraint, String workflowNode) {
440 List<WhenConstraint> whenConstraints = caseConstraint.getWhenConstraint();
441
442 if ("EQUALS".equals(caseConstraint.getOperator()) && whenConstraints != null) {
443 for (WhenConstraint whenConstraint : whenConstraints) {
444 List<Object> values = whenConstraint.getValues();
445 Constraint constraint = whenConstraint.getConstraint();
446
447 if (constraint.getErrorLevel() == ErrorLevel.ERROR && constraint.getMinOccurs() != null && constraint.getMinOccurs() > 0){
448
449
450
451
452
453 if (isWorkflowNodeFirstConstraintValue(workflowNode, values)) {
454
455
456
457 constraintMetadata.setRequiredForNextState(true);
458 if (DtoConstants.WORKFLOW_NODE_PRE_ROUTE.equals(workflowNode)){
459 constraintMetadata.setNextState(DtoState.SUBMITTED.toString());
460 } else {
461 constraintMetadata.setNextState(DtoState.APPROVED.toString());
462 }
463 constraintMetadata.setMinOccurs(0);
464 } else if (values.contains(workflowNode)){
465
466 constraintMetadata.setRequiredForNextState(false);
467 constraintMetadata.setNextState(null);
468 constraintMetadata.setMinOccurs(1);
469 }
470 }
471 }
472 }
473 }
474
475
476
477
478
479
480 private boolean isWorkflowNodeFirstConstraintValue(String workflowNode, List<Object> values){
481 if (values != null && !values.isEmpty()){
482 return values.get(0).equals(workflowNode);
483 } else {
484 return false;
485 }
486 }
487
488
489
490
491 private void processStateCaseConstraint(ConstraintMetadata constraintMetadata, CaseConstraint caseConstraint, String type, String state, String nextState, String workflowNode) {
492 List<WhenConstraint> whenConstraints = caseConstraint.getWhenConstraint();
493
494 if ("EQUALS".equals(caseConstraint.getOperator()) && whenConstraints != null) {
495 for (WhenConstraint whenConstraint : whenConstraints) {
496 List<Object> values = whenConstraint.getValues();
497 if (values != null) {
498 Constraint constraint = whenConstraint.getConstraint();
499
500 if (constraint.getErrorLevel() == ErrorLevel.ERROR){
501
502
503
504
505 if (values.contains(nextState)) {
506 if (constraint.getMinOccurs() != null && constraint.getMinOccurs() > 0) {
507 constraintMetadata.setRequiredForNextState(true);
508 constraintMetadata.setNextState(nextState);
509 }
510 }
511
512
513 if (values.contains(state)) {
514 updateConstraintMetadata(constraintMetadata, constraint, type, state, nextState, workflowNode);
515 }
516 }
517 }
518 }
519 }
520 }
521
522
523
524
525 private void processTypeCaseConstraint(ConstraintMetadata constraintMetadata, CaseConstraint caseConstraint, String type, String state, String nextState, String workflowNode) {
526 List<WhenConstraint> whenConstraints = caseConstraint.getWhenConstraint();
527
528 if ("EQUALS".equals(caseConstraint.getOperator()) && whenConstraints != null) {
529 for (WhenConstraint whenConstraint : whenConstraints) {
530 List<Object> values = whenConstraint.getValues();
531 if (values != null && values.contains(type)) {
532 Constraint constraint = whenConstraint.getConstraint();
533 updateConstraintMetadata(constraintMetadata, constraint, type, state, nextState, workflowNode);
534 }
535 }
536 }
537 }
538
539
540
541
542
543
544
545
546
547 protected Value convertDefaultValue(DataType dataType, Object value) {
548 Value v = null;
549 if (value instanceof String) {
550 String s = (String) value;
551 switch (dataType) {
552 case STRING:
553 v = new Data.StringValue(s);
554 break;
555 case BOOLEAN:
556 v = new Data.BooleanValue(Boolean.valueOf(s));
557 break;
558 case FLOAT:
559 v = new Data.FloatValue(Float.valueOf(s));
560 break;
561 case DATE:
562 try {
563 v = new Data.DateValue(DateFormatters.DEFAULT_DATE_FORMATTER.parse(s));
564 } catch (IllegalArgumentException e) {
565 LOG.error("Unable to get default date value from metadata definition");
566 }
567 break;
568 case LONG:
569 if (!s.isEmpty()) {
570 v = new Data.LongValue(Long.valueOf(s));
571 }
572 break;
573 case DOUBLE:
574 v = new Data.DoubleValue(Double.valueOf(s));
575 break;
576 case INTEGER:
577 v = new Data.IntegerValue(Integer.valueOf(s));
578 break;
579 }
580 } else {
581 v = convertDefaultValue(value);
582 }
583
584 return v;
585 }
586
587 protected Value convertDefaultValue(Object value) {
588 Value v = null;
589
590 if (value instanceof String) {
591 v = new Data.StringValue((String) value);
592 } else if (value instanceof Boolean) {
593 v = new Data.BooleanValue((Boolean) value);
594 } else if (value instanceof Integer) {
595 v = new Data.IntegerValue((Integer) value);
596 } else if (value instanceof Double) {
597 v = new Data.DoubleValue((Double) value);
598 } else if (value instanceof Long) {
599 v = new Data.LongValue((Long) value);
600 } else if (value instanceof Short) {
601 v = new Data.ShortValue((Short) value);
602 } else if (value instanceof Float) {
603 v = new Data.FloatValue((Float) value);
604 }
605
606 return v;
607 }
608
609 protected DataType convertDictionaryDataType(org.kuali.student.r1.common.dictionary.dto.DataType dataType) {
610 switch (dataType) {
611 case STRING:
612 return DataType.STRING;
613 case BOOLEAN:
614 return DataType.BOOLEAN;
615 case INTEGER:
616 return DataType.INTEGER;
617 case FLOAT:
618 return DataType.FLOAT;
619 case COMPLEX:
620 return DataType.DATA;
621 case DATE:
622 return DataType.DATE;
623 case DOUBLE:
624 return DataType.DOUBLE;
625 case LONG:
626 return DataType.LONG;
627 }
628
629 return null;
630 }
631
632 public void setUiLookupContext(String uiLookupContext) {
633 this.uiLookupContext = uiLookupContext;
634 init();
635
636 }
637
638 @SuppressWarnings("unchecked")
639 private void init() {
640 ApplicationContext ac = new ClassPathXmlApplicationContext(uiLookupContext);
641
642 Map<String, UILookupConfig> beansOfType = (Map<String, UILookupConfig>) ac.getBeansOfType(UILookupConfig.class);
643 lookupObjectStructures = new ArrayList<UILookupConfig>();
644 for (UILookupConfig objStr : beansOfType.values()) {
645 lookupObjectStructures.add(objStr);
646 }
647 System.out.println("UILookup loaded");
648 }
649
650 private String calcSimpleName(String objectKey) {
651 int lastDot = objectKey.lastIndexOf(".");
652 if (lastDot == -1) {
653 return objectKey;
654 }
655 return objectKey.substring(lastDot + 1);
656
657 }
658
659 private boolean matchesObjectKey(String objectKey, String path) {
660 String simpleName = calcSimpleName(objectKey);
661 if (path.toLowerCase().startsWith(simpleName.toLowerCase())) {
662
663 return true;
664 }
665
666 return false;
667 }
668
669 private boolean matchesType(String paramType, String lookupType) {
670
671 if (paramType == null && lookupType == null) {
672 return true;
673 }
674
675
676 if (paramType == null && lookupType != null) {
677 return false;
678 }
679
680
681
682
683
684 if (paramType != null && lookupType == null) {
685 return true;
686 }
687 if (paramType.equalsIgnoreCase(lookupType)) {
688
689 return true;
690 }
691
692 return false;
693 }
694
695 private void addLookupstoMetadata(String objectKey, Metadata metadata, String type) {
696 if (lookupObjectStructures != null) {
697 for (UILookupConfig lookup : lookupObjectStructures) {
698 if (!matchesObjectKey(objectKey, lookup.getPath())) {
699 continue;
700 }
701 if (!matchesType(type, lookup.getType())) {
702 continue;
703 }
704
705
706 Map<String, Metadata> parsedMetadataMap = metadata.getProperties();
707 Metadata parsedMetadata = null;
708 String parsedMetadataKey = "";
709 String lookupFieldPath = lookup.getPath();
710 String[] lookupPathTokens = getPathTokens(lookupFieldPath);
711 for (int i = 1; i < lookupPathTokens.length; i++) {
712 if (parsedMetadataMap == null) {
713 break;
714 }
715 if (i == lookupPathTokens.length - 1) {
716
717 parsedMetadata = parsedMetadataMap.get(lookupPathTokens[i]);
718 parsedMetadataKey = parsedMetadataKey + "." + lookupPathTokens[i];
719 }
720 if (parsedMetadataMap.get(lookupPathTokens[i]) != null) {
721 parsedMetadataMap = parsedMetadataMap.get(lookupPathTokens[i]).getProperties();
722 } else if (parsedMetadataMap.get("*") != null) {
723
724 parsedMetadataMap = parsedMetadataMap.get("*").getProperties();
725 i--;
726 }
727
728 }
729 if (parsedMetadata != null) {
730
731
732 UILookupData initialLookup = lookup.getInitialLookup();
733 if (initialLookup != null) {
734 mapLookupDatatoMeta(initialLookup);
735 parsedMetadata.setInitialLookup(mapLookupDatatoMeta(lookup.getInitialLookup()));
736 }
737 List<LookupMetadata> additionalLookupMetadata = null;
738 if (lookup.getAdditionalLookups() != null) {
739 additionalLookupMetadata = new ArrayList<LookupMetadata>();
740 for (UILookupData additionallookup : lookup.getAdditionalLookups()) {
741 additionalLookupMetadata.add(mapLookupDatatoMeta(additionallookup));
742 }
743 parsedMetadata.setAdditionalLookups(additionalLookupMetadata);
744 }
745 }
746 }
747 }
748 }
749
750 private LookupMetadata mapLookupDatatoMeta(UILookupData lookupData) {
751 LookupMetadata lookupMetadata = new LookupMetadata();
752 List<LookupParamMetadata> paramsMetadata;
753 BeanUtils.copyProperties(lookupData, lookupMetadata, new String[]{"widget", "usage", "widgetOptions", "params"});
754 if (lookupData.getWidget() != null) {
755 lookupMetadata.setWidget(org.kuali.student.r1.common.assembly.data.LookupMetadata.Widget.valueOf(lookupData.getWidget().toString()));
756 }
757 if (lookupData.getUsage() != null) {
758 lookupMetadata.setUsage(org.kuali.student.r1.common.assembly.data.LookupMetadata.Usage.valueOf(lookupData.getUsage().toString()));
759 }
760 if (lookupData.getWidgetOptions () != null) {
761 lookupMetadata.setWidgetOptions (new HashMap<WidgetOption, String> ());
762 for (UILookupData.WidgetOption wo: lookupData.getWidgetOptions ().keySet ()) {
763 String value = lookupData.getWidgetOptions ().get (wo);
764 LookupMetadata.WidgetOption key = LookupMetadata.WidgetOption.valueOf(wo.toString());
765 lookupMetadata.getWidgetOptions ().put (key, value);
766 }
767 }
768 if (lookupData.getParams() != null) {
769 paramsMetadata = new ArrayList<LookupParamMetadata>();
770 for (CommonLookupParam param : lookupData.getParams()) {
771 paramsMetadata.add(mapLookupParamMetadata(param));
772 }
773 lookupMetadata.setParams(paramsMetadata);
774 }
775
776 return lookupMetadata;
777 }
778
779 private LookupParamMetadata mapLookupParamMetadata(CommonLookupParam param) {
780 LookupParamMetadata paramMetadata = new LookupParamMetadata();
781 BeanUtils.copyProperties(param, paramMetadata, new String[]{"childLookup", "dataType", "writeAccess", "usage", "widget"});
782 if (param.getChildLookup() != null) {
783 paramMetadata.setChildLookup(mapLookupDatatoMeta((UILookupData) param.getChildLookup()));
784 }
785 if (param.getDataType() != null) {
786 paramMetadata.setDataType(org.kuali.student.r1.common.assembly.data.Data.DataType.valueOf(param.getDataType().toString()));
787 }
788 if (param.getWriteAccess() != null) {
789 paramMetadata.setWriteAccess(org.kuali.student.r1.common.assembly.data.Metadata.WriteAccess.valueOf(param.getWriteAccess().toString()));
790 }
791 if (param.getUsage() != null) {
792 paramMetadata.setUsage(org.kuali.student.r1.common.assembly.data.LookupMetadata.Usage.valueOf(param.getUsage().toString()));
793 }
794 if (param.getWidget() != null) {
795 paramMetadata.setWidget(org.kuali.student.r1.common.assembly.data.LookupParamMetadata.Widget.valueOf(param.getWidget().toString()));
796 }
797
798 return paramMetadata;
799 }
800
801 private static String[] getPathTokens(String fieldPath) {
802 return (fieldPath != null && fieldPath.contains(".") ? fieldPath.split("\\.") : new String[]{fieldPath});
803 }
804 }