1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.web.struts.form;
17
18 import org.apache.commons.beanutils.PropertyUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.struts.upload.FormFile;
21 import org.kuali.rice.core.api.CoreApiServiceLocator;
22 import org.kuali.rice.core.api.config.ConfigurationException;
23 import org.kuali.rice.kns.authorization.AuthorizationConstants;
24 import org.kuali.rice.core.api.encryption.EncryptionService;
25 import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
26 import org.kuali.rice.kns.document.MaintenanceDocumentBase;
27 import org.kuali.rice.kns.inquiry.Inquirable;
28 import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
29 import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
30 import org.kuali.rice.kns.service.KNSServiceLocator;
31 import org.kuali.rice.krad.bo.Exporter;
32 import org.kuali.rice.krad.bo.PersistableBusinessObject;
33 import org.kuali.rice.krad.datadictionary.exception.UnknownBusinessClassAttributeException;
34 import org.kuali.rice.krad.datadictionary.exception.UnknownDocumentTypeException;
35 import org.kuali.rice.krad.document.Document;
36 import org.kuali.rice.krad.service.DataDictionaryService;
37 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
38 import org.kuali.rice.krad.service.KualiModuleService;
39 import org.kuali.rice.krad.service.ModuleService;
40 import org.kuali.rice.krad.util.KRADConstants;
41 import org.kuali.rice.krad.util.ObjectUtils;
42
43 import javax.servlet.http.HttpServletRequest;
44 import java.lang.reflect.Constructor;
45 import java.lang.reflect.InvocationTargetException;
46 import java.security.GeneralSecurityException;
47 import java.util.ArrayList;
48 import java.util.Enumeration;
49 import java.util.HashMap;
50 import java.util.List;
51 import java.util.Map;
52 import java.util.regex.Matcher;
53
54
55
56
57 public class InquiryForm extends KualiForm {
58 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(InquiryForm.class);
59
60 private static final long serialVersionUID = 1L;
61 private String fieldConversions;
62 private List sections;
63 private String businessObjectClassName;
64 private Map editingMode;
65 private String formKey;
66 private boolean canExport;
67
68 @Override
69 public void addRequiredNonEditableProperties(){
70 super.addRequiredNonEditableProperties();
71 registerRequiredNonEditableProperty(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE);
72 registerRequiredNonEditableProperty(KRADConstants.DISPATCH_REQUEST_PARAMETER);
73 registerRequiredNonEditableProperty(KRADConstants.DOC_FORM_KEY);
74 registerRequiredNonEditableProperty(KRADConstants.FORM_KEY);
75 registerRequiredNonEditableProperty(KRADConstants.FIELDS_CONVERSION_PARAMETER);
76 registerRequiredNonEditableProperty(KRADConstants.BACK_LOCATION);
77 }
78
79
80
81
82
83 private Map<String, String> inquiryPrimaryKeys;
84
85 private Map<String, String> inquiryDecryptedPrimaryKeys;
86
87
88
89
90 private Map<String, Boolean> inactiveRecordDisplay;
91
92 private Inquirable inquirable;
93
94 public InquiryForm() {
95 super();
96 this.editingMode = new HashMap();
97 this.editingMode.put(AuthorizationConstants.EditMode.VIEW_ONLY, "TRUE");
98 this.inactiveRecordDisplay = null;
99 }
100
101 @Override
102 public void populate(HttpServletRequest request) {
103
104
105 this.inquirable = null;
106 super.populate(request);
107 if (request.getParameter("returnLocation") != null) {
108 setBackLocation(request.getParameter("returnLocation"));
109 }
110 if (request.getParameter(KRADConstants.DOC_FORM_KEY) != null) {
111 setFormKey(request.getParameter(KRADConstants.DOC_FORM_KEY));
112 }
113
114 if(!KRADConstants.DOWNLOAD_BO_ATTACHMENT_METHOD.equals(getMethodToCall())){
115 inquirable = getInquirable(getBusinessObjectClassName());
116
117
118 boolean passedFromPreviousInquiry = !KRADConstants.START_METHOD.equals(getMethodToCall()) && !KRADConstants.CONTINUE_WITH_INQUIRY_METHOD_TO_CALL.equals(getMethodToCall()) && !KRADConstants
119 .DOWNLOAD_CUSTOM_BO_ATTACHMENT_METHOD.equals(getMethodToCall());
120
121
122
123
124
125 this.inquiryPrimaryKeys = new HashMap<String, String>();
126 this.inquiryDecryptedPrimaryKeys = new HashMap<String, String>();
127
128 populatePKFieldValues(request, getBusinessObjectClassName(), passedFromPreviousInquiry);
129
130 populateInactiveRecordsInIntoInquirable(inquirable, request);
131 populateExportCapabilities(request, getBusinessObjectClassName());
132 }
133 }
134
135 protected Inquirable getInquirable(String boClassName) {
136 try {
137 Class customInquirableClass = null;
138
139 try {
140 BusinessObjectEntry entry = (BusinessObjectEntry) KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(boClassName);
141 customInquirableClass = entry.getInquiryDefinition().getInquirableClass();
142 }
143 catch (Exception e) {
144 LOG.error("Unable to correlate business object class with maintenance document entry");
145 }
146
147 Inquirable kualiInquirable = KNSServiceLocator.getKualiInquirable();
148
149 if (customInquirableClass != null) {
150 Class[] defaultConstructor = new Class[] {};
151 Constructor cons = customInquirableClass.getConstructor(defaultConstructor);
152 kualiInquirable = (Inquirable) cons.newInstance();
153 }
154
155 kualiInquirable.setBusinessObjectClass(Class.forName(boClassName));
156
157 return kualiInquirable;
158 }
159 catch (Exception e) {
160 LOG.error("Error attempting to retrieve inquirable.", e);
161 throw new RuntimeException("Error attempting to retrieve inquirable.");
162 }
163 }
164
165
166
167
168
169
170
171 private List<List<String>> getAltkeys(Class<?> clazz) {
172 final KualiModuleService kualiModuleService = KRADServiceLocatorWeb.getKualiModuleService();
173 final ModuleService moduleService = kualiModuleService.getResponsibleModuleService(clazz);
174
175 List<List<String>> altKeys = null;
176 if (moduleService != null) {
177 altKeys = moduleService.listAlternatePrimaryKeyFieldNames(clazz);
178 }
179
180 return altKeys != null ? altKeys : new ArrayList<List<String>>();
181 }
182
183 protected void populatePKFieldValues(HttpServletRequest request, String boClassName, boolean passedFromPreviousInquiry) {
184 try {
185 EncryptionService encryptionService = CoreApiServiceLocator.getEncryptionService();
186 DataDictionaryService dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
187 BusinessObjectAuthorizationService businessObjectAuthorizationService = KNSServiceLocator
188 .getBusinessObjectAuthorizationService();
189 BusinessObjectMetaDataService businessObjectMetaDataService = KNSServiceLocator
190 .getBusinessObjectMetaDataService();
191
192 Class businessObjectClass = Class.forName(boClassName);
193
194
195 List<String> boPKeys = businessObjectMetaDataService.listPrimaryKeyFieldNames(businessObjectClass);
196 final List<List<String>> altKeys = this.getAltkeys(businessObjectClass);
197
198 altKeys.add(boPKeys);
199 boolean bFound = false;
200 for(List<String> boKeys : altKeys ){
201 if(bFound)
202 break;
203 int keyCount = boKeys.size();
204 int foundCount = 0;
205 for (String boKey : boKeys) {
206 String pkParamName = boKey;
207 if (passedFromPreviousInquiry) {
208 pkParamName = KRADConstants.INQUIRY_PK_VALUE_PASSED_FROM_PREVIOUS_REQUEST_PREFIX + pkParamName;
209 }
210
211 if (request.getParameter(pkParamName) != null) {
212 foundCount++;
213 String parameter = request.getParameter(pkParamName);
214
215 Boolean forceUppercase = Boolean.FALSE;
216 try {
217 forceUppercase = dataDictionaryService.getAttributeForceUppercase(businessObjectClass, boKey);
218 } catch (UnknownBusinessClassAttributeException ex) {
219
220
221
222 LOG.warn("BO class " + businessObjectClassName + " property " + boKey + " should probably have a DD definition.", ex);
223 }
224 String parameterCopy = parameter;
225 if (forceUppercase) {
226 parameter = parameter.toUpperCase();
227 }
228
229 inquiryPrimaryKeys.put(boKey, parameter);
230 if (businessObjectAuthorizationService.attributeValueNeedsToBeEncryptedOnFormsAndLinks(businessObjectClass, boKey)) {
231 try {
232 if(CoreApiServiceLocator.getEncryptionService().isEnabled()) {
233 inquiryDecryptedPrimaryKeys.put(boKey, encryptionService.decrypt(parameterCopy));
234 }
235 } catch (GeneralSecurityException e) {
236 LOG.error("BO class " + businessObjectClassName + " property " + boKey + " should have been encrypted, but there was a problem decrypting it.");
237 throw e;
238 }
239 }
240 else {
241 inquiryDecryptedPrimaryKeys.put(boKey, parameter);
242 }
243 }
244 }
245 if (foundCount == keyCount) {
246 bFound = true;
247 }
248 }
249 if(!bFound){
250 LOG.error("All keys not given to lookup for bo class name " + businessObjectClass.getName());
251 throw new RuntimeException("All keys not given to lookup for bo class name " + businessObjectClass.getName());
252 }
253 }
254 catch (ClassNotFoundException e) {
255 LOG.error("Can't instantiate class: " + boClassName, e);
256 throw new RuntimeException("Can't instantiate class: " + boClassName);
257 }
258 catch (GeneralSecurityException e) {
259 LOG.error("Can't decrypt value", e);
260 throw new RuntimeException("Can't decrypt value");
261 }
262 }
263
264
265
266
267
268 protected void populateExportCapabilities(HttpServletRequest request, String boClassName) {
269 setCanExport(false);
270 BusinessObjectEntry businessObjectEntry = (BusinessObjectEntry) KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(boClassName);
271 Class<? extends Exporter> exporterClass = businessObjectEntry.getExporterClass();
272 if (exporterClass != null) {
273 try {
274 Exporter exporter = exporterClass.newInstance();
275 if (exporter.getSupportedFormats(businessObjectEntry.getBusinessObjectClass()).contains(KRADConstants.XML_FORMAT)) {
276 setCanExport(true);
277 }
278 } catch (Exception e) {
279 LOG.error("Failed to locate or create exporter class: " + exporterClass, e);
280 throw new RuntimeException("Failed to locate or create exporter class: " + exporterClass);
281 }
282 }
283 }
284
285
286
287
288
289 public String getFieldConversions() {
290 return fieldConversions;
291 }
292
293
294
295
296
297 public void setFieldConversions(String fieldConversions) {
298 this.fieldConversions = fieldConversions;
299 }
300
301
302
303
304
305 public List getSections() {
306 return sections;
307 }
308
309
310
311
312
313 public void setSections(List sections) {
314 this.sections = sections;
315 }
316
317
318
319
320 public String getBusinessObjectClassName() {
321 return businessObjectClassName;
322 }
323
324
325
326
327 public void setBusinessObjectClassName(String businessObjectClassName) {
328 this.businessObjectClassName = businessObjectClassName;
329 }
330
331 public Map getEditingMode() {
332 return editingMode;
333 }
334
335
336
337
338
339
340
341 public Map<String, String> getInquiryPrimaryKeys() {
342 return this.inquiryPrimaryKeys;
343 }
344
345
346
347
348
349
350
351
352 public Map<String, String> retrieveInquiryDecryptedPrimaryKeys() {
353 return this.inquiryDecryptedPrimaryKeys;
354 }
355
356
357
358
359
360
361 public void setInquiryPrimaryKeys(Map<String, String> inquiryPrimaryKeys) {
362 this.inquiryPrimaryKeys = inquiryPrimaryKeys;
363 }
364
365
366
367
368
369
370 public Map<String, Boolean> getInactiveRecordDisplay() {
371 return getInquirable().getInactiveRecordDisplay();
372 }
373
374 public Inquirable getInquirable() {
375 return inquirable;
376 }
377
378 protected void populateInactiveRecordsInIntoInquirable(Inquirable inquirable, HttpServletRequest request) {
379 for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
380 String paramName = (String) e.nextElement();
381 if (paramName.startsWith(KRADConstants.INACTIVE_RECORD_DISPLAY_PARAM_PREFIX)) {
382 String collectionName = StringUtils.substringAfter(paramName, KRADConstants.INACTIVE_RECORD_DISPLAY_PARAM_PREFIX);
383 Boolean showInactive = Boolean.parseBoolean(request.getParameter(paramName));
384 inquirable.setShowInactiveRecords(collectionName, showInactive);
385 }
386 }
387 }
388
389 public String getFormKey() {
390 return this.formKey;
391 }
392
393 public void setFormKey(String formKey) {
394 this.formKey = formKey;
395 }
396
397
398
399
400 public boolean isCanExport() {
401 return this.canExport;
402 }
403
404
405
406
407 public void setCanExport(boolean canExport) {
408 this.canExport = canExport;
409 }
410
411
412 }