Clover Coverage Report - KS Common 1.2-M6-SNAPSHOT (Aggregated)
Coverage timestamp: Mon Sep 12 2011 05:50:56 EDT
../../../../../../../../img/srcFileCovDistChart0.png 30% of files have more coverage
371   926   150   5.89
128   739   0.4   7
63     2.38  
9    
 
  SearchPanel       Line # 69 194 0% 72 294 0% 0.0
  SearchPanel.SearchStyle       Line # 82 0 - 0 0 - -1.0
  SearchPanel.SearchParametersWidget       Line # 114 0 - 0 0 - -1.0
  SearchPanel.CustomizedSearch       Line # 275 48 0% 16 67 0% 0.0
  SearchPanel.HasSearchParam       Line # 378 0 - 0 0 - -1.0
  SearchPanel.CustomLine       Line # 384 27 0% 9 37 0% 0.0
  SearchPanel.AdvancedSearch       Line # 450 61 0% 33 97 0% 0.0
  SearchPanel.SearchField       Line # 581 19 0% 9 32 0% 0.0
  SearchPanel.ParamListItems       Line # 746 22 0% 11 35 0% 0.0
 
No Tests
 
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.HashMap;
20    import java.util.LinkedHashMap;
21    import java.util.List;
22    import java.util.Map;
23   
24    import org.kuali.student.common.assembly.data.LookupMetadata;
25    import org.kuali.student.common.assembly.data.LookupParamMetadata;
26    import org.kuali.student.common.assembly.data.Metadata;
27    import org.kuali.student.common.assembly.data.LookupMetadata.Usage;
28    import org.kuali.student.common.assembly.data.Metadata.WriteAccess;
29    import org.kuali.student.common.search.dto.SearchParam;
30    import org.kuali.student.common.search.dto.SearchRequest;
31    import org.kuali.student.common.ui.client.application.Application;
32    import org.kuali.student.common.ui.client.configurable.mvc.DefaultWidgetFactory;
33    import org.kuali.student.common.ui.client.mvc.Callback;
34    import org.kuali.student.common.ui.client.util.UtilConstants;
35    import org.kuali.student.common.ui.client.widgets.KSButton;
36    import org.kuali.student.common.ui.client.widgets.KSDropDown;
37    import org.kuali.student.common.ui.client.widgets.KSLabel;
38    import org.kuali.student.common.ui.client.widgets.KSButtonAbstract.ButtonStyle;
39    import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations;
40    import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations.ButtonEnum;
41    import org.kuali.student.common.ui.client.widgets.field.layout.button.ActionCancelGroup;
42    import org.kuali.student.common.ui.client.widgets.field.layout.button.ButtonGroup;
43    import org.kuali.student.common.ui.client.widgets.field.layout.element.FieldElement;
44    import org.kuali.student.common.ui.client.widgets.layout.HorizontalBlockFlowPanel;
45    import org.kuali.student.common.ui.client.widgets.layout.VerticalFlowPanel;
46    import org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract;
47    import org.kuali.student.common.ui.client.widgets.list.ListItems;
48    import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent;
49    import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
50    import org.kuali.student.common.ui.client.widgets.searchtable.ResultRow;
51   
52    import com.google.gwt.core.client.GWT;
53    import com.google.gwt.event.dom.client.ClickEvent;
54    import com.google.gwt.event.dom.client.ClickHandler;
55    import com.google.gwt.event.dom.client.KeyCodes;
56    import com.google.gwt.event.dom.client.KeyDownEvent;
57    import com.google.gwt.event.dom.client.KeyDownHandler;
58    import com.google.gwt.event.shared.HandlerRegistration;
59    import com.google.gwt.user.client.Window;
60    import com.google.gwt.user.client.ui.Composite;
61    import com.google.gwt.user.client.ui.HTMLPanel;
62    import com.google.gwt.user.client.ui.HasText;
63    import com.google.gwt.user.client.ui.HasValue;
64    import com.google.gwt.user.client.ui.SimplePanel;
65    import com.google.gwt.user.client.ui.SuggestBox;
66    import com.google.gwt.user.client.ui.VerticalPanel;
67    import com.google.gwt.user.client.ui.Widget;
68   
 
