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.custom.updateactionlistener;
20  
21  import javax.el.ValueExpression;
22  import javax.faces.application.Application;
23  import javax.faces.component.ActionSource;
24  import javax.faces.component.UIComponent;
25  import javax.faces.context.FacesContext;
26  import javax.faces.convert.Converter;
27  import javax.faces.webapp.UIComponentClassicTagBase;
28  import javax.faces.webapp.UIComponentTag;
29  import javax.servlet.jsp.JspException;
30  import javax.servlet.jsp.tagext.Tag;
31  import javax.servlet.jsp.tagext.TagSupport;
32  
33  /**
34   * Registers an org.apache.myfaces.custom.updateactionlistener.UpdateActionListener 
35   * at the parent component (which must be an ActionSource). 
36   * 
37   * When the parent's action fires the specified value is evaluated, 
38   * then written into the specified property. 
39   * 
40   * Unless otherwise specified, all attributes accept static values or EL expressions. 
41   * 
42   * JSF 1.2 introduces a "setPropertyActionListener" with the same functionality like this. 
43   *
44   * @JSFJspTag
45   *   name="t:updateActionListener"
46   *   bodyContent="JSP"
47   *   tagHandler="org.apache.myfaces.custom.updateactionlistener.UpdateActionListenerTagHandler"
48   *   
49   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
50   * @version $Revision: 692184 $ $Date: 2008-09-04 13:21:52 -0500 (Thu, 04 Sep 2008) $
51   */
52  public class UpdateActionListenerTag
53          extends TagSupport
54  {
55      private static final long serialVersionUID = -6916153064327074092L;
56      //private static final Log log = LogFactory.getLog(UpdateActionListenerTag.class);
57      private ValueExpression _property;
58      private ValueExpression _value;
59      private String _converter;
60  
61      public UpdateActionListenerTag()
62      {
63      }
64  
65      /**
66       * A value-binding that specifies a property to be updated when 
67       * the parent's action occurs.
68       * 
69       * @JSFJspAttribute
70       *   required="true"
71       */
72      public void setProperty(ValueExpression property)
73      {
74          _property = property;
75      }
76  
77      /**
78       *  A literal value or value-binding that specifies what 
79       *  will be assigned to the destination specified by the 
80       *  property attribute.
81       * 
82       * @JSFJspAttribute
83       *   required="true"
84       */
85      public void setValue(ValueExpression value)
86      {
87          _value = value;
88      }
89  
90      /**
91       * The name of a registered Converter object which will be 
92       * invoked to convert the value into an appropriate datatype 
93       * for assigning to the specified property. If not specified 
94       * then an appropriate converter will be selected automatically.
95       * 
96       * @JSFJspAttribute
97       */
98      public void setConverter(String converter)
99      {
100         _converter = converter;
101     }
102 
103     public int doStartTag() throws JspException
104     {
105         if (_property == null) throw new JspException("property attribute not set");
106         if (_value == null) throw new JspException("value attribute not set");
107         if (_property.isLiteralText()) throw new JspException("property attribute is no valid value reference: " + _property);
108 
109         //Find parent UIComponentTag
110         UIComponentClassicTagBase componentELTag = UIComponentClassicTagBase.getParentUIComponentClassicTagBase(pageContext);
111         if (componentELTag == null){        
112             UIComponentTag componentTag = UIComponentTag.getParentUIComponentTag(pageContext);
113             if (componentTag == null)
114             {
115                 throw new JspException("UpdateActionListenerTag has no UIComponentTag ancestor");
116             }
117         }
118 
119         if (componentELTag.getCreated())
120         {
121             //Component was just created, so we add the Listener
122             UIComponent component = componentELTag.getComponentInstance();
123             if (component instanceof ActionSource)
124             {
125                 FacesContext facesContext = FacesContext.getCurrentInstance();
126                 Application application = facesContext.getApplication();
127                 UpdateActionListener al = new UpdateActionListener();
128                 al.setPropertyBinding(application.createValueBinding(_property.getExpressionString()));
129                 if (!_value.isLiteralText())
130                 {
131                     al.setValueBinding(application.createValueBinding(_value.getExpressionString()));
132                 }
133                 else
134                 {
135                     al.setValue(_value);
136                 }
137                 if (_converter != null)
138                 {
139                     Converter converter = application.createConverter(_converter);
140                     al.setConverter(converter);
141                 }
142                 ((ActionSource)component).addActionListener(al);
143             }
144             else
145             {
146                 throw new JspException("Component " + component.getId() + " is no ActionSource");
147             }
148         }
149 
150         return Tag.SKIP_BODY;
151     }
152 
153     public void release()
154     {
155         _property = null;
156         _converter = null;
157         _value = null;
158     }
159 
160 }