Clover Coverage Report - Kuali Student 1.2-M5-SNAPSHOT (Aggregated)
Coverage timestamp: Mon Aug 29 2011 05:04:27 EDT
../../../../../../../../img/srcFileCovDistChart0.png 42% of files have more coverage
369   924   148   5.86
126   736   0.4   7
63     2.35  
9    
 
  SearchPanel       Line # 69 192 0% 70 290 0% 0.0
  SearchPanel.SearchStyle       Line # 82 0 - 0 0 - -1.0
  SearchPanel.SearchParametersWidget       Line # 114 0 - 0 0 - -1.0
  SearchPanel.CustomizedSearch       Line # 273 48 0% 16 67 0% 0.0
  SearchPanel.HasSearchParam       Line # 376 0 - 0 0 - -1.0
  SearchPanel.CustomLine       Line # 382 27 0% 9 37 0% 0.0
  SearchPanel.AdvancedSearch       Line # 448 61 0% 33 97 0% 0.0
  SearchPanel.SearchField       Line # 579 19 0% 9 32 0% 0.0
  SearchPanel.ParamListItems       Line # 744 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   
148  0 resultsTablePanel.clear();
149  0 layout.clear();
150  0 resultsShown = 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() == Usage.CUSTOM) || (metaParam.getUsage() == Usage.ADVANCED_CUSTOM)) {
242  0 hasSearchParams = true;
243   
244  0 final CustomizedSearch customizedSearch = new CustomizedSearch(meta, listItems);
245  0 KSButton button = panel.addLinkToPanel(SearchStyle.ADVANCED, getMessage("searchPanelCustomizeSearch"), SearchStyle.CUSTOM);
246  0 button.addClickHandler(new ClickHandler(){
247   
 
248  0 toggle @Override
249    public void onClick(ClickEvent event) {
250  0 resultsTablePanel.setVisible(false);
251  0 activeSearchParametersWidget = customizedSearch;
252    }});
253  0 button.addStyleName("KS-Advanced-Search-Link");
254  0 button.getParent().addStyleName("clearfix");
255  0 panel.addPanel(SearchStyle.CUSTOM, customizedSearch);
256  0 button = panel.addLinkToPanel(SearchStyle.CUSTOM, getMessage("searchPanelReturnToAdvancedSearch"), SearchStyle.ADVANCED);
257  0 button.addClickHandler(new ClickHandler(){
258   
 
259  0 toggle @Override
260    public void onClick(ClickEvent event) {
261  0 resultsTablePanel.setVisible(false);
262  0 activeSearchParametersWidget = advancedSearch;
263    }});
264  0 button.addStyleName("KS-Advanced-Search-Link");
265  0 button.getParent().addStyleName("clearfix");
266  0 break;
267    }
268    }
269   
270  0 return panel;
271    }
272   
 