69    public class SearchPanel extends Composite{
70   
71    //Layout configuration
72    private VerticalFlowPanel layout = new VerticalFlowPanel();
73    private SimplePanel searchSelectorPanel = new SimplePanel();
74    private VerticalFlowPanel resultsTablePanel = new VerticalFlowPanel();
75    private HorizontalBlockFlowPanel enteredCriteriaString = new HorizontalBlockFlowPanel();
76    private CollapsablePanel modifySearchPanel;
77    private String criteriaInstructions = getMessage("searchPanelEnterFields");
78    private KSLabel enteredCriteriaHeading = new KSLabel(getMessage("searchPanelCriteria"));
79    private SearchResultsTable table;
80    private boolean isMultiSelect = true;
81   
 
82    public static enum SearchStyle{ADVANCED, CUSTOM};
83    private ActionCancelGroup actionCancelButtons;
84   
85    private String actionLabel = getMessage("search"); //set default action label
86    private boolean resultsSelected = false;
87    private boolean hasSearchParams = false; //indicates if there are any user supplied search parameters
88    //if false will auto default search and not display modify search link.
89   
90    //Search data
91    private List<LookupMetadata> lookups = new ArrayList<LookupMetadata>();
92    private boolean multiSelect = false;
93    private boolean resultsShown = false;
94    private SearchParametersWidget activeSearchParametersWidget = null;
95    // uses "name" of the lookup metadata to lookup the widget that layouts the search UI
96    private Map<String, SearchParametersWidget> searchParameterWidgetMap = new HashMap<String, SearchParametersWidget>();
97    private List<SearchField> searchFields = new ArrayList<SearchField>();
98    private List<Callback<LookupMetadata>> lookupChangedCallbacks = new ArrayList<Callback<LookupMetadata>>();
99    private String selectedLookupName;
100    private List<Callback<List<SelectedResults>>> selectedCompleteCallbacks = new ArrayList<Callback<List<SelectedResults>>>();
101    private List<Callback<Boolean>> actionCompletedCallbacks = new ArrayList<Callback<Boolean>>();
102   
103    private Callback<ButtonEnumerations.ButtonEnum> actionCancelCallback = new Callback<ButtonEnumerations.ButtonEnum>(){
104   
 
105  0 toggle @Override
106    public void exec(ButtonEnum result) {
107  0 if (result == ButtonEnumerations.SearchCancelEnum.SEARCH) {
108  0 table.getContentTable().removeContent();
109  0 getActionCompleteCallback().exec(true);
110    }
111    }
112    };
113   
 
114    interface SearchParametersWidget {
115    public SearchRequest getSearchRequest();
116    public LookupMetadata getLookupMetadata();
117    public List<HasSearchParam> getSearchParams();
118    }
119   
 
120  0 toggle public SearchPanel(LookupMetadata meta){
121  0 lookups.add(meta);
122  0 this.initWidget(layout);
123    }
124   
 
125  0 toggle public SearchPanel(List<LookupMetadata> metas){
126  0 lookups = metas;
127  0 this.initWidget(layout);
128    }
129   
 
130  0 toggle @SuppressWarnings("unchecked")
131    public ButtonGroup getButtons(){
132  0 return actionCancelButtons;
133    }
134   
 
135  0 toggle public void setMutipleSelect(boolean isMultiSelect){
136  0 this.isMultiSelect = isMultiSelect;
137    }
138   
 
139  0 toggle public void setupButtons() {
140  0 if (actionCancelButtons != null) {
141  0 actionCancelButtons.setButtonText(ButtonEnumerations.SearchCancelEnum.SEARCH, getActionLabel());
142  0 actionCancelButtons.addCallback(actionCancelCallback);
143    }
144    }
145   
 
146  0 toggle public void setupSearch() {
147  0 resultsTablePanel.clear();
148  0 layout.clear();
149  0 resultsShown = false;
150  0 hasSearchParams = false;
151   
152    //create search panel
153  0 Widget searchParamPanel;
154  0 if (lookups.size() == 1) {
155  0 searchParamPanel = createSearchParamPanel(lookups.get(0));
156  0 selectedLookupName = lookups.get(0).getName();
157  0 activeSearchParametersWidget = searchParameterWidgetMap.get(selectedLookupName);
158    } else {
159  0 LinkedHashMap<String, Widget> searches = new LinkedHashMap<String, Widget>();
160  0 LinkedHashMap<String, LookupMetadata> searchLookups = new LinkedHashMap<String, LookupMetadata>();
161  0 for(LookupMetadata lookup: lookups){
162  0 searches.put(lookup.getName(), createSearchParamPanel(lookup));
163  0 searchLookups.put(lookup.getName(), lookup);
164    }
165  0 selectedLookupName = lookups.get(0).getName();
166    // Sets the activeSearchParametersWidget to be the first search
167  0 activeSearchParametersWidget = searchParameterWidgetMap.get(selectedLookupName);
168  0 String actionLabel = (lookups.get(0) == null)? null : lookups.get(0)
169    .getWidgetOptionValue(LookupMetadata.WidgetOption.ADVANCED_LIGHTBOX_ACTION_LABEL);
170  0 setActionLabel(actionLabel);
171  0 searchParamPanel = new SwappablePanel(searches);
172  0 ((SwappablePanel)searchParamPanel).setSearchLookups(searchLookups);
173  0 ((SwappablePanel)searchParamPanel).addLookupChangedCallback(new Callback<LookupMetadata>() {
 
174  0 toggle @Override
175    public void exec(LookupMetadata selectedLookup) {
176  0 activeSearchParametersWidget = searchParameterWidgetMap.get(selectedLookup.getName());
177  0 selectedLookupName = selectedLookup.getName();
178  0 if (lookupChangedCallbacks != null) {
179  0 for (Callback<LookupMetadata> callback : lookupChangedCallbacks) {
180  0 callback.exec(selectedLookup);
181    }
182    }
183    }
184    });
185    }
186  0 searchSelectorPanel.setWidget(searchParamPanel);
187  0 layout.add(searchSelectorPanel);
188   
189    //Create layout for results screen
190   
191    //Entered criteria section
192  0 if (hasSearchParams){
193  0 enteredCriteriaHeading.addStyleName("ks-form-module-single-line-margin");
194  0 enteredCriteriaHeading.addStyleName("KS-Advanced-Search-Search-Criteria-Label");
195  0 resultsTablePanel.add(enteredCriteriaHeading);
196  0 resultsTablePanel.add(enteredCriteriaString);
197  0 resultsTablePanel.setVisible(false);
198    }
199   
200    //Search Results table
201  0 table = new SearchResultsTable();
202  0 table.setMutipleSelect(isMultiSelect);
203  0 table.addStyleName("KS-Advanced-Search-Results-Table");
204  0 resultsTablePanel.add(table);
205  0 layout.add(resultsTablePanel);
206   
207  0 table.getMslabel().addClickHandler(new ClickHandler(){
208   
 
209  0 toggle @Override
210    public void onClick(ClickEvent event) {
211  0 if(modifySearchPanel.isOpen()){
212  0 modifySearchPanel.close();
213    }
214    else{
215  0 modifySearchPanel.open();
216    }
217   
218  0 resultsTablePanel.setVisible(false);
219  0 resultsSelected = false;
220  0 actionCancelButtons.setButtonText(ButtonEnumerations.SearchCancelEnum.SEARCH, getActionLabel());
221    }
222    });
223   
224  0 resultsSelected = false;
225  0 actionCancelButtons.setButtonText(ButtonEnumerations.SearchCancelEnum.SEARCH, getActionLabel());
226   
227    //Execute the search and display the results of there are no user supplied search parameters defined
228  0 if (!hasSearchParams){
229  0 getActionCompleteCallback().exec(true);
230    }
231    }
232   
 
233  0 toggle private Widget createSearchParamPanel(LookupMetadata meta){
234  0 ParamListItems listItems = new ParamListItems(meta);
235  0 final AdvancedSearch advancedSearch = new AdvancedSearch(meta);
236  0 LinkPanel panel = new LinkPanel(SearchStyle.ADVANCED, advancedSearch);
237  0 searchParameterWidgetMap.put(meta.getName(), advancedSearch);
238   
239    //check whether we need custom tab i.e. whether we have at least one parameter that should appear on custom tab
240  0 for(LookupParamMetadata metaParam: meta.getParams()){
241  0 if (metaParam.getUsage() != null && metaParam.getUsage() != Usage.DEFAULT){
242  0 hasSearchParams = true; //Only set to true if this only has user supplied params (i.e. params without default values)
243    }
244  0 if ((metaParam.getUsage() == Usage.CUSTOM) || (metaParam.getUsage() == Usage.ADVANCED_CUSTOM)) {
245   
246  0 final CustomizedSearch customizedSearch = new CustomizedSearch(meta, listItems);
247  0 KSButton button = panel.addLinkToPanel(SearchStyle.ADVANCED, getMessage("searchPanelCustomizeSearch"), SearchStyle.CUSTOM);
248  0 button.addClickHandler(new ClickHandler(){
249   
 
250  0 toggle @Override
251    public void onClick(ClickEvent event) {
252  0 resultsTablePanel.setVisible(false);
253  0 activeSearchParametersWidget = customizedSearch;
254    }});
255  0 button.addStyleName("KS-Advanced-Search-Link");
256  0 button.getParent().addStyleName("clearfix");
257  0 panel.addPanel(SearchStyle.CUSTOM, customizedSearch);
258  0 button = panel.addLinkToPanel(SearchStyle.CUSTOM, getMessage("searchPanelReturnToAdvancedSearch"), SearchStyle.ADVANCED);
259  0 button.addClickHandler(new ClickHandler(){
260   
 
261  0 toggle @Override
262    public void onClick(ClickEvent event) {
263  0 resultsTablePanel.setVisible(false);
264  0 activeSearchParametersWidget = advancedSearch;
265    }});
266  0 button.addStyleName("KS-Advanced-Search-Link");
267  0 button.getParent().addStyleName("clearfix");
268  0 break;
269    }
270    }
271   
272  0 return panel;
273    }
274   
 
275    private class CustomizedSearch extends Composite implements SearchParametersWidget {
276   
277    private List<CustomLine> lines = new ArrayList<CustomLine>();
278    private List<HasSearchParam> searchParams = new ArrayList<HasSearchParam>();
279    private VerticalPanel layout = new VerticalPanel();
280    private VerticalPanel linePanel = new VerticalPanel();
281    private LookupMetadata meta;
282   
 
283  0 toggle public CustomizedSearch(final LookupMetadata meta, final ParamListItems listItems){
284   
285  0 KSLabel instrLabel = new KSLabel(criteriaInstructions);
286  0 layout.add(instrLabel);
287   
288  0 layout.add(linePanel);
289  0 CustomLine line = new CustomLine(meta, listItems);
290  0 line.addStyleName("ks-form-module-single-line-margin");
291  0 linePanel.add(line);
292  0 lines.add(line);
293  0 searchParams.add(line);
294  0 this.meta = meta;
295   
296  0 KSButton addCriteria = new KSButton(getMessage("searchPanelAddCriteria"), ButtonStyle.SECONDARY);
297  0 addCriteria.addClickHandler(new ClickHandler(){
298   
 
299  0 toggle @Override
300    public void onClick(ClickEvent event) {
301  0 CustomLine line = new CustomLine(meta, listItems);
302  0 line.addStyleName("ks-form-module-single-line-margin");
303  0 linePanel.add(line);
304  0 lines.add(line);
305  0 searchParams.add(line);
306    }
307    });
308   
309  0 addCriteria.addStyleName("ks-form-module-single-line-margin");
310  0 layout.add(addCriteria);
311   
312  0 this.initWidget(layout);
313    }
314   
 
315  0 toggle public LookupMetadata getLookupMetadata() {
316  0 return meta;
317    }
318   
 
319  0 toggle @Override
320    public SearchRequest getSearchRequest() {
321    //Create search request and then pass it to the table
322    //TODO pass search to the table
323  0 SearchRequest sr = new SearchRequest();
324  0 List<SearchParam> params = new ArrayList<SearchParam>();
325  0 for(CustomLine field: lines){
326  0 SearchParam param = field.getSearchParam();
327    //TODO is this check needed here? probably. assuming string here
328  0 if((param.getValue() != null)){
329  0 params.add(param);
330    }
331    }
332   
333    //add search criteria widgets to the custom tab
334  0 for(LookupParamMetadata metaParam: meta.getParams()){
335   
336    //select only parameters shown on custom search tab
337  0 if ((metaParam.getUsage() != Usage.CUSTOM) && (metaParam.getUsage() != Usage.ADVANCED_CUSTOM)) {
338  0 continue;
339    }
340   
341  0 if(metaParam.getWriteAccess() == WriteAccess.NEVER){
342  0 SearchParam param = new SearchParam();
343  0 param.setKey(metaParam.getKey());
344  0 if(metaParam.getDefaultValueList()==null){
345  0 param.setValue(metaParam.getDefaultValueString());
346    }else{
347  0 param.setValue(metaParam.getDefaultValueList());
348    }
349  0 params.add(param);
350    }
351  0 else if(metaParam.getWriteAccess() == WriteAccess.WHEN_NULL){
352  0 if((metaParam.getDefaultValueString() != null && !metaParam.getDefaultValueString().isEmpty())||
353    (metaParam.getDefaultValueList() != null && !metaParam.getDefaultValueList().isEmpty())){
354  0 SearchParam param = new SearchParam();
355  0 param.setKey(metaParam.getKey());
356  0 if(metaParam.getDefaultValueList()==null){
357  0 param.setValue(metaParam.getDefaultValueString());
358    }else{
359  0 param.setValue(metaParam.getDefaultValueList());
360    }
361  0 params.add(param);
362    }
363    }
364    }
365   
366  0 sr.setParams(params);
367  0 sr.setSearchKey(meta.getSearchTypeId());
368  0 return sr;
369    }
370   
 
371  0 toggle @Override
372    public List<HasSearchParam> getSearchParams() {
373  0 return searchParams;
374    }
375   
376    }
377   
 
378    private interface HasSearchParam{
379    public SearchParam getSearchParam();
380    public String getFieldName();
381    public String getSearchText();
382    }
383   
 
384    private static class CustomLine extends Composite implements HasSearchParam{
385    private KSDropDown paramSelector = new KSDropDown();
386    private SimplePanel widgetPanel = new SimplePanel();
387    private Widget widget = null;
388    private String key;
389    private HorizontalBlockFlowPanel layout = new HorizontalBlockFlowPanel();
390    private ParamListItems listItems;
391   
 
392  0 toggle public CustomLine(LookupMetadata meta, final ParamListItems listItems){
393   
394  0 List<LookupParamMetadata> customParams = new ArrayList<LookupParamMetadata>();
395   
396  0 for (LookupParamMetadata lookupParamMetadata : listItems.getParams()) {
397  0 if (lookupParamMetadata.getWriteAccess() != WriteAccess.NEVER){
398  0 if (lookupParamMetadata.getUsage() == Usage.CUSTOM || lookupParamMetadata.getUsage() == Usage.ADVANCED_CUSTOM ) {
399  0 customParams.add(lookupParamMetadata);
400    }
401    }
402    }
403   
404  0 ParamListItems customParamList = new ParamListItems(customParams);
405   
406  0 this.listItems = customParamList;
407  0 paramSelector.setBlankFirstItem(false);
408  0 paramSelector.setListItems(customParamList);
409   
410  0 String id = meta.getParams().get(0).getKey();
411  0 paramSelector.selectItem(id);
412  0 widget = listItems.getWidget(id);
413  0 key = id;
414  0 widgetPanel.setWidget(widget);
415  0 paramSelector.addSelectionChangeHandler(new SelectionChangeHandler(){
416   
 
417  0 toggle @Override
418    public void onSelectionChange(SelectionChangeEvent event) {
419  0 String id = ((KSSelectItemWidgetAbstract)event.getWidget()).getSelectedItem();
420  0 widget = listItems.getWidget(id);
421  0 widgetPanel.setWidget(widget);
422  0 key = id;
423   
424    }
425    });
426  0 layout.add(paramSelector);
427  0 layout.add(widgetPanel);
428  0 this.initWidget(layout);
429    }
430   
 
431  0 toggle public SearchParam getSearchParam(){
432  0 return SearchPanel.getSearchParam(widget, key);
433    }
434   
 
435  0 toggle public String getKey(){
436  0 return key;
437    }
438   
 
439  0 toggle public String getFieldName(){
440  0 String id = paramSelector.getSelectedItem();
441  0 return listItems.getItemText(id);
442    }
443   
 
444  0 toggle @Override
445    public String getSearchText() {
446  0 return SearchPanel.getSearchText(widget);
447    }
448    }
449   
 
450    private class AdvancedSearch extends Composite implements SearchParametersWidget {
451    private LookupMetadata meta;
452    private List<HasSearchParam> searchParams = new ArrayList<HasSearchParam>();
453   
 
454  0 toggle public AdvancedSearch(final LookupMetadata meta){
455  0 VerticalPanel panel = new VerticalPanel();
456   
457  0 KSLabel instrLabel = new KSLabel();
458  0 panel.add(instrLabel);
459  0 this.meta = meta;
460   
461    //add widget for each search criteria to the advanced tab
462  0 boolean allFieldsRequired = true;
463  0 for(LookupParamMetadata param: meta.getParams()){
464   
465    //select only parameters shown on advanced search tab
466  0 if ((param.getUsage() != Usage.ADVANCED) && (param.getUsage() != Usage.ADVANCED_CUSTOM)) {
467  0 continue;
468    }
469   
470  0 if ((param.getWriteAccess() == WriteAccess.ALWAYS) || (param.getWriteAccess() == WriteAccess.REQUIRED)){
471  0 SearchField paramField = new SearchField(param);
472  0 searchFields.add(paramField);
473  0 panel.add(paramField);
474  0 searchParams.add(paramField);
475    }
476  0 else if (param.getWriteAccess() == WriteAccess.WHEN_NULL){
477  0 if(param.getDefaultValueString() == null && param.getDefaultValueList() == null){
478  0 SearchField paramField = new SearchField(param);
479  0 searchFields.add(paramField);
480  0 panel.add(paramField);
481  0 searchParams.add(paramField);
482    }
483    }
484   
485  0 if (param.getWriteAccess() != Metadata.WriteAccess.REQUIRED) {
486  0 allFieldsRequired = false;
487    }
488    }
489   
490    //do not show criteria instructions if we have only one criteria field or in case all fields are required
491  0 if ((searchFields.size() > 1) || (allFieldsRequired == false)) {
492  0 instrLabel.setText(criteriaInstructions);
493    }
494  0 this.addKeyDownHandler(downHandler);
495  0 this.initWidget(panel);
496    }
497   
 
498  0 toggle public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
499  0 return addDomHandler(handler, KeyDownEvent.getType());
500    }
501   
 
502  0 toggle public LookupMetadata getLookupMetadata() {
503  0 return meta;
504    }
505   
506    private KeyDownHandler downHandler = new KeyDownHandler(){
507   
 
508  0 toggle @Override
509    public void onKeyDown(KeyDownEvent event) {
510  0 if(event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) // Enter button
511  0 actionCancelCallback.exec(ButtonEnumerations.SearchCancelEnum.SEARCH);
512    }
513   
514    };
515   
 
516  0 toggle @Override
517    public SearchRequest getSearchRequest() {
518  0 SearchRequest sr = new SearchRequest();
519  0 List<SearchParam> params = new ArrayList<SearchParam>();
520  0 List<HasSearchParam> searchParams = getSearchParams();
521   
522    //initialize search parameters if user entered values into search criteria fields in UI
523   
524  0 for(HasSearchParam field: searchParams){
525  0 SearchParam param = field.getSearchParam();
526    //TODO is this null check needed here? probably. assuming string here
527    //TODO make check more robust here/inserting params more robust
528    //do not pass to the search parameters that are empty
529    //FIXME hack - comparison to 'optional' - replace with check against 'optional' field and update related lookup metadata
530  0 if ((param.getValue() != null) && ((param.getValue().toString().trim().isEmpty() == false) || (param.getKey().toLowerCase().indexOf("optional") == -1))) {
531  0 params.add(param);
532    }
533    }
534   
535    //initialize search parameters that are hidden from the UI because they are set to default context specific values
536  0 for(LookupParamMetadata metaParam: meta.getParams()){
537  0 if(metaParam.getWriteAccess() == WriteAccess.NEVER){
538  0 if ((metaParam.getDefaultValueString() == null || metaParam.getDefaultValueString().isEmpty())&&
539    (metaParam.getDefaultValueList() == null || metaParam.getDefaultValueList().isEmpty())) {
540    //FIXME throw an exception?
541  0 GWT.log("Key = " + metaParam.getKey() + " has write access NEVER but has no default value!", null);
542  0 continue;
543    }
544  0 SearchParam param = new SearchParam();
545  0 param.setKey(metaParam.getKey());
546  0 if(metaParam.getDefaultValueList()==null){
547  0 param.setValue(metaParam.getDefaultValueString());
548    }else{
549  0 param.setValue(metaParam.getDefaultValueList());
550    }
551  0 params.add(param);
552    }
553  0 else if(metaParam.getWriteAccess() == WriteAccess.WHEN_NULL){
554  0 if((metaParam.getDefaultValueString() != null && !metaParam.getDefaultValueString().isEmpty())||
555    (metaParam.getDefaultValueList() != null && !metaParam.getDefaultValueList().isEmpty())){
556  0 SearchParam param = new SearchParam();
557  0 param.setKey(metaParam.getKey());
558  0 if(metaParam.getDefaultValueList()==null){
559  0 param.setValue(metaParam.getDefaultValueString());
560    }else{
561  0 param.setValue(metaParam.getDefaultValueList());
562    }
563  0 params.add(param);
564    }
565    }
566    }
567  0 sr.setParams(params);
568  0 if (meta.getResultSortKey() != null) {
569  0 sr.setSortColumn(meta.getResultSortKey());
570    }
571  0 sr.setSearchKey(meta.getSearchTypeId());
572  0 return sr;
573    }
574   
 
575  0 toggle @Override
576    public List<HasSearchParam> getSearchParams() {
577  0 return searchParams;
578    }
579    }
580   
 
