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