273    private class CustomizedSearch extends Composite implements SearchParametersWidget {
274   
275    private List<CustomLine> lines = new ArrayList<CustomLine>();
276    private List<HasSearchParam> searchParams = new ArrayList<HasSearchParam>();
277    private VerticalPanel layout = new VerticalPanel();
278    private VerticalPanel linePanel = new VerticalPanel();
279    private LookupMetadata meta;
280   
 
281  0 toggle public CustomizedSearch(final LookupMetadata meta, final ParamListItems listItems){
282   
283  0 KSLabel instrLabel = new KSLabel(criteriaInstructions);
284  0 layout.add(instrLabel);
285   
286  0 layout.add(linePanel);
287  0 CustomLine line = new CustomLine(meta, listItems);
288  0 line.addStyleName("ks-form-module-single-line-margin");
289  0 linePanel.add(line);
290  0 lines.add(line);
291  0 searchParams.add(line);
292  0 this.meta = meta;
293   
294  0 KSButton addCriteria = new KSButton(getMessage("searchPanelAddCriteria"), ButtonStyle.SECONDARY);
295  0 addCriteria.addClickHandler(new ClickHandler(){
296   
 
297  0 toggle @Override
298    public void onClick(ClickEvent event) {
299  0 CustomLine line = new CustomLine(meta, listItems);
300  0 line.addStyleName("ks-form-module-single-line-margin");
301  0 linePanel.add(line);
302  0 lines.add(line);
303  0 searchParams.add(line);
304    }
305    });
306   
307  0 addCriteria.addStyleName("ks-form-module-single-line-margin");
308  0 layout.add(addCriteria);
309   
310  0 this.initWidget(layout);
311    }
312   
 
313  0 toggle public LookupMetadata getLookupMetadata() {
314  0 return meta;
315    }
316   
 
317  0 toggle @Override
318    public SearchRequest getSearchRequest() {
319    //Create search request and then pass it to the table
320    //TODO pass search to the table
321  0 SearchRequest sr = new SearchRequest();
322  0 List<SearchParam> params = new ArrayList<SearchParam>();
323  0 for(CustomLine field: lines){
324  0 SearchParam param = field.getSearchParam();
325    //TODO is this check needed here? probably. assuming string here
326  0 if((param.getValue() != null)){
327  0 params.add(param);
328    }
329    }
330   
331    //add search criteria widgets to the custom tab
332  0 for(LookupParamMetadata metaParam: meta.getParams()){
333   
334    //select only parameters shown on custom search tab
335  0 if ((metaParam.getUsage() != Usage.CUSTOM) && (metaParam.getUsage() != Usage.ADVANCED_CUSTOM)) {
336  0 continue;
337    }
338   
339  0 if(metaParam.getWriteAccess() == WriteAccess.NEVER){
340  0 SearchParam param = new SearchParam();
341  0 param.setKey(metaParam.getKey());
342  0 if(metaParam.getDefaultValueList()==null){
343  0 param.setValue(metaParam.getDefaultValueString());
344    }else{
345  0 param.setValue(metaParam.getDefaultValueList());
346    }
347  0 params.add(param);
348    }
349  0 else if(metaParam.getWriteAccess() == WriteAccess.WHEN_NULL){
350  0 if((metaParam.getDefaultValueString() != null && !metaParam.getDefaultValueString().isEmpty())||
351    (metaParam.getDefaultValueList() != null && !metaParam.getDefaultValueList().isEmpty())){
352  0 SearchParam param = new SearchParam();
353  0 param.setKey(metaParam.getKey());
354  0 if(metaParam.getDefaultValueList()==null){
355  0 param.setValue(metaParam.getDefaultValueString());
356    }else{
357  0 param.setValue(metaParam.getDefaultValueList());
358    }
359  0 params.add(param);
360    }
361    }
362    }
363   
364  0 sr.setParams(params);
365  0 sr.setSearchKey(meta.getSearchTypeId());
366  0 return sr;
367    }
368   
 
369  0 toggle @Override
370    public List<HasSearchParam> getSearchParams() {
371  0 return searchParams;
372    }
373   
374    }
375   
 
376    private interface HasSearchParam{
377    public SearchParam getSearchParam();
378    public String getFieldName();
379    public String getSearchText();
380    }
381   
 
