001/** 002 * Copyright 2004-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016/* 017 * To change this template, choose Tools | Templates 018 * and open the template in the editor. 019 */ 020package org.kuali.student.contract.model.util; 021 022import java.util.List; 023 024import org.kuali.student.contract.exception.DictionaryExecutionException; 025import org.kuali.student.contract.model.Dictionary; 026import org.kuali.student.contract.model.DictionaryModel; 027import org.kuali.student.contract.model.Field; 028import org.kuali.student.contract.model.XmlType; 029 030/** 031 * 032 * @author nwright 033 */ 034public class DictionaryParentSetter { 035 036 private DictionaryModel model; 037 private ModelFinder finder; 038 039 public DictionaryParentSetter(DictionaryModel model) { 040 this.model = model; 041 this.finder = new ModelFinder(model); 042 } 043 044 public void set() { 045 for (int i = 1; i < model.getDictionary().size(); i++) { 046 Dictionary child = model.getDictionary().get(i); 047 Dictionary parent = calcParent(i, child); 048 child.setParent(parent); 049 } 050 } 051 052 private Dictionary calcParent(int index, Dictionary child) { 053 // if first field the parent is by default null 054 // course.official 055 if (index == 0) { 056 return null; 057 } 058 // if first field of the defnition of a new main type 059 // then the parent is null 060 // i.e. program.official is the start of a new cluInfo definition 061 XmlType xmlType = finder.findXmlType(child.getXmlObject()); 062 if (xmlType == null) { 063 throw new DictionaryExecutionException("child.getXmlObject ()=" + child.getXmlObject()); 064 } 065 if (xmlType.hasOwnCreateUpdate()) { 066 List<Field> fields = finder.findFields(child.getXmlObject()); 067 if (fields.get(0).getShortName().equalsIgnoreCase(child.getShortName())) { 068 return null; 069 } 070 } 071 Dictionary prev = model.getDictionary().get(index - 1); 072 // if this is just another field on same object as prev 073 // then they have the same parent 074 // course.official.no cluIdentifierInfo 075 // course.official.transcriptTitle cluIdentifierInfo << this has the same parent as previous 076 if (prev.getXmlObject().equalsIgnoreCase(child.getXmlObject())) { 077 return prev.getParent(); 078 } 079 // objects are different so check if we are going down or up 080 // if going down the hierarchy 081 Field prevField = finder.findField(prev); 082 if (prevField == null) { 083 throw new DictionaryExecutionException("Could not find field associated with dictionary entry with id =" + prev.getId()); 084 } 085 // going down heirarchy if this sub-object is the same type of the previous field 086 // because that means this field is the 1st field of the sub-type definition 087 if (calcType(prevField.getXmlType()).equalsIgnoreCase(child.getXmlObject())) { 088 // loop back to find the first (default) definition for that field -- that is the real parent 089 // not the state override 090 // course.desc <<<< Make this the parent 091 // course.desc.draft.private 092 // course.desc.template 093 // course.desc.draft.public <<<< not this 094 // course.desc.plain <<<< of this 095 for (int i = index - 2; i > -1; i--) { 096 Dictionary prev2 = model.getDictionary().get(i); 097 if (prev2.getXmlObject().equalsIgnoreCase(prev.getXmlObject())) { 098 if (prev2.getShortName().equalsIgnoreCase(prev.getShortName())) { 099 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}