Coverage Report - org.kuali.rice.krad.uif.widget.QuickFinder
 
Classes in this File Line Coverage Branch Coverage Complexity
QuickFinder
0%
0/153
0%
0/54
1.644
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.krad.uif.widget;
 17  
 
 18  
 import org.apache.commons.lang.StringUtils;
 19  
 import org.kuali.rice.krad.bo.DataObjectRelationship;
 20  
 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
 21  
 import org.kuali.rice.krad.uif.UifParameters;
 22  
 import org.kuali.rice.krad.uif.container.CollectionGroup;
 23  
 import org.kuali.rice.krad.uif.field.InputField;
 24  
 import org.kuali.rice.krad.uif.view.View;
 25  
 import org.kuali.rice.krad.uif.component.BindingInfo;
 26  
 import org.kuali.rice.krad.uif.component.Component;
 27  
 import org.kuali.rice.krad.uif.field.ActionField;
 28  
 import org.kuali.rice.krad.uif.util.ViewModelUtils;
 29  
 import org.kuali.rice.krad.util.KRADUtils;
 30  
 
 31  
 import java.util.HashMap;
 32  
 import java.util.List;
 33  
 import java.util.Map;
 34  
 
 35  
 /**
 36  
  * Widget for navigating to a lookup from a field (called a quickfinder)
 37  
  *
 38  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 39  
  */
 40  
 public class QuickFinder extends WidgetBase {
 41  
     private static final long serialVersionUID = 3302390972815386785L;
 42  
 
 43  
     // lookup configuration
 44  
     private String baseLookupUrl;
 45  
     private String dataObjectClassName;
 46  
     private String viewName;
 47  
 
 48  
     private String referencesToRefresh;
 49  
 
 50  
     private Map<String, String> fieldConversions;
 51  
     private Map<String, String> lookupParameters;
 52  
 
 53  
     // lookup view options
 54  
     private String readOnlySearchFields;
 55  
 
 56  
     private Boolean hideReturnLink;
 57  
     private Boolean suppressActions;
 58  
     private Boolean autoSearch;
 59  
     private Boolean lookupCriteriaEnabled;
 60  
     private Boolean supplementalActionsEnabled;
 61  
     private Boolean disableSearchButtons;
 62  
     private Boolean headerBarEnabled;
 63  
     private Boolean showMaintenanceLinks;
 64  
 
 65  
     private Boolean multipleValuesSelect;
 66  
     private String lookupCollectionName;
 67  
 
 68  
     private ActionField quickfinderActionField;
 69  
 
 70  
     public QuickFinder() {
 71  0
         super();
 72  
 
 73  0
         fieldConversions = new HashMap<String, String>();
 74  0
         lookupParameters = new HashMap<String, String>();
 75  0
     }
 76  
 
 77  
     /**
 78  
      * The following finalization is performed:
 79  
      *
 80  
      * <ul>
 81  
      * <li>
 82  
      * Sets defaults on collectionLookup such as collectionName, and the class if not set
 83  
      *
 84  
      * <p>
 85  
      * If the data object class was not configured for the lookup, the class configured for the collection group will
 86  
      * be used if it has a lookup defined. If not data object class is found for the lookup it will be disabled. The
 87  
      * collection name is also defaulted to the binding path for this collection group, so the results returned from
 88  
      * the lookup will populate this collection. Finally field conversions will be generated based on the PK fields of
 89  
      * the collection object class
 90  
      * </p>
 91  
      * </li>
 92  
      * </ul>
 93  
      *
 94  
      * @see org.kuali.rice.krad.uif.widget.Widget#performFinalize(org.kuali.rice.krad.uif.view.View,
 95  
      *      java.lang.Object, org.kuali.rice.krad.uif.component.Component)
 96  
      */
 97  
     @Override
 98  
     public void performFinalize(View view, Object model, Component parent) {
 99  0
         super.performFinalize(view, model, parent);
 100  
 
 101  0
         if (!isRender()) {
 102  0
             return;
 103  
         }
 104  
 
 105  0
         if (parent instanceof InputField) {
 106  0
             InputField field = (InputField) parent;
 107  
 
 108  
             // determine lookup class, field conversions and lookup parameters in
 109  
             // not set
 110  0
             if (StringUtils.isBlank(dataObjectClassName)) {
 111  0
                 DataObjectRelationship relationship = getRelationshipForField(view, model, field);
 112  
 
 113  
                 // if no relationship found cannot have a quickfinder
 114  0
                 if (relationship == null) {
 115  0
                     setRender(false);
 116  0
                     return;
 117  
                 }
 118  
 
 119  0
                 dataObjectClassName = relationship.getRelatedClass().getName();
 120  
 
 121  0
                 if ((fieldConversions == null) || fieldConversions.isEmpty()) {
 122  0
                     generateFieldConversions(field, relationship);
 123  
                 }
 124  
 
 125  0
                 if ((lookupParameters == null) || lookupParameters.isEmpty()) {
 126  0
                     generateLookupParameters(field, relationship);
 127  
                 }
 128  
             }
 129  
 
 130  
             // adjust paths based on associated attribute field
 131  0
             updateFieldConversions(field.getBindingInfo());
 132  0
             updateLookupParameters(field.getBindingInfo());
 133  0
         } else if (parent instanceof CollectionGroup) {
 134  0
             CollectionGroup collectionGroup = (CollectionGroup) parent;
 135  
 
 136  
             // check to see if data object class is configured for lookup, if so we will assume it should be enabled
 137  
             // if not and the class configured for the collection group is lookupable, use that
 138  0
             if (StringUtils.isBlank(getDataObjectClassName())) {
 139  0
                 Class<?> collectionObjectClass = collectionGroup.getCollectionObjectClass();
 140  0
                 boolean isCollectionClassLookupable = KRADServiceLocatorWeb.getViewDictionaryService().isLookupable(
 141  
                         collectionObjectClass);
 142  0
                 if (isCollectionClassLookupable) {
 143  0
                     setDataObjectClassName(collectionObjectClass.getName());
 144  
 
 145  0
                     if ((fieldConversions == null) || fieldConversions.isEmpty()) {
 146  
                         // use PK fields for collection class
 147  0
                         List<String> collectionObjectPKFields =
 148  
                                 KRADServiceLocatorWeb.getDataObjectMetaDataService().listPrimaryKeyFieldNames(
 149  
                                         collectionObjectClass);
 150  
 
 151  0
                         for (String pkField : collectionObjectPKFields) {
 152  0
                             fieldConversions.put(pkField, pkField);
 153  
                         }
 154  0
                     }
 155  
                 } else {
 156  
                     // no available data object class to lookup so need to disable quickfinder
 157  0
                     setRender(false);
 158  
                 }
 159  
             }
 160  
 
 161  
             // set the lookup return collection name to this collection path
 162  0
             if (isRender() && StringUtils.isBlank(getLookupCollectionName())) {
 163  0
                 setLookupCollectionName(collectionGroup.getBindingInfo().getBindingPath());
 164  
             }
 165  
         }
 166  
 
 167  0
         quickfinderActionField.addActionParameter(UifParameters.BASE_LOOKUP_URL, baseLookupUrl);
 168  0
         quickfinderActionField.addActionParameter(UifParameters.DATA_OBJECT_CLASS_NAME, dataObjectClassName);
 169  
 
 170  0
         if (!fieldConversions.isEmpty()) {
 171  0
             quickfinderActionField.addActionParameter(UifParameters.CONVERSION_FIELDS,
 172  
                     KRADUtils.buildMapParameterString(fieldConversions));
 173  
         }
 174  
 
 175  0
         if (!lookupParameters.isEmpty()) {
 176  0
             quickfinderActionField.addActionParameter(UifParameters.LOOKUP_PARAMETERS,
 177  
                     KRADUtils.buildMapParameterString(lookupParameters));
 178  
         }
 179  
 
 180  0
         addActionParameterIfNotNull(UifParameters.VIEW_NAME, viewName);
 181  0
         addActionParameterIfNotNull(UifParameters.READ_ONLY_FIELDS, readOnlySearchFields);
 182  0
         addActionParameterIfNotNull(UifParameters.HIDE_RETURN_LINK, hideReturnLink);
 183  0
         addActionParameterIfNotNull(UifParameters.SUPRESS_ACTIONS, suppressActions);
 184  0
         addActionParameterIfNotNull(UifParameters.REFERENCES_TO_REFRESH, referencesToRefresh);
 185  0
         addActionParameterIfNotNull(UifParameters.AUTO_SEARCH, autoSearch);
 186  0
         addActionParameterIfNotNull(UifParameters.LOOKUP_CRITERIA_ENABLED, lookupCriteriaEnabled);
 187  0
         addActionParameterIfNotNull(UifParameters.SUPPLEMENTAL_ACTIONS_ENABLED, supplementalActionsEnabled);
 188  0
         addActionParameterIfNotNull(UifParameters.DISABLE_SEARCH_BUTTONS, disableSearchButtons);
 189  0
         addActionParameterIfNotNull(UifParameters.HEADER_BAR_ENABLED, headerBarEnabled);
 190  0
         addActionParameterIfNotNull(UifParameters.SHOW_MAINTENANCE_LINKS, showMaintenanceLinks);
 191  0
         addActionParameterIfNotNull(UifParameters.MULTIPLE_VALUES_SELECT, multipleValuesSelect);
 192  0
         addActionParameterIfNotNull(UifParameters.LOOKUP_COLLECTION_NAME, lookupCollectionName);
 193  
 
 194  
         // TODO:
 195  
         // org.kuali.rice.kns.util.FieldUtils.populateQuickfinderDefaultsForLookup(Class,
 196  
         // String, Field)
 197  0
     }
 198  
 
 199  
     protected void addActionParameterIfNotNull(String parameterName, Object parameterValue) {
 200  0
         if ((parameterValue != null) && StringUtils.isNotBlank(parameterValue.toString())) {
 201  0
             quickfinderActionField.addActionParameter(parameterName, parameterValue.toString());
 202  
         }
 203  0
     }
 204  
 
 205  
     protected DataObjectRelationship getRelationshipForField(View view, Object model, InputField field) {
 206  0
         String propertyName = field.getBindingInfo().getBindingName();
 207  
 
 208  
         // get object instance and class for parent
 209  0
         Object parentObject = ViewModelUtils.getParentObjectForMetadata(view, model, field);
 210  0
         Class<?> parentObjectClass = null;
 211  0
         if (parentObject != null) {
 212  0
             parentObjectClass = parentObject.getClass();
 213  
         }
 214  
 
 215  
         // get relationship from metadata service
 216  0
         return KRADServiceLocatorWeb.getDataObjectMetaDataService().getDataObjectRelationship(parentObject,
 217  
                 parentObjectClass, propertyName, "", true, true, false);
 218  
     }
 219  
 
 220  
     protected void generateFieldConversions(InputField field, DataObjectRelationship relationship) {
 221  0
         fieldConversions = new HashMap<String, String>();
 222  0
         for (Map.Entry<String, String> entry : relationship.getParentToChildReferences().entrySet()) {
 223  0
             String fromField = entry.getValue();
 224  0
             String toField = entry.getKey();
 225  
 
 226  
             // TODO: displayedFieldnames in
 227  
             // org.kuali.rice.kns.lookup.LookupUtils.generateFieldConversions(BusinessObject,
 228  
             // String, DataObjectRelationship, String, List, String)
 229  
 
 230  0
             fieldConversions.put(fromField, toField);
 231  0
         }
 232  0
     }
 233  
 
 234  
     protected void generateLookupParameters(InputField field, DataObjectRelationship relationship) {
 235  0
         lookupParameters = new HashMap<String, String>();
 236  0
         for (Map.Entry<String, String> entry : relationship.getParentToChildReferences().entrySet()) {
 237  0
             String fromField = entry.getKey();
 238  0
             String toField = entry.getValue();
 239  
 
 240  
             // TODO: displayedFieldnames and displayedQFFieldNames in
 241  
             // generateLookupParameters(BusinessObject,
 242  
             // String, DataObjectRelationship, String, List, String)
 243  
 
 244  0
             if (relationship.getUserVisibleIdentifierKey() == null || relationship.getUserVisibleIdentifierKey().equals(
 245  
                     fromField)) {
 246  0
                 lookupParameters.put(fromField, toField);
 247  
             }
 248  0
         }
 249  0
     }
 250  
 
 251  
     /**
 252  
      * Adjusts the path on the field conversion to property to match the binding
 253  
      * path prefix of the given <code>BindingInfo</code>
 254  
      *
 255  
      * @param bindingInfo - binding info instance to copy binding path prefix from
 256  
      */
 257  
     public void updateFieldConversions(BindingInfo bindingInfo) {
 258  0
         Map<String, String> adjustedFieldConversions = new HashMap<String, String>();
 259  0
         for (String fromField : fieldConversions.keySet()) {
 260  0
             String toField = fieldConversions.get(fromField);
 261  0
             String adjustedToFieldPath = bindingInfo.getPropertyAdjustedBindingPath(toField);
 262  
 
 263  0
             adjustedFieldConversions.put(fromField, adjustedToFieldPath);
 264  0
         }
 265  
 
 266  0
         this.fieldConversions = adjustedFieldConversions;
 267  0
     }
 268  
 
 269  
     /**
 270  
      * Adjusts the path on the lookup parameter from property to match the binding
 271  
      * path prefix of the given <code>BindingInfo</code>
 272  
      *
 273  
      * @param bindingInfo - binding info instance to copy binding path prefix from
 274  
      */
 275  
     public void updateLookupParameters(BindingInfo bindingInfo) {
 276  0
         Map<String, String> adjustedLookupParameters = new HashMap<String, String>();
 277  0
         for (String fromField : lookupParameters.keySet()) {
 278  0
             String toField = lookupParameters.get(fromField);
 279  0
             String adjustedFromFieldPath = bindingInfo.getPropertyAdjustedBindingPath(fromField);
 280  
 
 281  0
             adjustedLookupParameters.put(adjustedFromFieldPath, toField);
 282  0
         }
 283  
 
 284  0
         this.lookupParameters = adjustedLookupParameters;
 285  0
     }
 286  
 
 287  
     /**
 288  
      * @see org.kuali.rice.krad.uif.component.ComponentBase#getComponentsForLifecycle()
 289  
      */
 290  
     @Override
 291  
     public List<Component> getComponentsForLifecycle() {
 292  0
         List<Component> components = super.getComponentsForLifecycle();
 293  
 
 294  0
         components.add(quickfinderActionField);
 295  
 
 296  0
         return components;
 297  
     }
 298  
 
 299  
     public String getBaseLookupUrl() {
 300  0
         return this.baseLookupUrl;
 301  
     }
 302  
 
 303  
     public void setBaseLookupUrl(String baseLookupUrl) {
 304  0
         this.baseLookupUrl = baseLookupUrl;
 305  0
     }
 306  
 
 307  
     public String getDataObjectClassName() {
 308  0
         return this.dataObjectClassName;
 309  
     }
 310  
 
 311  
     public void setDataObjectClassName(String dataObjectClassName) {
 312  0
         this.dataObjectClassName = dataObjectClassName;
 313  0
     }
 314  
 
 315  
     public String getViewName() {
 316  0
         return this.viewName;
 317  
     }
 318  
 
 319  
     public void setViewName(String viewName) {
 320  0
         this.viewName = viewName;
 321  0
     }
 322  
 
 323  
     public String getReferencesToRefresh() {
 324  0
         return this.referencesToRefresh;
 325  
     }
 326  
 
 327  
     public void setReferencesToRefresh(String referencesToRefresh) {
 328  0
         this.referencesToRefresh = referencesToRefresh;
 329  0
     }
 330  
 
 331  
     public Map<String, String> getFieldConversions() {
 332  0
         return this.fieldConversions;
 333  
     }
 334  
 
 335  
     public void setFieldConversions(Map<String, String> fieldConversions) {
 336  0
         this.fieldConversions = fieldConversions;
 337  0
     }
 338  
 
 339  
     public Map<String, String> getLookupParameters() {
 340  0
         return this.lookupParameters;
 341  
     }
 342  
 
 343  
     public void setLookupParameters(Map<String, String> lookupParameters) {
 344  0
         this.lookupParameters = lookupParameters;
 345  0
     }
 346  
 
 347  
     public String getReadOnlySearchFields() {
 348  0
         return this.readOnlySearchFields;
 349  
     }
 350  
 
 351  
     public void setReadOnlySearchFields(String readOnlySearchFields) {
 352  0
         this.readOnlySearchFields = readOnlySearchFields;
 353  0
     }
 354  
 
 355  
     public Boolean getHideReturnLink() {
 356  0
         return this.hideReturnLink;
 357  
     }
 358  
 
 359  
     public void setHideReturnLink(Boolean hideReturnLink) {
 360  0
         this.hideReturnLink = hideReturnLink;
 361  0
     }
 362  
 
 363  
     public Boolean getSuppressActions() {
 364  0
         return suppressActions;
 365  
     }
 366  
 
 367  
     public void setSuppressActions(Boolean suppressActions) {
 368  0
         this.suppressActions = suppressActions;
 369  0
     }
 370  
 
 371  
     public Boolean getAutoSearch() {
 372  0
         return this.autoSearch;
 373  
     }
 374  
 
 375  
     public void setAutoSearch(Boolean autoSearch) {
 376  0
         this.autoSearch = autoSearch;
 377  0
     }
 378  
 
 379  
     public Boolean getLookupCriteriaEnabled() {
 380  0
         return this.lookupCriteriaEnabled;
 381  
     }
 382  
 
 383  
     public void setLookupCriteriaEnabled(Boolean lookupCriteriaEnabled) {
 384  0
         this.lookupCriteriaEnabled = lookupCriteriaEnabled;
 385  0
     }
 386  
 
 387  
     public Boolean getSupplementalActionsEnabled() {
 388  0
         return this.supplementalActionsEnabled;
 389  
     }
 390  
 
 391  
     public void setSupplementalActionsEnabled(Boolean supplementalActionsEnabled) {
 392  0
         this.supplementalActionsEnabled = supplementalActionsEnabled;
 393  0
     }
 394  
 
 395  
     public Boolean getDisableSearchButtons() {
 396  0
         return this.disableSearchButtons;
 397  
     }
 398  
 
 399  
     public void setDisableSearchButtons(Boolean disableSearchButtons) {
 400  0
         this.disableSearchButtons = disableSearchButtons;
 401  0
     }
 402  
 
 403  
     public Boolean getHeaderBarEnabled() {
 404  0
         return this.headerBarEnabled;
 405  
     }
 406  
 
 407  
     public void setHeaderBarEnabled(Boolean headerBarEnabled) {
 408  0
         this.headerBarEnabled = headerBarEnabled;
 409  0
     }
 410  
 
 411  
     public Boolean getShowMaintenanceLinks() {
 412  0
         return this.showMaintenanceLinks;
 413  
     }
 414  
 
 415  
     public void setShowMaintenanceLinks(Boolean showMaintenanceLinks) {
 416  0
         this.showMaintenanceLinks = showMaintenanceLinks;
 417  0
     }
 418  
 
 419  
     public ActionField getQuickfinderActionField() {
 420  0
         return this.quickfinderActionField;
 421  
     }
 422  
 
 423  
     public void setQuickfinderActionField(ActionField quickfinderActionField) {
 424  0
         this.quickfinderActionField = quickfinderActionField;
 425  0
     }
 426  
 
 427  
     /**
 428  
      * Indicates whether a multi-values lookup should be requested
 429  
      *
 430  
      * @return boolean true if multi-value lookup should be requested, false for normal lookup
 431  
      */
 432  
     public Boolean getMultipleValuesSelect() {
 433  0
         return multipleValuesSelect;
 434  
     }
 435  
 
 436  
     /**
 437  
      * Setter for the multi-values lookup indicator
 438  
      *
 439  
      * @param multipleValuesSelect
 440  
      */
 441  
     public void setMultipleValuesSelect(Boolean multipleValuesSelect) {
 442  0
         this.multipleValuesSelect = multipleValuesSelect;
 443  0
     }
 444  
 
 445  
     /**
 446  
      * For the case of multi-value lookup, indicates the collection that should be populated with
 447  
      * the return results
 448  
      *
 449  
      * <p>
 450  
      * Note when the quickfinder is associated with a <code>CollectionGroup</code>, this property is
 451  
      * set automatically from the collection name associated with the group
 452  
      * </p>
 453  
      *
 454  
      * @return String collection name (must be full binding path)
 455  
      */
 456  
     public String getLookupCollectionName() {
 457  0
         return lookupCollectionName;
 458  
     }
 459  
 
 460  
     /**
 461  
      * Setter for the name of the collection that should be populated with lookup results
 462  
      *
 463  
      * @param lookupCollectionName
 464  
      */
 465  
     public void setLookupCollectionName(String lookupCollectionName) {
 466  0
         this.lookupCollectionName = lookupCollectionName;
 467  0
     }
 468  
 }