1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.lookup;
17
18 import org.apache.commons.beanutils.PropertyUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.kuali.rice.core.api.CoreApiServiceLocator;
21 import org.kuali.rice.core.api.encryption.EncryptionService;
22 import org.kuali.rice.core.api.search.SearchOperator;
23 import org.kuali.rice.krad.bo.BusinessObject;
24 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
25 import org.kuali.rice.krad.datadictionary.BusinessObjectEntry;
26 import org.kuali.rice.krad.datadictionary.RelationshipDefinition;
27 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
28 import org.kuali.rice.krad.service.ModuleService;
29 import org.kuali.rice.krad.util.BeanPropertyComparator;
30 import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
31 import org.kuali.rice.krad.util.KRADConstants;
32 import org.kuali.rice.krad.util.ObjectUtils;
33 import org.springframework.transaction.annotation.Transactional;
34
35 import java.security.GeneralSecurityException;
36 import java.util.ArrayList;
37 import java.util.Collections;
38 import java.util.HashMap;
39 import java.util.HashSet;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Set;
44
45
46
47
48 @Deprecated
49 @Transactional
50 public class KualiLookupableHelperServiceImpl extends AbstractLookupableHelperServiceImpl {
51
52 protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiLookupableHelperServiceImpl.class);
53 protected boolean searchUsingOnlyPrimaryKeyValues = false;
54
55
56
57
58
59
60
61
62
63
64 public List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues) {
65 return getSearchResultsHelper(
66 org.kuali.rice.krad.lookup.LookupUtils.forceUppercase(getBusinessObjectClass(), fieldValues), false);
67 }
68
69
70
71
72
73
74
75
76
77
78 public List<? extends BusinessObject> getSearchResultsUnbounded(Map<String, String> fieldValues) {
79 return getSearchResultsHelper(
80 org.kuali.rice.krad.lookup.LookupUtils.forceUppercase(getBusinessObjectClass(), fieldValues), true);
81 }
82
83
84
85
86
87
88
89
90 protected boolean isExternalBusinessObjectProperty(Object sampleBo, String propertyName) {
91 try {
92 if ( propertyName.indexOf( "." ) > 0 && !StringUtils.contains( propertyName, "add." ) ) {
93 Class propertyClass = PropertyUtils.getPropertyType(
94 sampleBo, StringUtils.substringBeforeLast( propertyName, "." ) );
95 if ( propertyClass != null ) {
96 return ExternalizableBusinessObjectUtils.isExternalizableBusinessObjectInterface( propertyClass );
97 } else {
98 if ( LOG.isDebugEnabled() ) {
99 LOG.debug( "unable to get class for " + StringUtils.substringBeforeLast( propertyName, "." ) + " on " + sampleBo.getClass().getName() );
100 }
101 }
102 }
103 } catch (Exception e) {
104 LOG.debug("Unable to determine type of property for " + sampleBo.getClass().getName() + "/" + propertyName, e );
105 }
106 return false;
107 }
108
109
110
111
112
113
114
115
116 protected String getExternalBusinessObjectProperty(Object sampleBo, String propertyName) {
117 if ( propertyName.indexOf( "." ) > 0 && !StringUtils.contains( propertyName, "add." ) ) {
118 return StringUtils.substringBeforeLast( propertyName, "." );
119 }
120 return null;
121 }
122
123
124
125
126 protected boolean hasExternalBusinessObjectProperty(Class boClass, Map<String,String> fieldValues ) {
127 try {
128 Object sampleBo = boClass.newInstance();
129 for ( String key : fieldValues.keySet() ) {
130 if ( isExternalBusinessObjectProperty( sampleBo, key )) {
131 return true;
132 }
133 }
134 } catch ( Exception ex ) {
135 LOG.debug("Unable to check " + boClass + " for EBO properties.", ex );
136 }
137 return false;
138 }
139
140
141
142
143
144 protected Map<String,String> removeExternalizableBusinessObjectFieldValues(Class boClass, Map<String,String> fieldValues ) {
145 Map<String,String> eboFieldValues = new HashMap<String,String>();
146 try {
147 Object sampleBo = boClass.newInstance();
148 for ( String key : fieldValues.keySet() ) {
149 if ( !isExternalBusinessObjectProperty( sampleBo, key )) {
150 eboFieldValues.put( key, fieldValues.get( key ) );
151 }
152 }
153 } catch ( Exception ex ) {
154 LOG.debug("Unable to check " + boClass + " for EBO properties.", ex );
155 }
156 return eboFieldValues;
157 }
158
159
160
161
162
163 protected Map<String,String> getExternalizableBusinessObjectFieldValues(String eboPropertyName, Map<String,String> fieldValues ) {
164 Map<String,String> eboFieldValues = new HashMap<String,String>();
165 for ( String key : fieldValues.keySet() ) {
166 if ( key.startsWith( eboPropertyName + "." ) ) {
167 eboFieldValues.put( StringUtils.substringAfterLast( key, "." ), fieldValues.get( key ) );
168 }
169 }
170 return eboFieldValues;
171 }
172
173
174
175
176
177
178 protected List<String> getExternalizableBusinessObjectProperties(Class boClass, Map<String,String> fieldValues ) {
179 Set<String> eboPropertyNames = new HashSet<String>();
180 try {
181 Object sampleBo = boClass.newInstance();
182 for ( String key : fieldValues.keySet() ) {
183 if ( isExternalBusinessObjectProperty( sampleBo, key )) {
184 eboPropertyNames.add( StringUtils.substringBeforeLast( key, "." ) );
185 }
186 }
187 } catch ( Exception ex ) {
188 LOG.debug("Unable to check " + boClass + " for EBO properties.", ex );
189 }
190 return new ArrayList<String>(eboPropertyNames);
191 }
192
193
194
195
196
197
198
199
200
201 protected Class<? extends ExternalizableBusinessObject> getExternalizableBusinessObjectClass(Class boClass, String propertyName) {
202 try {
203 return PropertyUtils.getPropertyType(
204 boClass.newInstance(), StringUtils.substringBeforeLast( propertyName, "." ) );
205 } catch (Exception e) {
206 LOG.debug("Unable to determine type of property for " + boClass.getName() + "/" + propertyName, e );
207 }
208 return null;
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223 protected List<? extends BusinessObject> getSearchResultsHelper(Map<String, String> fieldValues, boolean unbounded) {
224
225 LookupUtils.removeHiddenCriteriaFields(getBusinessObjectClass(), fieldValues);
226
227 searchUsingOnlyPrimaryKeyValues = getLookupService().allPrimaryKeyValuesPresentAndNotWildcard(getBusinessObjectClass(), fieldValues);
228
229 setBackLocation(fieldValues.get(KRADConstants.BACK_LOCATION));
230 setDocFormKey(fieldValues.get(KRADConstants.DOC_FORM_KEY));
231 setReferencesToRefresh(fieldValues.get(KRADConstants.REFERENCES_TO_REFRESH));
232 List searchResults;
233 Map<String,String> nonBlankFieldValues = new HashMap<String, String>();
234 for (String fieldName : fieldValues.keySet()) {
235 String fieldValue = fieldValues.get(fieldName);
236 if (StringUtils.isNotBlank(fieldValue) ) {
237 if (fieldValue.endsWith(EncryptionService.ENCRYPTION_POST_PREFIX)) {
238 String encryptedValue = StringUtils.removeEnd(fieldValue, EncryptionService.ENCRYPTION_POST_PREFIX);
239 try {
240 if(CoreApiServiceLocator.getEncryptionService().isEnabled()) {
241 fieldValue = getEncryptionService().decrypt(encryptedValue);
242 }
243 }
244 catch (GeneralSecurityException e) {
245 LOG.error("Error decrypting value for business object " + getBusinessObjectService() + " attribute " + fieldName, e);
246 throw new RuntimeException("Error decrypting value for business object " + getBusinessObjectService() + " attribute " + fieldName, e);
247 }
248 }
249 nonBlankFieldValues.put(fieldName, fieldValue);
250 }
251 }
252
253
254 if ( ExternalizableBusinessObjectUtils.isExternalizableBusinessObject( getBusinessObjectClass() ) ) {
255 ModuleService eboModuleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService( getBusinessObjectClass() );
256 BusinessObjectEntry ddEntry = eboModuleService.getExternalizableBusinessObjectDictionaryEntry(getBusinessObjectClass());
257 Map<String,String> filteredFieldValues = new HashMap<String, String>();
258 for (String fieldName : nonBlankFieldValues.keySet()) {
259 if (ddEntry.getAttributeNames().contains(fieldName)) {
260 filteredFieldValues.put(fieldName, nonBlankFieldValues.get(fieldName));
261 }
262 }
263 searchResults = eboModuleService.getExternalizableBusinessObjectsListForLookup(getBusinessObjectClass(), (Map)filteredFieldValues, unbounded);
264
265 } else if ( hasExternalBusinessObjectProperty( getBusinessObjectClass(), nonBlankFieldValues ) ) {
266 if ( LOG.isDebugEnabled() ) {
267 LOG.debug( "has EBO reference: " + getBusinessObjectClass() );
268 LOG.debug( "properties: " + nonBlankFieldValues );
269 }
270
271 Map<String,String> nonEboFieldValues = removeExternalizableBusinessObjectFieldValues( getBusinessObjectClass(), nonBlankFieldValues );
272 if ( LOG.isDebugEnabled() ) {
273 LOG.debug( "Non EBO properties removed: " + nonEboFieldValues );
274 }
275
276 List<String> eboPropertyNames = getExternalizableBusinessObjectProperties( getBusinessObjectClass(), nonBlankFieldValues );
277 if ( LOG.isDebugEnabled() ) {
278 LOG.debug( "EBO properties: " + eboPropertyNames );
279 }
280
281 for ( String eboPropertyName : eboPropertyNames ) {
282
283 Map<String,String> eboFieldValues = getExternalizableBusinessObjectFieldValues( eboPropertyName, nonBlankFieldValues );
284 if ( LOG.isDebugEnabled() ) {
285 LOG.debug( "EBO properties for master EBO property: " + eboPropertyName );
286 LOG.debug( "properties: " + eboFieldValues );
287 }
288
289 ModuleService eboModuleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService( getExternalizableBusinessObjectClass( getBusinessObjectClass(), eboPropertyName) );
290
291 List eboResults = Collections.emptyList();
292 if (eboModuleService != null)
293 {
294 eboResults = eboModuleService.getExternalizableBusinessObjectsListForLookup( getExternalizableBusinessObjectClass( getBusinessObjectClass(), eboPropertyName), (Map)eboFieldValues, unbounded);
295 }
296 else
297 {
298 LOG.debug( "EBO ModuleService is null: " + eboPropertyName );
299 }
300
301
302
303
304 Class eboParentClass;
305 String eboParentPropertyName;
306 if ( ObjectUtils.isNestedAttribute( eboPropertyName ) ) {
307 eboParentPropertyName = StringUtils.substringBeforeLast( eboPropertyName, "." );
308 try {
309 eboParentClass = PropertyUtils.getPropertyType( getBusinessObjectClass().newInstance(), eboParentPropertyName );
310 } catch ( Exception ex ) {
311 throw new RuntimeException( "Unable to create an instance of the business object class: " + getBusinessObjectClass().getName(), ex );
312 }
313 } else {
314 eboParentClass = getBusinessObjectClass();
315 eboParentPropertyName = null;
316 }
317 if ( LOG.isDebugEnabled() ) {
318 LOG.debug( "determined EBO parent class/property name: " + eboParentClass + "/" + eboParentPropertyName );
319 }
320
321
322
323 RelationshipDefinition rd = getBusinessObjectMetaDataService().getBusinessObjectRelationshipDefinition( eboParentClass, eboPropertyName );
324 if ( LOG.isDebugEnabled() ) {
325 LOG.debug( "Obtained RelationshipDefinition for " + eboPropertyName );
326 LOG.debug( rd );
327 }
328
329
330
331
332
333 if ( ObjectUtils.isNotNull(rd)) {
334 if ( rd.getPrimitiveAttributes().size() > 1 ) {
335 throw new RuntimeException( "EBO Links don't work for relationships with multiple-field primary keys." );
336 }
337 String boProperty = rd.getPrimitiveAttributes().get( 0 ).getSourceName();
338 String eboProperty = rd.getPrimitiveAttributes().get( 0 ).getTargetName();
339 StringBuffer boPropertyValue = new StringBuffer();
340
341
342 for ( Object ebo : eboResults ) {
343 if ( boPropertyValue.length() != 0 ) {
344 boPropertyValue.append( SearchOperator.OR.op() );
345 }
346 try {
347 boPropertyValue.append( PropertyUtils.getProperty( ebo, eboProperty ).toString() );
348 } catch ( Exception ex ) {
349 LOG.warn( "Unable to get value for " + eboProperty + " on " + ebo );
350 }
351 }
352 if ( eboParentPropertyName == null ) {
353
354 nonEboFieldValues.put( boProperty, boPropertyValue.toString() );
355 } else {
356
357 nonEboFieldValues.put( eboParentPropertyName + "." + boProperty, boPropertyValue.toString() );
358 }
359 }
360 }
361 if ( LOG.isDebugEnabled() ) {
362 LOG.debug( "Passing these results into the lookup service: " + nonEboFieldValues );
363 }
364
365
366 searchResults = (List) getLookupService().findCollectionBySearchHelper(getBusinessObjectClass(), nonEboFieldValues, unbounded);
367 } else {
368 searchResults = (List) getLookupService().findCollectionBySearchHelper(getBusinessObjectClass(), nonBlankFieldValues, unbounded);
369 }
370
371 if (searchResults == null) {
372 searchResults = new ArrayList();
373 }
374
375
376 List defaultSortColumns = getDefaultSortColumns();
377 if (defaultSortColumns.size() > 0) {
378 Collections.sort(searchResults, new BeanPropertyComparator(defaultSortColumns, true));
379 }
380 return searchResults;
381 }
382
383
384
385
386
387 @Override
388 public boolean isSearchUsingOnlyPrimaryKeyValues() {
389 return searchUsingOnlyPrimaryKeyValues;
390 }
391
392
393
394
395
396
397
398
399
400
401
402 @Override
403 public String getPrimaryKeyFieldLabels() {
404 StringBuilder buf = new StringBuilder();
405 List<String> primaryKeyFieldNames = KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(getBusinessObjectClass());
406 Iterator<String> pkIter = primaryKeyFieldNames.iterator();
407 while (pkIter.hasNext()) {
408 String pkFieldName = (String) pkIter.next();
409 buf.append(getDataDictionaryService().getAttributeLabel(getBusinessObjectClass(), pkFieldName));
410 if (pkIter.hasNext()) {
411 buf.append(", ");
412 }
413 }
414 return buf.length() == 0 ? KRADConstants.NOT_AVAILABLE_STRING : buf.toString();
415 }
416
417
418 }
419