1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.datadictionary;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.springframework.beans.factory.support.KualiDefaultListableBeanFactory;
22
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28
29
30
31
32
33
34
35 public class DataDictionaryIndex implements Runnable {
36 private static final Log LOG = LogFactory.getLog(DataDictionaryIndex.class);
37
38 private KualiDefaultListableBeanFactory ddBeans;
39
40
41 private Map<String, BusinessObjectEntry> businessObjectEntries;
42 private Map<String, DataObjectEntry> objectEntries;
43
44
45 private Map<String, DocumentEntry> documentEntries;
46
47 private Map<Class, DocumentEntry> documentEntriesByBusinessObjectClass;
48 private Map<Class, DocumentEntry> documentEntriesByMaintainableClass;
49 private Map<String, DataDictionaryEntry> entriesByJstlKey;
50
51
52 private Map<Class, Set<InactivationBlockingMetadata>> inactivationBlockersForClass;
53
54 public DataDictionaryIndex(KualiDefaultListableBeanFactory ddBeans) {
55 this.ddBeans = ddBeans;
56 }
57
58 public Map<String, BusinessObjectEntry> getBusinessObjectEntries() {
59 return this.businessObjectEntries;
60 }
61
62 public Map<String, DataObjectEntry> getDataObjectEntries() {
63 return this.objectEntries;
64 }
65
66 public Map<String, DocumentEntry> getDocumentEntries() {
67 return this.documentEntries;
68 }
69
70 public Map<Class, DocumentEntry> getDocumentEntriesByBusinessObjectClass() {
71 return this.documentEntriesByBusinessObjectClass;
72 }
73
74 public Map<Class, DocumentEntry> getDocumentEntriesByMaintainableClass() {
75 return this.documentEntriesByMaintainableClass;
76 }
77
78 public Map<String, DataDictionaryEntry> getEntriesByJstlKey() {
79 return this.entriesByJstlKey;
80 }
81
82 public Map<Class, Set<InactivationBlockingMetadata>> getInactivationBlockersForClass() {
83 return this.inactivationBlockersForClass;
84 }
85
86 private void buildDDIndicies() {
87
88 businessObjectEntries = new HashMap<String, BusinessObjectEntry>();
89 objectEntries = new HashMap<String, DataObjectEntry>();
90 documentEntries = new HashMap<String, DocumentEntry>();
91
92
93 documentEntriesByBusinessObjectClass = new HashMap<Class, DocumentEntry>();
94 documentEntriesByMaintainableClass = new HashMap<Class, DocumentEntry>();
95 entriesByJstlKey = new HashMap<String, DataDictionaryEntry>();
96
97
98 Map<String, DataObjectEntry> boBeans = ddBeans.getBeansOfType(DataObjectEntry.class);
99 for ( DataObjectEntry entry : boBeans.values() ) {
100
101 DataObjectEntry indexedEntry = objectEntries.get(entry.getJstlKey());
102 if (indexedEntry == null){
103 indexedEntry = businessObjectEntries.get(entry.getJstlKey());
104 }
105 if ( (indexedEntry != null)
106 && !(indexedEntry.getDataObjectClass().equals(entry.getDataObjectClass()))) {
107 throw new DataDictionaryException(new StringBuffer("Two object classes may not share the same jstl key: this=").append(entry.getDataObjectClass()).append(" / existing=").append(indexedEntry.getDataObjectClass()).toString());
108 }
109
110
111 objectEntries.put(entry.getDataObjectClass().getName(), entry);
112 objectEntries.put(entry.getDataObjectClass().getSimpleName(), entry);
113
114
115 if (entry instanceof BusinessObjectEntry){
116 BusinessObjectEntry boEntry = (BusinessObjectEntry)entry;
117
118 businessObjectEntries.put(boEntry.getBusinessObjectClass().getName(), boEntry);
119 businessObjectEntries.put(boEntry.getBusinessObjectClass().getSimpleName(), boEntry);
120
121 if (boEntry.getBaseBusinessObjectClass() != null) {
122 businessObjectEntries.put(boEntry.getBaseBusinessObjectClass().getName(), boEntry);
123 businessObjectEntries.put(boEntry.getBaseBusinessObjectClass().getSimpleName(), boEntry);
124 }
125 }
126
127 entriesByJstlKey.put(entry.getJstlKey(), entry);
128 }
129
130
131 Map<String,DocumentEntry> docBeans = ddBeans.getBeansOfType(DocumentEntry.class);
132 for ( DocumentEntry entry : docBeans.values() ) {
133 String entryName = entry.getDocumentTypeName();
134
135 if ((entry instanceof TransactionalDocumentEntry)
136 && (documentEntries.get(entry.getFullClassName()) != null)
137 && !StringUtils.equals(documentEntries.get(entry.getFullClassName()).getDocumentTypeName(), entry.getDocumentTypeName())) {
138 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 if ((documentEntries.get(entry.getJstlKey()) != null) && !((DocumentEntry)documentEntries.get(entry.getJstlKey())).getDocumentTypeName().equals(entry.getDocumentTypeName())) {
144 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 if (entryName != null) {
148 documentEntries.put(entryName, entry);
149 }
150
151 documentEntries.put(entry.getDocumentClass().getName(), entry);
152 if (entry.getBaseDocumentClass() != null) {
153 documentEntries.put(entry.getBaseDocumentClass().getName(), entry);
154 }
155 entriesByJstlKey.put(entry.getJstlKey(), entry);
156
157 if (entry instanceof TransactionalDocumentEntry) {
158 TransactionalDocumentEntry tde = (TransactionalDocumentEntry) entry;
159
160 documentEntries.put(tde.getDocumentClass().getSimpleName(), entry);
161 if (tde.getBaseDocumentClass() != null) {
162 documentEntries.put(tde.getBaseDocumentClass().getSimpleName(), entry);
163 }
164 }
165 if (entry instanceof MaintenanceDocumentEntry) {
166 MaintenanceDocumentEntry mde = (MaintenanceDocumentEntry) entry;
167
168 documentEntriesByBusinessObjectClass.put(mde.getDataObjectClass(), entry);
169 documentEntriesByMaintainableClass.put(mde.getMaintainableClass(), entry);
170 documentEntries.put(mde.getDataObjectClass().getSimpleName() + "MaintenanceDocument", entry);
171 }
172 }
173 }
174
175 private void buildDDInactivationBlockingIndices() {
176 inactivationBlockersForClass = new HashMap<Class, Set<InactivationBlockingMetadata>>();
177 Map<String,DataObjectEntry> doBeans = ddBeans.getBeansOfType(DataObjectEntry.class);
178 for ( DataObjectEntry entry : doBeans.values() ) {
179 List<InactivationBlockingDefinition> inactivationBlockingDefinitions = entry.getInactivationBlockingDefinitions();
180 if (inactivationBlockingDefinitions != null && !inactivationBlockingDefinitions.isEmpty()) {
181 for (InactivationBlockingDefinition inactivationBlockingDefinition : inactivationBlockingDefinitions) {
182 registerInactivationBlockingDefinition(inactivationBlockingDefinition);
183 }
184 }
185 }
186 }
187
188 private void registerInactivationBlockingDefinition(InactivationBlockingDefinition inactivationBlockingDefinition) {
189 Set<InactivationBlockingMetadata> inactivationBlockingDefinitions = inactivationBlockersForClass.get(inactivationBlockingDefinition.getBlockedBusinessObjectClass());
190 if (inactivationBlockingDefinitions == null) {
191 inactivationBlockingDefinitions = new HashSet<InactivationBlockingMetadata>();
192 inactivationBlockersForClass.put(inactivationBlockingDefinition.getBlockedBusinessObjectClass(), inactivationBlockingDefinitions);
193 }
194 boolean duplicateAdd = ! inactivationBlockingDefinitions.add(inactivationBlockingDefinition);
195 if (duplicateAdd) {
196 throw new DataDictionaryException("Detected duplicate InactivationBlockingDefinition for class " + inactivationBlockingDefinition.getBlockingReferenceBusinessObjectClass().getClass().getName());
197 }
198 }
199
200 public void run() {
201 LOG.info( "Starting DD Index Building" );
202 buildDDIndicies();
203 LOG.info( "Completed DD Index Building" );
204
205
206
207 LOG.info( "Started DD Inactivation Blocking Index Building" );
208 buildDDInactivationBlockingIndices();
209 LOG.info( "Completed DD Inactivation Blocking Index Building" );
210 }
211 }