KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > web > ui > common > component > data > UISortLink


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.data;
18
19 import java.io.IOException JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import javax.faces.component.NamingContainer;
23 import javax.faces.component.UICommand;
24 import javax.faces.component.UIComponent;
25 import javax.faces.context.FacesContext;
26 import javax.faces.context.ResponseWriter;
27 import javax.faces.el.ValueBinding;
28 import javax.faces.event.AbortProcessingException;
29 import javax.faces.event.ActionEvent;
30 import javax.faces.event.FacesEvent;
31
32 import org.apache.log4j.Logger;
33
34 import org.alfresco.web.data.IDataContainer;
35 import org.alfresco.web.ui.common.Utils;
36 import org.alfresco.web.ui.common.WebResources;
37
38 /**
39  * @author Kevin Roast
40  */

41 public class UISortLink extends UICommand
42 {
43    /**
44     * Default Constructor
45     */

46    public UISortLink()
47    {
48       setRendererType(null);
49    }
50    
51    /**
52     * @see javax.faces.component.UIComponent#encodeBegin(javax.faces.context.FacesContext)
53     */

54    public void encodeBegin(FacesContext context) throws IOException JavaDoc
55    {
56       ResponseWriter out = context.getResponseWriter();
57       
58       IDataContainer dataContainer = getDataContainer();
59       if (dataContainer == null)
60       {
61          throw new IllegalStateException JavaDoc("Must nest UISortLink inside component implementing IDataContainer!");
62       }
63       
64       // swap sort direction if we were last sorted column
65
boolean bPreviouslySorted = false;
66       boolean descending = true;
67       String JavaDoc lastSortedColumn = dataContainer.getCurrentSortColumn();
68       if (lastSortedColumn == (String JavaDoc)getValue())
69       {
70          descending = !dataContainer.isCurrentSortDescending();
71          bPreviouslySorted = true;
72       }
73       
74       // render sort link
75
StringBuilder JavaDoc buf = new StringBuilder JavaDoc(256);
76       buf.append("<nobr><a HREF='#' onclick=\"");
77       // generate some JavaScript to set a hidden form field and submit
78
// a form which request attributes that we can decode
79
buf.append(Utils.generateFormSubmit(context, this, getHiddenFieldName(context), getClientId(context)));
80       buf.append('"');
81       
82       if (getAttributes().get("style") != null)
83       {
84          buf.append(" style=\"")
85             .append(getAttributes().get("style"))
86             .append('"');
87       }
88       if (getAttributes().get("styleClass") != null)
89       {
90          buf.append(" class=")
91             .append(getAttributes().get("styleClass"));
92       }
93       if (getAttributes().get("tooltip") != null)
94       {
95          buf.append(" title=\"")
96             .append(getAttributes().get("tooltip"))
97             .append('"');
98       }
99       buf.append('>');
100       
101       // output column label
102
buf.append((String JavaDoc)getAttributes().get("label"));
103       
104       if (bPreviouslySorted == true)
105       {
106          if (descending == true)
107          {
108             buf.append(" ")
109                .append(Utils.buildImageTag(context, WebResources.IMAGE_SORTUP, 10, 6, null));
110          }
111          else
112          {
113             buf.append(" ")
114                .append(Utils.buildImageTag(context, WebResources.IMAGE_SORTDOWN, 10, 6, null));
115          }
116       }
117       else
118       {
119          buf.append(" ")
120             .append(Utils.buildImageTag(context, WebResources.IMAGE_SORTNONE, 10, 7, null));
121       }
122       buf.append("</a></nobr>");
123       
124       out.write(buf.toString());
125    }
126    
127    /**
128     * @see javax.faces.component.UIComponent#decode(javax.faces.context.FacesContext)
129     */

130    public void decode(FacesContext context)
131    {
132       Map JavaDoc requestMap = context.getExternalContext().getRequestParameterMap();
133       String JavaDoc fieldId = getHiddenFieldName(context);
134       String JavaDoc value = (String JavaDoc)requestMap.get(fieldId);
135       if (value != null && value.equals(getClientId(context)))
136       {
137          // we were clicked - queue an event to represent the click
138
// cannot handle the event here as other components etc. have not had
139
// a chance to decode() - we queue an event to be processed later
140
SortEvent actionEvent = new SortEvent(this, (String JavaDoc)this.getValue());
141          this.queueEvent(actionEvent);
142       }
143    }
144    
145    /**
146     * @see javax.faces.component.UIComponent#broadcast(javax.faces.event.FacesEvent)
147     */

148    public void broadcast(FacesEvent event) throws AbortProcessingException
149    {
150       if (event instanceof SortEvent == false)
151       {
152          // let the super class handle events which we know nothing about
153
super.broadcast(event);
154       }
155       else if ( ((SortEvent)event).Column.equals(getColumn()) )
156       {
157          // found a sort event for us!
158
if (s_logger.isDebugEnabled())
159             s_logger.debug("Handling sort event for column: " + ((SortEvent)event).Column);
160          
161          if (getColumn().equals(getDataContainer().getCurrentSortColumn()) == true)
162          {
163             // reverse sort direction
164
this.descending = !this.descending;
165          }
166          else
167          {
168             // revert to default sort direction
169
this.descending = true;
170          }
171          getDataContainer().sort(getColumn(), this.descending, getMode());
172       }
173    }
174    
175    /**
176     * We use a hidden field name based on the parent data container component Id and
177     * the string "sort" to give a field name that can be shared by all sort links
178     * within a single data container component.
179     *
180     * @param context FacesContext
181     *
182     * @return hidden field name
183     */

184    private String JavaDoc getHiddenFieldName(FacesContext context)
185    {
186       UIComponent dataContainer = (UIComponent)Utils.getParentDataContainer(context, this);
187       return dataContainer.getClientId(context) + NamingContainer.SEPARATOR_CHAR + "sort";
188    }
189    
190    /**
191     * Column name referenced by this link
192     *
193     * @return column name
194     */

195    public String JavaDoc getColumn()
196    {
197       return (String JavaDoc)getValue();
198    }
199    
200    /**
201     * Sorting mode - see IDataContainer constants
202     *
203     * @return sorting mode - see IDataContainer constants
204     */

205    public String JavaDoc getMode()
206    {
207       return this.mode;
208    }
209    
210    /**
211     * Set the sorting mode - see IDataContainer constants
212     *
213     * @param sortMode the sorting mode- see IDataContainer constants
214     */

215    public void setMode(String JavaDoc sortMode)
216    {
217       this.mode = sortMode;
218    }
219    
220    /**
221     * Returns true for descending sort, false for ascending
222     *
223     * @return true for descending sort, false for ascending
224     */

225    public boolean isDescending()
226    {
227       return this.descending;
228    }
229    
230    /**
231     * @return Returns the label.
232     */

233    public String JavaDoc getLabel()
234    {
235       ValueBinding vb = getValueBinding("label");
236       if (vb != null)
237       {
238          this.label = (String JavaDoc)vb.getValue(getFacesContext());
239       }
240       return this.label;
241    }
242
243    /**
244     * @param label The label to set.
245     */

246    public void setLabel(String JavaDoc label)
247    {
248       this.label = label;
249    }
250
251    /**
252     * @return Returns the tooltip.
253     */

254    public String JavaDoc getTooltip()
255    {
256       ValueBinding vb = getValueBinding("tooltip");
257       if (vb != null)
258       {
259          this.tooltip = (String JavaDoc)vb.getValue(getFacesContext());
260       }
261       return this.tooltip;
262    }
263
264    /**
265     * @param tooltip The tooltip to set.
266     */

267    public void setTooltip(String JavaDoc tooltip)
268    {
269       this.tooltip = tooltip;
270    }
271
272    /**
273     * @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
274     */

275    public void restoreState(FacesContext context, Object JavaDoc state)
276    {
277       Object JavaDoc values[] = (Object JavaDoc[])state;
278       // standard component attributes are restored by the super class
279
super.restoreState(context, values[0]);
280       this.descending = ((Boolean JavaDoc)values[1]).booleanValue();
281       this.mode = (String JavaDoc)values[2];
282       this.label = (String JavaDoc)values[3];
283       this.tooltip = (String JavaDoc)values[4];
284    }
285    
286    /**
287     * @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
288     */

289    public Object JavaDoc saveState(FacesContext context)
290    {
291       Object JavaDoc values[] = new Object JavaDoc[5];
292       // standard component attributes are saved by the super class
293
values[0] = super.saveState(context);
294       values[1] = (this.descending ? Boolean.TRUE : Boolean.FALSE);
295       values[2] = this.mode;
296       values[3] = this.label;
297       values[4] = this.tooltip;
298       return values;
299    }
300    
301    /**
302     * Return the parent data container for this component
303     */

304    private IDataContainer getDataContainer()
305    {
306       return Utils.getParentDataContainer(getFacesContext(), this);
307    }
308    
309    
310    // ------------------------------------------------------------------------------
311
// Inner classes
312

313    /**
314     * Class representing the clicking of a sortable column.
315     */

316    private static class SortEvent extends ActionEvent
317    {
318       public SortEvent(UIComponent component, String JavaDoc column)
319       {
320          super(component);
321          Column = column;
322       }
323       
324       public String JavaDoc Column = null;
325    }
326    
327    
328    // ------------------------------------------------------------------------------
329
// Constants
330

331    private static Logger s_logger = Logger.getLogger(IDataContainer.class);
332    
333    /** sorting mode */
334    private String JavaDoc mode = IDataContainer.SORT_CASEINSENSITIVE;
335    
336    private String JavaDoc label;
337    
338    private String JavaDoc tooltip;
339    
340    /** true for descending sort, false for ascending */
341    private boolean descending = false;
342 }
343
Popular Tags