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 }