Coverage Report - org.kuali.student.common.ui.client.widgets.suggestbox.SearchSuggestOracle
 
Classes in this File Line Coverage Branch Coverage Complexity
SearchSuggestOracle
0%
0/95
0%
0/28
2.737
SearchSuggestOracle$1
0%
0/11
0%
0/4
2.737
SearchSuggestOracle$2
0%
0/3
N/A
2.737
SearchSuggestOracle$3
0%
0/43
0%
0/24
2.737
SearchSuggestOracle$4
0%
0/17
0%
0/10
2.737
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 
 16  
 package org.kuali.student.common.ui.client.widgets.suggestbox;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.List;
 20  
 
 21  
 import org.kuali.student.common.assembly.data.LookupMetadata;
 22  
 import org.kuali.student.common.assembly.data.LookupParamMetadata;
 23  
 import org.kuali.student.common.assembly.data.Metadata.WriteAccess;
 24  
 import org.kuali.student.common.search.dto.SearchParam;
 25  
 import org.kuali.student.common.search.dto.SearchRequest;
 26  
 import org.kuali.student.common.search.dto.SearchResult;
 27  
 import org.kuali.student.common.search.dto.SearchResultCell;
 28  
 import org.kuali.student.common.search.dto.SearchResultRow;
 29  
 import org.kuali.student.common.ui.client.application.KSAsyncCallback;
 30  
 import org.kuali.student.common.ui.client.service.CachingSearchService;
 31  
 import org.kuali.student.common.ui.client.service.SearchRpcServiceAsync;
 32  
 import org.kuali.student.common.ui.client.service.SearchServiceFactory;
 33  
 import org.kuali.student.common.ui.client.widgets.KSErrorDialog;
 34  
 import org.kuali.student.common.ui.client.widgets.notification.LoadingDiv;
 35  
 
 36  
 import com.google.gwt.user.client.ui.HasText;
 37  
 import com.google.gwt.user.client.ui.Widget;
 38  
 import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
 39  
 
 40  0
 public class SearchSuggestOracle extends IdableSuggestOracle{
 41  
     
 42  
     private String searchTypeKey;
 43  
     private String searchIdKey;
 44  
     private String searchTextKey;
 45  
     private String resultIdKey;
 46  
     private Callback currentCallback;
 47  
     private Request pendingRequest;
 48  
     private Callback pendingCallback;
 49  
     private HasText textWidget;
 50  
     private String resultDisplayKey;
 51  
     private String resultSortKey;
 52  0
     private List<SearchParam> additionalParams = new ArrayList<SearchParam>();
 53  0
     private List<IdableSuggestion> lastSuggestions = new ArrayList<IdableSuggestion>();
 54  
     
 55  
     private LookupMetadata lookupMetaData;
 56  0
     private CachingSearchService cachingSearchService = CachingSearchService.getSearchService();
 57  0
     private SearchRpcServiceAsync searchService = SearchServiceFactory.getSearchService();
 58  
 
 59  0
     private List<org.kuali.student.common.ui.client.mvc.Callback<IdableSuggestion>> searchCompletedCallbacks = new ArrayList<org.kuali.student.common.ui.client.mvc.Callback<IdableSuggestion>>();
 60  
     
 61  0
     private LoadingDiv loading = new LoadingDiv();
 62  
     
 63  
     /**
 64  
      * @deprecated
 65  
      * @param searchTypeKey the type to be search on
 66  
      * @param searchTextKey the column/key that to search on
 67  
      * @param idKey the column/key that is the primary key for this type
 68  
      */
 69  0
     public SearchSuggestOracle(String searchTypeKey, String searchTextKey, String searchIdKey, String resultIdKey, String resultDisplayKey){
 70  0
         this.searchTypeKey = searchTypeKey;
 71  0
         this.searchTextKey = searchTextKey;
 72  0
         this.searchIdKey = searchIdKey;
 73  0
         this.resultIdKey = resultIdKey;
 74  0
         this.resultDisplayKey = resultDisplayKey;
 75  0
     }
 76  
     
 77  
     /*
 78  
      * 
 79  
      */
 80  0
     public SearchSuggestOracle(LookupMetadata lookupMetadata) {
 81  0
             this.lookupMetaData = lookupMetadata;
 82  0
         this.searchTypeKey = lookupMetaData.getSearchTypeId();
 83  
         
 84  0
         for (LookupParamMetadata param : lookupMetadata.getParams()) {
 85  0
                 if ((param.getUsage() != null) && param.getUsage().name().equals("DEFAULT")) {
 86  0
                         this.searchTextKey = param.getKey();
 87  
                 }
 88  
                 //Add in any writeaccess never default values to the additional params
 89  0
                 if(WriteAccess.NEVER.equals(param.getWriteAccess())||param.getDefaultValueString()!=null||param.getDefaultValueList()!=null){
 90  0
                         SearchParam searchParam = new SearchParam();
 91  0
                         searchParam.setKey(param.getKey());
 92  0
                                 if(param.getDefaultValueList()==null){
 93  0
                                         searchParam.setValue(param.getDefaultValueString());
 94  
                                 }else{
 95  0
                                         searchParam.setValue(param.getDefaultValueList());
 96  
                                 }
 97  0
                         additionalParams.add(searchParam);
 98  0
                 }
 99  
         }
 100  0
         if (this.searchTextKey == null) {
 101  0
                 KSErrorDialog.show(new Throwable("Cannot find searchTextKey for " + searchTypeKey) );
 102  
         }
 103  
         
 104  0
         this.searchIdKey = lookupMetadata.getSearchParamIdKey();
 105  0
         this.resultIdKey = lookupMetadata.getResultReturnKey();
 106  0
         this.resultDisplayKey = lookupMetadata.getResultDisplayKey();
 107  0
         this.resultSortKey = lookupMetadata.getResultSortKey();
 108  0
     }
 109  
 
 110  
     public void setAdditionalSearchParams(List<SearchParam> params){
 111  0
         additionalParams = params;
 112  0
     }
 113  
     
 114  0
     private Callback wrappedCallback = new Callback() {
 115  
 
 116  
         public void onSuggestionsReady(Request request, Response response) {
 117  0
           if (textWidget.getText().equals(request.getQuery())) {
 118  0
             currentCallback.onSuggestionsReady(request, response);
 119  0
             pendingRequest = null;
 120  0
             pendingCallback = null;
 121  
           }
 122  0
           currentCallback = null;
 123  0
           if (pendingCallback != null) {
 124  0
             requestSuggestions(pendingRequest, pendingCallback);
 125  0
             pendingRequest = null;
 126  0
             pendingCallback = null;
 127  
           }
 128  0
         }
 129  
 
 130  
     };
 131  
     
 132  
     @Override
 133  
     public void requestSuggestions(Request request, Callback callback) {
 134  0
         if (currentCallback == null) {
 135  0
           final int x = ((Widget)this.textWidget).getAbsoluteLeft() + ((Widget)this.textWidget).getOffsetWidth();
 136  0
                     final int y = ((Widget)this.textWidget).getAbsoluteTop() + ((Widget)this.textWidget).getOffsetHeight();
 137  0
                     loading.setPopupPositionAndShow(new PositionCallback(){
 138  
 
 139  
                                   @Override
 140  
                                   public void setPosition(int offsetWidth, int offsetHeight) {
 141  0
                                           loading.setPopupPosition(x - offsetWidth, y + 1);
 142  0
                                   }
 143  
                           });
 144  0
           currentCallback = callback;
 145  0
           sendRequest(request, wrappedCallback);
 146  0
         } else {
 147  0
           pendingRequest = request;
 148  0
           pendingCallback = callback;
 149  
         }        
 150  0
     }
 151  
     
 152  
     private SearchRequest buildSearchRequest(String query, String searchId) {
 153  0
             SearchRequest sr = new SearchRequest();
 154  0
             sr.setNeededTotalResults(false);
 155  0
             sr.setSearchKey(this.searchTypeKey);
 156  0
             sr.setSortColumn(this.resultSortKey);
 157  
 
 158  0
                 List<SearchParam> searchParams = new ArrayList<SearchParam>();
 159  0
                 SearchParam param1 = createParam(this.searchTextKey, query);
 160  0
                 searchParams.add(param1);
 161  
                 
 162  0
             sr.setParams(searchParams);
 163  
             
 164  0
             sr.getParams().addAll(additionalParams);
 165  
 
 166  0
         return sr;
 167  
     }
 168  
     
 169  
     private SearchRequest buildSearchRequestById(String query, String searchId) {
 170  0
             SearchRequest sr = new SearchRequest();
 171  0
             sr.setNeededTotalResults(false);
 172  0
             sr.setSearchKey(this.searchTypeKey);
 173  0
             sr.setSortColumn(this.resultSortKey);
 174  
 
 175  0
                 List<SearchParam> searchParams = new ArrayList<SearchParam>();
 176  0
                 SearchParam param2 = createParam(this.searchIdKey, searchId);
 177  0
                 searchParams.add(param2);
 178  
                 
 179  0
             sr.setParams(searchParams);
 180  
             
 181  0
             sr.getParams().addAll(additionalParams);
 182  
 
 183  0
         return sr;
 184  
     }
 185  
     
 186  
     private SearchParam createParam(String key, String value) {
 187  0
             SearchParam param = new SearchParam();
 188  
             
 189  0
             if(key == null) {
 190  0
                         param.setKey("");
 191  
                 } else {
 192  0
                         param.setKey(key);
 193  
                 }
 194  
 
 195  0
             if(value == null) {
 196  0
                         param.setValue("");
 197  
                 } else {
 198  0
                         param.setValue(value);
 199  
                 }
 200  
             
 201  0
             return param;
 202  
     }
 203  
 
 204  
     public void sendRequest(final Request request, final Callback callback){
 205  0
         String query = request.getQuery().trim();
 206  0
         SearchRequest searchRequest = buildSearchRequest(query, null);
 207  
         
 208  
         //case-sensitive?
 209  0
         if(query.length() > 0){
 210  0
                 searchService.search(searchRequest, new KSAsyncCallback<SearchResult>(){
 211  
     
 212  
                 @Override
 213  
                 public void onSuccess(SearchResult results) {
 214  0
                     lastSuggestions = createSuggestions(results, request.getLimit());
 215  0
                     Response response = new Response(lastSuggestions);
 216  0
                     loading.hide();
 217  0
                     callback.onSuggestionsReady(request, response);
 218  0
                     if (searchCompletedCallbacks != null &&
 219  
                             lastSuggestions != null && lastSuggestions.size() == 1) {
 220  0
                         for (org.kuali.student.common.ui.client.mvc.Callback<IdableSuggestion> callback : searchCompletedCallbacks) {
 221  0
                             callback.exec(lastSuggestions.get(0));
 222  
                         }
 223  
                     }
 224  0
                 }
 225  
                 
 226  
                 @Override
 227  
                 public void onFailure(Throwable caught) {
 228  0
                         loading.hide();
 229  0
                         super.onFailure(caught);
 230  0
                 }
 231  
                 
 232  
                 private List<IdableSuggestion> createSuggestions(SearchResult results, int limit){
 233  0
                     List<IdableSuggestion> suggestionsList = new ArrayList<IdableSuggestion>();
 234  0
                     String query = request.getQuery();
 235  0
                     query = query.trim();
 236  0
                     int count = 0;
 237  0
                     if(results != null){
 238  0
                         for (SearchResultRow r: results.getRows()){
 239  0
                             if(count == limit){
 240  0
                                 break;
 241  
                             }
 242  
 
 243  0
                             IdableSuggestion theSuggestion = new IdableSuggestion();
 244  0
                             for(SearchResultCell c: r.getCells()){
 245  0
                                 if(c.getKey().equals(resultDisplayKey)){
 246  0
                                     String itemText = c.getValue();
 247  0
                                     theSuggestion.addAttr(c.getKey(), c.getValue());
 248  0
                                     int index = (" " + itemText).toLowerCase().indexOf(" " + query.toLowerCase().trim());
 249  
                                     
 250  0
                                     if (index < 0) {
 251  
                                         //temporary fix to stop index out of bound exception in hosted mode
 252  
 //                                        continue;
 253  
                                         //Including fuzzy search results in the display list.
 254  0
                                         theSuggestion.setDisplayString(itemText);
 255  0
                                         theSuggestion.setReplacementString(itemText);
 256  
                                             //FIXME handle case when search for text is not appearing within search result - should not happen (misconfiguration)
 257  0
                                         continue;
 258  
                                     }
 259  
                                     
 260  0
                                     String htmlString = itemText.substring(0,index) + "<b>" + itemText.substring(index, index + query.length()) + "</b>" + itemText.substring(index + query.length(), itemText.length());
 261  0
                                     theSuggestion.setDisplayString(htmlString);
 262  0
                                     theSuggestion.setReplacementString(itemText);
 263  0
                                     if (c.getKey().equals(resultIdKey)){
 264  0
                                         theSuggestion.setId(c.getValue());
 265  
                                     }
 266  0
                                 } else if(c.getKey().equals(resultIdKey)){
 267  0
                                      theSuggestion.setId(c.getValue());
 268  0
                                      theSuggestion.addAttr(c.getKey(), c.getValue());
 269  
                                 } else{
 270  0
                                     theSuggestion.addAttr(c.getKey(), c.getValue());
 271  
                                 }
 272  
                             }
 273  0
                             suggestionsList.add(theSuggestion);
 274  0
                             count++;
 275  0
                         }
 276  
                     }
 277  0
                     return suggestionsList;
 278  
                 }
 279  
             });
 280  
         }
 281  0
     }
 282  
 
 283  
     @Override
 284  
     public boolean isDisplayStringHTML() {
 285  0
         return true;
 286  
     }
 287  
 
 288  
 /*    
 289  
     public IdableSuggestion getSuggestionById(String id) {
 290  
         IdableSuggestion suggestion = null;
 291  
         if(!(lastSuggestions.isEmpty())){
 292  
             for(IdableSuggestion is: lastSuggestions){
 293  
                 if(is.getId().equals(id)){
 294  
                     suggestion = is;
 295  
                     break;
 296  
                 }
 297  
             }
 298  
         }
 299  
         if(suggestion == null){
 300  
             searchOnId(id);
 301  
         }
 302  
         return suggestion;
 303  
     }*/
 304  
 
 305  
     @Override
 306  
     public IdableSuggestion getSuggestionByText(String text){
 307  0
         IdableSuggestion suggestion = null;
 308  0
         for(IdableSuggestion is: lastSuggestions){
 309  0
             if(is.getReplacementString().trim().equalsIgnoreCase(text.trim())){
 310  0
                 suggestion = is;
 311  0
                 break;
 312  
             }
 313  
         }
 314  0
         return suggestion;
 315  
     }
 316  
     
 317  
     public void setTextWidget(HasText widget){
 318  0
         textWidget = widget;
 319  0
     }
 320  
 
 321  
     @Override
 322  
     public void getSuggestionByIdSearch(String id, final org.kuali.student.common.ui.client.mvc.Callback<IdableSuggestion> callback) {
 323  0
         SearchRequest searchRequest = buildSearchRequestById(null, id);
 324  0
         cachingSearchService.search(searchRequest, new KSAsyncCallback<SearchResult>(){
 325  
             @Override
 326  
             public void onSuccess(SearchResult results) {
 327  0
                 IdableSuggestion theSuggestion = null;
 328  0
                 if(results != null && !results.getRows().isEmpty()){
 329  0
                         SearchResultRow r = results.getRows().get(0);
 330  0
                     theSuggestion = new IdableSuggestion();
 331  0
                     for(SearchResultCell c: r.getCells()){
 332  0
                         if(c.getKey().equals(resultDisplayKey)){
 333  0
                             String itemText = c.getValue();
 334  0
                             theSuggestion.addAttr(c.getKey(), c.getValue());
 335  0
                             theSuggestion.setDisplayString(itemText);
 336  0
                             theSuggestion.setReplacementString(itemText);
 337  0
                         } else if(c.getKey().equals(resultIdKey)){
 338  0
                              theSuggestion.setId(c.getValue());
 339  0
                              theSuggestion.addAttr(c.getKey(), c.getValue());
 340  
                         } else {
 341  0
                             theSuggestion.addAttr(c.getKey(), c.getValue());
 342  
                         }
 343  
                     }
 344  
                 }
 345  0
                 callback.exec(theSuggestion);
 346  0
             }
 347  
         });
 348  0
     }
 349  
 
 350  
     @Override
 351  
     public void addSearchCompletedCallback(org.kuali.student.common.ui.client.mvc.Callback<IdableSuggestion> callback) {
 352  0
         searchCompletedCallbacks.add(callback);
 353  0
     }
 354  
     
 355  
 }