382    private static class CustomLine extends Composite implements HasSearchParam{
383    private KSDropDown paramSelector = new KSDropDown();
384    private SimplePanel widgetPanel = new SimplePanel();
385    private Widget widget = null;
386    private String key;
387    private HorizontalBlockFlowPanel layout = new HorizontalBlockFlowPanel();
388    private ParamListItems listItems;
389   
 
390  0 toggle public CustomLine(LookupMetadata meta, final ParamListItems listItems){
391   
392  0 List<LookupParamMetadata> customParams = new ArrayList<LookupParamMetadata>();
393   
394  0 for (LookupParamMetadata lookupParamMetadata : listItems.getParams()) {
395  0 if (lookupParamMetadata.getWriteAccess() != WriteAccess.NEVER){
396  0 if (lookupParamMetadata.getUsage() == Usage.CUSTOM || lookupParamMetadata.getUsage() == Usage.ADVANCED_CUSTOM ) {
397  0 customParams.add(lookupParamMetadata);
398    }
399    }
400    }
401   
402  0 ParamListItems customParamList = new ParamListItems(customParams);
403   
404  0 this.listItems = customParamList;
405  0 paramSelector.setBlankFirstItem(false);
406  0 paramSelector.setListItems(customParamList);
407   
408  0 String id = meta.getParams().get(0).getKey();
409  0 paramSelector.selectItem(id);
410  0 widget = listItems.getWidget(id);
411  0 key = id;
412  0 widgetPanel.setWidget(widget);
413  0 paramSelector.addSelectionChangeHandler(new SelectionChangeHandler(){
414   
 
415  0 toggle @Override
416    public void onSelectionChange(SelectionChangeEvent event) {
417  0 String id = ((KSSelectItemWidgetAbstract)event.getWidget()).getSelectedItem();
418  0 widget = listItems.getWidget(id);
419  0 widgetPanel.setWidget(widget);
420  0 key = id;
421   
422    }
423    });
424  0 layout.add(paramSelector);
425  0 layout.add(widgetPanel);
426  0 this.initWidget(layout);
427    }
428   
 
429  0 toggle public SearchParam getSearchParam(){
430  0 return SearchPanel.getSearchParam(widget, key);
431    }
432   
 
433  0 toggle public String getKey(){
434  0 return key;
435    }
436   
 
437  0 toggle public String getFieldName(){
438  0 String id = paramSelector.getSelectedItem();
439  0 return listItems.getItemText(id);
440    }
441   
 
442  0 toggle @Override
443    public String getSearchText() {
444  0 return SearchPanel.getSearchText(widget);
445    }
446    }
447   
 
448    private class AdvancedSearch extends Composite implements SearchParametersWidget {
449    private LookupMetadata meta;
450    private List<HasSearchParam> searchParams = new ArrayList<HasSearchParam>();
451   
 
452  0 toggle public AdvancedSearch(final LookupMetadata meta){
453  0 VerticalPanel panel = new VerticalPanel();
454   
455  0 KSLabel instrLabel = new KSLabel();
456  0 panel.add(instrLabel);
457  0 this.meta = meta;
458   
459    //add widget for each search criteria to the advanced tab
460  0 boolean allFieldsRequired = true;
461  0 for(LookupParamMetadata param: meta.getParams()){
462   
463    //select only parameters shown on advanced search tab
464  0 if ((param.getUsage() != Usage.ADVANCED) && (param.getUsage() != Usage.ADVANCED_CUSTOM)) {
465  0 continue;
466    }
467   
468  0 if ((param.getWriteAccess() == WriteAccess.ALWAYS) || (param.getWriteAccess() == WriteAccess.REQUIRED)){
469  0 SearchField paramField = new SearchField(param);
470  0 searchFields.add(paramField);
471  0 panel.add(paramField);
472  0 searchParams.add(paramField);
473    }
474  0 else if (param.getWriteAccess() == WriteAccess.WHEN_NULL){
475  0 if(param.getDefaultValueString() == null && param.getDefaultValueList() == null){
476  0 SearchField paramField = new SearchField(param);
477  0 searchFields.add(paramField);
478  0 panel.add(paramField);
479  0 searchParams.add(paramField);
480    }
481    }
482   
483  0 if (param.getWriteAccess() != Metadata.WriteAccess.REQUIRED) {
484  0 allFieldsRequired = false;
485    }
486    }
487   
488    //do not show criteria instructions if we have only one criteria field or in case all fields are required
489  0 if ((searchFields.size() > 1) || (allFieldsRequired == false)) {
490  0 instrLabel.setText(criteriaInstructions);
491    }
492  0 this.addKeyDownHandler(downHandler);
493  0 this.initWidget(panel);
494    }
495   
 
496  0 toggle public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
497  0 return addDomHandler(handler, KeyDownEvent.getType());
498    }
499   
 
