001 /*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005 package org.kuali.student.contract.model.util;
006
007 import java.util.List;
008
009 import org.kuali.student.contract.exception.DictionaryExecutionException;
010 import org.kuali.student.contract.model.Dictionary;
011 import org.kuali.student.contract.model.DictionaryModel;
012 import org.kuali.student.contract.model.Field;
013 import org.kuali.student.contract.model.XmlType;
014
015 /**
016 *
017 * @author nwright
018 */
019 public class DictionaryParentSetter {
020
021 private DictionaryModel model;
022 private ModelFinder finder;
023
024 public DictionaryParentSetter(DictionaryModel model) {
025 this.model = model;
026 this.finder = new ModelFinder(model);
027 }
028
029 public void set() {
030 for (int i = 1; i < model.getDictionary().size(); i++) {
031 Dictionary child = model.getDictionary().get(i);
032 Dictionary parent = calcParent(i, child);
033 child.setParent(parent);
034 }
035 }
036
037 private Dictionary calcParent(int index, Dictionary child) {
038 // if first field the parent is by default null
039 // course.official
040 if (index == 0) {
041 return null;
042 }
043 // if first field of the defnition of a new main type
044 // then the parent is null
045 // i.e. program.official is the start of a new cluInfo definition
046 XmlType xmlType = finder.findXmlType(child.getXmlObject());
047 if (xmlType == null) {
048 throw new DictionaryExecutionException("child.getXmlObject ()=" + child.getXmlObject());
049 }
050 if (xmlType.hasOwnCreateUpdate()) {
051 List<Field> fields = finder.findFields(child.getXmlObject());
052 if (fields.get(0).getShortName().equalsIgnoreCase(child.getShortName())) {
053 return null;
054 }
055 }
056 Dictionary prev = model.getDictionary().get(index - 1);
057 // if this is just another field on same object as prev
058 // then they have the same parent
059 // course.official.no cluIdentifierInfo
060 // course.official.transcriptTitle cluIdentifierInfo << this has the same parent as previous
061 if (prev.getXmlObject().equalsIgnoreCase(child.getXmlObject())) {
062 return prev.getParent();
063 }
064 // objects are different so check if we are going down or up
065 // if going down the hierarchy
066 Field prevField = finder.findField(prev);
067 if (prevField == null) {
068 throw new DictionaryExecutionException("Could not find field associated with dictionary entry with id =" + prev.getId());
069 }
070 // going down heirarchy if this sub-object is the same type of the previous field
071 // because that means this field is the 1st field of the sub-type definition
072 if (calcType(prevField.getXmlType()).equalsIgnoreCase(child.getXmlObject())) {
073 // loop back to find the first (default) definition for that field -- that is the real parent
074 // not the state override
075 // course.desc <<<< Make this the parent
076 // course.desc.draft.private
077 // course.desc.template
078 // course.desc.draft.public <<<< not this
079 // course.desc.plain <<<< of this
080 for (int i = index - 2; i > -1; i--) {
081 Dictionary prev2 = model.getDictionary().get(i);
082 if (prev2.getXmlObject().equalsIgnoreCase(prev.getXmlObject())) {
083 if (prev2.getShortName().equalsIgnoreCase(prev.getShortName())) {
084 prev = prev2;
085 continue;
086 }
087 }
088 break;
089 }
090 return prev;
091 }
092 // we are popping up from down in the heirarchy
093 // have to go back to find the previous item at the same level
094 // course.desc cluInfo
095 // course.desc.draft.private cluInfo
096 // course.desc.template cluInfo
097 // course.desc.draft.public cluInfo << use this parent
098 // course.desc.plain richTextInfo
099 // course.desc.plain.draft.private richTextInfo
100 // course.desc.plain.draft.public richTextInfo
101 // course.desc.formatted richTextInfo
102 // course.desc.formatted.draft.private richTextInfo
103 // course.desc.formatted.draft.public richTextInfo
104 // course.rationale cluInfo << as this field's parent
105 for (int i = index - 1; i > -1; i--) {
106 Dictionary dict = model.getDictionary().get(i);
107 if (dict.getXmlObject().equalsIgnoreCase(child.getXmlObject())) {
108 return dict.getParent();
109 }
110 }
111 throw new DictionaryExecutionException("dictionary entry " + child.getId()
112 + " could not calculate the parent");
113 }
114
115 private String calcType(String type) {
116 if (type.endsWith("List")) {
117 type = type.substring(0, type.length() - "List".length());
118 }
119
120 return type;
121 }
122 }