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.DocumentHeader;
23 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
24 import org.kuali.rice.krad.data.CompoundKey;
25 import org.kuali.rice.krad.data.DataObjectUtils;
26 import org.kuali.rice.krad.data.KradDataServiceLocator;
27 import org.kuali.rice.krad.datadictionary.exception.UnknownBusinessClassAttributeException;
28 import org.kuali.rice.krad.service.DataDictionaryService;
29 import org.kuali.rice.krad.service.DataObjectAuthorizationService;
30 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
31 import org.kuali.rice.krad.service.KualiModuleService;
32 import org.kuali.rice.krad.service.LegacyDataAdapter;
33 import org.kuali.rice.krad.service.ModuleService;
34 import org.kuali.rice.krad.uif.service.impl.ViewHelperServiceImpl;
35 import org.kuali.rice.krad.uif.widget.Inquiry;
36 import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
37 import org.kuali.rice.krad.util.KRADConstants;
38 import org.kuali.rice.krad.util.KRADUtils;
39
40 import java.security.GeneralSecurityException;
41 import java.util.ArrayList;
42 import java.util.Collections;
43 import java.util.HashMap;
44 import java.util.List;
45 import java.util.Map;
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public class InquirableImpl extends ViewHelperServiceImpl implements Inquirable {
60 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(InquirableImpl.class);
61
62 protected Class<?> dataObjectClass;
63
64
65
66
67
68
69
70 public static List<Class<?>> SUPER_CLASS_TRANSLATOR_LIST = new ArrayList<Class<?>>();
71
72
73
74
75
76
77
78
79
80
81
82
83
84 @Override
85 public Object retrieveDataObject(Map<String, String> parameters) {
86 if (dataObjectClass == null) {
87 LOG.error("Data object class must be set in inquirable before retrieving the object");
88 throw new RuntimeException("Data object class must be set in inquirable before retrieving the object");
89 }
90
91
92 List<String> pkPropertyNames = getLegacyDataAdapter().listPrimaryKeyFieldNames(dataObjectClass);
93
94
95 List<List<String>> alternateKeyNameSets = getAlternateKeysForClass(dataObjectClass);
96
97
98 alternateKeyNameSets.add(0, pkPropertyNames);
99
100 List<String> dataObjectKeySet = retrieveKeySetFromMap(alternateKeyNameSets, parameters);
101 if ((dataObjectKeySet == null) || dataObjectKeySet.isEmpty()) {
102 LOG.warn("Matching key set not found in request for class: " + getDataObjectClass());
103
104 return null;
105 }
106
107
108 Map<String, Object> keyPropertyValues = new HashMap<String, Object>();
109 for (String keyPropertyName : dataObjectKeySet) {
110 String keyPropertyValue = parameters.get(keyPropertyName);
111
112
113 Boolean forceUppercase = Boolean.FALSE;
114 try {
115 forceUppercase = getDataDictionaryService().getAttributeForceUppercase(dataObjectClass,
116 keyPropertyName);
117 } catch (UnknownBusinessClassAttributeException ex) {
118
119
120 LOG.warn("Data object class "
121 + dataObjectClass
122 + " property "
123 + keyPropertyName
124 + " should probably have a DD definition.", ex);
125 }
126
127 if (forceUppercase.booleanValue() && (keyPropertyValue != null)) {
128 keyPropertyValue = keyPropertyValue.toUpperCase();
129 }
130
131
132 if (getDataObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(dataObjectClass,
133 keyPropertyName)) {
134 try {
135 if(CoreApiServiceLocator.getEncryptionService().isEnabled()) {
136 keyPropertyValue = getEncryptionService().decrypt(keyPropertyValue);
137 }
138 } catch (GeneralSecurityException e) {
139 LOG.error("Data object class "
140 + dataObjectClass
141 + " property "
142 + keyPropertyName
143 + " should have been encrypted, but there was a problem decrypting it.", e);
144 throw new RuntimeException("Data object class "
145 + dataObjectClass
146 + " property "
147 + keyPropertyName
148 + " should have been encrypted, but there was a problem decrypting it.", e);
149 }
150 }
151
152 keyPropertyValues.put(keyPropertyName, keyPropertyValue);
153 }
154
155
156 Object dataObject = null;
157
158 ModuleService moduleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(
159 getDataObjectClass());
160 if (moduleService != null && moduleService.isExternalizable(getDataObjectClass())) {
161 dataObject = moduleService.getExternalizableBusinessObject(getDataObjectClass().asSubclass(
162 ExternalizableBusinessObject.class), keyPropertyValues);
163 } else if ( KradDataServiceLocator.getDataObjectService().supports(getDataObjectClass())) {
164 dataObject = KradDataServiceLocator.getDataObjectService().find(getDataObjectClass(), new CompoundKey(keyPropertyValues));
165 } else if (BusinessObject.class.isAssignableFrom(getDataObjectClass())) {
166 dataObject = getLegacyDataAdapter().findByPrimaryKey(getDataObjectClass().asSubclass(
167 BusinessObject.class), keyPropertyValues);
168 } else {
169 throw new IllegalArgumentException( "ERROR: Unsupported object type passed to inquiry: " + getDataObjectClass() + " / keys=" + keyPropertyValues );
170 }
171 return dataObject;
172 }
173
174
175
176
177
178
179
180
181
182
183 protected List<String> retrieveKeySetFromMap(List<List<String>> potentialKeySets, Map<String, String> parameters) {
184 List<String> foundKeySet = null;
185
186 for (List<String> potentialKeySet : potentialKeySets) {
187 boolean keySetMatch = true;
188 for (String keyName : potentialKeySet) {
189 if (!parameters.containsKey(keyName) || StringUtils.isBlank(parameters.get(keyName))) {
190 keySetMatch = false;
191 }
192 }
193
194 if (keySetMatch) {
195 foundKeySet = potentialKeySet;
196 break;
197 }
198 }
199
200 return foundKeySet;
201 }
202
203
204
205
206
207
208
209
210 protected List<List<String>> getAlternateKeysForClass(Class<?> clazz) {
211 KualiModuleService kualiModuleService = getKualiModuleService();
212 ModuleService moduleService = kualiModuleService.getResponsibleModuleService(clazz);
213
214 List<List<String>> altKeys = null;
215 if (moduleService != null) {
216 altKeys = moduleService.listAlternatePrimaryKeyFieldNames(clazz);
217 }
218
219 return altKeys != null ? altKeys : new ArrayList<List<String>>();
220 }
221
222
223
224
225
226 @Override
227 public void buildInquirableLink(Object dataObject, String propertyName, Inquiry inquiry) {
228 Class<?> inquiryObjectClass = null;
229
230
231 Class<?> objectClass = KRADUtils.materializeClassForProxiedObject(dataObject);
232 if (propertyName.equals(KRADServiceLocatorWeb.getLegacyDataAdapter().getTitleAttribute(objectClass))) {
233 inquiryObjectClass = objectClass;
234 } else if (DataObjectUtils.isNestedAttribute(propertyName)) {
235 String nestedPropertyName = DataObjectUtils.getNestedAttributePrefix(propertyName);
236 Object nestedPropertyObject = KRADUtils.getNestedValue(dataObject, nestedPropertyName);
237
238 if (KRADUtils.isNotNull(nestedPropertyObject)) {
239 String nestedPropertyPrimitive = DataObjectUtils.getNestedAttributePrimitive(propertyName);
240 Class<?> nestedPropertyObjectClass = KRADUtils.materializeClassForProxiedObject(nestedPropertyObject);
241
242 if (nestedPropertyPrimitive.equals(KRADServiceLocatorWeb.getLegacyDataAdapter().getTitleAttribute(
243 nestedPropertyObjectClass))) {
244 inquiryObjectClass = nestedPropertyObjectClass;
245 }
246 }
247 }
248
249
250 if (inquiryObjectClass == null) {
251 inquiryObjectClass = getLegacyDataAdapter().getInquiryObjectClassIfNotTitle(dataObject,propertyName);
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) DataObjectUtils.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>(getLegacyDataAdapter().listPrimaryKeyFieldNames(
293 inquiryObjectClass));
294
295 if (keys == null) {
296 keys = Collections.emptyList();
297 }
298
299
300 Map<String, String> inquiryParameters = getLegacyDataAdapter().getInquiryParameters(dataObject,keys,propertyName);
301
302 inquiry.buildInquiryLink(dataObject, propertyName, inquiryObjectClass, inquiryParameters);
303 }
304
305
306
307
308 @Override
309 public void setDataObjectClass(Class<?> dataObjectClass) {
310 this.dataObjectClass = dataObjectClass;
311 }
312
313
314
315
316
317
318 protected Class<?> getDataObjectClass() {
319 return this.dataObjectClass;
320 }
321
322 protected LegacyDataAdapter getLegacyDataAdapter() {
323 return KRADServiceLocatorWeb.getLegacyDataAdapter();
324 }
325
326 protected KualiModuleService getKualiModuleService() {
327 return KRADServiceLocatorWeb.getKualiModuleService();
328 }
329
330 @Override
331 public DataDictionaryService getDataDictionaryService() {
332 return KRADServiceLocatorWeb.getDataDictionaryService();
333 }
334
335 protected DataObjectAuthorizationService getDataObjectAuthorizationService() {
336 return KRADServiceLocatorWeb.getDataObjectAuthorizationService();
337 }
338
339 protected EncryptionService getEncryptionService() {
340 return CoreApiServiceLocator.getEncryptionService();
341 }
342
343 }