Clover Coverage Report - KS Common Impl 1.3.0-SNAPSHOT
Coverage timestamp: Wed Dec 31 1969 19:00:00 EST
../../../../../../img/srcFileCovDistChart0.png 0% of files have more coverage
290   673   122   11.15
138   461   0.42   13
26     4.69  
2    
 
  MetadataServiceImpl       Line # 47 279 0% 118 437 0% 0.0
  MetadataServiceImpl.RecursionCounter       Line # 54 11 0% 4 17 0% 0.0
 
No Tests
 
1    /**
2    * Copyright 2010 The Kuali Foundation Licensed under the Educational Community License, Version 2.0 (the "License"); you may
3    * not use this file except in compliance with the License. You may obtain a copy of the License at
4    * http://www.osedu.org/licenses/ECL-2.0 Unless required by applicable law or agreed to in writing, software distributed
5    * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
6    * implied. See the License for the specific language governing permissions and limitations under the License.
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.Metadata.WriteAccess;
30    import org.kuali.student.common.dictionary.dto.CaseConstraint;
31    import org.kuali.student.common.dictionary.dto.CommonLookupParam;
32    import org.kuali.student.common.dictionary.dto.Constraint;
33    import org.kuali.student.common.dictionary.dto.FieldDefinition;
34    import org.kuali.student.common.dictionary.dto.ObjectStructureDefinition;
35    import org.kuali.student.common.dictionary.dto.WhenConstraint;
36    import org.kuali.student.common.dictionary.service.DictionaryService;
37    import org.kuali.student.common.dto.DtoConstants.DtoState;
38    import org.springframework.beans.BeanUtils;
39    import org.springframework.context.ApplicationContext;
40    import org.springframework.context.support.ClassPathXmlApplicationContext;
41   
42    /**
43    * This class provides metadata lookup for service dto objects.
44    *
45    * @author Kuali Student Team
46    */
 
