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  package org.apache.myfaces.taglib.core;
20  
21  import javax.servlet.jsp.tagext.TagSupport;
22  import javax.servlet.jsp.JspException;
23  import javax.faces.webapp.UIComponentClassicTagBase;
24  import javax.faces.webapp.UIComponentELTag;
25  import javax.faces.component.UIComponent;
26  import javax.faces.context.FacesContext;
27  import javax.el.ValueExpression;
28  import javax.el.ELContext;
29  
30  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspAttribute;
31  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspTag;
32  
33  /**
34   * This tag associates an attribute with the nearest parent UIComponent.
35   * <p>
36   * When the value is not an EL expression, this tag has the same effect as calling component.getAttributes.put(name,
37   * value). When the attribute name specified matches a standard property of the component, that property is set. However
38   * it is also valid to assign attributes to components using any arbitrary name; the component itself won't make any use
39   * of these but other objects such as custom renderers, validators or action listeners can later retrieve the attribute
40   * from the component by name.
41   * </p>
42   * <p>
43   * When the value is an EL expression, this tag has the same effect as calling component.setValueBinding. A call to
44   * method component.getAttributes().get(name) will then cause that expression to be evaluated and the result of the
45   * expression is returned, not the original EL expression string.
46   * </p>
47   * <p>
48   * See the javadoc for UIComponent.getAttributes for more details.
49   * </p>
50   * <p>
51   * Unless otherwise specified, all attributes accept static values or EL expressions.
52   * </p>
53   * 
54   * @author Manfred Geiler (latest modification by $Author$)
55   * @author Bruno Aranda (JSR-252)
56   * @version $Revision$ $Date$
57   */
58  @JSFJspTag(name = "f:attribute", bodyContent = "empty")
59  public class AttributeTag extends TagSupport
60  {
61      private static final long serialVersionUID = 31476300171678632L;
62      private ValueExpression _nameExpression;
63      private ValueExpression _valueExpression;
64  
65      /**
66       * The name of the attribute.
67       * 
68       * @param nameExpression
69       */
70      @JSFJspAttribute(className="javax.el.ValueExpression",
71              deferredValueType="java.lang.String")
72      public void setName(ValueExpression nameExpression)
73      {
74          _nameExpression = nameExpression;
75      }
76  
77      /**
78       * The attribute's value.
79       * 
80       * @param valueExpression
81       */
82      @JSFJspAttribute(className="javax.el.ValueExpression",
83              deferredValueType="java.lang.Object")
84      public void setValue(ValueExpression valueExpression)
85      {
86          _valueExpression = valueExpression;
87      }
88  
89      @Override
90      public int doStartTag() throws JspException
91      {
92          UIComponentClassicTagBase componentTag = UIComponentELTag.getParentUIComponentClassicTagBase(pageContext);
93          if (componentTag == null)
94          {
95              throw new JspException("no parent UIComponentTag found");
96          }
97          UIComponent component = componentTag.getComponentInstance();
98          if (component == null)
99          {
100             throw new JspException("parent UIComponentTag has no UIComponent");
101         }
102 
103         FacesContext facesContext = FacesContext.getCurrentInstance();
104         ELContext elContext = facesContext.getELContext();
105 
106         String name = null;
107         Object value = null;
108         boolean isLiteral = false;
109 
110         if (_nameExpression != null)
111         {
112             name = (String)_nameExpression.getValue(elContext);
113         }
114 
115         if (_valueExpression != null)
116         {
117             isLiteral = _valueExpression.isLiteralText();
118             value = _valueExpression.getValue(elContext);
119         }
120 
121         if (name != null)
122         {
123             if (component.getAttributes().get(name) == null)
124             {
125                 if (isLiteral)
126                 {
127                     component.getAttributes().put(name, value);
128                 }
129                 else
130                 {
131                     component.setValueExpression(name, _valueExpression);
132                 }
133             }
134         }
135 
136         return SKIP_BODY;
137     }
138     
139     @Override
140     public void release()
141     {
142         super.release();
143         _nameExpression = null;
144         _valueExpression = null;
145     }
146 }