500  0 toggle public LookupMetadata getLookupMetadata() {
501  0 return meta;
502    }
503   
504    private KeyDownHandler downHandler = new KeyDownHandler(){
505   
 
506  0 toggle @Override
507    public void onKeyDown(KeyDownEvent event) {
508  0 if(event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) // Enter button
509  0 actionCancelCallback.exec(ButtonEnumerations.SearchCancelEnum.SEARCH);
510    }
511   
512    };
513   
 
514  0 toggle @Override
515    public SearchRequest getSearchRequest() {
516  0 SearchRequest sr = new SearchRequest();
517  0 List<SearchParam> params = new ArrayList<SearchParam>();
518  0 List<HasSearchParam> searchParams = getSearchParams();
519   
520    //initialize search parameters if user entered values into search criteria fields in UI
521   
522  0 for(HasSearchParam field: searchParams){
523  0 SearchParam param = field.getSearchParam();
524    //TODO is this null check needed here? probably. assuming string here
525    //TODO make check more robust here/inserting params more robust
526    //do not pass to the search parameters that are empty
527    //FIXME hack - comparison to 'optional' - replace with check against 'optional' field and update related lookup metadata
528  0 if ((param.getValue() != null) && ((param.getValue().toString().trim().isEmpty() == false) || (param.getKey().toLowerCase().indexOf("optional") == -1))) {
529  0 params.add(param);
530    }
531    }
532   
533    //initialize search parameters that are hidden from the UI because they are set to default context specific values
534  0 for(LookupParamMetadata metaParam: meta.getParams()){
535  0 if(metaParam.getWriteAccess() == WriteAccess.NEVER){
536  0 if ((metaParam.getDefaultValueString() == null || metaParam.getDefaultValueString().isEmpty())&&
537    (metaParam.getDefaultValueList() == null || metaParam.getDefaultValueList().isEmpty())) {
538    //FIXME throw an exception?
539  0 GWT.log("Key = " + metaParam.getKey() + " has write access NEVER but has no default value!", null);
540  0 continue;
541    }
542  0 SearchParam param = new SearchParam();
543  0 param.setKey(metaParam.getKey());
544  0 if(metaParam.getDefaultValueList()==null){
545  0 param.setValue(metaParam.getDefaultValueString());
546    }else{
547  0 param.setValue(metaParam.getDefaultValueList());
548    }
549  0 params.add(param);
550    }
551  0 else if(metaParam.getWriteAccess() == WriteAccess.WHEN_NULL){
552  0 if((metaParam.getDefaultValueString() != null && !metaParam.getDefaultValueString().isEmpty())||
553    (metaParam.getDefaultValueList() != null && !metaParam.getDefaultValueList().isEmpty())){
554  0 SearchParam param = new SearchParam();
555  0 param.setKey(metaParam.getKey());
556  0 if(metaParam.getDefaultValueList()==null){
557  0 param.setValue(metaParam.getDefaultValueString());
558    }else{
559  0 param.setValue(metaParam.getDefaultValueList());
560    }
561  0 params.add(param);
562    }
563    }
564    }
565  0 sr.setParams(params);
566  0 if (meta.getResultSortKey() != null) {
567  0 sr.setSortColumn(meta.getResultSortKey());
568    }
569  0 sr.setSearchKey(meta.getSearchTypeId());
570  0 return sr;
571    }
572   
 
573  0 toggle @Override
574    public List<HasSearchParam> getSearchParams() {
575  0 return searchParams;
576    }
577    }
578   
 
