View Javadoc

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.search;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import org.kuali.student.common.ui.client.application.Application;
22  import org.kuali.student.common.ui.client.application.KSAsyncCallback;
23  import org.kuali.student.common.ui.client.service.SearchRpcService;
24  import org.kuali.student.common.ui.client.service.SearchRpcServiceAsync;
25  import org.kuali.student.common.ui.client.widgets.searchtable.ResultRow;
26  import org.kuali.student.common.ui.client.widgets.table.scroll.Column;
27  import org.kuali.student.common.ui.client.widgets.table.scroll.DefaultTableModel;
28  import org.kuali.student.common.ui.client.widgets.table.scroll.RetrieveAdditionalDataHandler;
29  import org.kuali.student.common.ui.client.widgets.table.scroll.Row;
30  import org.kuali.student.common.ui.client.widgets.table.scroll.RowComparator;
31  import org.kuali.student.common.ui.client.widgets.table.scroll.Table;
32  import org.kuali.student.core.assembly.data.LookupResultMetadata;
33  import org.kuali.student.core.assembly.data.Data.DataType;
34  import org.kuali.student.core.search.dto.SearchRequest;
35  import org.kuali.student.core.search.dto.SearchResult;
36  import org.kuali.student.core.search.dto.SearchResultCell;
37  import org.kuali.student.core.search.dto.SearchResultRow;
38  
39  import com.google.gwt.core.client.GWT;
40  import com.google.gwt.user.client.Window;
41  import com.google.gwt.user.client.ui.Composite;
42  import com.google.gwt.user.client.ui.VerticalPanel;
43  
44  public class SearchResultsTable extends Composite{
45  
46      private final int PAGE_SIZE = 10;
47      
48      private SearchRpcServiceAsync searchRpcServiceAsync = GWT.create(SearchRpcService.class);
49      
50      private VerticalPanel layout = new VerticalPanel();
51      
52      private DefaultTableModel tableModel;
53      private String resultIdColumnKey;
54      private SearchRequest searchRequest;
55      private Table table = new Table();
56      private boolean isMultiSelect = true;
57      
58      public SearchResultsTable(){
59          super();
60          redraw();
61          layout.setWidth("100%");
62          initWidget(layout);
63      }
64      
65      public void redraw(){
66          layout.clear();      
67      }
68      
69      public void setMutipleSelect(boolean isMultiSelect){
70      	this.isMultiSelect = isMultiSelect;
71      }
72      
73      //FIXME do we really need to recreate the table for every refresh?
74      public void initializeTable(List<LookupResultMetadata> listResultMetadata, String resultIdKey){ 
75      	table = new Table();
76          this.resultIdColumnKey = resultIdKey;
77          
78          tableModel = new DefaultTableModel();
79          tableModel.setMultipleSelectable(isMultiSelect);
80  
81          //create table heading
82          for (LookupResultMetadata r: listResultMetadata){
83              if(!r.isHidden()){
84                  Column col1 = new Column();
85                  col1.setId(r.getKey());
86                  String header = Application.getApplicationContext().getUILabel("", null, null, r.getName());
87                  col1.setName(header);
88                  col1.setId(r.getKey());
89                  col1.setWidth("100px");                    
90                  col1.setAscendingRowComparator(new FieldAscendingRowComparator(r.getKey(), r.getDataType()));
91                  col1.setDescendingRowComparator(new FieldDescendingRowComparator(r.getKey(), r.getDataType()));                
92                  
93                  tableModel.addColumn(col1);
94              }
95          }      
96                       
97       // TODO - there's a better way to do this
98          if (this.searchRequest.getSearchKey().toLowerCase().contains("cross")) {
99          	tableModel.setMoreData(false);
100         }
101         if(isMultiSelect){
102         	tableModel.installCheckBoxRowHeaderColumn();
103         }
104         
105         table.getScrollPanel().setHeight("300px");
106         table.setTableModel(tableModel);
107         
108         table.addRetrieveAdditionalDataHandler(new RetrieveAdditionalDataHandler(){
109 			@Override
110 			public void onAdditionalDataRequest() {
111 				 performOnDemandSearch(tableModel.getRowCount(), PAGE_SIZE);
112                  //tableModel.fireTableDataChanged();
113 			}
114 		});
115         
116         redraw();
117         layout.add(table);
118   }   
119     
120     public void performSearch(SearchRequest searchRequest, List<LookupResultMetadata> listResultMetadata, String resultIdKey, boolean pagedResults){
121         this.searchRequest = searchRequest;
122         initializeTable(listResultMetadata, resultIdKey);
123         if (this.searchRequest.getSearchKey().toLowerCase().contains("cross")) {
124             //FIXME Do we still need this if condition?
125             // Added an else to the if(pagedResults) line to prevent searches being executed
126             // twice if the search name includes cross
127             performOnDemandSearch(0, 0);
128         }
129         else if(pagedResults){
130         	performOnDemandSearch(0, PAGE_SIZE);
131         }
132         else{
133         	performOnDemandSearch(0, 0);
134         }
135     }    
136     
137     public void performSearch(SearchRequest searchRequest, List<LookupResultMetadata> listResultMetadata, String resultIdKey){
138         this.performSearch(searchRequest, listResultMetadata, resultIdKey, true);
139     }    
140     
141     private void performOnDemandSearch(int startAt, int size) {
142                 
143     	table.displayLoading(true);
144         searchRequest.setStartAt(startAt);
145         if (size != 0) {
146         	searchRequest.setNeededTotalResults(false);
147         	searchRequest.setMaxResults(size);
148         } else {
149         	searchRequest.setNeededTotalResults(true);
150         }
151 
152         searchRpcServiceAsync.search(searchRequest, new KSAsyncCallback<SearchResult>(){
153 
154             @Override
155             public void handleFailure(Throwable cause) {
156                 GWT.log("Failed to perform search", cause); //FIXME more detail info here
157                 Window.alert("Failed to perform search");
158                 table.displayLoading(false);
159             }
160 
161             @Override
162             public void onSuccess(SearchResult results) {
163 
164                 if(results != null && results.getRows() != null && results.getRows().size() != 0){
165                     for (SearchResultRow r: results.getRows()){
166                         ResultRow theRow = new ResultRow();
167                         for(SearchResultCell c: r.getCells()){
168                             if(c.getKey().equals(resultIdColumnKey)){
169                                 theRow.setId(c.getValue());
170                             }
171                             theRow.setValue(c.getKey(), c.getValue());
172                         }
173                        tableModel.addRow(new SearchResultsRow(theRow));
174                     }
175                 } else {
176                 	tableModel.setMoreData(false);
177                 }
178                 tableModel.fireTableDataChanged();
179                 table.displayLoading(false);
180             }
181         });
182     }
183     
184     public List<ResultRow> getSelectedRows(){
185         List<ResultRow> rows = new ArrayList<ResultRow>();
186         for(Row row : tableModel.getSelectedRows()){
187             rows.add(((SearchResultsRow)row).getResultRow());
188         }
189         return rows;
190     }
191 
192     public List<String> getSelectedIds(){
193         List<String> ids = new ArrayList<String>();
194         for(Row row : tableModel.getSelectedRows()){
195             ids.add(((SearchResultsRow)row).getResultRow().getId());
196         }                
197         return ids;
198     }        
199 }
200 
201 class SearchResultsRow extends Row {
202     
203     ResultRow row;
204     
205     public SearchResultsRow(ResultRow row){
206        this.row = row;
207     }
208     
209     @Override
210     public Object getCellData(String columnId) {
211         return row.getValue(columnId);        
212     }
213     
214     @Override
215     public void setCellData(String columnId, Object newValue) {
216         row.setValue(columnId, newValue.toString());
217     }
218     
219     @Override
220     public String toString(){
221         return row.toString();
222     }
223     
224     public ResultRow getResultRow() {
225         return row;
226     }
227 }   
228 
229 class FieldAscendingRowComparator extends RowComparator{
230     
231     String columnId;
232     DataType type;
233     
234     FieldAscendingRowComparator(String columnId, DataType type) {
235         this.columnId = columnId;
236         this.type = type;
237     }
238     
239     @Override
240     public int compare(Row row0, Row row1) {
241         String id0, id1;
242         
243         if (type.equals(DataType.STRING)) {
244             id0 = (String)row0.getCellData(columnId);
245             id1 = (String)row1.getCellData(columnId);
246         } else {
247             id0 = (String)row0.getCellData(columnId);
248             id1 = (String)row1.getCellData(columnId);            
249         }
250         return id0.compareTo(id1);
251     }    
252 }
253 
254 class FieldDescendingRowComparator extends RowComparator{
255     
256     String columnId;
257     DataType type;    
258     
259     FieldDescendingRowComparator(String columnId, DataType type) {
260         this.columnId = columnId;
261         this.type = type;        
262     }    
263     
264     @Override
265     public int compare(Row row0, Row row1) {
266         String id0, id1;
267         
268         if (type.equals(DataType.STRING)) {
269             id0 = (String)row0.getCellData(columnId);
270             id1 = (String)row1.getCellData(columnId);
271         } else {
272             id0 = (String)row0.getCellData(columnId);
273             id1 = (String)row1.getCellData(columnId);            
274         }
275         return id1.compareTo(id0);
276     }    
277 }