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.valueChangeNotifier;
20  
21  import javax.faces.component.EditableValueHolder;
22  import javax.faces.component.UIComponent;
23  import javax.faces.webapp.UIComponentTag;
24  import javax.servlet.jsp.JspException;
25  import javax.servlet.jsp.tagext.Tag;
26  import javax.servlet.jsp.tagext.TagSupport;
27  import javax.el.ValueExpression;
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  
31  /**
32   * <p>ValueChangeNotifier</p>
33   * 
34   * Like valueChangeListener, but will send valueChange events after the
35   * UPDATE_MODEL phase. <br />
36   * This simply means you CAN update your model values within such an event now.
37   * <br />
38   * <ul>
39   * <li>It wont be overwritten by the model update</li>
40   * <li>And wont trigger another valueChange if you update a value with an
41   * valueChangeListener attached</li>
42   * </ul>
43   * 
44   * @JSFJspTag
45   *   name="s:valueChangeNotifier"
46   *   bodyContent="JSP" 
47   * 
48   * @author Mario Ivankovits <imario - at - apache.org>  (latest modification by $Author: skitching $)
49   * @version $Revision: 673833 $ $Date: 2008-07-03 16:58:05 -0500 (Thu, 03 Jul 2008) $
50   */
51  public class ValueChangeNotifierTag extends TagSupport
52  {
53      private ValueExpression method = null;
54      
55      private static Log log = LogFactory.getLog(ValueChangeNotifierTag.class);
56  
57      public ValueChangeNotifierTag()
58      {
59      }
60  
61      /**
62       * The bean.method name of your valueChange method<br />
63       * Currently only methods listeners are supported.<br />
64       * e.g. myBean.myListenerMethod
65       * 
66       * @JSFJspAttribute
67       *   required = "true"
68       */
69      public void setMethod(ValueExpression method)
70      {
71          this.method = method;
72      }
73  
74      public int doStartTag() throws JspException
75      {
76          if (method == null)
77          {
78              throw new JspException("name attribute not set");
79          }
80  
81          // Find parent UIComponentTag
82          UIComponentTag componentTag = UIComponentTag
83                  .getParentUIComponentTag(pageContext);
84          if (componentTag == null)
85          {
86              throw new JspException(
87                      "ValueChangeListenerTag has no UIComponentTag ancestor");
88          }
89  
90          if (componentTag.getCreated())
91          {
92              // Component was just created, so we add the Listener
93              UIComponent component = componentTag.getComponentInstance();
94              if (component instanceof EditableValueHolder)
95              {
96                  setupClassListener(component);
97              }
98              else
99              {
100                 throw new JspException("Component " + component.getId()
101                         + " is no EditableValueHolder");
102             }
103         }
104 
105         return Tag.SKIP_BODY;
106     }
107 
108     protected void setupClassListener(UIComponent component)
109     {
110         //UIComponentTag.isValueReference(method)
111         if (!method.isLiteralText())
112         {
113                 ((EditableValueHolder) component)
114                 .addValueChangeListener(new ValueChangeCollector(method.getExpressionString()));
115         } 
116         else
117         {
118             if(log.isErrorEnabled()){
119                 log.error("Invalid expression " + method);
120             }
121         }
122     }
123 }