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.tabbedpane;
20  
21  import javax.faces.component.UIComponent;
22  import javax.faces.context.FacesContext;
23  import javax.faces.el.ValueBinding;
24  import javax.faces.webapp.UIComponentTag;
25  import javax.servlet.jsp.JspException;
26  import javax.servlet.jsp.tagext.Tag;
27  import javax.servlet.jsp.tagext.TagSupport;
28  
29  import org.apache.myfaces.shared_tomahawk.util.ClassUtils;
30  
31  
32  /**
33   * Adds a tab-change-listener to the enclosing t:panelTabbedPane component.
34   * <p>
35   * When the panelTabbedPane changes the displayed tab, the listener is invoked.
36   * </p>
37   *
38   * @JSFJspTag
39   *   name="t:tabChangeListener"
40   *   bodyContent="empty"
41   *   tagHandler = "org.apache.myfaces.custom.tabbedpane.TabChangeListenerTagHandler"
42   *   
43   * @author <a href="mailto:oliver@rossmueller.com">Oliver Rossmueller</a>
44   * @version $Revision: 698966 $ $Date: 2008-09-25 08:41:35 -0500 (Thu, 25 Sep 2008) $
45   */
46  public class TabChangeListenerTag extends TagSupport
47  {
48      private static final long serialVersionUID = -6903749011638483023L;
49      private String type = null;
50  
51  
52      public TabChangeListenerTag()
53      {
54      }
55  
56      /**
57       * Define a listener to be attached to the parent HtmlPanelTabbedPane instance.
58       * <p>
59       * This attribute may be a literal string containing a fully-qualified class name. The
60       * specified class must implement the TabChangeListener interface and have a no-arguments
61       * constructor. A new instance will be created when the view is created.
62       * </p>
63       * <p>
64       * This attribute may also be an EL expression that returns type String. The EL expression will be
65       * evaluated when the view is built, and the returned value must be a fully-qualified class name. The
66       * specified class must implement the TabChangeListener interface and have a no-arguments constructor.
67       * A new instance will be created when the view is created.
68       * </p>
69       * <p>
70       * This attribute may also be an EL expression that returns a TabChangeListener instance.
71       * </p>
72       * <p>
73       * It is an error if an EL expression returns an object of any type other than String or TabChangeListener.
74       * </p>
75       * 
76       * @JSFJspAttribute required = "true"
77       */
78      public void setType(String type)
79      {
80          this.type = type;
81      }
82  
83  
84      public int doStartTag() throws JspException
85      {
86          if (type == null)
87          {
88              throw new JspException("type attribute not set");
89          }
90  
91          //Find parent UIComponentTag
92          UIComponentTag parentComponentTag = UIComponentTag.getParentUIComponentTag(pageContext);
93          if (parentComponentTag == null)
94          {
95              throw new JspException("TabChangeListenerTag has no UIComponentTag ancestor");
96          }
97  
98          if (parentComponentTag.getCreated())
99          {
100             //Component was just created, so we add the Listener
101             UIComponent parent = parentComponentTag.getComponentInstance();
102             if (parent instanceof HtmlPanelTabbedPane)
103             {
104                 Object listenerRef = type;
105                 if (UIComponentTag.isValueReference(type))
106                 {
107                     FacesContext facesContext = FacesContext.getCurrentInstance();
108                     ValueBinding valueBinding = facesContext.getApplication().createValueBinding(type);
109                     listenerRef = valueBinding.getValue(facesContext);
110                 }
111 
112                 if(listenerRef instanceof String)
113                 {
114                     String className = (String) listenerRef;
115                     TabChangeListener listener = (TabChangeListener) ClassUtils.newInstance(className);
116                     ((HtmlPanelTabbedPane) parent).addTabChangeListener(listener);
117                 }
118                 else if(listenerRef instanceof TabChangeListener)
119                 {
120                     TabChangeListener listener = (TabChangeListener) listenerRef;
121                     ((HtmlPanelTabbedPane) parent).addTabChangeListener(listener);
122                 }
123                 else if (listenerRef == null)
124                 {
125                     throw new JspException("Property 'type' must not be null.");
126                 }
127                 else
128                 {
129                     throw new JspException(
130                        "Property 'type' must be either a string (containing a class name) " +
131                        "or a TabChangeListener instance.");
132                 }
133             }
134             else
135             {
136                 throw new JspException(
137                     "Component " + parent.getId() + " is not of type HtmlPanelTabbedPane");
138             }
139         }
140 
141         return Tag.SKIP_BODY;
142     }
143 }