581    private class SearchField extends Composite implements HasSearchParam{
582   
583    private Widget widget = null;
584    private LookupParamMetadata meta = null;
585    private VerticalFlowPanel panel = new VerticalFlowPanel();
586    private String fieldName;
587   
 
588  0 toggle public SearchParam getSearchParam(){
589  0 return SearchPanel.getSearchParam(widget, meta.getKey());
590    }
591   
 
592  0 toggle public SearchField(LookupParamMetadata param){
593  0 meta = param;
594    //TODO use message call here
595  0 fieldName = param.getName();
596  0 widget = DefaultWidgetFactory.getInstance().getWidget(param);
597  0 if(param.getDefaultValueString() != null){
598    //TODO Add handling of default value lists here
599  0 if(widget instanceof HasText){
600  0 ((HasText) widget).setText(param.getDefaultValueString().toString());
601    }
602  0 else if(widget instanceof HasValue){
603  0 ((HasValue) widget).setValue(param.getDefaultValueString());
604    }
605    }
606   
607    //FIXME: remove because required field '*' indication will be part of FieldElement class
608  0 if (param.getWriteAccess() == Metadata.WriteAccess.REQUIRED) {
609  0 fieldName += " *";
610    }
611   
612  0 FieldElement fieldElement = new FieldElement(fieldName, widget);
613  0 fieldElement.getTitleWidget().addStyleName("KS-Picker-Criteria-Text");
614  0 panel.add(fieldElement);
615  0 panel.addStyleName("clearfix");
616   
617  0 this.initWidget(panel);
618    }
619   
 
620  0 toggle public Widget getFieldPanel(){
621  0 return panel;
622    }
623   
 
624  0 toggle public String getFieldName() {
625  0 return fieldName;
626    }
627   
 
628  0 toggle @Override
629    public String getSearchText() {
630  0 return SearchPanel.getSearchText(widget);
631    }
632    }
633   
 
