1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.inquiry;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.CoreApiServiceLocator;
20 import org.kuali.rice.core.api.config.property.ConfigurationService;
21 import org.kuali.rice.core.api.encryption.EncryptionService;
22 import org.kuali.rice.krad.bo.BusinessObject;
23 import org.kuali.rice.krad.bo.BusinessObjectRelationship;
24 import org.kuali.rice.krad.bo.DocumentHeader;
25 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
26 import org.kuali.rice.krad.datadictionary.exception.UnknownBusinessClassAttributeException;
27 import org.kuali.rice.krad.service.BusinessObjectService;
28 import org.kuali.rice.krad.service.DataDictionaryService;
29 import org.kuali.rice.krad.service.DataObjectAuthorizationService;
30 import org.kuali.rice.krad.service.DataObjectMetaDataService;
31 import org.kuali.rice.krad.service.KRADServiceLocator;
32 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
33 import org.kuali.rice.krad.service.KualiModuleService;
34 import org.kuali.rice.krad.service.ModuleService;
35 import org.kuali.rice.krad.uif.service.impl.ViewHelperServiceImpl;
36 import org.kuali.rice.krad.uif.widget.Inquiry;
37 import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
38 import org.kuali.rice.krad.util.KRADConstants;
39 import org.kuali.rice.krad.util.ObjectUtils;
40
41 import java.security.GeneralSecurityException;
42 import java.util.ArrayList;
43 import java.util.Collections;
44 import java.util.HashMap;
45 import java.util.List;
46 import java.util.Map;
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class InquirableImpl extends ViewHelperServiceImpl implements Inquirable {
61 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(InquirableImpl.class);
62
63 protected Class<?> dataObjectClass;
64
65
66
67
68
69
70
71
72 public static List<Class<?>> SUPER_CLASS_TRANSLATOR_LIST = new ArrayList<Class<?>>();
73
74 private ConfigurationService configurationService;
75 private DataObjectMetaDataService dataObjectMetaDataService;
76 private KualiModuleService kualiModuleService;
77 private DataDictionaryService dataDictionaryService;
78 private DataObjectAuthorizationService dataObjectAuthorizationService;
79 private EncryptionService encryptionService;
80 private BusinessObjectService businessObjectService;
81
82
83
84
85
86
87
88
89
90
91
92
93
94 @Override
95 public Object retrieveDataObject(Map<String, String> parameters) {
96 if (dataObjectClass == null) {
97 LOG.error("Data object class must be set in inquirable before retrieving the object");
98 throw new RuntimeException("Data object class must be set in inquirable before retrieving the object");
99 }
100
101
102 List<String> pkPropertyNames = getDataObjectMetaDataService().listPrimaryKeyFieldNames(dataObjectClass);
103
104
105 List<List<String>> alternateKeyNames = this.getAlternateKeysForClass(dataObjectClass);
106
107
108 alternateKeyNames.add(0, pkPropertyNames);
109
110 List<String> dataObjectKeySet = retrieveKeySetFromMap(alternateKeyNames, parameters);
111 if ((dataObjectKeySet == null) || dataObjectKeySet.isEmpty()) {
112 LOG.warn("Matching key set not found in request for class: " + getDataObjectClass());
113
114 return null;
115 }
116
117
118 Map<String, Object> keyPropertyValues = new HashMap<String, Object>();
119 for (String keyPropertyName : dataObjectKeySet) {
120 String keyPropertyValue = parameters.get(keyPropertyName);
121
122
123 Boolean forceUppercase = Boolean.FALSE;
124 try {
125 forceUppercase = dataDictionaryService.getAttributeForceUppercase(dataObjectClass, keyPropertyName);
126 } catch (UnknownBusinessClassAttributeException ex) {
127
128
129 LOG.warn("Data object class " + dataObjectClass + " property " + keyPropertyName +
130 " should probably have a DD definition.", ex);
131 }
132
133 if (forceUppercase.booleanValue()) {
134 keyPropertyName = keyPropertyName.toUpperCase();
135 }
136
137
138 if (getDataObjectAuthorizationService()
139 .attributeValueNeedsToBeEncryptedOnFormsAndLinks(dataObjectClass, keyPropertyName)) {
140 try {
141 keyPropertyValue = encryptionService.decrypt(keyPropertyValue);
142 } catch (GeneralSecurityException e) {
143 LOG.error("Data object class " + dataObjectClass + " property " + keyPropertyName +
144 " should have been encrypted, but there was a problem decrypting it.", e);
145 throw new RuntimeException("Data object class " + dataObjectClass + " property " + keyPropertyName +
146 " should have been encrypted, but there was a problem decrypting it.", e);
147 }
148 }
149
150 keyPropertyValues.put(keyPropertyName, keyPropertyValue);
151 }
152
153
154 Object dataObject = null;
155
156 ModuleService moduleService =
157 KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(getDataObjectClass());
158 if (moduleService != null && moduleService.isExternalizable(getDataObjectClass())) {
159 dataObject = moduleService.getExternalizableBusinessObject(
160 getDataObjectClass().asSubclass(ExternalizableBusinessObject.class), keyPropertyValues);
161 } else if (BusinessObject.class.isAssignableFrom(getDataObjectClass())) {
162 dataObject = getBusinessObjectService()
163 .findByPrimaryKey(getDataObjectClass().asSubclass(BusinessObject.class), keyPropertyValues);
164 }
165
166 return dataObject;
167 }
168
169
170
171
172
173
174
175
176
177 protected List<String> retrieveKeySetFromMap(List<List<String>> potentialKeySets, Map<String, String> parameters) {
178 List<String> foundKeySet = null;
179
180 for (List<String> potentialKeySet : potentialKeySets) {
181 boolean keySetMatch = true;
182 for (String keyName : potentialKeySet) {
183 if (!parameters.containsKey(keyName) || StringUtils.isBlank(parameters.get(keyName))) {
184 keySetMatch = false;
185 }
186 }
187
188 if (keySetMatch) {
189 foundKeySet = potentialKeySet;
190 break;
191 }
192 }
193
194 return foundKeySet;
195 }
196
197
198
199
200
201
202
203
204 protected List<List<String>> getAlternateKeysForClass(Class<?> clazz) {
205 KualiModuleService kualiModuleService = getKualiModuleService();
206 ModuleService moduleService = kualiModuleService.getResponsibleModuleService(clazz);
207
208 List<List<String>> altKeys = null;
209 if (moduleService != null) {
210 altKeys = moduleService.listAlternatePrimaryKeyFieldNames(clazz);
211 }
212
213 return altKeys != null ? altKeys : new ArrayList<List<String>>();
214 }
215
216
217
218
219
220 @Override
221 public void buildInquirableLink(Object dataObject, String propertyName, Inquiry inquiry) {
222 Class<?> inquiryObjectClass = null;
223
224
225 Class<?> objectClass = ObjectUtils.materializeClassForProxiedObject(dataObject);
226 if (propertyName.equals(getDataObjectMetaDataService().getTitleAttribute(objectClass))) {
227 inquiryObjectClass = objectClass;
228 } else if (ObjectUtils.isNestedAttribute(propertyName)) {
229 String nestedPropertyName = ObjectUtils.getNestedAttributePrefix(propertyName);
230 Object nestedPropertyObject = ObjectUtils.getNestedValue(dataObject, nestedPropertyName);
231
232 if (ObjectUtils.isNotNull(nestedPropertyObject)) {
233 String nestedPropertyPrimitive = ObjectUtils.getNestedAttributePrimitive(propertyName);
234 Class<?> nestedPropertyObjectClass = ObjectUtils.materializeClassForProxiedObject(nestedPropertyObject);
235
236 if (nestedPropertyPrimitive
237 .equals(getDataObjectMetaDataService().getTitleAttribute(nestedPropertyObjectClass))) {
238 inquiryObjectClass = nestedPropertyObjectClass;
239 }
240 }
241 }
242
243
244 BusinessObjectRelationship relationship = null;
245 if (inquiryObjectClass == null) {
246 relationship = getDataObjectMetaDataService()
247 .getDataObjectRelationship(dataObject, objectClass, propertyName, "", true, false, true);
248 if (relationship != null) {
249 inquiryObjectClass = relationship.getRelatedClass();
250 }
251 }
252
253
254 if (inquiryObjectClass == null) {
255 inquiry.setRender(false);
256
257 return;
258 }
259
260 if (DocumentHeader.class.isAssignableFrom(inquiryObjectClass)) {
261 String documentNumber = (String) ObjectUtils.getPropertyValue(dataObject, propertyName);
262 if (StringUtils.isNotBlank(documentNumber)) {
263 inquiry.getInquiryLinkField().setHrefText(
264 getConfigurationService().getPropertyString(KRADConstants.WORKFLOW_URL_KEY) +
265 KRADConstants.DOCHANDLER_DO_URL + documentNumber + KRADConstants.DOCHANDLER_URL_CHUNK);
266 inquiry.getInquiryLinkField().setLinkLabel(documentNumber);
267 inquiry.setRender(true);
268 }
269
270 return;
271 }
272
273 synchronized (SUPER_CLASS_TRANSLATOR_LIST) {
274 for (Class<?> clazz : SUPER_CLASS_TRANSLATOR_LIST) {
275 if (clazz.isAssignableFrom(inquiryObjectClass)) {
276 inquiryObjectClass = clazz;
277 break;
278 }
279 }
280 }
281
282 if (!inquiryObjectClass.isInterface() &&
283 ExternalizableBusinessObject.class.isAssignableFrom(inquiryObjectClass)) {
284 inquiryObjectClass = ExternalizableBusinessObjectUtils
285 .determineExternalizableBusinessObjectSubInterface(inquiryObjectClass);
286 }
287
288
289
290 List<String> keys =
291 new ArrayList<String>(getDataObjectMetaDataService().listPrimaryKeyFieldNames(inquiryObjectClass));
292
293 if (keys == null) {
294 keys = Collections.emptyList();
295 }
296
297
298 Map<String, String> inquiryParameters = new HashMap<String, String>();
299 for (String keyName : keys) {
300 String keyConversion = keyName;
301 if (relationship != null) {
302 keyConversion = relationship.getChildAttributeForParentAttribute(keyName);
303 } else if (ObjectUtils.isNestedAttribute(propertyName)) {
304 String nestedAttributePrefix = ObjectUtils.getNestedAttributePrefix(propertyName);
305 keyConversion = nestedAttributePrefix + "." + keyName;
306 }
307
308 inquiryParameters.put(keyConversion, keyName);
309 }
310
311 inquiry.buildInquiryLink(dataObject, propertyName, inquiryObjectClass, inquiryParameters);
312 }
313
314
315
316
317 @Override
318 public void setDataObjectClass(Class<?> dataObjectClass) {
319 this.dataObjectClass = dataObjectClass;
320 }
321
322
323
324
325
326
327 protected Class<?> getDataObjectClass() {
328 return this.dataObjectClass;
329 }
330
331 protected ConfigurationService getConfigurationService() {
332 if (configurationService == null) {
333 configurationService = KRADServiceLocator.getKualiConfigurationService();
334 }
335 return this.configurationService;
336 }
337
338 public void setConfigurationService(ConfigurationService configurationService) {
339 this.configurationService = configurationService;
340 }
341
342 protected DataObjectMetaDataService getDataObjectMetaDataService() {
343 if (dataObjectMetaDataService == null) {
344 this.dataObjectMetaDataService = KRADServiceLocatorWeb.getDataObjectMetaDataService();
345 }
346 return dataObjectMetaDataService;
347 }
348
349 public void setDataObjectMetaDataService(DataObjectMetaDataService dataObjectMetaDataService) {
350 this.dataObjectMetaDataService = dataObjectMetaDataService;
351 }
352
353 protected KualiModuleService getKualiModuleService() {
354 if (kualiModuleService == null) {
355 this.kualiModuleService = KRADServiceLocatorWeb.getKualiModuleService();
356 }
357 return kualiModuleService;
358 }
359
360 public void setKualiModuleService(KualiModuleService kualiModuleService) {
361 this.kualiModuleService = kualiModuleService;
362 }
363
364 protected DataDictionaryService getDataDictionaryService() {
365 if (dataDictionaryService == null) {
366 this.dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
367 }
368 return dataDictionaryService;
369 }
370
371 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
372 this.dataDictionaryService = dataDictionaryService;
373 }
374
375 protected DataObjectAuthorizationService getDataObjectAuthorizationService() {
376 if (dataObjectAuthorizationService == null) {
377 this.dataObjectAuthorizationService = KRADServiceLocatorWeb.getDataObjectAuthorizationService();
378 }
379 return dataObjectAuthorizationService;
380 }
381
382 public void setDataObjectAuthorizationService(DataObjectAuthorizationService dataObjectAuthorizationService) {
383 this.dataObjectAuthorizationService = dataObjectAuthorizationService;
384 }
385
386 protected EncryptionService getEncryptionService() {
387 if (encryptionService == null) {
388 this.encryptionService = CoreApiServiceLocator.getEncryptionService();
389 }
390 return encryptionService;
391 }
392
393 public void setEncryptionService(EncryptionService encryptionService) {
394 this.encryptionService = encryptionService;
395 }
396
397 protected BusinessObjectService getBusinessObjectService() {
398 if (businessObjectService == null) {
399 this.businessObjectService = KRADServiceLocator.getBusinessObjectService();
400 }
401 return businessObjectService;
402 }
403
404 public void setBusinessObjectService(BusinessObjectService businessObjectService) {
405 this.businessObjectService = businessObjectService;
406 }
407 }