1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
30
31
32
33
34 public class DataDictionaryIndex implements Runnable {
35 private static final Log LOG = LogFactory.getLog(DataDictionaryIndex.class);
36
37 private DefaultListableBeanFactory ddBeans;
38
39
40 private Map<String, BusinessObjectEntry> businessObjectEntries;
41
42 private Map<String, DocumentEntry> documentEntries;
43
44 private Map<Class, DocumentEntry> documentEntriesByBusinessObjectClass;
45 private Map<Class, DocumentEntry> documentEntriesByMaintainableClass;
46 private Map<String, DataDictionaryEntry> entriesByJstlKey;
47
48
49 private Map<Class, Set<InactivationBlockingMetadata>> inactivationBlockersForClass;
50
51 public DataDictionaryIndex(DefaultListableBeanFactory ddBeans) {
52 this.ddBeans = ddBeans;
53 }
54
55 public Map<String, BusinessObjectEntry> getBusinessObjectEntries() {
56 return this.businessObjectEntries;
57 }
58
59 public Map<String, DocumentEntry> getDocumentEntries() {
60 return this.documentEntries;
61 }
62
63 public Map<Class, DocumentEntry> getDocumentEntriesByBusinessObjectClass() {
64 return this.documentEntriesByBusinessObjectClass;
65 }
66
67 public Map<Class, DocumentEntry> getDocumentEntriesByMaintainableClass() {
68 return this.documentEntriesByMaintainableClass;
69 }
70
71 public Map<String, DataDictionaryEntry> getEntriesByJstlKey() {
72 return this.entriesByJstlKey;
73 }
74
75 public Map<Class, Set<InactivationBlockingMetadata>> getInactivationBlockersForClass() {
76 return this.inactivationBlockersForClass;
77 }
78
79 private void buildDDIndicies() {
80
81 businessObjectEntries = new HashMap<String, BusinessObjectEntry>();
82 documentEntries = new HashMap<String, DocumentEntry>();
83
84
85 documentEntriesByBusinessObjectClass = new HashMap<Class, DocumentEntry>();
86 documentEntriesByMaintainableClass = new HashMap<Class, DocumentEntry>();
87 entriesByJstlKey = new HashMap<String, DataDictionaryEntry>();
88
89
90 Map<String,BusinessObjectEntry> boBeans = ddBeans.getBeansOfType(BusinessObjectEntry.class);
91 for ( BusinessObjectEntry entry : boBeans.values() ) {
92
93 if ((businessObjectEntries.get(entry.getJstlKey()) != null)
94 && !((BusinessObjectEntry)businessObjectEntries.get(entry.getJstlKey())).getBusinessObjectClass().equals(entry.getBusinessObjectClass())) {
95 throw new DataDictionaryException(new StringBuffer("Two business object classes may not share the same jstl key: this=").append(entry.getBusinessObjectClass()).append(" / existing=").append(((BusinessObjectEntry)businessObjectEntries.get(entry.getJstlKey())).getBusinessObjectClass()).toString());
96 }
97
98 businessObjectEntries.put(entry.getBusinessObjectClass().getName(), entry);
99 businessObjectEntries.put(entry.getBusinessObjectClass().getSimpleName(), entry);
100
101 if (entry.getBaseBusinessObjectClass() != null) {
102 businessObjectEntries.put(entry.getBaseBusinessObjectClass().getName(), entry);
103 businessObjectEntries.put(entry.getBaseBusinessObjectClass().getSimpleName(), entry);
104 }
105 entriesByJstlKey.put(entry.getJstlKey(), entry);
106 }
107 Map<String,DocumentEntry> docBeans = ddBeans.getBeansOfType(DocumentEntry.class);
108 for ( DocumentEntry entry : docBeans.values() ) {
109 String entryName = entry.getDocumentTypeName();
110
111 if ((entry instanceof TransactionalDocumentEntry)
112 && (documentEntries.get(entry.getFullClassName()) != null)
113 && !((DocumentEntry)documentEntries.get(entry.getFullClassName())).getDocumentTypeName()
114 .equals(entry.getDocumentTypeName())) {
115 throw new DataDictionaryException(new StringBuffer("Two transactional document types may not share the same document class: this=")
116 .append(entry.getDocumentTypeName())
117 .append(" / existing=")
118 .append(((DocumentEntry)documentEntries.get(entry.getDocumentClass().getName())).getDocumentTypeName()).toString());
119 }
120 if ((entriesByJstlKey.get(entry.getJstlKey()) != null) && !((DocumentEntry)documentEntries.get(entry.getJstlKey())).getDocumentTypeName().equals(entry.getDocumentTypeName())) {
121 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());
122 }
123
124 documentEntries.put(entryName, entry);
125
126 documentEntries.put(entry.getDocumentClass().getName(), entry);
127 if (entry.getBaseDocumentClass() != null) {
128 documentEntries.put(entry.getBaseDocumentClass().getName(), entry);
129 }
130 entriesByJstlKey.put(entry.getJstlKey(), entry);
131
132 if (entry instanceof TransactionalDocumentEntry) {
133 TransactionalDocumentEntry tde = (TransactionalDocumentEntry) entry;
134
135 documentEntries.put(tde.getDocumentClass().getSimpleName(), entry);
136 if (tde.getBaseDocumentClass() != null) {
137 documentEntries.put(tde.getBaseDocumentClass().getSimpleName(), entry);
138 }
139 }
140 if (entry instanceof MaintenanceDocumentEntry) {
141 MaintenanceDocumentEntry mde = (MaintenanceDocumentEntry) entry;
142
143 documentEntriesByBusinessObjectClass.put(mde.getBusinessObjectClass(), entry);
144 documentEntriesByMaintainableClass.put(mde.getMaintainableClass(), entry);
145 documentEntries.put(mde.getBusinessObjectClass().getSimpleName() + "MaintenanceDocument", entry);
146 }
147 }
148 }
149
150 private void buildDDInactivationBlockingIndices() {
151 inactivationBlockersForClass = new HashMap<Class, Set<InactivationBlockingMetadata>>();
152 Map<String,BusinessObjectEntry> boBeans = ddBeans.getBeansOfType(BusinessObjectEntry.class);
153 for ( BusinessObjectEntry entry : boBeans.values() ) {
154 List<InactivationBlockingDefinition> inactivationBlockingDefinitions = entry.getInactivationBlockingDefinitions();
155 if (inactivationBlockingDefinitions != null && !inactivationBlockingDefinitions.isEmpty()) {
156 for (InactivationBlockingDefinition inactivationBlockingDefinition : inactivationBlockingDefinitions) {
157 registerInactivationBlockingDefinition(inactivationBlockingDefinition);
158 }
159 }
160 }
161 }
162
163 private void registerInactivationBlockingDefinition(InactivationBlockingDefinition inactivationBlockingDefinition) {
164 Set<InactivationBlockingMetadata> inactivationBlockingDefinitions = inactivationBlockersForClass.get(inactivationBlockingDefinition.getBlockedBusinessObjectClass());
165 if (inactivationBlockingDefinitions == null) {
166 inactivationBlockingDefinitions = new HashSet<InactivationBlockingMetadata>();
167 inactivationBlockersForClass.put(inactivationBlockingDefinition.getBlockedBusinessObjectClass(), inactivationBlockingDefinitions);
168 }
169 boolean duplicateAdd = ! inactivationBlockingDefinitions.add(inactivationBlockingDefinition);
170 if (duplicateAdd) {
171 throw new DataDictionaryException("Detected duplicate InactivationBlockingDefinition for class " + inactivationBlockingDefinition.getBlockingReferenceBusinessObjectClass().getClass().getName());
172 }
173 }
174
175 public void run() {
176 LOG.info( "Starting DD Index Building" );
177 buildDDIndicies();
178 LOG.info( "Completed DD Index Building" );
179
180
181
182 LOG.info( "Started DD Inactivation Blocking Index Building" );
183 buildDDInactivationBlockingIndices();
184 LOG.info( "Completed DD Inactivation Blocking Index Building" );
185 }
186 }