634  0 toggle private static SearchParam getSearchParam(final Widget widget, String key){
635  0 SearchParam param = new SearchParam();
636  0 param.setKey(key);
637  0 if(widget instanceof HasText){
638  0 param.setValue(((HasText) widget).getText());
639    }
640  0 else if(widget instanceof HasValue){
641  0 Object value = ((HasValue) widget).getValue();
642  0 if(value != null){
643    //TODO need to handle date and other types here, how they are converted for search, etc
644  0 if(value instanceof String){
645  0 param.setValue((String)value);
646    }
647    else{
648  0 param.setValue(value.toString());
649  0 GWT.log("Fields in search probably(?) shouldnt have values other than string", null);
650    }
651    }
652    }
653  0 else if (widget instanceof KSPicker){
654  0 KSPicker pickerWidget = (KSPicker)widget;
655  0 String pickerValue = pickerWidget.getValue().toString();
656  0 if (UtilConstants.IMPOSSIBLE_CHARACTERS.equals(pickerValue)){
657  0 SuggestBox suggestBox = (SuggestBox)pickerWidget.getInputWidget();
658  0 pickerValue = suggestBox.getText();
659    }
660   
661  0 param.setValue(pickerValue);
662    }
663    else {
664  0 param.setValue("");
665    }
666   
667  0 return param;
668    }
669   
 
