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.DataObjectRelationship;
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 public static List<Class<?>> SUPER_CLASS_TRANSLATOR_LIST = new ArrayList<Class<?>>();
72
73
74
75
76
77
78
79
80
81
82
83
84
85 @Override
86 public Object retrieveDataObject(Map<String, String> parameters) {
87 if (dataObjectClass == null) {
88 LOG.error("Data object class must be set in inquirable before retrieving the object");
89 throw new RuntimeException("Data object class must be set in inquirable before retrieving the object");
90 }
91
92
93 List<String> pkPropertyNames = getDataObjectMetaDataService().listPrimaryKeyFieldNames(dataObjectClass);
94
95
96 List<List<String>> alternateKeyNames = this.getAlternateKeysForClass(dataObjectClass);
97
98
99 alternateKeyNames.add(0, pkPropertyNames);
100
101 List<String> dataObjectKeySet = retrieveKeySetFromMap(alternateKeyNames, parameters);
102 if ((dataObjectKeySet == null) || dataObjectKeySet.isEmpty()) {
103 LOG.warn("Matching key set not found in request for class: " + getDataObjectClass());
104
105 return null;
106 }
107
108
109 Map<String, Object> keyPropertyValues = new HashMap<String, Object>();
110 for (String keyPropertyName : dataObjectKeySet) {
111 String keyPropertyValue = parameters.get(keyPropertyName);
112
113
114 Boolean forceUppercase = Boolean.FALSE;
115 try {
116 forceUppercase = getDataDictionaryService().getAttributeForceUppercase(dataObjectClass,
117 keyPropertyName);
118 } catch (UnknownBusinessClassAttributeException ex) {
119
120
121 LOG.warn("Data object class "
122 + dataObjectClass
123 + " property "
124 + keyPropertyName
125 + " should probably have a DD definition.", ex);
126 }
127
128 if (forceUppercase.booleanValue() && (keyPropertyValue != null)) {
129 keyPropertyValue = keyPropertyValue.toUpperCase();
130 }
131
132
133 if (getDataObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(dataObjectClass,
134 keyPropertyName)) {
135 try {
136 keyPropertyValue = getEncryptionService().decrypt(keyPropertyValue);
137 } catch (GeneralSecurityException e) {
138 LOG.error("Data object class "
139 + dataObjectClass
140 + " property "
141 + keyPropertyName
142 + " should have been encrypted, but there was a problem decrypting it.", e);
143 throw new RuntimeException("Data object class "
144 + dataObjectClass
145 + " property "
146 + keyPropertyName
147 + " should have been encrypted, but there was a problem decrypting it.", e);
148 }
149 }
150
151 keyPropertyValues.put(keyPropertyName, keyPropertyValue);
152 }
153
154
155 Object dataObject = null;
156
157 ModuleService moduleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(
158 getDataObjectClass());
159 if (moduleService != null && moduleService.isExternalizable(getDataObjectClass())) {
160 dataObject = moduleService.getExternalizableBusinessObject(getDataObjectClass().asSubclass(
161 ExternalizableBusinessObject.class), keyPropertyValues);
162 } else if (BusinessObject.class.isAssignableFrom(getDataObjectClass())) {
163 dataObject = getBusinessObjectService().findByPrimaryKey(getDataObjectClass().asSubclass(
164 BusinessObject.class), keyPropertyValues);
165 }
166
167 return dataObject;
168 }
169
170
171
172
173
174
175
176
177
178 protected List<String> retrieveKeySetFromMap(List<List<String>> potentialKeySets, Map<String, String> parameters) {
179 List<String> foundKeySet = null;
180
181 for (List<String> potentialKeySet : potentialKeySets) {
182 boolean keySetMatch = true;
183 for (String keyName : potentialKeySet) {
184 if (!parameters.containsKey(keyName) || StringUtils.isBlank(parameters.get(keyName))) {
185 keySetMatch = false;
186 }
187 }
188
189 if (keySetMatch) {
190 foundKeySet = potentialKeySet;
191 break;
192 }
193 }
194
195 return foundKeySet;
196 }
197
198
199
200
201
202
203
204
205 protected List<List<String>> getAlternateKeysForClass(Class<?> clazz) {
206 KualiModuleService kualiModuleService = getKualiModuleService();
207 ModuleService moduleService = kualiModuleService.getResponsibleModuleService(clazz);
208
209 List<List<String>> altKeys = null;
210 if (moduleService != null) {
211 altKeys = moduleService.listAlternatePrimaryKeyFieldNames(clazz);
212 }
213
214 return altKeys != null ? altKeys : new ArrayList<List<String>>();
215 }
216
217
218
219
220
221 @Override
222 public void buildInquirableLink(Object dataObject, String propertyName, Inquiry inquiry) {
223 Class<?> inquiryObjectClass = null;
224
225
226 Class<?> objectClass = ObjectUtils.materializeClassForProxiedObject(dataObject);
227 if (propertyName.equals(getDataObjectMetaDataService().getTitleAttribute(objectClass))) {
228 inquiryObjectClass = objectClass;
229 } else if (ObjectUtils.isNestedAttribute(propertyName)) {
230 String nestedPropertyName = ObjectUtils.getNestedAttributePrefix(propertyName);
231 Object nestedPropertyObject = ObjectUtils.getNestedValue(dataObject, nestedPropertyName);
232
233 if (ObjectUtils.isNotNull(nestedPropertyObject)) {
234 String nestedPropertyPrimitive = ObjectUtils.getNestedAttributePrimitive(propertyName);
235 Class<?> nestedPropertyObjectClass = ObjectUtils.materializeClassForProxiedObject(nestedPropertyObject);
236
237 if (nestedPropertyPrimitive.equals(getDataObjectMetaDataService().getTitleAttribute(
238 nestedPropertyObjectClass))) {
239 inquiryObjectClass = nestedPropertyObjectClass;
240 }
241 }
242 }
243
244
245 DataObjectRelationship relationship = null;
246 if (inquiryObjectClass == null) {
247 relationship = getDataObjectMetaDataService().getDataObjectRelationship(dataObject, objectClass,
248 propertyName, "", true, false, true);
249 if (relationship != null) {
250 inquiryObjectClass = relationship.getRelatedClass();
251 }
252 }
253
254
255 if (inquiryObjectClass == null) {
256 inquiry.setRender(false);
257
258 return;
259 }
260
261 if (DocumentHeader.class.isAssignableFrom(inquiryObjectClass)) {
262 String documentNumber = (String) ObjectUtils.getPropertyValue(dataObject, propertyName);
263 if (StringUtils.isNotBlank(documentNumber)) {
264 inquiry.getInquiryLink().setHref(getConfigurationService().getPropertyValueAsString(
265 KRADConstants.WORKFLOW_URL_KEY)
266 + KRADConstants.DOCHANDLER_DO_URL
267 + documentNumber
268 + KRADConstants.DOCHANDLER_URL_CHUNK);
269 inquiry.getInquiryLink().setLinkText(documentNumber);
270 inquiry.setRender(true);
271 }
272
273 return;
274 }
275
276 synchronized (SUPER_CLASS_TRANSLATOR_LIST) {
277 for (Class<?> clazz : SUPER_CLASS_TRANSLATOR_LIST) {
278 if (clazz.isAssignableFrom(inquiryObjectClass)) {
279 inquiryObjectClass = clazz;
280 break;
281 }
282 }
283 }
284
285 if (!inquiryObjectClass.isInterface() && ExternalizableBusinessObject.class.isAssignableFrom(
286 inquiryObjectClass)) {
287 inquiryObjectClass = ExternalizableBusinessObjectUtils.determineExternalizableBusinessObjectSubInterface(
288 inquiryObjectClass);
289 }
290
291
292 List<String> keys = new ArrayList<String>(getDataObjectMetaDataService().listPrimaryKeyFieldNames(
293 inquiryObjectClass));
294
295 if (keys == null) {
296 keys = Collections.emptyList();
297 }
298
299
300 Map<String, String> inquiryParameters = new HashMap<String, String>();
301 for (String keyName : keys) {
302 String keyConversion = keyName;
303 if (relationship != null) {
304 keyConversion = relationship.getParentAttributeForChildAttribute(keyName);
305 } else if (ObjectUtils.isNestedAttribute(propertyName)) {
306 String nestedAttributePrefix = ObjectUtils.getNestedAttributePrefix(propertyName);
307 keyConversion = nestedAttributePrefix + "." + keyName;
308 }
309
310 inquiryParameters.put(keyConversion, keyName);
311 }
312
313 inquiry.buildInquiryLink(dataObject, propertyName, inquiryObjectClass, inquiryParameters);
314 }
315
316
317
318
319 @Override
320 public void setDataObjectClass(Class<?> dataObjectClass) {
321 this.dataObjectClass = dataObjectClass;
322 }
323
324
325
326
327
328
329 protected Class<?> getDataObjectClass() {
330 return this.dataObjectClass;
331 }
332
333 protected DataObjectMetaDataService getDataObjectMetaDataService() {
334 return KRADServiceLocatorWeb.getDataObjectMetaDataService();
335 }
336
337 protected KualiModuleService getKualiModuleService() {
338 return KRADServiceLocatorWeb.getKualiModuleService();
339 }
340
341 protected DataDictionaryService getDataDictionaryService() {
342 return KRADServiceLocatorWeb.getDataDictionaryService();
343 }
344
345 protected DataObjectAuthorizationService getDataObjectAuthorizationService() {
346 return KRADServiceLocatorWeb.getDataObjectAuthorizationService();
347 }
348
349 protected EncryptionService getEncryptionService() {
350 return CoreApiServiceLocator.getEncryptionService();
351 }
352
353 protected BusinessObjectService getBusinessObjectService() {
354 return KRADServiceLocator.getBusinessObjectService();
355 }
356
357 }