579    private class SearchField extends Composite implements HasSearchParam{
580   
581    private Widget widget = null;
582    private LookupParamMetadata meta = null;
583    private VerticalFlowPanel panel = new VerticalFlowPanel();
584    private String fieldName;
585   
 
586  0 toggle public SearchParam getSearchParam(){
587  0 return SearchPanel.getSearchParam(widget, meta.getKey());
588    }
589   
 
590  0 toggle public SearchField(LookupParamMetadata param){
591  0 meta = param;
592    //TODO use message call here
593  0 fieldName = param.getName();
594  0 widget = DefaultWidgetFactory.getInstance().getWidget(param);
595  0 if(param.getDefaultValueString() != null){
596    //TODO Add handling of default value lists here
597  0 if(widget instanceof HasText){
598  0 ((HasText) widget).setText(param.getDefaultValueString().toString());
599    }
600  0 else if(widget instanceof HasValue){
601  0 ((HasValue) widget).setValue(param.getDefaultValueString());
602    }
603    }
604   
605    //FIXME: remove because required field '*' indication will be part of FieldElement class
606  0 if (param.getWriteAccess() == Metadata.WriteAccess.REQUIRED) {
607  0 fieldName += " *";
608    }
609   
610  0 FieldElement fieldElement = new FieldElement(fieldName, widget);
611  0 fieldElement.getTitleWidget().addStyleName("KS-Picker-Criteria-Text");
612  0 panel.add(fieldElement);
613  0 panel.addStyleName("clearfix");
614   
615  0 this.initWidget(panel);
616    }
617   
 
618  0 toggle public Widget getFieldPanel(){
619  0 return panel;
620    }
621   
 
622  0 toggle public String getFieldName() {
623  0 return fieldName;
624    }
625   
 
626  0 toggle @Override
627    public String getSearchText() {
628  0 return SearchPanel.getSearchText(widget);
629    }
630    }
631   
 
632  0 toggle private static SearchParam getSearchParam(final Widget widget, String key){
633  0 SearchParam param = new SearchParam();
634  0 param.setKey(key);
635  0 if(widget instanceof HasText){
636  0 param.setValue(((HasText) widget).getText());
637    }
638  0 else if(widget instanceof HasValue){
639  0 Object value = ((HasValue) widget).getValue();
640  0 if(value != null){
641    //TODO need to handle date and other types here, how they are converted for search, etc
642  0 if(value instanceof String){
643  0 param.setValue((String)value);
644    }
645    else{
646  0 param.setValue(value.toString());
647  0 GWT.log("Fields in search probably(?) shouldnt have values other than string", null);
648    }
649    }
650    }
651  0 else if (widget instanceof KSPicker){
652  0 KSPicker pickerWidget = (KSPicker)widget;
653  0 String pickerValue = pickerWidget.getValue().toString();
654  0 if (UtilConstants.IMPOSSIBLE_CHARACTERS.equals(pickerValue)){
655  0 SuggestBox suggestBox = (SuggestBox)pickerWidget.getInputWidget();
656  0 pickerValue = suggestBox.getText();
657    }
658   
659  0 param.setValue(pickerValue);
660    }
661    else {
662  0 param.setValue("");
663    }
664   
665  0 return param;
666    }
667   
 
668  0 toggle private static String getSearchText(final Widget widget){
669  0 if(widget instanceof HasText){
670  0 return ((HasText) widget).getText();
671    }
672  0 else if(widget instanceof HasValue){
673  0 Object value = ((HasValue) widget).getValue();
674  0 if(value != null){
675    //TODO need to handle date and other types here, how they are converted for search, etc
676  0 if(value instanceof String){
677  0 return (String)value;
678    }
679    else{
680  0 GWT.log("Fields in search probably(?) shouldnt have values other than string", null);
681  0 return value.toString();
682    }
683    }
684    }
685  0 else if (widget instanceof KSPicker){
686  0 return ((KSPicker)widget).getDisplayValue();
687    }
688  0 return "";
689    }
690   
 
691  0 toggle private void showCriteriaChosen(List<HasSearchParam> fields){
692  0 enteredCriteriaString.clear();
693  0 boolean first = true;;
694  0 for(HasSearchParam field: fields){
695  0 String name = field.getFieldName();
696  0 String value = field.getSearchText();
697  0 if(!value.isEmpty()&&value.equals("$$##@@"))
698  0 value = field.getSearchParam().getValue().toString().toUpperCase();
699  0 if(!value.isEmpty()){
700  0 HTMLPanel label = new HTMLPanel(name + ": <b>" + value + "</b>&nbsp;");
701  0 if (!first) {
702  0 label.addStyleName("KS-Advanced-Search-Search-Criteria-Text");
703    }
704  0 enteredCriteriaString.add(label);
705  0 first = false;
706    }
707    }
708    }
709   
 