670  0 toggle private static String getSearchText(final Widget widget){
671  0 if(widget instanceof HasText){
672  0 return ((HasText) widget).getText();
673    }
674  0 else if(widget instanceof HasValue){
675  0 Object value = ((HasValue) widget).getValue();
676  0 if(value != null){
677    //TODO need to handle date and other types here, how they are converted for search, etc
678  0 if(value instanceof String){
679  0 return (String)value;
680    }
681    else{
682  0 GWT.log("Fields in search probably(?) shouldnt have values other than string", null);
683  0 return value.toString();
684    }
685    }
686    }
687  0 else if (widget instanceof KSPicker){
688  0 return ((KSPicker)widget).getDisplayValue();
689    }
690  0 return "";
691    }
692   
 
693  0 toggle private void showCriteriaChosen(List<HasSearchParam> fields){
694  0 enteredCriteriaString.clear();
695  0 boolean first = true;;
696  0 for(HasSearchParam field: fields){
697  0 String name = field.getFieldName();
698  0 String value = field.getSearchText();
699  0 if(!value.isEmpty()&&value.equals("$$##@@"))
700  0 value = field.getSearchParam().getValue().toString().toUpperCase();
701  0 if(!value.isEmpty()){
702  0 HTMLPanel label = new HTMLPanel(name + ": <b>" + value + "</b>&nbsp;");
703  0 if (!first) {
704  0 label.addStyleName("KS-Advanced-Search-Search-Criteria-Text");
705    }
706  0 enteredCriteriaString.add(label);
707  0 first = false;
708    }
709    }
710    }
711   
 
