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 * <p>Create a new instance of the specified {@link TabChangeListener} 075 * class, and register it with the {@link javax.faces.component.UIComponent} instance associated 076 * with our most immediately surrounding {@link javax.faces.webapp.UIComponentTag} instance, if 077 * the {@link javax.faces.component.UIComponent} instance was created by this execution of the 078 * containing JSP page.</p> 079 * 080 * @throws JspException if a JSP error occurs 081 */ 082 public int doStartTag() throws JspException { 083 084 // Locate our parent UIComponentTag 085 UIComponentTag tag = 086 UIComponentTag.getParentUIComponentTag(pageContext); 087 if (tag == null) { 088 // TODO Message resource i18n 089 throw new JspException("Not nested in faces tag"); 090 } 091 092 if (!tag.getCreated()) { 093 return (SKIP_BODY); 094 } 095 096 UIComponent component = tag.getComponentInstance(); 097 if (component == null) { 098 // TODO Message resource i18n 099 throw new JspException("Component Instance is null"); 100 } 101 if (!(component instanceof TabChangeSource)) { 102 // TODO Message resource i18n 103 throw new JspException("Component " + component.getClass().getName() + " is not instanceof TabChangeSource"); 104 } 105 TabChangeSource changeSource = (TabChangeSource) component; 106 107 TabChangeListener handler = null; 108 ValueBinding valueBinding = null; 109 if (binding != null && UIComponentTag.isValueReference(binding)) { 110 valueBinding = ComponentUtil.createValueBinding(binding); 111 if (valueBinding != null) { 112 Object obj = valueBinding.getValue(FacesContext.getCurrentInstance()); 113 if (obj != null && obj instanceof TabChangeListener) { 114 handler = (TabChangeListener) obj; 115 } 116 } 117 } 118 119 if (handler == null && type != null) { 120 handler = createTabChangeListener(type); 121 if (handler != null && valueBinding != null) { 122 valueBinding.setValue(FacesContext.getCurrentInstance(), handler); 123 } 124 } 125 if (handler != null) { 126 if (valueBinding != null) { 127 changeSource.addTabChangeListener(new TabChangeListenerValueBindingDelegate(type, valueBinding)); 128 } else { 129 changeSource.addTabChangeListener(handler); 130 } 131 } 132 // TODO else LOG.warn? 133 return (SKIP_BODY); 134 } 135 136 137 /** 138 * <p>Release references to any acquired resources. 139 */ 140 public void release() { 141 this.type = null; 142 this.binding = null; 143 } 144 145 /** 146 * <p>Create and return a new {@link TabChangeListener} to be registered 147 * on our surrounding {@link javax.faces.component.UIComponent}.</p> 148 * 149 * @throws javax.servlet.jsp.JspException if a new instance cannot be created 150 */ 151 protected TabChangeListener createTabChangeListener(String className) throws JspException { 152 try { 153 Class clazz = getClass().getClassLoader().loadClass(className); 154 return ((TabChangeListener) clazz.newInstance()); 155 } catch (Exception e) { 156 throw new JspException(e); 157 } 158 } 159 }