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.Tag;
021 import org.apache.myfaces.tobago.apt.annotation.BodyContent;
022 import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
023 import org.apache.myfaces.tobago.component.ComponentUtil;
024 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_CONVERTER;
025
026 import javax.servlet.jsp.tagext.TagSupport;
027 import javax.servlet.jsp.JspException;
028 import javax.faces.webapp.UIComponentTag;
029 import javax.faces.component.UIComponent;
030 import javax.faces.component.ValueHolder;
031 import javax.faces.el.ValueBinding;
032 import javax.faces.context.FacesContext;
033 import javax.faces.convert.Converter;
034
035 /*
036 * Date: Oct 13, 2006
037 * Time: 6:01:59 PM
038 */
039 /**
040 * Register an Converter instance on the UIComponent
041 * associated with the closest parent UIComponent.
042 */
043 @Tag(name = "converter", bodyContent = BodyContent.EMPTY)
044 public class ConverterTag extends TagSupport {
045
046 private static final long serialVersionUID = 8565994799165107984L;
047
048 /**
049 * The converterId of the {@link javax.faces.convert.Converter}
050 */
051 private String converterId;
052 private String binding;
053
054 /**
055 * The converterId of a registered converter.
056 *
057 * @param converterId A valid converterId
058 */
059 @TagAttribute()
060 public void setConverterId(String converterId) {
061 this.converterId = converterId;
062 }
063
064 /**
065 * The value binding expression to a converter.
066 *
067 * @param binding A valid binding
068 */
069 @TagAttribute
070 public void setBinding(String binding) {
071 this.binding = binding;
072 }
073
074 /**
075 * Create a new instance of the specified {@link javax.faces.convert.Converter}
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.
080 *
081 * @throws javax.servlet.jsp.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 ValueHolder)) {
103 // TODO Message resource i18n
104 throw new JspException("Component " + component.getClass().getName() + " is not instanceof ValueHolder");
105 }
106 ValueHolder valueHolder = (ValueHolder) component;
107
108 Converter converter = null;
109
110 if (binding != null && UIComponentTag.isValueReference(binding)) {
111 ValueBinding valueBinding = ComponentUtil.createValueBinding(binding);
112 if (valueBinding != null) {
113 Object obj = valueBinding.getValue(FacesContext.getCurrentInstance());
114 if (obj != null && obj instanceof Converter) {
115 converter = (Converter) obj;
116 }
117 }
118 }
119
120 if (converter == null && converterId != null) {
121 String localConverterId;
122 // evaluate any VB expression that we were passed
123 if (UIComponentTag.isValueReference(converterId)) {
124 ValueBinding typeValueBinding = ComponentUtil.createValueBinding(converterId);
125 localConverterId = (String) typeValueBinding.getValue(FacesContext.getCurrentInstance());
126 } else {
127 localConverterId = converterId;
128 }
129 converter = FacesContext.getCurrentInstance().getApplication().createConverter(localConverterId);
130 if (converter != null && binding != null) {
131 ComponentUtil.setValueForValueBinding(binding, converter);
132 }
133 }
134 if (converter != null) {
135 if (UIComponentTag.isValueReference(binding)) {
136 component.setValueBinding(ATTR_CONVERTER, ComponentUtil.createValueBinding(binding));
137 } else {
138 valueHolder.setConverter(converter);
139 }
140 }
141 // TODO else LOG.warn?
142 return (SKIP_BODY);
143 }
144
145
146 /**
147 * <p>Release references to any acquired resources.
148 */
149 public void release() {
150 this.converterId = null;
151 this.binding = null;
152 }
153
154
155 }