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