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