KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > web > ui > common > component > UIGenericPicker


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.web.ui.common.component;
18
19 import java.io.IOException JavaDoc;
20 import java.text.MessageFormat JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.ResourceBundle JavaDoc;
23
24 import javax.faces.component.UICommand;
25 import javax.faces.component.UIComponent;
26 import javax.faces.context.FacesContext;
27 import javax.faces.context.ResponseWriter;
28 import javax.faces.el.MethodBinding;
29 import javax.faces.el.ValueBinding;
30 import javax.faces.event.AbortProcessingException;
31 import javax.faces.event.ActionEvent;
32 import javax.faces.event.FacesEvent;
33 import javax.faces.model.SelectItem;
34
35 import org.alfresco.web.app.Application;
36 import org.alfresco.web.ui.common.Utils;
37
38 /**
39  * @author Kevin Roast
40  */

41 public class UIGenericPicker extends UICommand
42 {
43    /** action ids */
44    private final static int ACTION_NONE = -1;
45    private final static int ACTION_SEARCH = 0;
46    private final static int ACTION_CLEAR = 1;
47    private final static int ACTION_FILTER = 2;
48    private final static int ACTION_ADD = 3;
49    
50    /** form field postfixes */
51    private final static String JavaDoc FIELD_FILTER = "_filter";
52    private final static String JavaDoc FIELD_CONTAINS = "_contains";
53    private final static String JavaDoc FIELD_RESULTS = "_results";
54    
55    /** I18N message strings */
56    private final static String JavaDoc MSG_SEARCH = "search";
57    private final static String JavaDoc MSG_CLEAR = "clear";
58    private final static String JavaDoc MSG_ADD = "add";
59    private final static String JavaDoc MSG_RESULTS1 = "results_contains";
60    private final static String JavaDoc MSG_RESULTS2 = "results_contains_filter";
61    
62    private final static int DEFAULT_HEIGHT = 100;
63    private final static int DEFAULT_WIDTH = 250;
64    
65    private MethodBinding queryCallback = null;
66    private Boolean JavaDoc showFilter = null;
67    private Boolean JavaDoc showContains = null;
68    private Boolean JavaDoc showAddButton = null;
69    private Boolean JavaDoc filterRefresh = null;
70    private String JavaDoc addButtonLabel;
71    private Integer JavaDoc width = null;
72    private Integer JavaDoc height = null;
73    
74    private SelectItem[] filters = null;
75    private int filterIndex = 0;
76    private String JavaDoc contains = "";
77    private String JavaDoc[] selectedResults = null;
78    private SelectItem[] currentResults = null;
79    
80    
81    // ------------------------------------------------------------------------------
82
// Component implementation
83

84    /**
85     * Default constructor
86     */

87    public UIGenericPicker()
88    {
89       setRendererType(null);
90    }
91    
92    /**
93     * @see javax.faces.component.UIComponent#getFamily()
94     */

95    public String JavaDoc getFamily()
96    {
97       return "org.alfresco.faces.GenericPicker";
98    }
99
100    /**
101     * @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
102     */

103    public void restoreState(FacesContext context, Object JavaDoc state)
104    {
105       Object JavaDoc values[] = (Object JavaDoc[])state;
106       // standard component attributes are restored by the super class
107
super.restoreState(context, values[0]);
108       showFilter = (Boolean JavaDoc)values[1];
109       showContains = (Boolean JavaDoc)values[2];
110       showAddButton = (Boolean JavaDoc)values[3];
111       addButtonLabel = (String JavaDoc)values[4];
112       width = (Integer JavaDoc)values[5];
113       height = (Integer JavaDoc)values[6];
114       filterIndex = (Integer JavaDoc)values[7];
115       contains = (String JavaDoc)values[8];
116       queryCallback = (MethodBinding)values[9];
117       selectedResults = (String JavaDoc[])values[10];
118       currentResults = (SelectItem[])values[11];
119       filters = (SelectItem[])values[12];
120       filterRefresh = (Boolean JavaDoc)values[13];
121    }
122    
123    /**
124     * @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
125     */

126    public Object JavaDoc saveState(FacesContext context)
127    {
128       Object JavaDoc values[] = new Object JavaDoc[14];
129       // standard component attributes are saved by the super class
130
values[0] = super.saveState(context);
131       values[1] = showFilter;
132       values[2] = showContains;
133       values[3] = showAddButton;
134       values[4] = addButtonLabel;
135       values[5] = width;
136       values[6] = height;
137       values[7] = filterIndex;
138       values[8] = contains;
139       values[9] = queryCallback;
140       values[10] = selectedResults;
141       values[11] = currentResults;
142       values[12] = filters;
143       values[13] = filterRefresh;
144       return (values);
145    }
146    
147    /**
148     * @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
149     */

150    public void decode(FacesContext context)
151    {
152       Map JavaDoc requestMap = context.getExternalContext().getRequestParameterMap();
153       Map JavaDoc valuesMap = context.getExternalContext().getRequestParameterValuesMap();
154       String JavaDoc fieldId = getHiddenFieldName();
155       String JavaDoc value = (String JavaDoc)requestMap.get(fieldId);
156       
157       int action = ACTION_NONE;
158       if (value != null && value.length() != 0)
159       {
160          // decode the values - we are expecting an action identifier
161
action = Integer.parseInt(value);
162       }
163       
164       // we always process these values to keep the component up-to-date
165

166       // now find the Filter drop-down value
167
int filterIndex = 0;
168       String JavaDoc strFilterIndex = (String JavaDoc)requestMap.get(fieldId + FIELD_FILTER);
169       if (strFilterIndex != null && strFilterIndex.length() != 0)
170       {
171          filterIndex = Integer.parseInt(strFilterIndex);
172       }
173       
174       // and the Contains text box value
175
String JavaDoc contains = (String JavaDoc)requestMap.get(fieldId + FIELD_CONTAINS);
176       
177       // and the Results selections
178
String JavaDoc[] results = (String JavaDoc[])valuesMap.get(fieldId + FIELD_RESULTS);
179       
180       // queue an event
181
PickerEvent event = new PickerEvent(this, action, filterIndex, contains, results);
182       queueEvent(event);
183    }
184    
185    /**
186     * @see javax.faces.component.UIComponentBase#broadcast(javax.faces.event.FacesEvent)
187     */

188    public void broadcast(FacesEvent event) throws AbortProcessingException
189    {
190       if (event instanceof PickerEvent)
191       {
192          PickerEvent pickerEvent = (PickerEvent)event;
193          
194          // set component state from event properties
195
this.filterIndex = pickerEvent.FilterIndex;
196          this.contains = pickerEvent.Contains;
197          this.selectedResults = pickerEvent.Results;
198          
199          // delegate to appropriate action logic
200
switch (pickerEvent.Action)
201          {
202             case ACTION_ADD:
203                // call super for actionlistener execution
204
// it's up to the handler to get the results from the getSelectedResults() method
205
super.broadcast(event);
206                break;
207             
208             case ACTION_CLEAR:
209                this.contains = "";
210                this.filterIndex = 0;
211                this.selectedResults = null;
212                this.currentResults = null;
213                break;
214             
215             case ACTION_FILTER:
216                // filter changed then query with new settings
217
case ACTION_SEARCH:
218                // query with current settings
219
MethodBinding callback = getQueryCallback();
220                if (callback != null)
221                {
222                   // use reflection to execute the query callback method and retrieve results
223
Object JavaDoc result = callback.invoke(getFacesContext(), new Object JavaDoc[] {
224                      this.filterIndex, this.contains});
225                   
226                   if (result instanceof SelectItem[])
227                   {
228                      this.currentResults = (SelectItem[])result;
229                   }
230                   else
231                   {
232                      this.currentResults = null;
233                   }
234                }
235                break;
236          }
237       }
238       else
239       {
240          super.broadcast(event);
241       }
242    }
243    
244    /**
245     * @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
246     */

247    public void encodeBegin(FacesContext context) throws IOException JavaDoc
248    {
249       if (isRendered() == false)
250       {
251          return;
252       }
253       
254       ResponseWriter out = context.getResponseWriter();
255       
256       ResourceBundle JavaDoc bundle = Application.getBundle(context);
257       
258       String JavaDoc clientId = getClientId(context);
259       
260       // start outer table
261
out.write("<table border=0 cellspacing=4 cellpadding=0>");
262       
263       // top row
264
out.write("<tr valign=top><td>");
265       
266       // filter drop-down
267
if (getShowFilter() == true)
268       {
269          out.write("<select name='");
270          out.write(clientId + FIELD_FILTER);
271          out.write("' size='1'");
272          
273          // apply onchange Form submit here if component attributes require it
274
if (getFilterRefresh() == true)
275          {
276             out.write(" onchange=\"");
277             out.write(generateFormSubmit(context, ACTION_FILTER));
278             out.write("\"");
279          }
280          
281          out.write(">");
282          
283          // output filter options
284
SelectItem[] items = getFilterOptions();
285          if (items != null)
286          {
287             for (int i=0; i<items.length; i++)
288             {
289                out.write("<option value=\"");
290                out.write(items[i].getValue().toString());
291                if (this.filterIndex != i)
292                {
293                   out.write("\">");
294                }
295                else
296                {
297                   out.write("\" selected=\"true\">");
298                }
299                out.write(items[i].getLabel());
300                out.write("</option>");
301             }
302          }
303          
304          out.write("</select>");
305       }
306       out.write("</td><td align=right>");
307       
308       // Contains textbox
309
if (getShowContains() == true)
310       {
311          out.write("<input name='");
312          out.write(clientId + FIELD_CONTAINS);
313          out.write("' type='text' maxlength='256' style='width:120px' value=\"");
314          out.write(Utils.replace(this.contains, "\"", "&quot;"));
315          out.write("\">&nbsp;");
316       }
317       
318       // Search button
319
out.write("<input type='submit' value='");
320       out.write(Utils.encode(bundle.getString(MSG_SEARCH)));
321       out.write("' onclick=\"");
322       out.write(generateFormSubmit(context, ACTION_SEARCH));
323       out.write("\">");
324       out.write("</td></tr>");
325       
326       // information row
327
if (this.currentResults != null && getShowContains() == true)
328       {
329          out.write("<tr><td colspan=3>");
330          String JavaDoc resultsMsg;
331          if (getShowFilter() == false)
332          {
333             resultsMsg = MessageFormat.format(bundle.getString(MSG_RESULTS1), new Object JavaDoc[] {this.contains});
334          }
335          else
336          {
337             String JavaDoc filterMsg = this.filters[this.filterIndex].getLabel();
338             resultsMsg = MessageFormat.format(bundle.getString(MSG_RESULTS2), new Object JavaDoc[] {this.contains, filterMsg});
339          }
340          out.write(resultsMsg);
341          out.write("&nbsp;");
342          out.write("<a HREF='#' onclick=\"");
343          out.write(generateFormSubmit(context, ACTION_CLEAR));
344          out.write("\">");
345          out.write(Utils.encode(bundle.getString(MSG_CLEAR)));
346          out.write("</a></td></tr>");
347       }
348       
349       // results list row
350
out.write("<tr><td colspan=2>");
351       out.write("<select size='8' style='width:");
352       out.write(Integer.toString(getWidth()));
353       out.write("px;height:");
354       out.write(Integer.toString(getHeight()));
355       out.write("px' name='");
356       out.write(clientId + FIELD_RESULTS);
357       out.write("' multiple>");
358       
359       // results
360
if (currentResults != null)
361       {
362          // show each of the items in the results listbox
363
for (int i=0; i<currentResults.length; i++)
364          {
365             out.write("<option value=\"");
366             out.write(currentResults[i].getValue().toString());
367             out.write("\">");
368             out.write(currentResults[i].getLabel());
369             out.write("</option>");
370          }
371       }
372       
373       // end results list
374
out.write("</select>");
375       out.write("</td></tr>");
376       
377       // bottom row - add button
378
if (getShowAddButton() == true)
379       {
380          out.write("<tr><td colspan=2>");
381          out.write("<input type='submit' value='");
382          String JavaDoc msg = getAddButtonLabel();
383          if (msg == null || msg.length() == 0)
384          {
385             msg = bundle.getString(MSG_ADD);
386          }
387          out.write(Utils.encode(msg));
388          out.write("' onclick=\"");
389          out.write(generateFormSubmit(context, ACTION_ADD));
390          out.write("\">");
391          out.write("</td></tr>");
392       }
393       
394       // end outer table
395
out.write("</table>");
396    }
397    
398    /**
399     * @return the filter options
400     */

401    public SelectItem[] getFilterOptions()
402    {
403       if (this.filters == null)
404       {
405          ValueBinding vb = (ValueBinding)getValueBinding("filters");
406          if (vb != null)
407          {
408             this.filters = (SelectItem[])vb.getValue(getFacesContext());
409          }
410       }
411       
412       return this.filters;
413    }
414    
415    /**
416     * @return current filter drop-down selected index value
417     */

418    public int getFilterIndex()
419    {
420       return this.filterIndex;
421    }
422
423    /**
424     * @return Returns the addButtonLabel.
425     */

426    public String JavaDoc getAddButtonLabel()
427    {
428       ValueBinding vb = getValueBinding("addButtonLabel");
429       if (vb != null)
430       {
431          this.addButtonLabel = (String JavaDoc)vb.getValue(getFacesContext());
432       }
433       
434       return this.addButtonLabel;
435    }
436
437    /**
438     * @param addButtonLabel The addButtonLabel to set.
439     */

440    public void setAddButtonLabel(String JavaDoc addButtonLabel)
441    {
442       this.addButtonLabel = addButtonLabel;
443    }
444    
445    /**
446     * @return Returns the showAddButton.
447     */

448    public boolean getShowAddButton()
449    {
450       ValueBinding vb = getValueBinding("showAddButton");
451       if (vb != null)
452       {
453          this.showAddButton = (Boolean JavaDoc)vb.getValue(getFacesContext());
454       }
455       
456       return showAddButton != null ? showAddButton.booleanValue() : true;
457    }
458
459    /**
460     * @param showAddButton The showAddButton to set.
461     */

462    public void setShowAddButton(boolean showAddButton)
463    {
464       this.showAddButton = Boolean.valueOf(showAddButton);
465    }
466
467    /**
468     * @return Returns the showContains.
469     */

470    public boolean getShowContains()
471    {
472       ValueBinding vb = getValueBinding("showContains");
473       if (vb != null)
474       {
475          this.showContains = (Boolean JavaDoc)vb.getValue(getFacesContext());
476       }
477       
478       return showContains != null ? showContains.booleanValue() : true;
479    }
480
481    /**
482     * @param showContains The showContains to set.
483     */

484    public void setShowContains(boolean showContains)
485    {
486       this.showContains = Boolean.valueOf(showContains);
487    }
488
489    /**
490     * @return Returns the showFilter.
491     */

492    public boolean getShowFilter()
493    {
494       ValueBinding vb = getValueBinding("showFilter");
495       if (vb != null)
496       {
497          this.showFilter = (Boolean JavaDoc)vb.getValue(getFacesContext());
498       }
499       
500       return showFilter != null ? showFilter.booleanValue() : true;
501    }
502
503    /**
504     * @param showFilter The showFilter to set.
505     */

506    public void setShowFilter(boolean showFilter)
507    {
508       this.showFilter = Boolean.valueOf(showFilter);
509    }
510
511    /**
512     * @return Returns the filterRefresh.
513     */

514    public boolean getFilterRefresh()
515    {
516       ValueBinding vb = getValueBinding("filterRefresh");
517       if (vb != null)
518       {
519          this.filterRefresh = (Boolean JavaDoc)vb.getValue(getFacesContext());
520       }
521       
522       return filterRefresh != null ? filterRefresh.booleanValue() : false;
523    }
524
525    /**
526     * @param filterRefresh The filterRefresh to set.
527     */

528    public void setFilterRefresh(boolean filterRefresh)
529    {
530       this.filterRefresh = Boolean.valueOf(filterRefresh);
531    }
532
533    /**
534     * @return Returns the width.
535     */

536    public int getWidth()
537    {
538       ValueBinding vb = getValueBinding("width");
539       if (vb != null)
540       {
541          this.width = (Integer JavaDoc)vb.getValue(getFacesContext());
542       }
543       
544       return width != null ? width.intValue() : DEFAULT_WIDTH;
545    }
546
547    /**
548     * @param width The width to set.
549     */

550    public void setWidth(int width)
551    {
552       this.width = Integer.valueOf(width);
553    }
554    
555    /**
556     * @return Returns the height.
557     */

558    public int getHeight()
559    {
560       ValueBinding vb = getValueBinding("height");
561       if (vb != null)
562       {
563          this.height = (Integer JavaDoc)vb.getValue(getFacesContext());
564       }
565       
566       return height != null ? height.intValue() : DEFAULT_HEIGHT;
567    }
568
569    /**
570     * @param height The height to set.
571     */

572    public void setHeight(int height)
573    {
574       this.height = Integer.valueOf(height);
575    }
576    
577    /**
578     * @return Returns the queryCallback.
579     */

580    public MethodBinding getQueryCallback()
581    {
582       return this.queryCallback;
583    }
584
585    /**
586     * @param binding The queryCallback MethodBinding to set.
587     */

588    public void setQueryCallback(MethodBinding binding)
589    {
590       this.queryCallback = binding;
591    }
592    
593    /**
594     * @return The selected results. An array of whatever string objects were attached to the
595     * SelectItem[] objects supplied as the result of the picker query.
596     */

597    public String JavaDoc[] getSelectedResults()
598    {
599       return this.selectedResults;
600    }
601    
602    
603    // ------------------------------------------------------------------------------
604
// Private helpers
605

606    /**
607     * We use a hidden field per picker instance on the page.
608     *
609     * @return hidden field name
610     */

611    private String JavaDoc getHiddenFieldName()
612    {
613       return getClientId(getFacesContext());
614    }
615    
616    /**
617     * Generate FORM submit JavaScript for the specified action
618     *
619     * @param context FacesContext
620     * @param action Action index
621     *
622     * @return FORM submit JavaScript
623     */

624    private String JavaDoc generateFormSubmit(FacesContext context, int action)
625    {
626       return Utils.generateFormSubmit(context, this, getHiddenFieldName(), Integer.toString(action));
627    }
628    
629    
630    // ------------------------------------------------------------------------------
631
// Inner classes
632

633    /**
634     * Class representing the an action relevant to the Generic Selector component.
635     */

636    public static class PickerEvent extends ActionEvent
637    {
638       public PickerEvent(UIComponent component, int action, int filterIndex, String JavaDoc contains, String JavaDoc[] results)
639       {
640          super(component);
641          Action = action;
642          FilterIndex = filterIndex;
643          Contains = contains;
644          Results = results;
645       }
646       
647       public int Action;
648       public int FilterIndex;
649       public String JavaDoc Contains;
650       public String JavaDoc[] Results;
651    }
652 }
653
Popular Tags