Coverage Report - org.kuali.rice.kns.uif.service.impl.AttributeQueryServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
AttributeQueryServiceImpl
0%
0/122
0%
0/82
7.5
 
 1  
 package org.kuali.rice.kns.uif.service.impl;
 2  
 
 3  
 import org.apache.commons.lang.StringUtils;
 4  
 import org.kuali.rice.core.api.config.property.ConfigurationService;
 5  
 import org.kuali.rice.core.api.services.CoreApiServiceLocator;
 6  
 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
 7  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 8  
 import org.kuali.rice.kns.service.KNSServiceLocatorWeb;
 9  
 import org.kuali.rice.kns.service.LookupService;
 10  
 import org.kuali.rice.kns.uif.UifConstants;
 11  
 import org.kuali.rice.kns.uif.container.View;
 12  
 import org.kuali.rice.kns.uif.core.MethodInvokerConfig;
 13  
 import org.kuali.rice.kns.uif.field.AttributeField;
 14  
 import org.kuali.rice.kns.uif.field.AttributeQuery;
 15  
 import org.kuali.rice.kns.uif.field.AttributeQueryResult;
 16  
 import org.kuali.rice.kns.uif.service.AttributeQueryService;
 17  
 import org.kuali.rice.kns.uif.util.ObjectPropertyUtils;
 18  
 import org.kuali.rice.kns.uif.widget.Suggest;
 19  
 import org.kuali.rice.kns.util.BeanPropertyComparator;
 20  
 import org.springframework.scheduling.quartz.SimpleTriggerBean;
 21  
 import org.springframework.util.MethodInvoker;
 22  
 
 23  
 import java.text.MessageFormat;
 24  
 import java.util.ArrayList;
 25  
 import java.util.Collection;
 26  
 import java.util.Collections;
 27  
 import java.util.HashMap;
 28  
 import java.util.List;
 29  
 import java.util.Map;
 30  
 import java.util.Set;
 31  
 
 32  
 /**
 33  
  * Implementation of <code>AttributeQueryService</code> that prepares the attribute queries and
 34  
  * delegates to the <code>LookupService</code>
 35  
  *
 36  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 37  
  */
 38  0
 public class AttributeQueryServiceImpl implements AttributeQueryService {
 39  
 
 40  
     private LookupService lookupService;
 41  
     private ConfigurationService configurationService;
 42  
 
 43  
     /**
 44  
      * @see org.kuali.rice.kns.uif.service.AttributeQueryService#performFieldSuggestQuery(
 45  
      *org.kuali.rice.kns.uif.container.View, java.lang.String, java.lang.String, java.util.Map<java.lang.String,
 46  
      *      java.lang.String>)
 47  
      */
 48  
     @Override
 49  
     public AttributeQueryResult performFieldSuggestQuery(View view, String fieldId, String fieldTerm,
 50  
             Map<String, String> queryParameters) {
 51  0
         AttributeQueryResult queryResult = new AttributeQueryResult();
 52  
 
 53  
         // retrieve attribute field from view index
 54  0
         AttributeField attributeField = (AttributeField) view.getViewIndex().getComponentById(fieldId);
 55  0
         if (attributeField == null) {
 56  0
             throw new RuntimeException("Unable to find attribute field instance for id: " + fieldId);
 57  
         }
 58  
 
 59  0
         Suggest fieldSuggest = attributeField.getFieldSuggest();
 60  0
         AttributeQuery suggestQuery = fieldSuggest.getSuggestQuery();
 61  
 
 62  
         // add term as a like criteria
 63  0
         Map<String, String> additionalCriteria = new HashMap<String, String>();
 64  0
         additionalCriteria.put(fieldSuggest.getSourcePropertyName(), fieldTerm + "*");
 65  
 
 66  
         // execute suggest query
 67  0
         Collection<?> results = null;
 68  0
         if (suggestQuery.hasConfiguredMethod()) {
 69  0
             Object queryMethodResult = executeAttributeQueryMethod(view, suggestQuery, queryParameters);
 70  0
             if ((queryMethodResult != null) && (queryMethodResult instanceof Collection<?>)) {
 71  0
                 results = (Collection<?>) queryMethodResult;
 72  
             }
 73  0
         } else {
 74  0
             results = executeAttributeQueryCriteria(suggestQuery, queryParameters, additionalCriteria);
 75  
         }
 76  
 
 77  
         // build list of suggest data from result records
 78  0
         if (results != null) {
 79  0
             List<String> suggestData = new ArrayList<String>();
 80  0
             for (Object result : results) {
 81  0
                 Object suggestFieldValue =
 82  
                         ObjectPropertyUtils.getPropertyValue(result, fieldSuggest.getSourcePropertyName());
 83  0
                 if (suggestFieldValue != null) {
 84  
                     // TODO: need to apply formatter for field or have method in object property utils
 85  0
                     suggestData.add(suggestFieldValue.toString());
 86  
                 }
 87  0
             }
 88  
 
 89  0
             queryResult.setResultData(suggestData);
 90  
         }
 91  
 
 92  0
         return queryResult;
 93  
     }
 94  
 
 95  
     /**
 96  
      * @see org.kuali.rice.kns.uif.service.AttributeQueryService#performFieldQuery(org.kuali.rice.kns.uif.container.View,
 97  
      *      java.lang.String, java.util.Map<java.lang.String,java.lang.String>)
 98  
      */
 99  
     @Override
 100  
     public AttributeQueryResult performFieldQuery(View view, String fieldId, Map<String, String> queryParameters) {
 101  0
         AttributeQueryResult queryResult = new AttributeQueryResult();
 102  
 
 103  
         // retrieve attribute field from view index
 104  0
         AttributeField attributeField = (AttributeField) view.getViewIndex().getComponentById(fieldId);
 105  0
         if (attributeField == null) {
 106  0
             throw new RuntimeException("Unable to find attribute field instance for id: " + fieldId);
 107  
         }
 108  
 
 109  0
         AttributeQuery fieldQuery = attributeField.getFieldAttributeQuery();
 110  0
         if (fieldQuery == null) {
 111  0
             throw new RuntimeException("Field query not defined for field instance with id: " + fieldId);
 112  
         }
 113  
 
 114  
         // execute query and get result
 115  0
         Object resultObject = null;
 116  0
         if (fieldQuery.hasConfiguredMethod()) {
 117  0
             Object queryMethodResult = executeAttributeQueryMethod(view, fieldQuery, queryParameters);
 118  0
             if (queryMethodResult != null) {
 119  
                 // if method returned the result then no further processing needed
 120  0
                 if (queryMethodResult instanceof AttributeQueryResult) {
 121  0
                     return (AttributeQueryResult) queryMethodResult;
 122  
                 }
 123  
 
 124  
                 // if method returned collection, take first record
 125  0
                 if (queryMethodResult instanceof Collection<?>) {
 126  0
                     Collection<?> methodResultCollection = (Collection<?>) queryMethodResult;
 127  0
                     if (!methodResultCollection.isEmpty()) {
 128  0
                         resultObject = methodResultCollection.iterator().next();
 129  
                     }
 130  0
                 } else {
 131  0
                     resultObject = queryMethodResult;
 132  
                 }
 133  
             }
 134  0
         } else {
 135  
             // execute field query as object lookup
 136  0
             Collection<?> results = executeAttributeQueryCriteria(fieldQuery, queryParameters, null);
 137  
 
 138  0
             if ((results != null) && !results.isEmpty()) {
 139  
                 // expect only one returned row for field query
 140  0
                 if (results.size() > 1) {
 141  0
                     throw new RuntimeException("");
 142  
                 }
 143  
 
 144  0
                 resultObject = results.iterator().next();
 145  
             }
 146  
         }
 147  
 
 148  0
         if (resultObject != null) {
 149  
             // build result field data map
 150  0
             Map<String, String> resultFieldData = new HashMap<String, String>();
 151  0
             for (String returnField : fieldQuery.getReturnFieldMapping().keySet()) {
 152  0
                 String fromField = fieldQuery.getReturnFieldMapping().get(returnField);
 153  
 
 154  0
                 String fieldValueStr = "";
 155  0
                 Object fieldValue = ObjectPropertyUtils.getPropertyValue(resultObject, fromField);
 156  0
                 if (fieldValue != null) {
 157  0
                     fieldValueStr = fieldValue.toString();
 158  
                 }
 159  0
                 resultFieldData.put(returnField, fieldValueStr);
 160  0
             }
 161  0
             queryResult.setResultFieldData(resultFieldData);
 162  
 
 163  0
             fieldQuery.setReturnMessageText("");
 164  0
         } else {
 165  
             // add data not found message
 166  0
             if (fieldQuery.isRenderNotFoundMessage()) {
 167  0
                 String messageTemplate =
 168  
                         getConfigurationService().getPropertyString(UifConstants.MessageKeys.QUERY_DATA_NOT_FOUND);
 169  0
                 String message = MessageFormat.format(messageTemplate, attributeField.getLabel());
 170  0
                 fieldQuery.setReturnMessageText(message.toLowerCase());
 171  
             }
 172  
         }
 173  
 
 174  
         // set message and message style classes on query result
 175  0
         queryResult.setResultMessage(fieldQuery.getReturnMessageText());
 176  0
         queryResult.setResultMessageStyleClasses(fieldQuery.getReturnMessageStyleClasses());
 177  
 
 178  0
         return queryResult;
 179  
     }
 180  
 
 181  
     /**
 182  
      * Prepares the method configured on the attribute query then performs the method invocation
 183  
      *
 184  
      * @param view - view instance the field is contained within
 185  
      * @param attributeQuery - attribute query instance to execute
 186  
      * @param queryParameters - map of query parameters that provide values for the method arguments
 187  
      * @return Object type depends on method being invoked, could be AttributeQueryResult in which
 188  
      *         case the method has prepared the return result, or an Object that needs to be parsed for the result
 189  
      */
 190  
     protected Object executeAttributeQueryMethod(View view, AttributeQuery attributeQuery,
 191  
             Map<String, String> queryParameters) {
 192  0
         String queryMethodToCall = attributeQuery.getQueryMethodToCall();
 193  0
         MethodInvokerConfig queryMethodInvoker = attributeQuery.getQueryMethodInvokerConfig();
 194  
 
 195  0
         if (queryMethodInvoker == null) {
 196  0
             queryMethodInvoker = new MethodInvokerConfig();
 197  
         }
 198  
 
 199  
         // if method not set on invoker, use queryMethodToCall, note staticMethod could be set(don't know since
 200  
         // there is not a getter), if so it will override the target method in prepare
 201  0
         if (StringUtils.isBlank(queryMethodInvoker.getTargetMethod())) {
 202  0
             queryMethodInvoker.setTargetMethod(queryMethodToCall);
 203  
         }
 204  
 
 205  
         // if target class or object not set, use view helper service
 206  0
         if ((queryMethodInvoker.getTargetClass() == null) && (queryMethodInvoker.getTargetObject() == null)) {
 207  0
             queryMethodInvoker.setTargetObject(view.getViewHelperService());
 208  
         }
 209  
 
 210  
         // setup query method arguments
 211  0
         Object[] arguments = null;
 212  0
         if ((attributeQuery.getQueryMethodArgumentFieldList() != null) &&
 213  
                 (!attributeQuery.getQueryMethodArgumentFieldList().isEmpty())) {
 214  
             // retrieve argument types for conversion
 215  0
             Class[] argumentTypes = queryMethodInvoker.getArgumentTypes();
 216  0
             if ((argumentTypes == null) ||
 217  
                     (argumentTypes.length != attributeQuery.getQueryMethodArgumentFieldList().size())) {
 218  0
                 throw new RuntimeException(
 219  
                         "Query method argument field list size does not match found method argument list size");
 220  
             }
 221  
 
 222  0
             arguments = new Object[attributeQuery.getQueryMethodArgumentFieldList().size()];
 223  0
             for (int i = 0; i < attributeQuery.getQueryMethodArgumentFieldList().size(); i++) {
 224  0
                 String methodArgumentFromField = attributeQuery.getQueryMethodArgumentFieldList().get(i);
 225  0
                 if (queryParameters.containsKey(methodArgumentFromField)) {
 226  0
                     arguments[i] = queryParameters.get(methodArgumentFromField);
 227  
                 } else {
 228  0
                     arguments[i] = null;
 229  
                 }
 230  
             }
 231  
         }
 232  0
         queryMethodInvoker.setArguments(arguments);
 233  
 
 234  
         try {
 235  0
             queryMethodInvoker.prepare();
 236  
 
 237  0
             return queryMethodInvoker.invoke();
 238  0
         } catch (Exception e) {
 239  0
             throw new RuntimeException("Unable to invoke query method: " + queryMethodInvoker.getTargetMethod(), e);
 240  
         }
 241  
     }
 242  
 
 243  
     /**
 244  
      * Prepares a query using the configured data object, parameters, and criteria, then executes
 245  
      * the query and returns the result Collection
 246  
      *
 247  
      * @param attributeQuery - attribute query instance to perform query for
 248  
      * @param queryParameters - map of parameters that will be used in the query criteria
 249  
      * @param additionalCriteria - map of additional name/value pairs to add to the critiera
 250  
      * @return Collection<?> results of query
 251  
      */
 252  
     protected Collection<?> executeAttributeQueryCriteria(AttributeQuery attributeQuery,
 253  
             Map<String, String> queryParameters, Map<String, String> additionalCriteria) {
 254  0
         Collection<?> results = null;
 255  
 
 256  
         // build criteria for query
 257  0
         Map<String, String> queryCriteria = new HashMap<String, String>();
 258  0
         for (String fieldName : attributeQuery.getQueryFieldMapping().keySet()) {
 259  0
             if (queryParameters.containsKey(fieldName) && StringUtils.isNotBlank(queryParameters.get(fieldName))) {
 260  0
                 queryCriteria.put(fieldName, queryParameters.get(fieldName));
 261  
             }
 262  
         }
 263  
 
 264  
         // add any static criteria
 265  0
         for (String fieldName : attributeQuery.getAdditionalCriteria().keySet()) {
 266  0
             queryCriteria.put(fieldName, attributeQuery.getAdditionalCriteria().get(fieldName));
 267  
         }
 268  
 
 269  
         // add additional criteria
 270  0
         if (additionalCriteria != null) {
 271  0
             queryCriteria.putAll(additionalCriteria);
 272  
         }
 273  
 
 274  0
         Class<?> queryClass = null;
 275  
         try {
 276  0
             queryClass = Class.forName(attributeQuery.getDataObjectClassName());
 277  0
         } catch (ClassNotFoundException e) {
 278  0
             throw new RuntimeException(
 279  
                     "Invalid data object class given for suggest query: " + attributeQuery.getDataObjectClassName(), e);
 280  0
         }
 281  
 
 282  
         // run query
 283  0
         results = getLookupService().findCollectionBySearchUnbounded(queryClass, queryCriteria);
 284  
 
 285  
         // sort results
 286  0
         if (!attributeQuery.getSortPropertyNames().isEmpty() && (results != null) && (results.size() > 1)) {
 287  0
             Collections.sort((List<?>) results, new BeanPropertyComparator(attributeQuery.getSortPropertyNames()));
 288  
         }
 289  
 
 290  0
         return results;
 291  
     }
 292  
 
 293  
     protected LookupService getLookupService() {
 294  0
         if (lookupService == null) {
 295  0
             lookupService = KNSServiceLocatorWeb.getLookupService();
 296  
         }
 297  
 
 298  0
         return lookupService;
 299  
     }
 300  
 
 301  
     public void setLookupService(LookupService lookupService) {
 302  0
         this.lookupService = lookupService;
 303  0
     }
 304  
 
 305  
     protected ConfigurationService getConfigurationService() {
 306  0
         if (configurationService == null) {
 307  0
             configurationService = KNSServiceLocator.getKualiConfigurationService();
 308  
         }
 309  
 
 310  0
         return configurationService;
 311  
     }
 312  
 
 313  
     public void setConfigurationService(ConfigurationService configurationService) {
 314  0
         this.configurationService = configurationService;
 315  0
     }
 316  
 }