001 package org.apache.myfaces.tobago.taglib.component; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more 005 * contributor license agreements. See the NOTICE file distributed with 006 * this work for additional information regarding copyright ownership. 007 * The ASF licenses this file to You under the Apache License, Version 2.0 008 * (the "License"); you may not use this file except in compliance with 009 * the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 import org.apache.myfaces.tobago.apt.annotation.BodyContent; 021 import org.apache.myfaces.tobago.apt.annotation.Tag; 022 import org.apache.myfaces.tobago.apt.annotation.TagAttribute; 023 import org.apache.myfaces.tobago.component.ComponentUtil; 024 import org.apache.myfaces.tobago.event.TabChangeListener; 025 import org.apache.myfaces.tobago.event.TabChangeSource; 026 import org.apache.myfaces.tobago.event.TabChangeListenerValueBindingDelegate; 027 import org.apache.commons.logging.Log; 028 import org.apache.commons.logging.LogFactory; 029 030 import javax.faces.component.UIComponent; 031 import javax.faces.context.FacesContext; 032 import javax.faces.el.ValueBinding; 033 import javax.faces.webapp.UIComponentTag; 034 import javax.servlet.jsp.JspException; 035 import javax.servlet.jsp.tagext.TagSupport; 036 037 /** 038 * Register an TabChangedListener instance on the UIComponent 039 * associated with the closest parent UIComponent custom action. 040 */ 041 @Tag(name = "tabChangeListener", bodyContent = BodyContent.EMPTY) 042 public class TabChangeListenerTag extends TagSupport { 043 044 private static final long serialVersionUID = -419199086962377873L; 045 046 private static final Log LOG = LogFactory.getLog(TabChangeListenerTag.class); 047 048 /** 049 * <p>The fully qualified class name of the {@link TabChangeListener} 050 * instance to be created.</p> 051 */ 052 private String type; 053 private String binding; 054 055 /** 056 * Fully qualified Java class name of a TabChangeListener to be 057 * created and registered. 058 */ 059 @TagAttribute(required = true) 060 public void setType(String type) { 061 this.type = type; 062 } 063 064 /** 065 * The value binding expression to a TabChangeListener. 066 */ 067 @TagAttribute 068 public void setBinding(String binding) { 069 this.binding = binding; 070 } 071 072 073 074 /** 075 * <p>Create a new instance of the specified {@link TabChangeListener} 076 * class, and register it with the {@link javax.faces.component.UIComponent} instance associated 077 * with our most immediately surrounding {@link javax.faces.webapp.UIComponentTag} instance, if 078 * the {@link javax.faces.component.UIComponent} instance was created by this execution of the 079 * containing JSP page.</p> 080 * 081 * @throws JspException if a JSP error occurs 082 */ 083 public int doStartTag() throws JspException { 084 085 // Locate our parent UIComponentTag 086 UIComponentTag tag = 087 UIComponentTag.getParentUIComponentTag(pageContext); 088 if (tag == null) { 089 // TODO Message resource i18n 090 throw new JspException("Not nested in faces tag"); 091 } 092 093 if (!tag.getCreated()) { 094 return (SKIP_BODY); 095 } 096 097 UIComponent component = tag.getComponentInstance(); 098 if (component == null) { 099 // TODO Message resource i18n 100 throw new JspException("Component Instance is null"); 101 } 102 if (!(component instanceof TabChangeSource)) { 103 // TODO Message resource i18n 104 throw new JspException("Component "+ component.getClass().getName() + " is not instanceof TabChangeSource"); 105 } 106 TabChangeSource changeSource = (TabChangeSource) component; 107 108 TabChangeListener handler = null; 109 ValueBinding valueBinding = null; 110 if (binding != null && UIComponentTag.isValueReference(binding)) { 111 valueBinding = ComponentUtil.createValueBinding(binding); 112 if (valueBinding != null) { 113 Object obj = valueBinding.getValue(FacesContext.getCurrentInstance()); 114 if (obj != null && obj instanceof TabChangeListener) { 115 handler = (TabChangeListener) obj; 116 } 117 } 118 } 119 120 if (handler == null && type != null) { 121 handler = createTabChangeListener(type); 122 if (handler != null && valueBinding != null) { 123 valueBinding.setValue(FacesContext.getCurrentInstance(), handler); 124 } 125 } 126 if (handler != null) { 127 if (valueBinding != null) { 128 changeSource.addTabChangeListener(new TabChangeListenerValueBindingDelegate(type, valueBinding)); 129 } else { 130 changeSource.addTabChangeListener(handler); 131 } 132 } 133 // TODO else LOG.warn? 134 return (SKIP_BODY); 135 } 136 137 138 /** 139 * <p>Release references to any acquired resources. 140 */ 141 public void release() { 142 this.type = null; 143 this.binding = null; 144 } 145 146 /** 147 * <p>Create and return a new {@link TabChangeListener} to be registered 148 * on our surrounding {@link javax.faces.component.UIComponent}.</p> 149 * 150 * @throws javax.servlet.jsp.JspException if a new instance cannot be created 151 */ 152 protected TabChangeListener createTabChangeListener(String className) throws JspException { 153 try { 154 Class clazz = getClass().getClassLoader().loadClass(className); 155 return ((TabChangeListener) clazz.newInstance()); 156 } catch (Exception e) { 157 throw new JspException(e); 158 } 159 } 160 }