1
2
3
4 package org.kuali.ole.sys.web.dddumper;
5
6 import java.beans.PropertyDescriptor;
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.Collections;
10 import java.util.HashSet;
11 import java.util.List;
12 import java.util.Set;
13
14 import javax.servlet.http.HttpServletRequest;
15 import javax.servlet.http.HttpServletResponse;
16
17 import org.apache.commons.beanutils.PropertyUtils;
18 import org.apache.log4j.Logger;
19 import org.apache.ojb.broker.metadata.ClassDescriptor;
20 import org.apache.ojb.broker.metadata.DescriptorRepository;
21 import org.apache.ojb.broker.metadata.FieldDescriptor;
22 import org.apache.ojb.broker.metadata.MetadataManager;
23 import org.apache.struts.action.ActionForm;
24 import org.apache.struts.action.ActionForward;
25 import org.apache.struts.action.ActionMapping;
26 import org.kuali.rice.kew.api.KewApiServiceLocator;
27 import org.kuali.rice.kew.api.doctype.DocumentType;
28 import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
29 import org.kuali.rice.kns.datadictionary.InquiryDefinition;
30 import org.kuali.rice.kns.datadictionary.LookupDefinition;
31 import org.kuali.rice.kns.datadictionary.MaintainableCollectionDefinition;
32 import org.kuali.rice.kns.datadictionary.MaintainableFieldDefinition;
33 import org.kuali.rice.kns.datadictionary.MaintainableItemDefinition;
34 import org.kuali.rice.kns.datadictionary.MaintainableSectionDefinition;
35 import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
36 import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
37 import org.kuali.rice.kns.service.DataDictionaryService;
38 import org.kuali.rice.kns.service.KNSServiceLocator;
39 import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
40 import org.kuali.rice.kns.service.TransactionalDocumentDictionaryService;
41 import org.kuali.rice.kns.web.struts.action.KualiAction;
42 import org.kuali.rice.krad.bo.BusinessObject;
43 import org.kuali.rice.krad.bo.PersistableBusinessObject;
44 import org.kuali.rice.krad.datadictionary.AttributeDefinition;
45 import org.kuali.rice.krad.datadictionary.AttributeSecurity;
46 import org.kuali.rice.krad.datadictionary.DocumentEntry;
47 import org.kuali.rice.krad.datadictionary.ReferenceDefinition;
48 import org.kuali.rice.krad.document.Document;
49 import org.kuali.rice.krad.service.PersistenceStructureService;
50
51 public class DataDictionaryDumperDetailAction extends KualiAction {
52 protected transient MaintenanceDocumentDictionaryService maintDocSvc;
53 protected transient BusinessObjectDictionaryService boSvc;
54 protected transient DataDictionaryService ddSvc;
55 protected transient BusinessObjectMetaDataService boMetaSvc;
56 protected transient TransactionalDocumentDictionaryService transDocSvc;
57 protected transient MetadataManager mm;
58 protected PersistenceStructureService persistSS;
59 protected transient DescriptorRepository dr;
60 protected Set<String> documentClasses = new HashSet<String>();
61 protected Set<String> objectsToSkip = new HashSet<String>();
62 protected DataDictionaryDumperDetailForm dumperDetailForm;
63 protected String entityClass;
64 protected String jstlKey;
65 protected String docClass;
66 protected String type;
67 protected List<DataDictionaryDumperDocumentRow> rowList;
68 protected List<DataDictionaryDumperSection> sectionList;
69 protected List<DataDictionaryDumperDocumentRow> unprocessedRows;
70
71 protected static final Logger LOG = Logger.getLogger(DataDictionaryDumperDetailAction.class);
72
73 public DataDictionaryDumperDetailAction() {
74 maintDocSvc = KNSServiceLocator.getMaintenanceDocumentDictionaryService();
75 boSvc = KNSServiceLocator.getBusinessObjectDictionaryService();
76 ddSvc = KNSServiceLocator.getDataDictionaryService();
77 boMetaSvc = KNSServiceLocator.getBusinessObjectMetaDataService();
78 transDocSvc = KNSServiceLocator.getTransactionalDocumentDictionaryService();
79
80 mm = MetadataManager.getInstance();
81 dr = mm.getRepository();
82 }
83
84 @Override
85 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
86 dumperDetailForm = (DataDictionaryDumperDetailForm) form;
87 entityClass = request.getParameter("entryClass");
88
89 jstlKey = request.getParameter("jstlKey");
90 docClass = request.getParameter("docClass");
91 type = request.getParameter("type");
92 sectionList = dumperDetailForm.getSections();
93 dumperDetailForm.setTitle(request.getParameter("title"));
94
95 if (docClass.endsWith("MaintenanceDocument")) {
96 processDumpDataDictionary_MaintenanceDocuments();
97 }
98 else {
99 processDumpDataDictionary_TransactionalDocuments();
100 }
101
102 return mapping.findForward("basic");
103 }
104
105 public void processDumpDataDictionary_MaintenanceDocuments() {
106 Class<BusinessObject> boClass = maintDocSvc.getDataObjectClass(jstlKey);
107 processDumpDataDictionary_MaintenanceDocuments(boClass);
108
109
110
111
112
113
114 for (MaintainableCollectionDefinition boCollection : maintDocSvc.getMaintainableCollections(jstlKey)) {
115
116 if (LOG.isDebugEnabled()) {
117 LOG.debug("*******" + boCollection.getName());
118 }
119 Class<BusinessObject> collectionClass = (Class<BusinessObject>) boCollection.getBusinessObjectClass();
120 processDumpDataDictionary_MaintenanceDocumentCollections(collectionClass);
121 processUnprocessedRows(collectionClass, unprocessedRows);
122 }
123 }
124
125 protected DataDictionaryDumperSection getDetailSectionForBoClass( Class<? extends BusinessObject> boClass ) {
126 DataDictionaryDumperSection detailSection = new DataDictionaryDumperSection();
127 rowList = detailSection.getDocumentRows();
128 unprocessedRows = new ArrayList<DataDictionaryDumperDocumentRow>();
129
130 detailSection.setDocId(jstlKey);
131 DocumentEntry documentEntry = ddSvc.getDataDictionary().getDocumentEntry(jstlKey);
132 entityClass = boClass.getName();
133 detailSection.setBusinessObject(entityClass);
134
135 DocumentType docType = KewApiServiceLocator.getDocumentTypeService().getDocumentTypeByName(documentEntry.getDocumentTypeName());
136 if ( docType != null ) {
137 detailSection.setDocName(docType.getLabel());
138 } else {
139 detailSection.setDocName("Not Found: " + documentEntry.getDocumentTypeName() );
140 }
141
142 if ( documentEntry.getDocumentAuthorizerClass() != null ) {
143 detailSection.setDocumentAuthorizerClass(documentEntry.getDocumentAuthorizerClass().getName());
144 }
145 if ( documentEntry.getBusinessRulesClass() != null ) {
146 detailSection.setBusinessObjectRulesClass(documentEntry.getBusinessRulesClass().getName());
147 }
148 if ( dr.getDescriptorFor(boClass) != null ) {
149 detailSection.setTable(dr.getDescriptorFor(boClass).getFullTableName());
150 }
151 return detailSection;
152 }
153
154 protected void processDumpDataDictionary_MaintenanceDocuments(Class<BusinessObject> boClass) {
155 DataDictionaryDumperSection detailSection = getDetailSectionForBoClass(boClass);
156
157 if (boClass != null) {
158
159 ClassDescriptor cd = dr.getDescriptorFor(boClass);
160 List<MaintainableSectionDefinition> sections = maintDocSvc.getMaintainableSections(jstlKey);
161 Collection<ReferenceDefinition> existenceChecks = maintDocSvc.getDefaultExistenceChecks(jstlKey);
162 for (MaintainableSectionDefinition section : sections) {
163 Collection<MaintainableItemDefinition> items = section.getMaintainableItems();
164 for (MaintainableItemDefinition item : items) {
165 DataDictionaryDumperDocumentRow detailRow = new DataDictionaryDumperDocumentRow();
166 if (item.getName().endsWith("versionNumber")) {
167 continue;
168 }
169 StringBuilder row = new StringBuilder(1000);
170 if (item instanceof MaintainableFieldDefinition) {
171 MaintainableFieldDefinition field = (MaintainableFieldDefinition) item;
172 String fieldName = field.getName();
173 FieldDescriptor fd = cd.getFieldDescriptorByName(fieldName);
174 LookupDefinition ld = null;
175 InquiryDefinition id = null;
176 if (ddSvc.getDataDictionary().getBusinessObjectEntry(boClass.getSimpleName()) != null) {
177 ld = ((BusinessObjectEntry)ddSvc.getDataDictionary().getBusinessObjectEntry(boClass.getSimpleName())).getLookupDefinition();
178 id = ((BusinessObjectEntry)ddSvc.getDataDictionary().getBusinessObjectEntry(boClass.getSimpleName())).getInquiryDefinition();
179 }
180 List<String> lookupFields = (ld == null) ? Collections.EMPTY_LIST : ld.getLookupFieldNames();
181 List<String> resultFields = (ld == null) ? Collections.EMPTY_LIST : ld.getResultFieldNames();
182
183 detailRow.setName(ddSvc.getAttributeLabel(boClass, fieldName));
184 detailRow.setFieldName(fieldName);
185 detailRow.setRequired(field.isRequired());
186 detailRow.setDefaultValue((field.getDefaultValue() == null) ? ((field.getDefaultValueFinderClass() != null) ? field.getDefaultValueFinderClass().getSimpleName() : "") : field.getDefaultValue());
187 detailRow.setReadOnly(field.isUnconditionallyReadOnly());
188 if (ddSvc.getAttributeValidatingExpression(boClass, fieldName) != null) {
189 detailRow.setValidationRules(ddSvc.getAttributeValidatingExpression(boClass, fieldName).toString());
190 }
191 else {
192 detailRow.setValidationRules("(null)");
193 }
194 if (ddSvc.getAttributeMaxLength(boClass, fieldName) != null) {
195 detailRow.setMaxLength(ddSvc.getAttributeMaxLength(boClass, fieldName).toString());
196 }
197 else {
198 detailRow.setMaxLength("(null)");
199 }
200 detailRow.setExistenceCheck(hasExistenceCheck(existenceChecks, fieldName));
201 detailRow.setLookupParam(lookupFields.contains(fieldName));
202 detailRow.setLookupResult(resultFields.contains(fieldName));
203 try {
204 String fullControlDefinition = ddSvc.getAttributeControlDefinition(boClass, fieldName).getClass().getSimpleName();
205 detailRow.setControlDefinition(fullControlDefinition.substring(0, fullControlDefinition.indexOf("ControlDefinition")));
206 }
207 catch (NullPointerException npe) {
208
209 break;
210 }
211 AttributeSecurity fieldSecurity = ddSvc.getAttributeSecurity(boClass.getName(), fieldName);
212 if (fieldSecurity != null) {
213 detailRow.setFieldSecurity((fieldSecurity.isHide() ? "Hide<br>" : "") + (fieldSecurity.isMask() ? "Mask<br>" : "") + (fieldSecurity.isPartialMask() ? "Partial Mask<br>" : "") + (fieldSecurity.isReadOnly() ? "Read Only" : ""));
214 }
215 else {
216 detailRow.setFieldSecurity("");
217 }
218 if (fd != null) {
219 detailRow.setFieldType(fd.getColumnType());
220 detailRow.setColumn(fd.getColumnName());
221 detailRow.setColumnNo(fd.getColNo());
222 rowList.add(detailRow);
223 }
224 else {
225 unprocessedRows.add(detailRow);
226 }
227
228 }
229
230 }
231 }
232
233 }
234 Collections.sort(rowList);
235 detailSection.setDocumentRows(rowList);
236 sectionList.add(detailSection);
237
238 }
239
240 protected void processDumpDataDictionary_MaintenanceDocumentCollections(Class<BusinessObject> boClass) {
241 DataDictionaryDumperSection detailSection = getDetailSectionForBoClass(boClass);
242 detailSection.setCollection(true);
243
244 if (boClass != null) {
245
246 ClassDescriptor cd = dr.getDescriptorFor(boClass);
247 List<MaintainableSectionDefinition> sections = maintDocSvc.getMaintainableSections(jstlKey);
248 Collection<ReferenceDefinition> existenceChecks = maintDocSvc.getDefaultExistenceChecks(jstlKey);
249 Collection<AttributeDefinition> items = ddSvc.getDataDictionary().getBusinessObjectEntry(boClass.getSimpleName()).getAttributes();
250 for (AttributeDefinition item : items) {
251 DataDictionaryDumperDocumentRow detailRow = new DataDictionaryDumperDocumentRow();
252
253 if (item.getName().endsWith("versionNumber")) {
254 continue;
255 }
256 StringBuilder row = new StringBuilder(1000);
257
258 FieldDescriptor fd = cd.getFieldDescriptorByName(item.getName());
259 LookupDefinition ld = null;
260 InquiryDefinition id = null;
261 if (ddSvc.getDataDictionary().getBusinessObjectEntry(boClass.getSimpleName()) != null) {
262 ld = ((BusinessObjectEntry)ddSvc.getDataDictionary().getBusinessObjectEntry(boClass.getSimpleName())).getLookupDefinition();
263 id = ((BusinessObjectEntry)ddSvc.getDataDictionary().getBusinessObjectEntry(boClass.getSimpleName())).getInquiryDefinition();
264 }
265 List<String> lookupFields = (ld == null) ? Collections.EMPTY_LIST : ld.getLookupFieldNames();
266 List<String> resultFields = (ld == null) ? Collections.EMPTY_LIST : ld.getResultFieldNames();
267
268 detailRow.setName(ddSvc.getAttributeLabel(boClass, item.getName()));
269 detailRow.setFieldName(item.getName());
270 detailRow.setRequired(item.isRequired());
271 if (ddSvc.getAttributeValidatingExpression(boClass, item.getName()) != null) {
272 detailRow.setValidationRules(ddSvc.getAttributeValidatingExpression(boClass, item.getName()).toString());
273 }
274 else {
275 detailRow.setValidationRules("(null)");
276 }
277 if (ddSvc.getAttributeMaxLength(boClass, item.getName()) != null) {
278 detailRow.setMaxLength(ddSvc.getAttributeMaxLength(boClass, item.getName()).toString());
279 }
280 else {
281 detailRow.setMaxLength("(null)");
282 }
283 detailRow.setExistenceCheck(hasExistenceCheck(existenceChecks, item.getName()));
284 detailRow.setLookupParam(lookupFields.contains(item.getName()));
285 detailRow.setLookupResult(resultFields.contains(item.getName()));
286 try {
287 String fullControlDefinition = ddSvc.getAttributeControlDefinition(boClass, item.getName()).getClass().getSimpleName();
288 detailRow.setControlDefinition(fullControlDefinition.substring(0, fullControlDefinition.indexOf("ControlDefinition")));
289 }
290 catch (NullPointerException npe) {
291
292 break;
293 }
294 AttributeSecurity fieldSecurity = ddSvc.getAttributeSecurity(boClass.getName(), item.getName());
295 if (fieldSecurity != null) {
296 detailRow.setFieldSecurity((fieldSecurity.isHide() ? "Hide<br>" : "") + (fieldSecurity.isMask() ? "Mask<br>" : "") + (fieldSecurity.isPartialMask() ? "Partial Mask<br>" : "") + (fieldSecurity.isReadOnly() ? "Read Only" : ""));
297 }
298 else {
299 detailRow.setFieldSecurity("");
300 }
301 if (fd != null) {
302 detailRow.setFieldType(fd.getColumnType());
303 detailRow.setColumn(fd.getColumnName());
304 detailRow.setColumnNo(fd.getColNo());
305 rowList.add(detailRow);
306 }
307 else {
308 unprocessedRows.add(detailRow);
309 }
310
311
312 }
313
314
315 }
316 Collections.sort(rowList);
317 detailSection.setDocumentRows(rowList);
318 sectionList.add(detailSection);
319
320 }
321
322
323
324
325
326
327 protected void processUnprocessedRows(Class<BusinessObject> boClass, List<DataDictionaryDumperDocumentRow> processingRows) {
328 DataDictionaryDumperSection detailSection = new DataDictionaryDumperSection();
329 rowList = detailSection.getDocumentRows();
330 unprocessedRows = new ArrayList<DataDictionaryDumperDocumentRow>();
331 if ( rowList != null ) {
332 detailSection.setDocId(jstlKey);
333 DocumentType docType = KewApiServiceLocator.getDocumentTypeService().getDocumentTypeByName(jstlKey);
334 if ( docType != null ) {
335 detailSection.setDocName(docType.getLabel());
336 } else {
337 detailSection.setDocName("Not Found: " + jstlKey );
338 }
339
340
341 for (DataDictionaryDumperDocumentRow row : processingRows) {
342
343 DataDictionaryDumperDocumentRow detailRow = new DataDictionaryDumperDocumentRow();
344
345 detailRow.setName(row.getName());
346 detailRow.setRequired(row.isRequired());
347 detailRow.setDefaultValue(row.getDefaultValue());
348 detailRow.setReadOnly(row.isReadOnly());
349 detailRow.setValidationRules(row.getValidationRules());
350 detailRow.setMaxLength(row.getMaxLength());
351 detailRow.setExistenceCheck(row.isExistenceCheck());
352 detailRow.setLookupParam(row.isLookupParam());
353 detailRow.setLookupResult(row.isLookupResult());
354 detailRow.setControlDefinition(row.getControlDefinition());
355 detailRow.setFieldSecurity(row.getFieldSecurity());
356 if (boClass != null) {
357 detailSection.setBusinessObject(boClass.getName());
358 if ( dr.hasDescriptorFor(boClass) ) {
359 detailSection.setTable(dr.getDescriptorFor(boClass).getFullTableName());
360 String fieldName = row.getFieldName().substring(row.getFieldName().indexOf('.') + 1);
361 FieldDescriptor fd = dr.getDescriptorFor(boClass).getFieldDescriptorByName(fieldName);
362 if (fd != null) {
363 detailRow.setFieldType(fd.getColumnType());
364 detailRow.setColumn(fd.getColumnName());
365 detailRow.setColumnNo(fd.getColNo());
366 rowList.add(detailRow);
367 }
368 } else {
369 unprocessedRows.add(row);
370 }
371 }
372 else {
373
374
375
376 }
377 }
378 Collections.sort(rowList);
379 detailSection.setDocumentRows(rowList);
380 if (detailSection.getDocumentRows().size() > 0) {
381 sectionList.add(detailSection);
382 }
383 }
384 }
385
386 public void processDumpDataDictionary_TransactionalDocuments() {
387 try {
388 Class<? extends Document> documentClazz = (Class<? extends Document>) Class.forName(entityClass);
389 processDumpDataDictionary_TransactionalDocuments(documentClazz);
390 } catch (ClassNotFoundException ex) {
391 LOG.error( "Unable to find document class: " + entityClass );
392 }
393 }
394
395 public void processDumpDataDictionary_TransactionalDocuments(Class<? extends Document> documentClazz) {
396
397
398
399
400
401
402 DataDictionaryDumperSection detailSection = getDetailSectionForBoClass(documentClazz);
403
404 if (!dr.hasDescriptorFor(documentClazz)) {
405 return;
406 }
407 ClassDescriptor cd = dr.getDescriptorFor(documentClazz);
408 List<AttributeDefinition> attributes = ddSvc.getDataDictionary().getDocumentEntry(jstlKey).getAttributes();
409
410 for (AttributeDefinition attribute : attributes) {
411 DataDictionaryDumperDocumentRow detailRow = new DataDictionaryDumperDocumentRow();
412 String attributeName = attribute.getName();
413 if (attributeName.startsWith("documentHeader.")) {
414 continue;
415 }
416 if (attributeName.endsWith("versionNumber")) {
417 continue;
418 }
419 StringBuilder row = new StringBuilder(1000);
420 FieldDescriptor fd = cd.getFieldDescriptorByName(attributeName);
421
422 detailRow.setName(attribute.getLabel());
423
424 detailRow.setRequired(attribute.isRequired());
425 detailRow.setValidationRules((attribute.getValidationPattern() == null) ? "" : attribute.getValidationPattern().getRegexPattern().toString());
426 detailRow.setMaxLength((attribute.getMaxLength() == null) ? "" : attribute.getMaxLength().toString());
427 detailRow.setFieldType((fd == null) ? "" : fd.getColumnType());
428
429 detailRow.setControlDefinition(ddSvc.getAttributeControlDefinition(documentClazz, attributeName).getClass().getSimpleName());
430 AttributeSecurity fieldSecurity = ddSvc.getAttributeSecurity(documentClazz.getName(), attributeName);
431 if (fieldSecurity != null) {
432 detailRow.setFieldSecurity((fieldSecurity.isHide() ? "Hide<br>" : "") + (fieldSecurity.isMask() ? "Mask<br>" : "") + (fieldSecurity.isPartialMask() ? "Partial Mask<br>" : "") + (fieldSecurity.isReadOnly() ? "Read Only" : ""));
433 }
434 else {
435 detailRow.setFieldSecurity("");
436 }
437
438 if (fd != null) {
439 detailRow.setFieldType(fd.getColumnType());
440 detailRow.setColumn(fd.getColumnName());
441 detailRow.setColumnNo(fd.getColNo());
442
443 }
444
445
446 rowList.add(detailRow);
447 }
448 PropertyDescriptor[] props = PropertyUtils.getPropertyDescriptors(documentClazz);
449 for (PropertyDescriptor prop : props) {
450 DataDictionaryDumperDocumentRow detailRow = new DataDictionaryDumperDocumentRow();
451
452 if (!objectsToSkip.contains(prop.getDisplayName()) && prop.getPropertyType() != null && PersistableBusinessObject.class.isAssignableFrom(prop.getPropertyType()) && ddSvc.getDataDictionary().getBusinessObjectEntry(prop.getPropertyType().getSimpleName()) != null) {
453 if (!dr.hasDescriptorFor(prop.getPropertyType())) {
454 continue;
455 }
456 cd = dr.getDescriptorFor(prop.getPropertyType());
457
458 attributes = ddSvc.getDataDictionary().getBusinessObjectEntry(prop.getPropertyType().getSimpleName()).getAttributes();
459 for (AttributeDefinition attribute : attributes) {
460 String attributeName = attribute.getName();
461 if (attributeName.endsWith("versionNumber")) {
462 continue;
463 }
464 FieldDescriptor fd = cd.getFieldDescriptorByName(attributeName);
465
466 detailRow.setName(prop.getName());
467
468 detailRow.setValidationRules(prop.getClass().getSimpleName());
469
470 detailRow.setFieldType(prop.getPropertyType().getSimpleName());
471 detailRow.setColumn("Property");
472
473
474
475
476
477 rowList.add(detailRow);
478 }
479 }
480 }
481
482
483
484
485 detailSection.setDocumentRows(rowList);
486 sectionList.add(detailSection);
487
488 }
489
490 protected boolean hasExistenceCheck(Collection<ReferenceDefinition> existenceChecks, String attributeName) {
491
492 for (ReferenceDefinition ref : existenceChecks) {
493 if (attributeName.equals(ref.getAttributeToHighlightOnFail())) {
494 return true;
495 }
496 }
497 return false;
498 }
499 }