712  0 toggle public List<String> getSelectedIds(){
713  0 List<String> ids = new ArrayList<String>();
714  0 if(table != null){
715  0 ids = table.getSelectedIds();
716    }
717  0 return ids;
718    }
719   
 
720  0 toggle public List<SelectedResults> getSelectedValues() {
721   
722  0 List<SelectedResults> selectedValues = new ArrayList<SelectedResults>();
723  0 if (table != null) {
724  0 List<ResultRow> selectedRows = table.getSelectedRows();
725  0 for (ResultRow row : selectedRows) {
726  0 String displayKey = row.getValue(activeSearchParametersWidget.getLookupMetadata().getResultDisplayKey());
727  0 String returnKey = row.getValue(activeSearchParametersWidget.getLookupMetadata().getResultReturnKey());
728  0 selectedValues.add(new SelectedResults(displayKey, returnKey, row));
729  0 if (multiSelect == false) {
730  0 break;
731    }
732    }
733    }
734   
735  0 return selectedValues;
736    }
737   
 
738  0 toggle public boolean isMultiSelect() {
739  0 return multiSelect;
740    }
741   
 
742  0 toggle public void setMultiSelect(boolean multiSelect) {
743  0 this.multiSelect = multiSelect;
744    }
745   
 
746    private static class ParamListItems implements ListItems{
747   
748    private List<LookupParamMetadata> params = new ArrayList<LookupParamMetadata>();
749   
 
750  0 toggle public ParamListItems(LookupMetadata meta){
751  0 params = meta.getParams();
752    }
753   
 
754  0 toggle public ParamListItems(List<LookupParamMetadata> params){
755  0 this.params = params;
756    }
757   
 
758  0 toggle @Override
759    public List<String> getAttrKeys() {
760  0 return new ArrayList<String>();
761    }
762   
 
763  0 toggle @Override
764    public String getItemAttribute(String id, String attrkey) {
765  0 return "";
766    }
767   
 
768  0 toggle @Override
769    public int getItemCount() {
770  0 return params.size();
771    }
772   
 
773  0 toggle @Override
774    public List<String> getItemIds() {
775  0 List<String> ids = new ArrayList<String>();
776  0 for(LookupParamMetadata param: params){
777  0 ids.add(param.getKey());
778    }
779  0 return ids;
780    }
781   
 
782  0 toggle @Override
783    public String getItemText(String id) {
784  0 String itemText = id;
785  0 for(LookupParamMetadata param: params){
786  0 if(param.getKey().equals(id)){
787    //TODO this should be a message key
788  0 itemText = param.getName();
789  0 break;
790    }
791    }
792  0 return itemText;
793    }
794   
 
795  0 toggle public Widget getWidget(String id){
796  0 Widget w = null;
797  0 for(LookupParamMetadata param: params){
798  0 if(param.getKey().equals(id)){
799  0 w = DefaultWidgetFactory.getInstance().getWidget(param);
800  0 break;
801    }
802    }
803  0 return w;
804    }
805   
 
806  0 toggle public List<LookupParamMetadata> getParams() {
807  0 return params;
808    }
809    }
810   
 
