001    /*
002     * Copyright 2011 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 1.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/ecl1.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    package org.kuali.student.datadictionary.util;
017    
018    import java.util.ArrayList;
019    import java.util.Arrays;
020    import java.util.List;
021    import java.util.Stack;
022    import org.kuali.rice.krad.datadictionary.AttributeDefinition;
023    import org.kuali.rice.krad.datadictionary.ComplexAttributeDefinition;
024    import org.kuali.rice.krad.datadictionary.DataDictionaryDefinitionBase;
025    import org.kuali.rice.krad.datadictionary.DataObjectEntry;
026    
027    public class Dictionary2BeanComparer {
028    
029        private String className;
030        private DataObjectEntry osDict;
031    
032        public Dictionary2BeanComparer(String className, DataObjectEntry osDict) {
033            this.className = className;
034            this.osDict = osDict;
035        }
036    
037        public List<String> compare() {
038            if (className == null) {
039                return Arrays.asList(osDict.getFullClassName() + " does not have a corresponding java class");
040            }
041            Class<?> clazz = null;
042            try {
043                clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
044                // had to change the standard Class.forName below to the above so it uses the right class loader
045                // that is defined in KSDictionaryDocMojo.java
046    //            clazz = Class.forName(className);
047            } catch (ClassNotFoundException ex) {
048                return Arrays.asList("Cannot compare the dictionary entry to it's object because the object's class cannot be found");
049            }
050            Stack<DataDictionaryDefinitionBase> parentFields = new Stack<DataDictionaryDefinitionBase>();
051            Stack<Class<?>> parentClasses = new Stack<Class<?>>();
052            DataObjectEntry osBean = new Bean2DictionaryConverter(clazz, parentFields, parentClasses).convert();
053            return compare(osDict, osBean);
054    
055        }
056    
057        private List<String> compare(DataObjectEntry osDict,
058                DataObjectEntry osBean) {
059            List<String> discrepancies = new ArrayList();
060            compareAddDiscrepancy(discrepancies, "Java class name", osDict.getFullClassName(), osBean.getFullClassName());
061            compareAddDiscrepancy(discrepancies, "Entry class", osDict.getEntryClass(), osBean.getEntryClass());
062            for (AttributeDefinition adDict : osDict.getAttributes()) {
063                AttributeDefinition adBean = findAttributeDefinition(adDict.getName(), osBean);
064                if (adBean == null) {
065    //                if (!adDict.isDynamic()) {
066                    discrepancies.add("Field " + adDict.getName() + " does not exist in the corresponding java class");
067    //                }
068                    continue;
069                }
070                compareAddDiscrepancy(discrepancies, adDict.getName() + " dataType", adDict.getDataType(), adBean.getDataType());
071                // TODO: deal with collections
072    //            compareAddDiscrepancy(discrepancies, adDict.getName() + " maxOccurs", adDict.getMaximumNumberOfElements(), adBean.getMaximumNumberOfElements());
073            }
074            for (ComplexAttributeDefinition cadDict : osDict.getComplexAttributes()) {
075                ComplexAttributeDefinition cadBean = findComplexAttributeDefinition(cadDict.getName(), osBean);
076                if (cadBean == null) {
077    //                if (!adDict.isDynamic()) {
078                    discrepancies.add("Field " + cadDict.getName() + " does not exist in the corresponding java class");
079    //                }
080                    continue;
081                }
082                 // TODO: deal with collections
083    //            compareAddDiscrepancy(discrepancies, adDict.getName() + " maxOccurs", adDict.getMaximumNumberOfElements(), adBean.getMaximumNumberOfElements());
084            }
085            for (AttributeDefinition fdBean : osBean.getAttributes()) {
086                AttributeDefinition fdDict = findAttributeDefinition(fdBean.getName(), osDict);
087                if (fdDict == null) {
088                    discrepancies.add("Field " + fdBean.getName() + " missing from the dictictionary");
089                    continue;
090                }
091            }
092            for (ComplexAttributeDefinition fdBean : osBean.getComplexAttributes()) {
093                ComplexAttributeDefinition fdDict = findComplexAttributeDefinition(fdBean.getName(), osDict);
094                if (fdDict == null) {
095                    discrepancies.add("Field " + fdBean.getName() + " missing from the dictictionary");
096                    continue;
097                }
098            }
099            return discrepancies;
100        }
101    
102        private AttributeDefinition findAttributeDefinition(String name, DataObjectEntry ode) {
103            for (AttributeDefinition fd : ode.getAttributes()) {
104                if (name.equals(fd.getName())) {
105                    return fd;
106                }
107            }
108            return null;
109        }
110    
111        private ComplexAttributeDefinition findComplexAttributeDefinition(String name, DataObjectEntry ode) {
112            for (ComplexAttributeDefinition cad : ode.getComplexAttributes()) {
113                if (name.equals(cad.getName())) {
114                    return cad;
115                }
116            }
117            return null;
118        }
119    
120        private void compareAddDiscrepancy(List<String> discrepancies, String field, boolean value1,
121                boolean value2) {
122            String discrep = compare(field, value1, value2);
123            if (discrep != null) {
124                discrepancies.add(discrep);
125            }
126        }
127    
128        private void compareAddDiscrepancy(List<String> discrepancies, String field, Object value1,
129                Object value2) {
130            String discrep = compare(field, value1, value2);
131            if (discrep != null) {
132                discrepancies.add(discrep);
133            }
134        }
135    
136        private String compare(String field, boolean value1, boolean value2) {
137            if (value1) {
138                if (value2) {
139                    return null;
140                }
141            }
142            if (!value1) {
143                if (!value2) {
144                    return null;
145                }
146            }
147            return field + " inconsistent: dictionary='" + value1 + "', java class='" + value2 + "'";
148        }
149    
150        private String compare(String field, Object value1, Object value2) {
151            if (value1 == null) {
152                if (value2 == null) {
153                    return null;
154                }
155            } else {
156                if (value1.equals(value2)) {
157                    return null;
158                }
159            }
160            return field + " inconsistent: dictionary='" + value1 + "'], java class='" + value2 + "'";
161        }
162    }