Coverage Report - org.kuali.rice.kns.datadictionary.DataDictionaryIndex
 
Classes in this File Line Coverage Branch Coverage Complexity
DataDictionaryIndex
0%
0/83
0%
0/46
3.167
 
 1  
 /*
 2  
  * Copyright 2007-2010 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  
 package org.kuali.rice.kns.datadictionary;
 17  
 
 18  
 import java.util.HashMap;
 19  
 import java.util.HashSet;
 20  
 import java.util.List;
 21  
 import java.util.Map;
 22  
 import java.util.Set;
 23  
 
 24  
 import org.apache.commons.logging.Log;
 25  
 import org.apache.commons.logging.LogFactory;
 26  
 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 27  
 
 28  
 /**
 29  
  * Encapsulates a set of statically generated (typically during startup)
 30  
  * DataDictionary indexes 
 31  
  * 
 32  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 33  
  */
 34  
 public class DataDictionaryIndex implements Runnable {
 35  0
         private static final Log LOG = LogFactory.getLog(DataDictionaryIndex.class);
 36  
         
 37  
         private DefaultListableBeanFactory ddBeans;
 38  
         
 39  
         // keyed by BusinessObject class
 40  
         private Map<String, BusinessObjectEntry> businessObjectEntries;
 41  
         private Map<String, DataObjectEntry> objectEntries;
 42  
         
 43  
         // keyed by documentTypeName
 44  
         private Map<String, DocumentEntry> documentEntries;
 45  
         // keyed by other things
 46  
         private Map<Class, DocumentEntry> documentEntriesByBusinessObjectClass;
 47  
         private Map<Class, DocumentEntry> documentEntriesByMaintainableClass;
 48  
         private Map<String, DataDictionaryEntry> entriesByJstlKey;
 49  
 
 50  
         // keyed by a class object, and the value is a set of classes that may block the class represented by the key from inactivation 
 51  
         private Map<Class, Set<InactivationBlockingMetadata>> inactivationBlockersForClass;
 52  
 
 53  0
         public DataDictionaryIndex(DefaultListableBeanFactory ddBeans) {
 54  0
                 this.ddBeans = ddBeans;
 55  0
         }
 56  
 
 57  
         public Map<String, BusinessObjectEntry> getBusinessObjectEntries() {
 58  0
                 return this.businessObjectEntries;
 59  
         }
 60  
 
 61  
         public Map<String, DataObjectEntry> getDataObjectEntries() {
 62  0
                 return this.objectEntries;
 63  
         }
 64  
 
 65  
         public Map<String, DocumentEntry> getDocumentEntries() {
 66  0
                 return this.documentEntries;
 67  
         }
 68  
 
 69  
         public Map<Class, DocumentEntry> getDocumentEntriesByBusinessObjectClass() {
 70  0
                 return this.documentEntriesByBusinessObjectClass;
 71  
         }
 72  
 
 73  
         public Map<Class, DocumentEntry> getDocumentEntriesByMaintainableClass() {
 74  0
                 return this.documentEntriesByMaintainableClass;
 75  
         }
 76  
 
 77  
         public Map<String, DataDictionaryEntry> getEntriesByJstlKey() {
 78  0
                 return this.entriesByJstlKey;
 79  
         }
 80  
 
 81  
         public Map<Class, Set<InactivationBlockingMetadata>> getInactivationBlockersForClass() {
 82  0
                 return this.inactivationBlockersForClass;
 83  
         }
 84  
 
 85  
         private void buildDDIndicies() {
 86  
         // primary indices
 87  0
         businessObjectEntries = new HashMap<String, BusinessObjectEntry>();
 88  0
         objectEntries = new HashMap<String, DataObjectEntry>();
 89  0
         documentEntries = new HashMap<String, DocumentEntry>();
 90  
 
 91  
         // alternate indices
 92  0
         documentEntriesByBusinessObjectClass = new HashMap<Class, DocumentEntry>();
 93  0
         documentEntriesByMaintainableClass = new HashMap<Class, DocumentEntry>();
 94  0
         entriesByJstlKey = new HashMap<String, DataDictionaryEntry>();
 95  
         
 96  
         // loop over all beans in the context
 97  0
         Map<String, DataObjectEntry> boBeans = ddBeans.getBeansOfType(DataObjectEntry.class);
 98  0
         for ( DataObjectEntry entry : boBeans.values() ) {
 99  
                 
 100  0
             DataObjectEntry indexedEntry = objectEntries.get(entry.getJstlKey());
 101  0
             if (indexedEntry == null){
 102  0
                     indexedEntry = businessObjectEntries.get(entry.getJstlKey());
 103  
             }
 104  0
                 if ( (indexedEntry != null) 
 105  
                     && !(indexedEntry.getObjectClass().equals(entry.getObjectClass()))) {
 106  0
                 throw new DataDictionaryException(new StringBuffer("Two object classes may not share the same jstl key: this=").append(entry.getObjectClass()).append(" / existing=").append(indexedEntry.getObjectClass()).toString());
 107  
             }
 108  
 
 109  
                 // put all BO and DO entries in the objectEntries map
 110  0
                 objectEntries.put(entry.getObjectClass().getName(), entry);
 111  0
             objectEntries.put(entry.getObjectClass().getSimpleName(), entry);
 112  
             
 113  
             // keep a separate map of BO entries for now
 114  0
                 if (entry instanceof BusinessObjectEntry){
 115  0
                         BusinessObjectEntry boEntry = (BusinessObjectEntry)entry; 
 116  
                 
 117  0
                     businessObjectEntries.put(boEntry.getBusinessObjectClass().getName(), boEntry);
 118  0
                     businessObjectEntries.put(boEntry.getBusinessObjectClass().getSimpleName(), boEntry);
 119  
                     // If a "base" class is defined for the entry, index the entry by that class as well.
 120  0
                     if (boEntry.getBaseBusinessObjectClass() != null) {
 121  0
                         businessObjectEntries.put(boEntry.getBaseBusinessObjectClass().getName(), boEntry);
 122  0
                         businessObjectEntries.put(boEntry.getBaseBusinessObjectClass().getSimpleName(), boEntry);
 123  
                     }
 124  
                 }
 125  
             
 126  0
                 entriesByJstlKey.put(entry.getJstlKey(), entry);
 127  0
         }
 128  
         
 129  
         //Build Document Entry Index
 130  0
         Map<String,DocumentEntry> docBeans = ddBeans.getBeansOfType(DocumentEntry.class);
 131  0
         for ( DocumentEntry entry : docBeans.values() ) {
 132  0
             String entryName = entry.getDocumentTypeName();
 133  
 
 134  0
             if ((entry instanceof TransactionalDocumentEntry) 
 135  
                     && (documentEntries.get(entry.getFullClassName()) != null) 
 136  
                     && !((DocumentEntry)documentEntries.get(entry.getFullClassName())).getDocumentTypeName()
 137  
                             .equals(entry.getDocumentTypeName())) {
 138  0
                 throw new DataDictionaryException(new StringBuffer("Two transactional document types may not share the same document class: this=")
 139  
                         .append(entry.getDocumentTypeName())
 140  
                         .append(" / existing=")
 141  
                         .append(((DocumentEntry)documentEntries.get(entry.getDocumentClass().getName())).getDocumentTypeName()).toString());
 142  
             }
 143  0
             if ((entriesByJstlKey.get(entry.getJstlKey()) != null) && !((DocumentEntry)documentEntries.get(entry.getJstlKey())).getDocumentTypeName().equals(entry.getDocumentTypeName())) {
 144  0
                 throw new DataDictionaryException(new StringBuffer("Two document types may not share the same jstl key: this=").append(entry.getDocumentTypeName()).append(" / existing=").append(((DocumentEntry)documentEntries.get(entry.getJstlKey())).getDocumentTypeName()).toString());
 145  
             }
 146  
 
 147  0
             documentEntries.put(entryName, entry);
 148  
             //documentEntries.put(entry.getFullClassName(), entry);
 149  0
             documentEntries.put(entry.getDocumentClass().getName(), entry);
 150  0
             if (entry.getBaseDocumentClass() != null) {
 151  0
                     documentEntries.put(entry.getBaseDocumentClass().getName(), entry);
 152  
             }
 153  0
             entriesByJstlKey.put(entry.getJstlKey(), entry);
 154  
 
 155  0
             if (entry instanceof TransactionalDocumentEntry) {
 156  0
                 TransactionalDocumentEntry tde = (TransactionalDocumentEntry) entry;
 157  
 
 158  0
                 documentEntries.put(tde.getDocumentClass().getSimpleName(), entry);
 159  0
                 if (tde.getBaseDocumentClass() != null) {
 160  0
                         documentEntries.put(tde.getBaseDocumentClass().getSimpleName(), entry);
 161  
                 }
 162  
             }
 163  0
             if (entry instanceof MaintenanceDocumentEntry) {
 164  0
                 MaintenanceDocumentEntry mde = (MaintenanceDocumentEntry) entry;
 165  
 
 166  0
                 documentEntriesByBusinessObjectClass.put(mde.getBusinessObjectClass(), entry);
 167  0
                 documentEntriesByMaintainableClass.put(mde.getMaintainableClass(), entry);
 168  0
                 documentEntries.put(mde.getBusinessObjectClass().getSimpleName() + "MaintenanceDocument", entry);
 169  
             }
 170  0
         }
 171  0
     }
 172  
 
 173  
     private void buildDDInactivationBlockingIndices() {
 174  0
         inactivationBlockersForClass = new HashMap<Class, Set<InactivationBlockingMetadata>>();
 175  0
         Map<String,BusinessObjectEntry> boBeans = ddBeans.getBeansOfType(BusinessObjectEntry.class);
 176  0
         for ( BusinessObjectEntry entry : boBeans.values() ) {
 177  0
             List<InactivationBlockingDefinition> inactivationBlockingDefinitions = entry.getInactivationBlockingDefinitions();
 178  0
             if (inactivationBlockingDefinitions != null && !inactivationBlockingDefinitions.isEmpty()) {
 179  0
                 for (InactivationBlockingDefinition inactivationBlockingDefinition : inactivationBlockingDefinitions) {
 180  0
                     registerInactivationBlockingDefinition(inactivationBlockingDefinition);
 181  
                 }
 182  
             }
 183  0
         }
 184  0
     }
 185  
     
 186  
     private void registerInactivationBlockingDefinition(InactivationBlockingDefinition inactivationBlockingDefinition) {
 187  0
         Set<InactivationBlockingMetadata> inactivationBlockingDefinitions = inactivationBlockersForClass.get(inactivationBlockingDefinition.getBlockedBusinessObjectClass());
 188  0
         if (inactivationBlockingDefinitions == null) {
 189  0
             inactivationBlockingDefinitions = new HashSet<InactivationBlockingMetadata>();
 190  0
             inactivationBlockersForClass.put(inactivationBlockingDefinition.getBlockedBusinessObjectClass(), inactivationBlockingDefinitions);
 191  
         }
 192  0
         boolean duplicateAdd = ! inactivationBlockingDefinitions.add(inactivationBlockingDefinition);
 193  0
         if (duplicateAdd) {
 194  0
             throw new DataDictionaryException("Detected duplicate InactivationBlockingDefinition for class " + inactivationBlockingDefinition.getBlockingReferenceBusinessObjectClass().getClass().getName());
 195  
         }
 196  0
     }
 197  
     
 198  
     public void run() {
 199  0
         LOG.info( "Starting DD Index Building" );
 200  0
         buildDDIndicies();
 201  0
         LOG.info( "Completed DD Index Building" );
 202  
 //        LOG.info( "Starting DD Validation" );
 203  
 //        validateDD();
 204  
 //        LOG.info( "Ending DD Validation" );
 205  0
         LOG.info( "Started DD Inactivation Blocking Index Building" );
 206  0
         buildDDInactivationBlockingIndices();
 207  0
         LOG.info( "Completed DD Inactivation Blocking Index Building" );
 208  0
     }
 209  
 }