1 /**
2 * Copyright 2004-2014 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 /*
17 * To change this template, choose Tools | Templates
18 * and open the template in the editor.
19 */
20 package org.kuali.student.contract.model.util;
21
22 import java.util.List;
23
24 import org.kuali.student.contract.exception.DictionaryExecutionException;
25 import org.kuali.student.contract.model.Dictionary;
26 import org.kuali.student.contract.model.DictionaryModel;
27 import org.kuali.student.contract.model.Field;
28 import org.kuali.student.contract.model.XmlType;
29
30 /**
31 *
32 * @author nwright
33 */
34 public class DictionaryParentSetter {
35
36 private DictionaryModel model;
37 private ModelFinder finder;
38
39 public DictionaryParentSetter(DictionaryModel model) {
40 this.model = model;
41 this.finder = new ModelFinder(model);
42 }
43
44 public void set() {
45 for (int i = 1; i < model.getDictionary().size(); i++) {
46 Dictionary child = model.getDictionary().get(i);
47 Dictionary parent = calcParent(i, child);
48 child.setParent(parent);
49 }
50 }
51
52 private Dictionary calcParent(int index, Dictionary child) {
53 // if first field the parent is by default null
54 // course.official
55 if (index == 0) {
56 return null;
57 }
58 // if first field of the defnition of a new main type
59 // then the parent is null
60 // i.e. program.official is the start of a new cluInfo definition
61 XmlType xmlType = finder.findXmlType(child.getXmlObject());
62 if (xmlType == null) {
63 throw new DictionaryExecutionException("child.getXmlObject ()=" + child.getXmlObject());
64 }
65 if (xmlType.hasOwnCreateUpdate()) {
66 List<Field> fields = finder.findFields(child.getXmlObject());
67 if (fields.get(0).getShortName().equalsIgnoreCase(child.getShortName())) {
68 return null;
69 }
70 }
71 Dictionary prev = model.getDictionary().get(index - 1);
72 // if this is just another field on same object as prev
73 // then they have the same parent
74 // course.official.no cluIdentifierInfo
75 // course.official.transcriptTitle cluIdentifierInfo << this has the same parent as previous
76 if (prev.getXmlObject().equalsIgnoreCase(child.getXmlObject())) {
77 return prev.getParent();
78 }
79 // objects are different so check if we are going down or up
80 // if going down the hierarchy
81 Field prevField = finder.findField(prev);
82 if (prevField == null) {
83 throw new DictionaryExecutionException("Could not find field associated with dictionary entry with id =" + prev.getId());
84 }
85 // going down heirarchy if this sub-object is the same type of the previous field
86 // because that means this field is the 1st field of the sub-type definition
87 if (calcType(prevField.getXmlType()).equalsIgnoreCase(child.getXmlObject())) {
88 // loop back to find the first (default) definition for that field -- that is the real parent
89 // not the state override
90 // course.desc <<<< Make this the parent
91 // course.desc.draft.private
92 // course.desc.template
93 // course.desc.draft.public <<<< not this
94 // course.desc.plain <<<< of this
95 for (int i = index - 2; i > -1; i--) {
96 Dictionary prev2 = model.getDictionary().get(i);
97 if (prev2.getXmlObject().equalsIgnoreCase(prev.getXmlObject())) {
98 if (prev2.getShortName().equalsIgnoreCase(prev.getShortName())) {
99 prev = prev2;
100 continue;
101 }
102 }
103 break;
104 }
105 return prev;
106 }
107 // we are popping up from down in the heirarchy
108 // have to go back to find the previous item at the same level
109 // course.desc cluInfo
110 // course.desc.draft.private cluInfo
111 // course.desc.template cluInfo
112 // course.desc.draft.public cluInfo << use this parent
113 // course.desc.plain richTextInfo
114 // course.desc.plain.draft.private richTextInfo
115 // course.desc.plain.draft.public richTextInfo
116 // course.desc.formatted richTextInfo
117 // course.desc.formatted.draft.private richTextInfo
118 // course.desc.formatted.draft.public richTextInfo
119 // course.rationale cluInfo << as this field's parent
120 for (int i = index - 1; i > -1; i--) {
121 Dictionary dict = model.getDictionary().get(i);
122 if (dict.getXmlObject().equalsIgnoreCase(child.getXmlObject())) {
123 return dict.getParent();
124 }
125 }
126 throw new DictionaryExecutionException("dictionary entry " + child.getId()
127 + " could not calculate the parent");
128 }
129
130 private String calcType(String type) {
131 if (type.endsWith("List")) {
132 type = type.substring(0, type.length() - "List".length());
133 }
134
135 return type;
136 }
137 }