710  0 toggle public List<String> getSelectedIds(){
711  0 List<String> ids = new ArrayList<String>();
712  0 if(table != null){
713  0 ids = table.getSelectedIds();
714    }
715  0 return ids;
716    }
717   
 
718  0 toggle public List<SelectedResults> getSelectedValues() {
719   
720  0 List<SelectedResults> selectedValues = new ArrayList<SelectedResults>();
721  0 if (table != null) {
722  0 List<ResultRow> selectedRows = table.getSelectedRows();
723  0 for (ResultRow row : selectedRows) {
724  0 String displayKey = row.getValue(activeSearchParametersWidget.getLookupMetadata().getResultDisplayKey());
725  0 String returnKey = row.getValue(activeSearchParametersWidget.getLookupMetadata().getResultReturnKey());
726  0 selectedValues.add(new SelectedResults(displayKey, returnKey, row));
727  0 if (multiSelect == false) {
728  0 break;
729    }
730    }
731    }
732   
733  0 return selectedValues;
734    }
735   
 
736  0 toggle public boolean isMultiSelect() {
737  0 return multiSelect;
738    }
739   
 
740  0 toggle public void setMultiSelect(boolean multiSelect) {
741  0 this.multiSelect = multiSelect;
742    }
743   
 
744    private static class ParamListItems implements ListItems{
745   
746    private List<LookupParamMetadata> params = new ArrayList<LookupParamMetadata>();
747   
 
748  0 toggle public ParamListItems(LookupMetadata meta){
749  0 params = meta.getParams();
750    }
751   
 
752  0 toggle public ParamListItems(List<LookupParamMetadata> params){
753  0 this.params = params;
754    }
755   
 
756  0 toggle @Override
757    public List<String> getAttrKeys() {
758  0 return new ArrayList<String>();
759    }
760   
 
761  0 toggle @Override
762    public String getItemAttribute(String id, String attrkey) {
763  0 return "";
764    }
765   
 
766  0 toggle @Override
767    public int getItemCount() {
768  0 return params.size();
769    }
770   
 
771  0 toggle @Override
772    public List<String> getItemIds() {
773  0 List<String> ids = new ArrayList<String>();
774  0 for(LookupParamMetadata param: params){
775  0 ids.add(param.getKey());
776    }
777  0 return ids;
778    }
779   
 
780  0 toggle @Override
781    public String getItemText(String id) {
782  0 String itemText = id;
783  0 for(LookupParamMetadata param: params){
784  0 if(param.getKey().equals(id)){
785    //TODO this should be a message key
786  0 itemText = param.getName();
787  0 break;
788    }
789    }
790  0 return itemText;
791    }
792   
 
793  0 toggle public Widget getWidget(String id){
794  0 Widget w = null;
795  0 for(LookupParamMetadata param: params){
796  0 if(param.getKey().equals(id)){
797  0 w = DefaultWidgetFactory.getInstance().getWidget(param);
798  0 break;
799    }
800    }
801  0 return w;
802    }
803   
 
804  0 toggle public List<LookupParamMetadata> getParams() {
805  0 return params;
806    }
807    }
808   
 
809  0 toggle private String getMessage(final String msgKey) {
810  0 return Application.getApplicationContext().getMessage(msgKey);
811    }
812   
 
813  0 toggle public void addLookupChangedCallback(Callback<LookupMetadata> callback) {
814  0 lookupChangedCallbacks.add(callback);
815    }
816   
817    //FIXME: Is an action complete callback really necessary here, couldn't this simply be a method to perform the seach action.
 
