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