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.encryption.EncryptionService;
21 import org.kuali.rice.krad.bo.BusinessObject;
22 import org.kuali.rice.krad.bo.DataObjectRelationship;
23 import org.kuali.rice.krad.bo.DocumentHeader;
24 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
25 import org.kuali.rice.krad.datadictionary.exception.UnknownBusinessClassAttributeException;
26 import org.kuali.rice.krad.service.DataDictionaryService;
27 import org.kuali.rice.krad.service.DataObjectAuthorizationService;
28 import org.kuali.rice.krad.service.DataObjectMetaDataService;
29 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
30 import org.kuali.rice.krad.service.KualiModuleService;
31 import org.kuali.rice.krad.service.ModuleService;
32 import org.kuali.rice.krad.uif.service.impl.ViewHelperServiceImpl;
33 import org.kuali.rice.krad.uif.widget.Inquiry;
34 import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
35 import org.kuali.rice.krad.util.KRADConstants;
36 import org.kuali.rice.krad.util.ObjectUtils;
37
38 import java.security.GeneralSecurityException;
39 import java.util.ArrayList;
40 import java.util.Collections;
41 import java.util.HashMap;
42 import java.util.List;
43 import java.util.Map;
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class InquirableImpl extends ViewHelperServiceImpl implements Inquirable {
58 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(InquirableImpl.class);
59
60 protected Class<?> dataObjectClass;
61
62
63
64
65
66
67
68 public static List<Class<?>> SUPER_CLASS_TRANSLATOR_LIST = new ArrayList<Class<?>>();
69
70
71
72
73
74
75
76
77
78
79
80
81
82 @Override
83 public Object retrieveDataObject(Map<String, String> parameters) {
84 if (dataObjectClass == null) {
85 LOG.error("Data object class must be set in inquirable before retrieving the object");
86 throw new RuntimeException("Data object class must be set in inquirable before retrieving the object");
87 }
88
89
90 List<String> pkPropertyNames = getDataObjectMetaDataService().listPrimaryKeyFieldNames(dataObjectClass);
91
92
93 List<List<String>> alternateKeyNames = this.getAlternateKeysForClass(dataObjectClass);
94
95
96 alternateKeyNames.add(0, pkPropertyNames);
97
98 List<String> dataObjectKeySet = retrieveKeySetFromMap(alternateKeyNames, parameters);
99 if ((dataObjectKeySet == null) || dataObjectKeySet.isEmpty()) {
100 LOG.warn("Matching key set not found in request for class: " + getDataObjectClass());
101
102 return null;
103 }
104
105
106 Map<String, Object> keyPropertyValues = new HashMap<String, Object>();
107 for (String keyPropertyName : dataObjectKeySet) {
108 String keyPropertyValue = parameters.get(keyPropertyName);
109
110
111 Boolean forceUppercase = Boolean.FALSE;
112 try {
113 forceUppercase = getDataDictionaryService().getAttributeForceUppercase(dataObjectClass,
114 keyPropertyName);
115 } catch (UnknownBusinessClassAttributeException ex) {
116
117
118 LOG.warn("Data object class "
119 + dataObjectClass
120 + " property "
121 + keyPropertyName
122 + " should probably have a DD definition.", ex);
123 }
124
125 if (forceUppercase.booleanValue() && (keyPropertyValue != null)) {
126 keyPropertyValue = keyPropertyValue.toUpperCase();
127 }
128
129
130 if (getDataObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(dataObjectClass,
131 keyPropertyName)) {
132 try {
133 if(CoreApiServiceLocator.getEncryptionService().isEnabled()) {
134 keyPropertyValue = getEncryptionService().decrypt(keyPropertyValue);
135 }
136 } catch (GeneralSecurityException e) {
137 LOG.error("Data object class "
138 + dataObjectClass
139 + " property "
140 + keyPropertyName
141 + " should have been encrypted, but there was a problem decrypting it.", e);
142 throw new RuntimeException("Data object class "
143 + dataObjectClass
144 + " property "
145 + 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 = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(
157 getDataObjectClass());
158 if (moduleService != null && moduleService.isExternalizable(getDataObjectClass())) {
159 dataObject = moduleService.getExternalizableBusinessObject(getDataObjectClass().asSubclass(
160 ExternalizableBusinessObject.class), keyPropertyValues);
161 } else if (BusinessObject.class.isAssignableFrom(getDataObjectClass())) {
162 dataObject = getBusinessObjectService().findByPrimaryKey(getDataObjectClass().asSubclass(
163 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.equals(getDataObjectMetaDataService().getTitleAttribute(
237 nestedPropertyObjectClass))) {
238 inquiryObjectClass = nestedPropertyObjectClass;
239 }
240 }
241 }
242
243
244 DataObjectRelationship relationship = null;
245 if (inquiryObjectClass == null) {
246 relationship = getDataObjectMetaDataService().getDataObjectRelationship(dataObject, objectClass,
247 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.getInquiryLink().setHref(getConfigurationService().getPropertyValueAsString(
264 KRADConstants.WORKFLOW_URL_KEY)
265 + KRADConstants.DOCHANDLER_DO_URL
266 + documentNumber
267 + KRADConstants.DOCHANDLER_URL_CHUNK);
268 inquiry.getInquiryLink().setLinkText(documentNumber);
269 inquiry.setRender(true);
270 }
271
272 return;
273 }
274
275 synchronized (SUPER_CLASS_TRANSLATOR_LIST) {
276 for (Class<?> clazz : SUPER_CLASS_TRANSLATOR_LIST) {
277 if (clazz.isAssignableFrom(inquiryObjectClass)) {
278 inquiryObjectClass = clazz;
279 break;
280 }
281 }
282 }
283
284 if (!inquiryObjectClass.isInterface() && ExternalizableBusinessObject.class.isAssignableFrom(
285 inquiryObjectClass)) {
286 inquiryObjectClass = ExternalizableBusinessObjectUtils.determineExternalizableBusinessObjectSubInterface(
287 inquiryObjectClass);
288 }
289
290
291 List<String> keys = new ArrayList<String>(getDataObjectMetaDataService().listPrimaryKeyFieldNames(
292 inquiryObjectClass));
293
294 if (keys == null) {
295 keys = Collections.emptyList();
296 }
297
298
299 Map<String, String> inquiryParameters = new HashMap<String, String>();
300 for (String keyName : keys) {
301 String keyConversion = keyName;
302 if (relationship != null) {
303 keyConversion = relationship.getParentAttributeForChildAttribute(keyName);
304 } else if (ObjectUtils.isNestedAttribute(propertyName)) {
305 String nestedAttributePrefix = ObjectUtils.getNestedAttributePrefix(propertyName);
306 keyConversion = nestedAttributePrefix + "." + keyName;
307 }
308
309 inquiryParameters.put(keyConversion, keyName);
310 }
311
312 inquiry.buildInquiryLink(dataObject, propertyName, inquiryObjectClass, inquiryParameters);
313 }
314
315
316
317
318 @Override
319 public void setDataObjectClass(Class<?> dataObjectClass) {
320 this.dataObjectClass = dataObjectClass;
321 }
322
323
324
325
326
327
328 protected Class<?> getDataObjectClass() {
329 return this.dataObjectClass;
330 }
331
332 protected DataObjectMetaDataService getDataObjectMetaDataService() {
333 return KRADServiceLocatorWeb.getDataObjectMetaDataService();
334 }
335
336 protected KualiModuleService getKualiModuleService() {
337 return KRADServiceLocatorWeb.getKualiModuleService();
338 }
339
340 protected DataDictionaryService getDataDictionaryService() {
341 return KRADServiceLocatorWeb.getDataDictionaryService();
342 }
343
344 protected DataObjectAuthorizationService getDataObjectAuthorizationService() {
345 return KRADServiceLocatorWeb.getDataObjectAuthorizationService();
346 }
347
348 protected EncryptionService getEncryptionService() {
349 return CoreApiServiceLocator.getEncryptionService();
350 }
351
352 }