KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > web > ui > common > renderer > DatePickerRenderer


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.renderer;
18
19 import java.io.IOException JavaDoc;
20 import java.text.DateFormatSymbols JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Calendar JavaDoc;
23 import java.util.Date JavaDoc;
24 import java.util.GregorianCalendar JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Locale JavaDoc;
28 import java.util.Map JavaDoc;
29
30 import javax.faces.component.EditableValueHolder;
31 import javax.faces.component.UIComponent;
32 import javax.faces.component.ValueHolder;
33 import javax.faces.context.FacesContext;
34 import javax.faces.context.ResponseWriter;
35 import javax.faces.convert.ConverterException;
36 import javax.faces.model.SelectItem;
37
38 import org.alfresco.web.app.Application;
39
40 /**
41  * @author kevinr
42  *
43  * Example of a custom JSF renderer. This demonstrates how to encode/decode a set
44  * of input field params that we use to generate a Date object. This object is held
45  * in our component and the renderer will output it to the page.
46  */

47 public class DatePickerRenderer extends BaseRenderer
48 {
49    private static final String JavaDoc FIELD_YEAR = "_year";
50    private static final String JavaDoc FIELD_MONTH = "_month";
51    private static final String JavaDoc FIELD_DAY = "_day";
52    private static final String JavaDoc FIELD_HOUR = "_hour";
53    private static final String JavaDoc FIELD_MINUTE = "_minute";
54
55    /**
56     * @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
57     *
58     * The decode method takes the parameters from the external requests, finds the
59     * ones revelant to this component and decodes the results into an object known
60     * as the "submitted value".
61     */

62    public void decode(FacesContext context, UIComponent component)
63    {
64       try
65       {
66          // TODO: should check for disabled/readonly here - no need to decode
67
String JavaDoc clientId = component.getClientId(context);
68          Map JavaDoc params = context.getExternalContext().getRequestParameterMap();
69          String JavaDoc year = (String JavaDoc)params.get(clientId + FIELD_YEAR);
70          if (year != null)
71          {
72             // found data for our component
73
String JavaDoc month = (String JavaDoc)params.get(clientId + FIELD_MONTH);
74             String JavaDoc day = (String JavaDoc)params.get(clientId + FIELD_DAY);
75             String JavaDoc hour = (String JavaDoc)params.get(clientId + FIELD_HOUR);
76             String JavaDoc minute = (String JavaDoc)params.get(clientId + FIELD_MINUTE);
77             
78             // we encode the values needed for the component as we see fit
79
int[] parts = new int[5];
80             parts[0] = Integer.parseInt(year);
81             parts[1] = Integer.parseInt(month);
82             parts[2] = Integer.parseInt(day);
83             parts[3] = Integer.parseInt(hour);
84             parts[4] = Integer.parseInt(minute);
85             
86             // save the data in an object for our component as the "EditableValueHolder"
87
// all UI Input Components support this interface for the submitted value
88
((EditableValueHolder)component).setSubmittedValue(parts);
89          }
90       }
91       catch (NumberFormatException JavaDoc nfe)
92       {
93          // just ignore the error and skip the update of the property
94
}
95    }
96    
97    /**
98     * @see javax.faces.render.Renderer#getConvertedValue(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object)
99     *
100     * In the Process Validations phase, this method is called to convert the values
101     * to the datatype as required by the component.
102     *
103     * It is possible at this point that a custom Converter instance will be used - this
104     * is why we have not yet converted the values to a data type.
105     */

106    public Object JavaDoc getConvertedValue(FacesContext context, UIComponent component, Object JavaDoc val) throws ConverterException
107    {
108       int[] parts = (int[])val;
109       Calendar JavaDoc date = new GregorianCalendar JavaDoc(parts[0], parts[1], parts[2], parts[3], parts[4]);
110       return date.getTime();
111    }
112    
113    /**
114     * @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
115     *
116     * All rendering logic for this component is implemented here. A renderer for an
117     * input component must render the submitted value if it's set, and use the local
118     * value only if there is no submitted value.
119     */

120    public void encodeBegin(FacesContext context, UIComponent component)
121          throws IOException JavaDoc
122    {
123       // always check for this flag - as per the spec
124
if (component.isRendered() == true)
125       {
126          Date JavaDoc date = null;
127          
128          // this is part of the spec:
129
// first you attempt to build the date from the submitted value
130
int[] submittedValue = (int[])((EditableValueHolder)component).getSubmittedValue();
131          if (submittedValue != null)
132          {
133             date = (Date JavaDoc)getConvertedValue(context, component, submittedValue);
134          }
135          else
136          {
137             // second if no submitted value is found, default to the current value
138
Object JavaDoc value = ((ValueHolder)component).getValue();
139             // finally check for null value and create default if needed
140
date = value instanceof Date JavaDoc ? (Date JavaDoc)value : new Date JavaDoc();
141          }
142          
143          // get the attributes from the component we need for rendering
144
int nStartYear;
145          Integer JavaDoc startYear = (Integer JavaDoc)component.getAttributes().get("startYear");
146          if (startYear != null)
147          {
148             nStartYear = startYear.intValue();
149          }
150          else
151          {
152             nStartYear = new Date JavaDoc().getYear() + 1900 + 2; // for "effectivity date" searches
153
}
154          
155          int nYearCount = 25;
156          Integer JavaDoc yearCount = (Integer JavaDoc)component.getAttributes().get("yearCount");
157          if (yearCount != null)
158          {
159             nYearCount = yearCount.intValue();
160          }
161          
162          // now we render the output for our component
163
// we create 3 drop-down menus for day, month and year and
164
// two text fields for the hour and minute
165
String JavaDoc clientId = component.getClientId(context);
166          ResponseWriter out = context.getResponseWriter();
167          
168          // note that we build a client id for our form elements that we are then
169
// able to decode() as above.
170
Calendar JavaDoc calendar = new GregorianCalendar JavaDoc();
171          calendar.setTime(date);
172          renderMenu(out, component, getDays(), calendar.get(Calendar.DAY_OF_MONTH), clientId + FIELD_DAY);
173          renderMenu(out, component, getMonths(), calendar.get(Calendar.MONTH), clientId + FIELD_MONTH);
174          renderMenu(out, component, getYears(nStartYear, nYearCount), calendar.get(Calendar.YEAR), clientId + FIELD_YEAR);
175          
176          // make sure we have a flag to determine whether to show the time
177
Boolean JavaDoc showTime = (Boolean JavaDoc)component.getAttributes().get("showTime");
178          if (showTime == null)
179          {
180             showTime = Boolean.FALSE;
181          }
182          
183          out.write(" ");
184          renderTimeElement(out, component, calendar.get(Calendar.HOUR_OF_DAY), clientId + FIELD_HOUR, showTime.booleanValue());
185          if (showTime.booleanValue())
186          {
187             out.write(" : ");
188          }
189          renderTimeElement(out, component, calendar.get(Calendar.MINUTE), clientId + FIELD_MINUTE, showTime.booleanValue());
190       }
191    }
192    
193    /**
194     * Render a drop-down menu to represent an element for the date picker.
195     *
196     * @param out Response Writer to output too
197     * @param component The compatible component
198     * @param items To display in the drop-down list
199     * @param selected Which item index is selected
200     * @param clientId Client Id to use
201     *
202     * @throws IOException
203     */

204    private void renderMenu(ResponseWriter out, UIComponent component, List JavaDoc items,
205          int selected, String JavaDoc clientId)
206       throws IOException JavaDoc
207    {
208       out.write("<select");
209       outputAttribute(out, clientId, "name");
210       
211       if (component.getAttributes().get("styleClass") != null)
212       {
213          outputAttribute(out, component.getAttributes().get("styleClass"), "class");
214       }
215       if (component.getAttributes().get("style") != null)
216       {
217          outputAttribute(out, component.getAttributes().get("style"), "style");
218       }
219       if (component.getAttributes().get("disabled") != null)
220       {
221          outputAttribute(out, component.getAttributes().get("disabled"), "disabled");
222       }
223       out.write(">");
224       
225       for (Iterator JavaDoc i=items.iterator(); i.hasNext(); /**/)
226       {
227          SelectItem item = (SelectItem)i.next();
228          Integer JavaDoc value = (Integer JavaDoc)item.getValue();
229          out.write("<option");
230          outputAttribute(out, value, "value");
231          
232          // show selected value
233
if (value.intValue() == selected)
234          {
235             outputAttribute(out, "selected", "selected");
236          }
237          out.write(">");
238          out.write(item.getLabel());
239          out.write("</option>");
240       }
241       out.write("</select>");
242    }
243    
244    /**
245     * Renders either the hour or minute field
246     *
247     * @param out The ResponseWriter
248     * @param currentValue The value of the hour or minute
249     * @param clientId The id to use for the field
250     */

251    private void renderTimeElement(ResponseWriter out, UIComponent component,
252          int currentValue, String JavaDoc clientId, boolean showTime) throws IOException JavaDoc
253    {
254       out.write("<input");
255       outputAttribute(out, clientId, "name");
256       
257       if (showTime)
258       {
259          out.write(" type='text' size='1' maxlength='2'");
260          
261          if (component.getAttributes().get("disabled") != null)
262          {
263             outputAttribute(out, component.getAttributes().get("disabled"), "disabled");
264          }
265       }
266       else
267       {
268          out.write(" type='hidden'");
269       }
270       
271       // make sure there are always 2 digits
272
String JavaDoc strValue = Integer.toString(currentValue);
273       if (strValue.length() == 1)
274       {
275          strValue = "0" + strValue;
276       }
277       
278       outputAttribute(out, strValue, "value");
279       out.write("/>");
280    }
281    
282    private List JavaDoc getYears(int startYear, int yearCount)
283    {
284       List JavaDoc<SelectItem> years = new ArrayList JavaDoc<SelectItem>();
285       for (int i=startYear; i>startYear - yearCount; i--)
286       {
287          Integer JavaDoc year = Integer.valueOf(i);
288          years.add(new SelectItem(year, year.toString()));
289       }
290       return years;
291    }
292    
293    private List JavaDoc getMonths()
294    {
295       // get names of the months for default locale
296
Locale JavaDoc locale = Application.getLanguage(FacesContext.getCurrentInstance());
297       if (locale == null)
298       {
299          locale = locale.getDefault();
300       }
301       DateFormatSymbols JavaDoc dfs = new DateFormatSymbols JavaDoc(locale);
302       String JavaDoc[] names = dfs.getMonths();
303       List JavaDoc<SelectItem> months = new ArrayList JavaDoc<SelectItem>(12);
304       for (int i=0; i<12; i++)
305       {
306          Integer JavaDoc key = Integer.valueOf(i);
307          months.add(new SelectItem(key, names[i]));
308       }
309       return months;
310    }
311    
312    private List JavaDoc getDays()
313    {
314       List JavaDoc<SelectItem> days = new ArrayList JavaDoc<SelectItem>(31);
315       for (int i=1; i<32; i++)
316       {
317          Integer JavaDoc day = Integer.valueOf(i);
318          days.add(new SelectItem(day, day.toString()));
319       }
320       return days;
321    }
322 }
323
Popular Tags