818  0 toggle public Callback<Boolean> getActionCompleteCallback() {
819  0 return new Callback<Boolean>() {
820   
 
821  0 toggle @Override
822    public void exec(Boolean result) {
823   
824  0 if (resultsSelected == true) {
825  0 List<SelectedResults> selectedItems = getSelectedValues();
826  0 if (selectedItems.isEmpty())
827  0 Window.alert("Please, select a value");
828    else
829    {
830  0 for(Callback<List<SelectedResults>> callback: selectedCompleteCallbacks){
831  0 callback.exec(selectedItems);
832    }
833  0 return;
834    }
835    }
836   
837  0 actionCancelButtons.setButtonText(ButtonEnumerations.SearchCancelEnum.SEARCH, getMessage("select"));
838  0 resultsSelected = true;
839   
840  0 SearchRequest sr = getSearchRequest();
841  0 table.performSearch(sr, activeSearchParametersWidget.getLookupMetadata().getResults(), activeSearchParametersWidget.getLookupMetadata().getResultReturnKey());
842  0 resultsTablePanel.setVisible(true);
843  0 List<HasSearchParam> userCriteria = new ArrayList<HasSearchParam>();
844  0 List<HasSearchParam> searchParams = activeSearchParametersWidget.getSearchParams();
845   
846    //initialize search parameters if user entered values into search criteria fields in UI
847  0 for(HasSearchParam field: searchParams){
848  0 SearchParam param = field.getSearchParam();
849    //TODO is this null check needed here? probably. assuming string here
850    //TODO make check more robust here/inserting params more robust
851    //do not pass to the search parameters that are empty
852    //FIXME hack - comparison to 'optional' - replace with check against 'optional' field and update related lookup metadata
853  0 if ((param.getValue() != null) && ((param.getValue().toString().trim().isEmpty() == false) || (param.getKey().toLowerCase().indexOf("optional") == -1))) {
854  0 userCriteria.add(field);
855    }
856    }
857  0 showCriteriaChosen(userCriteria);
858   
859  0 if (hasSearchParams){
860    //Only display modify link if there are search parametes available.
861  0 if(!resultsShown){
862  0 searchSelectorPanel.removeFromParent();
863  0 modifySearchPanel = new CollapsablePanel(getMessage("searchPanelModifySearch"), searchSelectorPanel, false);
864  0 modifySearchPanel.getLabel().addClickHandler(new ClickHandler(){
 
865  0 toggle @Override
866    public void onClick(ClickEvent event) {
867  0 resultsTablePanel.setVisible(false);
868  0 actionCancelButtons.setButtonText(ButtonEnumerations.SearchCancelEnum.SEARCH, getActionLabel());
869  0 resultsSelected = false;
870    }});
871  0 SearchPanel.this.layout.insert(modifySearchPanel, 0);
872   
873    }
874    else{
875  0 modifySearchPanel.close();
876    }
877    }
878  0 resultsShown = true;
879   
880  0 for(Callback<Boolean> callback: actionCompletedCallbacks){
881  0 callback.exec( Boolean.valueOf(true));
882    }
883    }
884    };
885    }
886   
 
887  0 toggle public SearchRequest getSearchRequest() {
888  0 if (activeSearchParametersWidget != null) {
889  0 return activeSearchParametersWidget.getSearchRequest();
890    }
891  0 return null;
892    }
893   
 
894  0 toggle public void setActionCancelButtonGroup(ActionCancelGroup actionCancelButtons) {
895  0 this.actionCancelButtons = actionCancelButtons;
896    }
897   
 
898  0 toggle public String getSelectedLookupName() {
899  0 return selectedLookupName;
900    }
901   
 
902  0 toggle public void setSelectedLookupName(String selectedLookupName) {
903  0 this.selectedLookupName = selectedLookupName;
904    }
905   
 
906  0 toggle public void addSelectionCompleteCallback(Callback<List<SelectedResults>> callback){
907  0 selectedCompleteCallbacks.add(callback);
908    }
909   
 
910  0 toggle public void addActionCompleteCallback(Callback<Boolean> callback){
911  0 actionCompletedCallbacks.add(callback);
912    }
913   
 
914  0 toggle public String getActionLabel() {
915  0 return actionLabel;
916    }
917   
 
918  0 toggle public void setActionLabel(String actionLabel) {
919  0 if ((actionLabel != null) && (actionLabel.trim().length() > 0)) {
920  0 this.actionLabel = actionLabel;
921    }
922    }
923   
924    }