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 if(CoreApiServiceLocator.getEncryptionService().isEnabled()) {
137 keyPropertyValue = getEncryptionService().decrypt(keyPropertyValue);
138 }
139 } catch (GeneralSecurityException e) {
140 LOG.error("Data object class "
141 + dataObjectClass
142 + " property "
143 + keyPropertyName
144 + " should have been encrypted, but there was a problem decrypting it.", e);
145 throw new RuntimeException("Data object class "
146 + dataObjectClass
147 + " property "
148 + keyPropertyName
149 + " should have been encrypted, but there was a problem decrypting it.", e);
150 }
151 }
152
153 keyPropertyValues.put(keyPropertyName, keyPropertyValue);
154 }
155
156
157 Object dataObject = null;
158
159 ModuleService moduleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(
160 getDataObjectClass());
161 if (moduleService != null && moduleService.isExternalizable(getDataObjectClass())) {
162 dataObject = moduleService.getExternalizableBusinessObject(getDataObjectClass().asSubclass(
163 ExternalizableBusinessObject.class), keyPropertyValues);
164 } else if (BusinessObject.class.isAssignableFrom(getDataObjectClass())) {
165 dataObject = getBusinessObjectService().findByPrimaryKey(getDataObjectClass().asSubclass(
166 BusinessObject.class), keyPropertyValues);
167 }
168
169 return dataObject;
170 }
171
172
173
174
175
176
177
178
179
180 protected List<String> retrieveKeySetFromMap(List<List<String>> potentialKeySets, Map<String, String> parameters) {
181 List<String> foundKeySet = null;
182
183 for (List<String> potentialKeySet : potentialKeySets) {
184 boolean keySetMatch = true;
185 for (String keyName : potentialKeySet) {
186 if (!parameters.containsKey(keyName) || StringUtils.isBlank(parameters.get(keyName))) {
187 keySetMatch = false;
188 }
189 }
190
191 if (keySetMatch) {
192 foundKeySet = potentialKeySet;
193 break;
194 }
195 }
196
197 return foundKeySet;
198 }
199
200
201
202
203
204
205
206
207 protected List<List<String>> getAlternateKeysForClass(Class<?> clazz) {
208 KualiModuleService kualiModuleService = getKualiModuleService();
209 ModuleService moduleService = kualiModuleService.getResponsibleModuleService(clazz);
210
211 List<List<String>> altKeys = null;
212 if (moduleService != null) {
213 altKeys = moduleService.listAlternatePrimaryKeyFieldNames(clazz);
214 }
215
216 return altKeys != null ? altKeys : new ArrayList<List<String>>();
217 }
218
219
220
221
222
223 @Override
224 public void buildInquirableLink(Object dataObject, String propertyName, Inquiry inquiry) {
225 Class<?> inquiryObjectClass = null;
226
227
228 Class<?> objectClass = ObjectUtils.materializeClassForProxiedObject(dataObject);
229 if (propertyName.equals(getDataObjectMetaDataService().getTitleAttribute(objectClass))) {
230 inquiryObjectClass = objectClass;
231 } else if (ObjectUtils.isNestedAttribute(propertyName)) {
232 String nestedPropertyName = ObjectUtils.getNestedAttributePrefix(propertyName);
233 Object nestedPropertyObject = ObjectUtils.getNestedValue(dataObject, nestedPropertyName);
234
235 if (ObjectUtils.isNotNull(nestedPropertyObject)) {
236 String nestedPropertyPrimitive = ObjectUtils.getNestedAttributePrimitive(propertyName);
237 Class<?> nestedPropertyObjectClass = ObjectUtils.materializeClassForProxiedObject(nestedPropertyObject);
238
239 if (nestedPropertyPrimitive.equals(getDataObjectMetaDataService().getTitleAttribute(
240 nestedPropertyObjectClass))) {
241 inquiryObjectClass = nestedPropertyObjectClass;
242 }
243 }
244 }
245
246
247 DataObjectRelationship relationship = null;
248 if (inquiryObjectClass == null) {
249 relationship = getDataObjectMetaDataService().getDataObjectRelationship(dataObject, objectClass,
250 propertyName, "", true, false, true);
251 if (relationship != null) {
252 inquiryObjectClass = relationship.getRelatedClass();
253 }
254 }
255
256
257 if (inquiryObjectClass == null) {
258 inquiry.setRender(false);
259
260 return;
261 }
262
263 if (DocumentHeader.class.isAssignableFrom(inquiryObjectClass)) {
264 String documentNumber = (String) ObjectUtils.getPropertyValue(dataObject, propertyName);
265 if (StringUtils.isNotBlank(documentNumber)) {
266 inquiry.getInquiryLink().setHref(getConfigurationService().getPropertyValueAsString(
267 KRADConstants.WORKFLOW_URL_KEY)
268 + KRADConstants.DOCHANDLER_DO_URL
269 + documentNumber
270 + KRADConstants.DOCHANDLER_URL_CHUNK);
271 inquiry.getInquiryLink().setLinkText(documentNumber);
272 inquiry.setRender(true);
273 }
274
275 return;
276 }
277
278 synchronized (SUPER_CLASS_TRANSLATOR_LIST) {
279 for (Class<?> clazz : SUPER_CLASS_TRANSLATOR_LIST) {
280 if (clazz.isAssignableFrom(inquiryObjectClass)) {
281 inquiryObjectClass = clazz;
282 break;
283 }
284 }
285 }
286
287 if (!inquiryObjectClass.isInterface() && ExternalizableBusinessObject.class.isAssignableFrom(
288 inquiryObjectClass)) {
289 inquiryObjectClass = ExternalizableBusinessObjectUtils.determineExternalizableBusinessObjectSubInterface(
290 inquiryObjectClass);
291 }
292
293
294 List<String> keys = new ArrayList<String>(getDataObjectMetaDataService().listPrimaryKeyFieldNames(
295 inquiryObjectClass));
296
297 if (keys == null) {
298 keys = Collections.emptyList();
299 }
300
301
302 Map<String, String> inquiryParameters = new HashMap<String, String>();
303 for (String keyName : keys) {
304 String keyConversion = keyName;
305 if (relationship != null) {
306 keyConversion = relationship.getParentAttributeForChildAttribute(keyName);
307 } else if (ObjectUtils.isNestedAttribute(propertyName)) {
308 String nestedAttributePrefix = ObjectUtils.getNestedAttributePrefix(propertyName);
309 keyConversion = nestedAttributePrefix + "." + keyName;
310 }
311
312 inquiryParameters.put(keyConversion, keyName);
313 }
314
315 inquiry.buildInquiryLink(dataObject, propertyName, inquiryObjectClass, inquiryParameters);
316 }
317
318
319
320
321 @Override
322 public void setDataObjectClass(Class<?> dataObjectClass) {
323 this.dataObjectClass = dataObjectClass;
324 }
325
326
327
328
329
330
331 protected Class<?> getDataObjectClass() {
332 return this.dataObjectClass;
333 }
334
335 protected DataObjectMetaDataService getDataObjectMetaDataService() {
336 return KRADServiceLocatorWeb.getDataObjectMetaDataService();
337 }
338
339 protected KualiModuleService getKualiModuleService() {
340 return KRADServiceLocatorWeb.getKualiModuleService();
341 }
342
343 protected DataDictionaryService getDataDictionaryService() {
344 return KRADServiceLocatorWeb.getDataDictionaryService();
345 }
346
347 protected DataObjectAuthorizationService getDataObjectAuthorizationService() {
348 return KRADServiceLocatorWeb.getDataObjectAuthorizationService();
349 }
350
351 protected EncryptionService getEncryptionService() {
352 return CoreApiServiceLocator.getEncryptionService();
353 }
354
355 protected BusinessObjectService getBusinessObjectService() {
356 return KRADServiceLocator.getBusinessObjectService();
357 }
358
359 }