47    public class MetadataServiceImpl {
48    final Logger LOG = Logger.getLogger(MetadataServiceImpl.class);
49   
50    private Map<String, DictionaryService> dictionaryServiceMap;
51    private List<UILookupConfig> lookupObjectStructures;
52    private String uiLookupContext;
53   
 
54    private static class RecursionCounter {
55    public static final int MAX_DEPTH = 4;
56   
57    private Map<String, Integer> recursions = new HashMap<String, Integer>();
58   
 
59  0 toggle public int increment(String objectName) {
60  0 Integer hits = recursions.get(objectName);
61   
62  0 if (hits == null) {
63  0 hits = new Integer(1);
64    } else {
65  0 hits++;
66    }
67  0 recursions.put(objectName, hits);
68  0 return hits;
69    }
70   
 
71  0 toggle public int decrement(String objectName) {
72  0 Integer hits = recursions.get(objectName);
73  0 if (hits >= 1) {
74  0 hits--;
75    }
76   
77  0 recursions.put(objectName, hits);
78  0 return hits;
79    }
80    }
81   
82    /**
83    * Create a metadata service initializing it with all known dictionary services
84    *
85    * @param dictionaryServices
86    */
 
87  0 toggle public MetadataServiceImpl(DictionaryService... dictionaryServices) {
88  0 if (dictionaryServices != null) {
89  0 this.dictionaryServiceMap = new HashMap<String, DictionaryService>();
90  0 for (DictionaryService d : dictionaryServices) {
91  0 List<String> objectTypes = d.getObjectTypes();
92  0 for (String objectType : objectTypes) {
93  0 dictionaryServiceMap.put(objectType, d);
94    }
95    }
96    }
97    }
98   
99    /**
100    * This method gets the metadata for the given object key, type, state and nextState
101    *
102    * @param objectKey
103    * @param type The type of the object (value can be null)
104    * @param state The state for which to retrieve object constraints (value can be null)
105    * @param nextState The state to to check requiredForNextState indicators (value can be null)
106    * @return
107    */
 
108  0 toggle public Metadata getMetadata(String objectKey, String type, String state, String nextState) {
109  0 return getMetadataFromDictionaryService(objectKey, type, state, nextState);
110    }
111   
112    /**
113    * This method gets the metadata for the given object key, type and state
114    *
115    * @param objectKey
116    * @param type The type of the object (value can be null)
117    * @param state The state for which to retrieve object constraints (value can be null)
118    * @return
119    */
 
120  0 toggle public Metadata getMetadata(String objectKey, String type, String state) {
121  0 return getMetadata(objectKey, type, state, null);
122    }
123   
124   
125    /**
126    * This method gets the metadata for the given object key and state
127    *
128    * @param objectKey
129    * @param type The type of the object (value can be null)
130    */
 
131  0 toggle public Metadata getMetadata(String objectKey, String state) {
132  0 return getMetadata(objectKey, null, state);
133    }
134   
135    /**
136    * This method gets the metadata for the given object key for state DRAFT.
137    *
138    * @see MetadataServiceImpl#getMetadata(String, String)
139    * @param objectKey
140    * @return
141    */
 
142  0 toggle public Metadata getMetadata(String objectKey) {
143  0 return getMetadata(objectKey, null, null);
144    }
145   
146    /**
147    * This invokes the appropriate dictionary service to get the object structure and then converts it to a metadata
148    * structure.
149    *
150    * @param objectKey
151    * @param type
152    * @param state
153    * @return
154    */
 
155  0 toggle protected Metadata getMetadataFromDictionaryService(String objectKey, String type, String state, String nextState) {
156  0 Metadata metadata = new Metadata();
157   
158  0 ObjectStructureDefinition objectStructure = getObjectStructure(objectKey);
159   
160  0 metadata.setProperties(getProperties(objectStructure, type, state, nextState, new RecursionCounter()));
161   
162  0 metadata.setWriteAccess(WriteAccess.ALWAYS);
163  0 metadata.setDataType(DataType.DATA);
164  0 addLookupstoMetadata(objectKey, metadata, type);
165  0 return metadata;
166    }
167   
168    /**
169    * This method is used to convert a list of dictionary fields into metadata properties
170    *
171    * @param fields
172    * @param type
173    * @param state
174    * @return
175    */
 
176  0 toggle private Map<String, Metadata> getProperties(ObjectStructureDefinition objectStructure, String type, String state, String nextState, RecursionCounter counter) {
177  0 String objectId = objectStructure.getName();
178  0 int hits = counter.increment(objectId);
179   
180  0 Map<String, Metadata> properties = null;
181   
182  0 if (hits < RecursionCounter.MAX_DEPTH) {
183  0 properties = new HashMap<String, Metadata>();
184   
185  0 List<FieldDefinition> attributes = objectStructure.getAttributes();
186  0 for (FieldDefinition fd : attributes) {
187   
188  0 Metadata metadata = new Metadata();
189   
190    // Set constraints, authz flags, default value
191  0 metadata.setWriteAccess(WriteAccess.ALWAYS);
192  0 metadata.setDataType(convertDictionaryDataType(fd.getDataType()));
193  0 metadata.setConstraints(getConstraints(fd, type, state, nextState));
194  0 metadata.setCanEdit(!fd.isReadOnly());
195  0 metadata.setCanUnmask(!fd.isMask());
196  0 metadata.setCanView(!fd.isHide());
197  0 metadata.setDynamic(fd.isDynamic());
198  0 metadata.setLabelKey(fd.getLabelKey());
199  0 metadata.setDefaultValue(convertDefaultValue(metadata.getDataType(), fd.getDefaultValue()));
200  0 metadata.setDefaultValuePath(fd.getDefaultValuePath());
201   
202  0 if (fd.isPartialMask()){
203  0 metadata.setPartialMaskFormatter(fd.getPartialMaskFormatter());
204    }
205   
206  0 if (fd.isMask()){
207  0 metadata.setMaskFormatter(fd.getMaskFormatter());
208    }
209   
210    // Get properties for nested object structure
211  0 Map<String, Metadata> nestedProperties = null;
212  0 if (fd.getDataType() == org.kuali.student.common.dictionary.dto.DataType.COMPLEX && fd.getDataObjectStructure() != null) {
213  0 nestedProperties = getProperties(fd.getDataObjectStructure(), type, state, nextState, counter);
214    }
215   
216    // For repeating field, create a LIST with wildcard in metadata structure
217  0 if (isRepeating(fd)) {
218  0 Metadata repeatingMetadata = new Metadata();
219  0 metadata.setDataType(DataType.LIST);
220   
221  0 repeatingMetadata.setWriteAccess(WriteAccess.ALWAYS);
222  0 repeatingMetadata.setOnChangeRefreshMetadata(false);
223  0 repeatingMetadata.setDataType(convertDictionaryDataType(fd.getDataType()));
224   
225  0 if (nestedProperties != null) {
226  0 repeatingMetadata.setProperties(nestedProperties);
227    }
228   
229  0 Map<String, Metadata> repeatingProperty = new HashMap<String, Metadata>();
230  0 repeatingProperty.put("*", repeatingMetadata);
231  0 metadata.setProperties(repeatingProperty);
232  0 } else if (nestedProperties != null) {
233  0 metadata.setProperties(nestedProperties);
234    }
235   
236  0 properties.put(fd.getName(), metadata);
237   
238    }
239    }
240   
241  0 counter.decrement(objectId);
242  0 return properties;
243    }
244   
245    /**
246    * This method determines if a field is repeating
247    *
248    * @param fd
249    * @return
250    */
 
251  0 toggle protected boolean isRepeating(FieldDefinition fd) {
252  0 boolean isRepeating = false;
253  0 try {
254  0 int maxOccurs = Integer.parseInt(fd.getMaxOccurs());
255  0 isRepeating = maxOccurs > 1;
256    } catch (NumberFormatException nfe) {
257  0 isRepeating = FieldDefinition.UNBOUNDED.equals(fd.getMaxOccurs());
258    }
259   
260  0 return isRepeating;
261    }
262   
263    /**
264    * This method gets the object structure for given objectKey from a dictionaryService
265    *
266    * @param objectKey
267    * @return
268    */
 
269  0 toggle protected ObjectStructureDefinition getObjectStructure(String objectKey) {
270  0 DictionaryService dictionaryService = dictionaryServiceMap.get(objectKey);
271   
272  0 if (dictionaryService == null) {
273  0 throw new RuntimeException("Dictionary service not provided for objectKey=[" + objectKey + "].");
274    }
275   
276  0 return dictionaryService.getObjectStructure(objectKey);
277    }
278   
 
279  0 toggle protected List<ConstraintMetadata> getConstraints(FieldDefinition fd, String type, String state, String nextState) {
280  0 List<ConstraintMetadata> constraints = new ArrayList<ConstraintMetadata>();
281   
282  0 ConstraintMetadata constraintMetadata = new ConstraintMetadata();
283   
284  0 updateConstraintMetadata(constraintMetadata, (Constraint) fd, type, state, nextState);
285  0 constraints.add(constraintMetadata);
286   
287  0 return constraints;
288    }
289   
290    /**
291    * This updates the constraintMetadata with defintions from the dictionary constraint field.
292    *
293    * @param constraintMetadata
294    * @param constraint
295    */
 
296  0 toggle protected void updateConstraintMetadata(ConstraintMetadata constraintMetadata, Constraint constraint, String type, String state, String nextState) {
297    // For now ignoring the serverSide flag and making determination of which constraints
298    // should be passed up to the UI via metadata.
299   
300    // Min Length
301  0 if (constraint.getMinLength() != null) {
302  0 constraintMetadata.setMinLength(constraint.getMinLength());
303    }
304   
305    // Max Length
306  0 try {
307  0 if (constraint.getMaxLength() != null) {
308  0 constraintMetadata.setMaxLength(Integer.parseInt(constraint.getMaxLength()));
309    }
310    // Do we need to add another constraint and label it required if minOccurs = 1
311    } catch (NumberFormatException nfe) {
312    // Ignoring an unbounded length, cannot be handled in metadata structure, maybe change Metadata to string or set
313    // to -1
314  0 constraintMetadata.setMaxLength(9999);
315    }
316   
317    // Min Occurs
318  0 if (constraint.getMinOccurs() != null) {
319  0 constraintMetadata.setMinOccurs(constraint.getMinOccurs());
320    }
321   
322    // Max Occurs
323  0 String maxOccurs = constraint.getMaxOccurs();
324  0 if (maxOccurs != null) {
325  0 try {
326  0 constraintMetadata.setMaxOccurs(Integer.parseInt(maxOccurs));
327  0 if (!FieldDefinition.SINGLE.equals(maxOccurs)) {
328  0 constraintMetadata.setId("repeating");
329    }
330    } catch (NumberFormatException nfe) {
331    // Setting unbounded to a value of 9999, since unbounded not handled by metadata
332  0 if (FieldDefinition.UNBOUNDED.equals(maxOccurs)) {
333  0 constraintMetadata.setId("repeating");
334  0 constraintMetadata.setMaxOccurs(9999);
335    }
336    }
337    }
338   
339    // Min Value
340  0 if (constraint.getExclusiveMin() != null) {
341  0 constraintMetadata.setMinValue(constraint.getExclusiveMin());
342    }
343   
344    // Max Value
345  0 if (constraint.getInclusiveMax() != null) {
346  0 constraintMetadata.setMaxValue(constraint.getInclusiveMax());
347    }
348   
349  0 if (constraint.getValidChars() != null) {
350  0 constraintMetadata.setValidChars(constraint.getValidChars().getValue());
351  0 constraintMetadata.setValidCharsMessageId(constraint.getValidChars().getLabelKey());
352    }
353   
354    // Case constraints
355  0 if (constraint.getCaseConstraint() != null) {
356  0 processCaseConstraint(constraintMetadata, constraint.getCaseConstraint(), type, state, nextState);
357    }
358    }
359   
 
360  0 toggle protected void processCaseConstraint(ConstraintMetadata constraintMetadata, CaseConstraint caseConstraint, String type, String state, String nextState) {
361  0 String fieldPath = caseConstraint.getFieldPath();
362  0 List<WhenConstraint> whenConstraints = caseConstraint.getWhenConstraint();
363   
364  0 fieldPath = (fieldPath != null ? fieldPath.toUpperCase() : fieldPath);
365  0 if ("STATE".equals(fieldPath)) {
366    // Process a state constraint
367   
368    // Defaults for state and nextState
369  0 state = (state == null ? DtoState.DRAFT.toString():state);
370  0 nextState = (nextState == null ? DtoState.getNextStateAsString(state):nextState);
371   
372  0 if ("EQUALS".equals(caseConstraint.getOperator()) && whenConstraints != null) {
373  0 for (WhenConstraint whenConstraint : whenConstraints) {
374  0 List<Object> values = whenConstraint.getValues();
375  0 if (values != null) {
376  0 Constraint constraint = whenConstraint.getConstraint();
377   
378    // Set the required for next state flag
379  0 if (values.contains(nextState)) {
380  0 if (constraint.getMinOccurs() > 0) {
381  0 constraintMetadata.setRequiredForNextState(true);
382  0 constraintMetadata.setNextState(nextState);
383    }
384    }
385   
386    // Update constraints based on state constraints
387  0 if (values.contains(state.toUpperCase())) {
388  0 updateConstraintMetadata(constraintMetadata, constraint, type, state, nextState);
389    }
390    }
391    }
392    }
393  0 } else if ("TYPE".equals(fieldPath)) {
394    // Process a type constraint
395   
396  0 if ("EQUALS".equals(caseConstraint.getOperator()) && whenConstraints != null) {
397  0 for (WhenConstraint whenConstraint : whenConstraints) {
398  0 List<Object> values = whenConstraint.getValues();
399  0 if (values != null && values.contains(type)) {
400  0 Constraint constraint = whenConstraint.getConstraint();
401  0 updateConstraintMetadata(constraintMetadata, constraint, type, state, nextState);
402    }
403    }
404    }
405    }
406    }
407   
408    /**
409    * Convert Object value to respective DataType. Method return null for object Value.
410    *
411    * @param dataType
412    * @param value
413    * @return
414    */
 
415  0 toggle protected Value convertDefaultValue(DataType dataType, Object value) {
416  0 Value v = null;
417  0 if (value instanceof String) {
418  0 String s = (String) value;
419  0 switch (dataType) {
420  0 case STRING:
421  0 v = new Data.StringValue(s);
422  0 break;
423  0 case BOOLEAN:
424  0 v = new Data.BooleanValue(Boolean.valueOf(s));
425  0 break;
426  0 case FLOAT:
427  0 v = new Data.FloatValue(Float.valueOf(s));
428  0 break;
429  0 case DATE:
430  0 DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
431  0 try {
432  0 v = new Data.DateValue(format.parse(s));
433    } catch (ParseException e) {
434  0 LOG.error("Unable to get default date value from metadata definition");
435    }
436  0 break;
437  0 case LONG:
438  0 if (!s.isEmpty()) {
439  0 v = new Data.LongValue(Long.valueOf(s));
440    }
441  0 break;
442  0 case DOUBLE:
443  0 v = new Data.DoubleValue(Double.valueOf(s));
444  0 break;
445  0 case INTEGER:
446  0 v = new Data.IntegerValue(Integer.valueOf(s));
447  0 break;
448    }
449    } else {
450  0 v = convertDefaultValue(value);
451    }
452   
453  0 return v;
454    }
455   
 
456  0 toggle protected Value convertDefaultValue(Object value) {
457  0 Value v = null;
458   
459  0 if (value instanceof String) {
460  0 v = new Data.StringValue((String) value);
461  0 } else if (value instanceof Boolean) {
462  0 v = new Data.BooleanValue((Boolean) value);
463  0 } else if (value instanceof Integer) {
464  0 v = new Data.IntegerValue((Integer) value);
465  0 } else if (value instanceof Double) {
466  0 v = new Data.DoubleValue((Double) value);
467  0 } else if (value instanceof Long) {
468  0 v = new Data.LongValue((Long) value);
469  0 } else if (value instanceof Short) {
470  0 v = new Data.ShortValue((Short) value);
471  0 } else if (value instanceof Float) {
472  0 v = new Data.FloatValue((Float) value);
473    }
474   
475  0 return v;
476    }
477   
 
478  0 toggle protected DataType convertDictionaryDataType(org.kuali.student.common.dictionary.dto.DataType dataType) {
479  0 switch (dataType) {
480  0 case STRING:
481  0 return DataType.STRING;
482  0 case BOOLEAN:
483  0 return DataType.BOOLEAN;
484  0 case INTEGER:
485  0 return DataType.INTEGER;
486  0 case FLOAT:
487  0 return DataType.FLOAT;
488  0 case COMPLEX:
489  0 return DataType.DATA;
490  0 case DATE:
491  0 return DataType.DATE;
492  0 case DOUBLE:
493  0 return DataType.DOUBLE;
494  0 case LONG:
495  0 return DataType.LONG;
496    }
497   
498  0 return null;
499    }
500   
 
501  0 toggle public void setUiLookupContext(String uiLookupContext) {
502  0 this.uiLookupContext = uiLookupContext;
503  0 init();
504   
505    }
506   
 
507  0 toggle @SuppressWarnings("unchecked")
508    private void init() {
509  0 ApplicationContext ac = new ClassPathXmlApplicationContext(uiLookupContext);
510   
511  0 Map<String, UILookupConfig> beansOfType = (Map<String, UILookupConfig>) ac.getBeansOfType(UILookupConfig.class);
512  0 lookupObjectStructures = new ArrayList<UILookupConfig>();
513  0 for (UILookupConfig objStr : beansOfType.values()) {
514  0 lookupObjectStructures.add(objStr);
515    }
516  0 System.out.println("UILookup loaded");
517    }
518   
 
519  0 toggle private String calcSimpleName(String objectKey) {
520  0 int lastDot = objectKey.lastIndexOf(".");
521  0 if (lastDot == -1) {
522  0 return objectKey;
523    }
524  0 return objectKey.substring(lastDot + 1);
525   
526    }
527   
 
528  0 toggle private boolean matchesObjectKey(String objectKey, String path) {
529  0 String simpleName = calcSimpleName(objectKey);
530  0 if (path.toLowerCase().startsWith(simpleName.toLowerCase())) {
531    // System.out.println ("matchesObjectKey: is TRUE for " + objectKey + " and " + path);
532  0 return true;
533    }
534    // System.out.println ("matchesObjectKey: is FALSE for " + objectKey + " and " + path);
535  0 return false;
536    }
537   
 
538  0 toggle private boolean matchesType(String paramType, String lookupType) {
539    // both null
540  0 if (paramType == null && lookupType == null) {
541  0 return true;
542    }
543    // not asking for type specific but the lookup defnition is type specific then
544    // no match
545  0 if (paramType == null && lookupType != null) {
546  0 return false;
547    }
548    // if looking for type specific but the lookup is not specific then
549    // take as default
550    // If configuration has both a null type (i.e. default) AND has a type
551    // specific one the type specific one has to be entered into the configuration
552    // file first so it is found first
553  0 if (paramType != null && lookupType == null) {
554  0 return true;
555    }
556  0 if (paramType.equalsIgnoreCase(lookupType)) {
557    // System.out.println ("matchesType: is TRUE for " + paramType + " and " + lookupType);
558  0 return true;
559    }
560    // System.out.println ("matchesType: is FALSE for " + paramType + " and " + lookupType);
561  0 return false;
562    }
563   
 
564  0 toggle private void addLookupstoMetadata(String objectKey, Metadata metadata, String type) {
565  0 if (lookupObjectStructures != null) {
566  0 for (UILookupConfig lookup : lookupObjectStructures) {
567  0 if (!matchesObjectKey(objectKey, lookup.getPath())) {
568  0 continue;
569    }
570  0 if (!matchesType(type, lookup.getType())) {
571  0 continue;
572    }
573    // TODO: figure out why path=courseInfo.creditOptions.type matches any structure that has a type on it so
574    // that lookup gets returned for all types
575  0 Map<String, Metadata> parsedMetadataMap = metadata.getProperties();
576  0 Metadata parsedMetadata = null;
577  0 String parsedMetadataKey = "";
578  0 String lookupFieldPath = lookup.getPath();
579  0 String[] lookupPathTokens = getPathTokens(lookupFieldPath);
580  0 for (int i = 1; i < lookupPathTokens.length; i++) {
581  0 if (parsedMetadataMap == null) {
582  0 break;
583    }
584  0 if (i == lookupPathTokens.length - 1) {
585    // get the metadata on the last path key token
586  0 parsedMetadata = parsedMetadataMap.get(lookupPathTokens[i]);
587  0 parsedMetadataKey = parsedMetadataKey + "." + lookupPathTokens[i];
588    }
589  0 if (parsedMetadataMap.get(lookupPathTokens[i]) != null) {
590  0 parsedMetadataMap = parsedMetadataMap.get(lookupPathTokens[i]).getProperties();
591  0 } else if (parsedMetadataMap.get("*") != null) {
592    // Lookup wildcard in case of unbounded elements in metadata.
593  0 parsedMetadataMap = parsedMetadataMap.get("*").getProperties();
594  0 i--;
595    }
596   
597    }
598  0 if (parsedMetadata != null) {
599    // System.out.println ("addLookupstoMetadata:" + parsedMetadataKey + " was found as a match for " +
600    // lookup.getPath ());
601  0 UILookupData initialLookup = lookup.getInitialLookup();
602  0 if (initialLookup != null) {
603  0 mapLookupDatatoMeta(initialLookup);
604  0 parsedMetadata.setInitialLookup(mapLookupDatatoMeta(lookup.getInitialLookup()));
605    }
606  0 List<LookupMetadata> additionalLookupMetadata = null;
607  0 if (lookup.getAdditionalLookups() != null) {
608  0 additionalLookupMetadata = new ArrayList<LookupMetadata>();
609  0 for (UILookupData additionallookup : lookup.getAdditionalLookups()) {
610  0 additionalLookupMetadata.add(mapLookupDatatoMeta(additionallookup));
611    }
612  0 parsedMetadata.setAdditionalLookups(additionalLookupMetadata);
613    }
614    }
615    }
616    }
617    }
618   
 
619  0 toggle private LookupMetadata mapLookupDatatoMeta(UILookupData lookupData) {
620  0 LookupMetadata lookupMetadata = new LookupMetadata();
621  0 List<LookupParamMetadata> paramsMetadata;
622  0 BeanUtils.copyProperties(lookupData, lookupMetadata, new String[]{"widget", "usage", "widgetOptions", "params"});
623  0 if (lookupData.getWidget() != null) {
624  0 lookupMetadata.setWidget(org.kuali.student.common.assembly.data.LookupMetadata.Widget.valueOf(lookupData.getWidget().toString()));
625    }
626  0 if (lookupData.getUsage() != null) {
627  0 lookupMetadata.setUsage(org.kuali.student.common.assembly.data.LookupMetadata.Usage.valueOf(lookupData.getUsage().toString()));
628    }
629  0 if (lookupData.getWidgetOptions () != null) {
630  0 lookupMetadata.setWidgetOptions (new HashMap ());
631  0 for (UILookupData.WidgetOption wo: lookupData.getWidgetOptions ().keySet ()) {
632  0 String value = lookupData.getWidgetOptions ().get (wo);
633  0 LookupMetadata.WidgetOption key = LookupMetadata.WidgetOption.valueOf(wo.toString());
634  0 lookupMetadata.getWidgetOptions ().put (key, value);
635    }
636    }
637  0 if (lookupData.getParams() != null) {
638  0 paramsMetadata = new ArrayList<LookupParamMetadata>();
639  0 for (CommonLookupParam param : lookupData.getParams()) {
640  0 paramsMetadata.add(mapLookupParamMetadata(param));
641    }
642  0 lookupMetadata.setParams(paramsMetadata);
643    }
644    // WidgetOptions is not used as of now. So not setting it into metadata.
645  0 return lookupMetadata;
646    }
647   
 
648  0 toggle private LookupParamMetadata mapLookupParamMetadata(CommonLookupParam param) {
649  0 LookupParamMetadata paramMetadata = new LookupParamMetadata();
650  0 BeanUtils.copyProperties(param, paramMetadata, new String[]{"childLookup", "dataType", "writeAccess", "usage", "widget"});
651  0 if (param.getChildLookup() != null) {
652  0 paramMetadata.setChildLookup(mapLookupDatatoMeta((UILookupData) param.getChildLookup()));
653    }
654  0 if (param.getDataType() != null) {
655  0 paramMetadata.setDataType(org.kuali.student.common.assembly.data.Data.DataType.valueOf(param.getDataType().toString()));
656    }
657  0 if (param.getWriteAccess() != null) {
658  0 paramMetadata.setWriteAccess(org.kuali.student.common.assembly.data.Metadata.WriteAccess.valueOf(param.getWriteAccess().toString()));
659    }
660  0 if (param.getUsage() != null) {
661  0 paramMetadata.setUsage(org.kuali.student.common.assembly.data.LookupMetadata.Usage.valueOf(param.getUsage().toString()));
662    }
663  0 if (param.getWidget() != null) {
664  0 paramMetadata.setWidget(org.kuali.student.common.assembly.data.LookupParamMetadata.Widget.valueOf(param.getWidget().toString()));
665    }
666   
667  0 return paramMetadata;
668    }
669   
 
670  0 toggle private static String[] getPathTokens(String fieldPath) {
671  0 return (fieldPath != null && fieldPath.contains(".") ? fieldPath.split("\\.") : new String[]{fieldPath});
672    }
673    }