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.InTag;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  import javax.el.MethodExpression;
32  import javax.el.ValueExpression;
33  import javax.servlet.jsp.JspException;
34  
35  /**
36   * Renders a text input field with 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:in value="#{value}">
47   *     ...
48   *   &lt;/tc:in>
49   * &lt;/tc:panel>
50   * </pre>
51   */
52  
53  @Tag(name = "in")
54  @ExtensionTag(baseClassName = "org.apache.myfaces.tobago.internal.taglib.InTag")
55  public class InExtensionTag extends TobagoExtensionBodyTagSupport {
56  
57    private ValueExpression binding;
58    private ValueExpression converter;
59    private MethodExpression validator;
60    private ValueExpression disabled;
61    private ValueExpression focus;
62    private ValueExpression label;
63    private ValueExpression password;
64    private ValueExpression readonly;
65    private ValueExpression rendered;
66    private ValueExpression required;
67    private ValueExpression tip;
68    private ValueExpression value;
69    private MethodExpression valueChangeListener;
70    private ValueExpression onchange;
71    private MethodExpression suggestMethod;
72    private ValueExpression suggestMinChars;
73    private ValueExpression suggestDelay;
74    private ValueExpression markup;
75    private ValueExpression labelWidth;
76    private ValueExpression tabIndex;
77    private ValueExpression validatorMessage;
78    private ValueExpression converterMessage;
79    private ValueExpression requiredMessage;
80    private String fieldId;
81  
82    private LabelExtensionTag labelTag;
83    private InTag inTag;
84  
85    @Override
86    public int doStartTag() throws JspException {
87  
88      labelTag = new LabelExtensionTag();
89      labelTag.setPageContext(pageContext);
90      if (id != null) {
91        labelTag.setId(id);
92      }
93      if (label != null) {
94        labelTag.setValue(label);
95      }
96      if (tip != null) {
97        labelTag.setTip(tip);
98      }
99      if (rendered != null) {
100       labelTag.setRendered(rendered);
101     }
102     if (labelWidth != null) {
103       labelTag.setColumns(createStringValueExpression(labelWidth.getExpressionString() + ";*"));
104     }
105     if (markup != null) {
106       labelTag.setMarkup(markup);
107     }
108     labelTag.setParent(getParent());
109     labelTag.setJspId(nextJspId());
110     labelTag.doStartTag();
111 
112     inTag = new InTag();
113     inTag.setPageContext(pageContext);
114     if (value != null) {
115       inTag.setValue(value);
116     }
117     if (valueChangeListener != null) {
118       inTag.setValueChangeListener(valueChangeListener);
119     }
120     if (label != null) {
121       inTag.setLabel(label);
122     }
123     if (binding != null) {
124       inTag.setBinding(binding);
125     }
126     if (converter != null) {
127       inTag.setConverter(converter);
128     }
129     if (validator != null) {
130       inTag.setValidator(validator);
131     }
132     if (onchange != null) {
133       inTag.setOnchange(onchange);
134     }
135     if (suggestMethod != null) {
136       inTag.setSuggestMethod(suggestMethod);
137     }
138     if (suggestMinChars != null) {
139       inTag.setSuggestMinChars(suggestMinChars);
140     }
141     if (suggestDelay != null) {
142       inTag.setSuggestDelay(suggestDelay);
143     }
144     if (disabled != null) {
145       inTag.setDisabled(disabled);
146     }
147     if (focus != null) {
148       inTag.setFocus(focus);
149     }
150     if (fieldId != null) {
151       inTag.setId(fieldId);
152     }
153     if (password != null) {
154       inTag.setPassword(password);
155     }
156     if (readonly != null) {
157       inTag.setReadonly(readonly);
158     }
159     if (required != null) {
160       inTag.setRequired(required);
161     }
162     if (markup != null) {
163       inTag.setMarkup(markup);
164     }
165     if (tabIndex != null) {
166       inTag.setTabIndex(tabIndex);
167     }
168     if (validatorMessage != null) {
169       inTag.setValidatorMessage(validatorMessage);
170     }
171     if (converterMessage != null) {
172       inTag.setConverterMessage(converterMessage);
173     }
174     if (requiredMessage != null) {
175       inTag.setRequiredMessage(requiredMessage);
176     }
177     inTag.setParent(labelTag);
178     inTag.setJspId(nextJspId());
179     inTag.doStartTag();
180 
181     return super.doStartTag();
182   }
183 
184   @Override
185   public int doEndTag() throws JspException {
186     inTag.doEndTag();
187     labelTag.doEndTag();
188     return super.doEndTag();
189   }
190 
191   private static final Logger LOG = LoggerFactory.getLogger(InExtensionTag.class);
192 
193   @Override
194   public void release() {
195     super.release();
196     binding = null;
197     converter = null;
198     validator = null;
199     disabled = null;
200     labelWidth = null;
201     focus = null;
202     label = null;
203     password = null;
204     readonly = null;
205     rendered = null;
206     required = null;
207     tip = null;
208     value = null;
209     valueChangeListener = null;
210     onchange = null;
211     suggestMethod = null;
212     suggestMinChars = null;
213     suggestDelay = null;
214     markup = null;
215     tabIndex = null;
216     inTag = null;
217     labelTag = null;
218     validatorMessage = null;
219     converterMessage = null;
220     requiredMessage = null;
221     fieldId = null;
222   }
223 
224   /**
225    * Indicate markup of this component.
226    * Possible value is 'none'. But this can be overridden in the theme.
227    */
228   @TagAttribute
229   @UIComponentTagAttribute(defaultValue = "none", type = "java.lang.String[]")
230   public void setMarkup(ValueExpression markup) {
231     this.markup = markup;
232   }
233 
234   /**
235    * The current value of this component.
236    */
237   @TagAttribute
238   @UIComponentTagAttribute(type = "java.lang.Object")
239   public void setValue(ValueExpression value) {
240     this.value = value;
241   }
242 
243   /**
244    * MethodBinding representing a value change listener method
245    * that will be notified when a new value has been set for this input component.
246    * The expression must evaluate to a public method that takes a ValueChangeEvent
247    * parameter, with a return type of void.
248    *
249    * @param valueChangeListener
250    */
251   @TagAttribute
252   @UIComponentTagAttribute(
253       type = {},
254       expression = DynamicExpression.METHOD_EXPRESSION_REQUIRED,
255       methodSignature = "javax.faces.event.ValueChangeEvent")
256   public void setValueChangeListener(MethodExpression valueChangeListener) {
257     this.valueChangeListener = valueChangeListener;
258   }
259 
260   /**
261    * Text value to display as label.
262    * If text contains an underscore the next character is used as accesskey.
263    */
264   @TagAttribute
265   @UIComponentTagAttribute()
266   public void setLabel(ValueExpression label) {
267     this.label = label;
268   }
269 
270   /**
271    * Flag indicating this component should receive the focus.
272    */
273   @TagAttribute
274   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
275   public void setFocus(ValueExpression focus) {
276     this.focus = focus;
277   }
278 
279   /**
280    * The value binding expression linking this
281    * component to a property in a backing bean.
282    */
283   @TagAttribute
284   @UIComponentTagAttribute(type = "javax.faces.component.UIComponent")
285   public void setBinding(ValueExpression binding) {
286     this.binding = binding;
287   }
288 
289   /**
290    * Flag indicating whether or not this component should be rendered
291    * (during Render Response Phase), or processed on any subsequent form submit.
292    */
293   @TagAttribute
294   @UIComponentTagAttribute(type = "boolean", defaultValue = "true")
295   public void setRendered(ValueExpression rendered) {
296     this.rendered = rendered;
297   }
298 
299   /**
300    * An expression that specifies the Converter for this component.
301    * If the value binding expression is a String,
302    * the String is used as an ID to look up a Converter.
303    * If the value binding expression is a Converter,
304    * uses that instance as the converter.
305    * The value can either be a static value (ID case only)
306    * or an EL expression.
307    */
308   @TagAttribute
309   @UIComponentTagAttribute(type = "javax.faces.convert.Converter",
310       expression = DynamicExpression.VALUE_EXPRESSION)
311   public void setConverter(ValueExpression converter) {
312     this.converter = converter;
313   }
314 
315   /**
316    * Clientside script function to add to this component's onchange handler.
317    */
318   @TagAttribute
319   @UIComponentTagAttribute()
320   public void setOnchange(ValueExpression onchange) {
321     this.onchange = onchange;
322   }
323 
324   /**
325    * MethodBinding which generates a list of suggested input values based on
326    * the currently entered text, which could be retrieved via getSubmittedValue() on the UIIn.
327    * The expression has to evaluate to a public method which has a javax.faces.component.UIInput parameter
328    * and returns a List&lt;String>(deprecated), a List&lt;org.apache.myfaces.tobago.model.AutoSuggestItem>
329    * or a org.apache.myfaces.tobago.model.AutoSuggestItems.
330    */
331   @TagAttribute
332   @UIComponentTagAttribute(type = {},
333       expression = DynamicExpression.METHOD_EXPRESSION_REQUIRED,
334       methodSignature = "java.lang.String")
335   public void setSuggestMethod(MethodExpression suggestMethod) {
336     this.suggestMethod = suggestMethod;
337   }
338 
339   /**
340    * Minimum number of chars to type before the list will be requested.
341    *
342    * @since 1.5.9 and 1.6.0
343    */
344   @TagAttribute
345   @UIComponentTagAttribute(type = "java.lang.Integer", defaultValue = "1")
346   public void setSuggestMinChars(ValueExpression suggestMinChars) {
347     this.suggestMinChars = suggestMinChars;
348   }
349 
350   /**
351    * Time in milli seconds before the list will be requested.
352    *
353    * @since 1.5.9 and 1.6.0
354    */
355   @TagAttribute
356   @UIComponentTagAttribute(type = "java.lang.Integer", defaultValue = "300")
357   public void setSuggestDelay(ValueExpression suggestDelay) {
358     this.suggestDelay = suggestDelay;
359   }
360 
361   /**
362    * A method binding EL expression,
363    * accepting FacesContext, UIComponent,
364    * and Object parameters, and returning void, that validates
365    * the component's local value.
366    */
367   @TagAttribute
368   @UIComponentTagAttribute(type = {},
369       expression = DynamicExpression.METHOD_EXPRESSION,
370       methodSignature = {"javax.faces.context.FacesContext", "javax.faces.component.UIComponent", "java.lang.Object"})
371   public void setValidator(MethodExpression validator) {
372     this.validator = validator;
373   }
374 
375   /**
376    * Flag indicating whether or not this component should be rendered as
377    * password field , so you will not see the typed charakters.
378    */
379   @TagAttribute
380   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
381   public void setPassword(ValueExpression password) {
382     this.password = password;
383   }
384 
385   /**
386    * Flag indicating that this component will prohibit changes by the user.
387    */
388   @TagAttribute
389   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
390   public void setReadonly(ValueExpression readonly) {
391     this.readonly = readonly;
392   }
393 
394   /**
395    * Flag indicating that this element is disabled.
396    */
397   @TagAttribute()
398   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
399   public void setDisabled(ValueExpression disabled) {
400     this.disabled = disabled;
401   }
402 
403   /**
404    * Flag indicating that a value is required.
405    * If the value is an empty string a
406    * ValidationError occurs and a Error Message is rendered.
407    */
408   @TagAttribute
409   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
410   public void setRequired(ValueExpression required) {
411     this.required = required;
412   }
413 
414   /**
415    * Text value to display as tooltip.
416    */
417   @TagAttribute
418   @UIComponentTagAttribute()
419   public void setTip(ValueExpression tip) {
420     this.tip = tip;
421   }
422 
423   /**
424    * The width for the label component. Default: 'auto'.
425    * This value is used in the gridLayouts columns attribute.
426    * See gridLayout tag for valid values.
427    */
428   @TagAttribute
429   @UIComponentTagAttribute()
430   public void setLabelWidth(ValueExpression labelWidth) {
431     this.labelWidth = labelWidth;
432   }
433 
434   @TagAttribute
435   @UIComponentTagAttribute(type = "java.lang.Integer")
436   public void setTabIndex(ValueExpression tabIndex) {
437     this.tabIndex = tabIndex;
438   }
439 
440   /**
441    * An expression that specifies the validator message
442    */
443   @TagAttribute
444   @UIComponentTagAttribute()
445   public void setValidatorMessage(ValueExpression validatorMessage) {
446     this.validatorMessage = validatorMessage;
447   }
448 
449   /**
450    * An expression that specifies the converter message
451    */
452   @TagAttribute
453   @UIComponentTagAttribute()
454   public void setConverterMessage(ValueExpression converterMessage) {
455     this.converterMessage = converterMessage;
456   }
457 
458   /**
459    * An expression that specifies the required message
460    */
461   @TagAttribute
462   @UIComponentTagAttribute()
463   public void setRequiredMessage(ValueExpression requiredMessage) {
464     this.requiredMessage = requiredMessage;
465   }
466 
467   /**
468    * The component identifier for the input field component inside of the container.
469    * This value must be unique within the closest parent component that is a naming container.
470    */
471   @TagAttribute(rtexprvalue = true)
472   @UIComponentTagAttribute
473   public void setFieldId(String fieldId) {
474     this.fieldId = fieldId;
475   }
476 
477   /**
478    * The component identifier for this component.
479    * This value must be unique within the closest parent component that is a naming container.
480    * For tx components the id will be set to the container (e. g. the panel).
481    * To set the id of the input field, you have to use the attribute "fieldId".
482    */
483   @TagAttribute(rtexprvalue = true)
484   @UIComponentTagAttribute
485   public void setId(String id) {
486     super.setId(id);
487   }
488 }