View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.tobago.internal.taglib.extension;
21  
22  import org.apache.myfaces.tobago.apt.annotation.DynamicExpression;
23  import org.apache.myfaces.tobago.apt.annotation.ExtensionTag;
24  import org.apache.myfaces.tobago.apt.annotation.Tag;
25  import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
26  import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
27  import org.apache.myfaces.tobago.internal.taglib.DatePickerTag;
28  import org.apache.myfaces.tobago.internal.taglib.DateTag;
29  import org.apache.myfaces.tobago.internal.taglib.FormTag;
30  
31  import javax.el.MethodExpression;
32  import javax.el.ValueExpression;
33  import javax.servlet.jsp.JspException;
34  
35  /**
36   * Renders a date input field with a date picker and a label.
37   * <br />
38   * Short syntax of:
39   * <p/>
40   * <pre>
41   * &lt;tc:panel>
42   *   &lt;f:facet name="layout">
43   *     &lt;tc:gridLayout columns="auto;*"/>
44   *   &lt;/f:facet>
45   *   &lt;tc:label value="#{label}" for="@auto"/>
46   *   &lt;tc:date value="#{value}">
47   *     ...
48   *   &lt;/tc:in>
49   * &lt;/tc:panel>
50   * </pre>
51   */
52  @Tag(name = "date")
53  @ExtensionTag(
54      baseClassName = "org.apache.myfaces.tobago.internal.taglib.DateTag",
55      faceletHandler = "org.apache.myfaces.tobago.facelets.extension.DateExtensionHandler")
56  public class DateExtensionTag extends TobagoExtensionBodyTagSupport {
57  
58    private static final long serialVersionUID = 1L;
59  
60    private ValueExpression binding;
61    private ValueExpression converter;
62    private MethodExpression validator;
63    private ValueExpression disabled;
64    private ValueExpression focus;
65    private ValueExpression label;
66    private ValueExpression accessKey;
67    private ValueExpression readonly;
68    private ValueExpression rendered;
69    private ValueExpression required;
70    private ValueExpression tip;
71    private ValueExpression placeholder;
72    private ValueExpression value;
73    private MethodExpression valueChangeListener;
74    private ValueExpression onchange;
75    private ValueExpression tabIndex;
76    private ValueExpression markup;
77    private ValueExpression validatorMessage;
78    private ValueExpression converterMessage;
79    private ValueExpression requiredMessage;
80    private String fieldId;
81    private String pickerId;
82    private String formId;
83  
84    private ValueExpression labelWidth;
85    private LabelExtensionTag labelTag;
86    private DateTag dateTag;
87  
88    @Override
89    public int doStartTag() throws JspException {
90  
91      labelTag = new LabelExtensionTag();
92      labelTag.setPageContext(pageContext);
93      if (id != null) {
94        labelTag.setId(id);
95      }
96      if (label != null) {
97        labelTag.setValue(label);
98      }
99      if (accessKey != null) {
100       labelTag.setAccessKey(accessKey);
101     }
102     if (labelWidth != null) {
103       labelTag.setColumns(createStringValueExpression(labelWidth.getExpressionString() + ";*;auto"));
104     } else {
105       labelTag.setColumns(createStringValueExpression("auto;*;auto"));
106     }
107     if (tip != null) {
108       labelTag.setTip(tip);
109     }
110     if (rendered != null) {
111       labelTag.setRendered(rendered);
112     }
113     if (markup != null) {
114       labelTag.setMarkup(markup);
115     }
116     labelTag.setParent(getParent());
117     labelTag.setJspId(nextJspId());
118     labelTag.doStartTag();
119 
120     dateTag = new DateTag();
121     dateTag.setPageContext(pageContext);
122     if (value != null) {
123       dateTag.setValue(value);
124     }
125     if (valueChangeListener != null) {
126       dateTag.setValueChangeListener(valueChangeListener);
127     }
128     if (placeholder != null) {
129       dateTag.setPlaceholder(placeholder);
130     }
131     if (binding != null) {
132       dateTag.setBinding(binding);
133     }
134     if (converter != null) {
135       dateTag.setConverter(converter);
136     }
137     if (validator != null) {
138       dateTag.setValidator(validator);
139     }
140     if (disabled != null) {
141       dateTag.setDisabled(disabled);
142     }
143     if (onchange != null) {
144       dateTag.setOnchange(onchange);
145     }
146     if (focus != null) {
147       dateTag.setFocus(focus);
148     }
149     if (fieldId != null) {
150       dateTag.setId(fieldId);
151     }
152     if (label != null) {
153       dateTag.setLabel(label);
154     }
155     if (readonly != null) {
156       dateTag.setReadonly(readonly);
157     }
158     if (required != null) {
159       dateTag.setRequired(required);
160     }
161     if (markup != null) {
162       dateTag.setMarkup(markup);
163     }
164     if (tabIndex != null) {
165       dateTag.setTabIndex(tabIndex);
166     }
167     if (validatorMessage != null) {
168       dateTag.setValidatorMessage(validatorMessage);
169     }
170     if (converterMessage != null) {
171       dateTag.setConverterMessage(converterMessage);
172     }
173     if (requiredMessage != null) {
174       dateTag.setRequiredMessage(requiredMessage);
175     }
176 
177     dateTag.setParent(labelTag);
178     dateTag.setJspId(nextJspId());
179     dateTag.doStartTag();
180 
181     return super.doStartTag();
182   }
183 
184   @Override
185   public int doEndTag() throws JspException {
186     dateTag.doEndTag();
187     final FormTag formTag = new FormTag();
188     formTag.setPageContext(pageContext);
189     formTag.setParent(labelTag);
190     if (formId != null) {
191       formTag.setId(formId);
192     }
193     formTag.setJspId(nextJspId());
194     formTag.doStartTag();
195 
196     final DatePickerTag datePicker = new DatePickerTag();
197     datePicker.setPageContext(pageContext);
198     datePicker.setFor("@auto");
199     if (tabIndex != null) {
200       datePicker.setTabIndex(tabIndex);
201     }
202     if (markup != null) {
203       datePicker.setMarkup(markup);
204     }
205     datePicker.setParent(formTag);
206     if (pickerId != null) {
207       datePicker.setId(pickerId);
208     }
209     datePicker.setJspId(nextJspId());
210     datePicker.doStartTag();
211     datePicker.doEndTag();
212     formTag.doEndTag();
213 
214     labelTag.doEndTag();
215     return super.doEndTag();
216   }
217 
218   @Override
219   public void release() {
220     super.release();
221     binding = null;
222     converter = null;
223     validator = null;
224     disabled = null;
225     labelWidth = null;
226     focus = null;
227     label = null;
228     accessKey = null;
229     readonly = null;
230     rendered = null;
231     required = null;
232     tip = null;
233     placeholder = null;
234     value = null;
235     valueChangeListener = null;
236     onchange = null;
237     markup = null;
238     tabIndex = null;
239     labelTag = null;
240     dateTag = null;
241     validatorMessage = null;
242     converterMessage = null;
243     requiredMessage = null;
244     fieldId = null;
245     pickerId = null;
246     formId = null;
247   }
248 
249   /**
250    * The current value of this component.
251    */
252   @TagAttribute
253   @UIComponentTagAttribute(type = "java.lang.Object")
254   public void setValue(final ValueExpression value) {
255     this.value = value;
256   }
257 
258   /**
259    * MethodBinding representing a value change listener method
260    * that will be notified when a new value has been set for this input component.
261    * The expression must evaluate to a public method that takes a ValueChangeEvent
262    * parameter, with a return type of void.
263    */
264   @TagAttribute
265   @UIComponentTagAttribute(
266           type = {},
267           expression = DynamicExpression.METHOD_EXPRESSION_REQUIRED,
268           methodSignature = "javax.faces.event.ValueChangeEvent")
269   public void setValueChangeListener(final MethodExpression valueChangeListener) {
270     this.valueChangeListener = valueChangeListener;
271   }
272 
273   /**
274    * Text value to display as label.
275    * If text contains an underscore the next character is used as accesskey.
276    */
277   @TagAttribute
278   @UIComponentTagAttribute()
279   public void setLabel(final ValueExpression label) {
280     this.label = label;
281   }
282 
283   /**
284    * The accessKey of this component.
285    */
286   @TagAttribute
287   @UIComponentTagAttribute(type = "java.lang.Character")
288   public void setAccessKey(final javax.el.ValueExpression accessKey) {
289     this.accessKey = accessKey;
290   }
291 
292   /**
293    * Client side script function to add to this component's onchange handler.
294    */
295   @TagAttribute
296   @UIComponentTagAttribute()
297   public void setOnchange(final ValueExpression onchange) {
298     this.onchange = onchange;
299   }
300 
301   /**
302    * Flag indicating this component should receive the focus.
303    */
304   @TagAttribute
305   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
306   public void setFocus(final ValueExpression focus) {
307     this.focus = focus;
308   }
309 
310   /**
311    * The value binding expression linking this
312    * component to a property in a backing bean.
313    */
314   @TagAttribute
315   @UIComponentTagAttribute(type = "javax.faces.component.UIComponent")
316   public void setBinding(final ValueExpression binding) {
317     this.binding = binding;
318   }
319 
320   /**
321    * Flag indicating whether or not this component should be rendered
322    * (during Render Response Phase), or processed on any subsequent form submit.
323    */
324   @TagAttribute
325   @UIComponentTagAttribute(type = "boolean", defaultValue = "true")
326   public void setRendered(final ValueExpression rendered) {
327     this.rendered = rendered;
328   }
329 
330   /**
331    * An expression that specifies the Converter for this component.
332    * If the value binding expression is a String,
333    * the String is used as an ID to look up a Converter.
334    * If the value binding expression is a Converter,
335    * uses that instance as the converter.
336    * The value can either be a static value (ID case only)
337    * or an EL expression.
338    */
339   @TagAttribute
340   @UIComponentTagAttribute(type = "javax.faces.convert.Converter",
341       expression = DynamicExpression.VALUE_EXPRESSION)
342   public void setConverter(final ValueExpression converter) {
343     this.converter = converter;
344   }
345 
346   /**
347    * A method binding EL expression,
348    * accepting FacesContext, UIComponent,
349    * and Object parameters, and returning void, that validates
350    * the component's local value.
351    */
352   @TagAttribute
353   @UIComponentTagAttribute(type = {},
354       expression = DynamicExpression.METHOD_EXPRESSION,
355       methodSignature = { "javax.faces.context.FacesContext", "javax.faces.component.UIComponent", "java.lang.Object" })
356   public void setValidator(final MethodExpression validator) {
357     this.validator = validator;
358   }
359 
360   /**
361    * Flag indicating that this component will prohibit changes by the user.
362    */
363   @TagAttribute
364   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
365   public void setReadonly(final ValueExpression readonly) {
366     this.readonly = readonly;
367   }
368 
369   /**
370    * Flag indicating that this element is disabled.
371    */
372   @TagAttribute()
373   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
374   public void setDisabled(final ValueExpression disabled) {
375     this.disabled = disabled;
376   }
377 
378   /**
379    * Flag indicating that a value is required.
380    * If the value is an empty string a
381    * ValidationError occurs and a Error Message is rendered.
382    */
383   @TagAttribute
384   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
385   public void setRequired(final ValueExpression required) {
386     this.required = required;
387   }
388 
389   /**
390    * Text value to display as tooltip.
391    */
392   @TagAttribute
393   @UIComponentTagAttribute()
394   public void setTip(final ValueExpression tip) {
395     this.tip = tip;
396   }
397 
398   /**
399    * Displays a short text in the input field, that describes the meaning of this field.
400    * This is part of HTML 5, the theme should emulate the behaviour, when the browser doesn't support it.
401    */
402   @TagAttribute
403   @UIComponentTagAttribute()
404   public void setPlaceholder(final ValueExpression placeholder) {
405     this.placeholder = placeholder;
406   }
407 
408    /**
409    * The width for the label component. Default: 'auto'.
410    * This value is used in the gridLayouts columns attribute.
411    * See gridLayout tag for valid values.
412    */
413   @TagAttribute
414   @UIComponentTagAttribute()
415   public void setLabelWidth(final ValueExpression labelWidth) {
416     this.labelWidth = labelWidth;
417   }
418 
419   /**
420    * Indicate markup of this component.
421    * Possible value is 'none'. But this can be overridden in the theme.
422    */
423   @TagAttribute
424   @UIComponentTagAttribute(type = "java.lang.String[]", defaultValue = "none")
425   public void setMarkup(final ValueExpression markup) {
426     this.markup = markup;
427   }
428 
429   @TagAttribute
430   @UIComponentTagAttribute(type = "java.lang.Integer")
431   public void setTabIndex(final ValueExpression tabIndex) {
432     this.tabIndex = tabIndex;
433   }
434 
435   /**
436    * An expression that specifies the validator message
437    */
438   @TagAttribute
439   @UIComponentTagAttribute()
440   public void setValidatorMessage(final ValueExpression validatorMessage) {
441     this.validatorMessage = validatorMessage;
442   }
443 
444   /**
445    * An expression that specifies the converter message
446    */
447   @TagAttribute
448   @UIComponentTagAttribute()
449   public void setConverterMessage(final ValueExpression converterMessage) {
450     this.converterMessage = converterMessage;
451   }
452 
453   /**
454    * An expression that specifies the required message
455    */
456   @TagAttribute
457   @UIComponentTagAttribute()
458   public void setRequiredMessage(final ValueExpression requiredMessage) {
459     this.requiredMessage = requiredMessage;
460   }
461 
462   /**
463    * The component identifier for the input field component inside of the container.
464    * This value must be unique within the closest parent component that is a naming container.
465    */
466   @TagAttribute(rtexprvalue = true)
467   @UIComponentTagAttribute
468   public void setFieldId(final String fieldId) {
469     this.fieldId = fieldId;
470   }
471 
472   /**
473    * The component identifier for the automatically created picker component inside of the container.
474    * This value must be unique within the closest parent component that is a naming container.
475    */
476   @TagAttribute(rtexprvalue = true)
477   @UIComponentTagAttribute
478   public void setPickerId(final String pickerId) {
479     this.pickerId = pickerId;
480   }
481 
482   /**
483    * The component identifier for the automatically created form component inside of the container.
484    * This value must be unique within the closest parent component that is a naming container.
485    */
486   @TagAttribute(rtexprvalue = true)
487   @UIComponentTagAttribute
488   public void setFormId(final String formId) {
489     this.formId = formId;
490   }
491 
492   /**
493    * The component identifier for this component.
494    * This value must be unique within the closest parent component that is a naming container.
495    * For tx components the id will be set to the container (e. g. the panel).
496    * To set the id of the input field, you have to use the attribute "fieldId".
497    */
498   @TagAttribute(rtexprvalue = true)
499   @UIComponentTagAttribute
500   public void setId(final String id) {
501     super.setId(id);
502   }
503 }