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 org.apache.myfaces.tobago.component.UICommand;
027 import org.apache.myfaces.tobago.TobagoConstants;
028
029 import javax.servlet.jsp.tagext.TagSupport;
030 import javax.servlet.jsp.JspException;
031 import javax.faces.webapp.UIComponentTag;
032 import javax.faces.component.UIComponent;
033 import javax.faces.component.EditableValueHolder;
034 import javax.faces.component.ValueHolder;
035 import javax.faces.el.ValueBinding;
036 import javax.faces.context.FacesContext;
037
038 /*
039 * Date: Oct 14, 2006
040 * Time: 1:47:13 PM
041 */
042
043 /**
044 * Add an attribute on the UIComponent
045 * associated with the closest parent UIComponent custom action.
046 */
047 @Tag(name = "attribute", bodyContent = BodyContent.EMPTY)
048 public class AttributeTag extends TagSupport {
049
050 private static final long serialVersionUID = 6231531736083277631L;
051
052 /**
053 * <p>The name of the attribute</p>
054 */
055 private String name;
056
057 /**
058 * <p>The value of the attribute</p>
059 */
060 private String value;
061
062 /**
063 * The name of a attribute.
064 *
065 * @param name A attribute name
066 */
067 @TagAttribute(required = true)
068 public void setName(String name) {
069 this.name = name;
070 }
071
072 /**
073 * The value of a attribute
074 *
075 * @param value A attribute value
076 */
077 @TagAttribute(required = true)
078 public void setValue(String value) {
079 this.value = value;
080 }
081
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 String attributeName = name;
105
106 if (UIComponentTag.isValueReference(name)) {
107 ValueBinding valueBinding = ComponentUtil.createValueBinding(name);
108 if (valueBinding != null) {
109 attributeName = (String) valueBinding.getValue(FacesContext.getCurrentInstance());
110 } else {
111 // TODO Message resource i18n
112 throw new JspException("Can not get ValueBinding for attribute name " + name);
113 }
114 }
115 if (component instanceof EditableValueHolder
116 && TobagoConstants.ATTR_VALIDATOR.equals(attributeName)) {
117 ComponentUtil.setValidator((EditableValueHolder) component, value);
118 } else if (component instanceof ValueHolder
119 && TobagoConstants.ATTR_CONVERTER.equals(attributeName)) {
120 ComponentUtil.setConverter((ValueHolder) component, value);
121 } else if (TobagoConstants.ATTR_STYLE_CLASS.equals(attributeName)) {
122 ComponentUtil.setStyleClasses(component, value);
123 } else if (TobagoConstants.ATTR_RENDERED_PARTIALLY.equals(attributeName)
124 && component instanceof UICommand) {
125 ComponentUtil.setRenderedPartially((UICommand) component, value);
126 } else if (UIComponentTag.isValueReference(value)) {
127 ValueBinding valueBinding = ComponentUtil.createValueBinding(value);
128 if (valueBinding != null) {
129 component.setValueBinding(name, valueBinding);
130 } else {
131 // TODO Message resource i18n
132 throw new JspException("Can not get ValueBinding for attribute value " + value);
133 }
134 } else {
135 component.getAttributes().put(attributeName, value);
136 }
137
138 return (SKIP_BODY);
139 }
140
141
142 /**
143 * <p>Release references to any acquired resources.
144 */
145 public void release() {
146 super.release();
147 this.name = null;
148 this.value = null;
149 }
150 }