811  0 toggle private String getMessage(final String msgKey) {
812  0 return Application.getApplicationContext().getMessage(msgKey);
813    }
814   
 
815  0 toggle public void addLookupChangedCallback(Callback<LookupMetadata> callback) {
816  0 lookupChangedCallbacks.add(callback);
817    }
818   
819    //FIXME: Is an action complete callback really necessary here, couldn't this simply be a method to perform the seach action.
 
820  0 toggle public Callback<Boolean> getActionCompleteCallback() {
821  0 return new Callback<Boolean>() {
822   
 
823  0 toggle @Override
824    public void exec(Boolean result) {
825   
826  0 if (resultsSelected == true) {
827  0 List<SelectedResults> selectedItems = getSelectedValues();
828  0 if (selectedItems.isEmpty())
829  0 Window.alert("Please, select a value");
830    else
831    {
832  0 for(Callback<List<SelectedResults>> callback: selectedCompleteCallbacks){
833  0 callback.exec(selectedItems);
834    }
835  0 return;
836    }
837    }
838   
839  0 actionCancelButtons.setButtonText(ButtonEnumerations.SearchCancelEnum.SEARCH, getMessage("select"));
840  0 resultsSelected = true;
841   
842  0 SearchRequest sr = getSearchRequest();
843  0 table.performSearch(sr, activeSearchParametersWidget.getLookupMetadata().getResults(), activeSearchParametersWidget.getLookupMetadata().getResultReturnKey());
844  0 resultsTablePanel.setVisible(true);
845  0 List<HasSearchParam> userCriteria = new ArrayList<HasSearchParam>();
846  0 List<HasSearchParam> searchParams = activeSearchParametersWidget.getSearchParams();
847   
848    //initialize search parameters if user entered values into search criteria fields in UI
849  0 for(HasSearchParam field: searchParams){
850  0 SearchParam param = field.getSearchParam();
851    //TODO is this null check needed here? probably. assuming string here
852    //TODO make check more robust here/inserting params more robust
853    //do not pass to the search parameters that are empty
854    //FIXME hack - comparison to 'optional' - replace with check against 'optional' field and update related lookup metadata
855  0 if ((param.getValue() != null) && ((param.getValue().toString().trim().isEmpty() == false) || (param.getKey().toLowerCase().indexOf("optional") == -1))) {
856  0 userCriteria.add(field);
857    }
858    }
859  0 showCriteriaChosen(userCriteria);
860   
861  0 if (hasSearchParams){
862    //Only display modify link if there are search parametes available.
863  0 if(!resultsShown){
864  0 searchSelectorPanel.removeFromParent();
865  0 modifySearchPanel = new CollapsablePanel(getMessage("searchPanelModifySearch"), searchSelectorPanel, false);
866  0 modifySearchPanel.getLabel().addClickHandler(new ClickHandler(){
 
867  0 toggle @Override
868    public void onClick(ClickEvent event) {
869  0 resultsTablePanel.setVisible(false);
870  0 actionCancelButtons.setButtonText(ButtonEnumerations.SearchCancelEnum.SEARCH, getActionLabel());
871  0 resultsSelected = false;
872    }});
873  0 SearchPanel.this.layout.insert(modifySearchPanel, 0);
874   
875    }
876    else{
877  0 modifySearchPanel.close();
878    }
879    }
880  0 resultsShown = true;
881   
882  0 for(Callback<Boolean> callback: actionCompletedCallbacks){
883  0 callback.exec( Boolean.valueOf(true));
884    }
885    }
886    };
887    }
888   
 
889  0 toggle public SearchRequest getSearchRequest() {
890  0 if (activeSearchParametersWidget != null) {
891  0 return activeSearchParametersWidget.getSearchRequest();
892    }
893  0 return null;
894    }
895   
 
896  0 toggle public void setActionCancelButtonGroup(ActionCancelGroup actionCancelButtons) {
897  0 this.actionCancelButtons = actionCancelButtons;
898    }
899   
 
900  0 toggle public String getSelectedLookupName() {
901  0 return selectedLookupName;
902    }
903   
 
904  0 toggle public void setSelectedLookupName(String selectedLookupName) {
905  0 this.selectedLookupName = selectedLookupName;
906    }
907   
 
908  0 toggle public void addSelectionCompleteCallback(Callback<List<SelectedResults>> callback){
909  0 selectedCompleteCallbacks.add(callback);
910    }
911   
 
912  0 toggle public void addActionCompleteCallback(Callback<Boolean> callback){
913  0 actionCompletedCallbacks.add(callback);
914    }
915   
 
916  0 toggle public String getActionLabel() {
917  0 return actionLabel;
918    }
919   
 
920  0 toggle public void setActionLabel(String actionLabel) {
921  0 if ((actionLabel != null) && (actionLabel.trim().length() > 0)) {
922  0 this.actionLabel = actionLabel;
923    }
924    }
925   
926    }