/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.faces.webapp;
import javax.el.
ELException;
import javax.el.
ELContext;
import javax.el.
ValueExpression;
import javax.faces.
FacesException;
import javax.faces.application.
Application;
import javax.faces.component.
UIComponent;
import javax.faces.context.
FacesContext;
import javax.servlet.jsp.
JspException;
import javax.servlet.jsp.tagext.
Tag;
/**
* <p>{@link UIComponentELTag} specializes its superclass to allow for
* properties that take their values from EL API expressions.</p>
*
* <p>This tag is designed for use with Faces version 1.2 and JSP
* version 2.1 containers.</p>
*
*/
public abstract class
UIComponentELTag extends
UIComponentClassicTagBase implements
Tag {
// ------------------------------------------------------------- Attributes
/**
* <p>The value binding expression (if any) used to wire up this component
* to a {@link UIComponent} property of a JavaBean class.</p>
*/
private
ValueExpression binding = null;
/**
* <p>Set the value expression for our component.</p>
*
* @param binding The new value expression
*
* @throws JspException if an error occurs
*/
public void
setBinding(
ValueExpression binding) throws
JspException {
this.
binding =
binding;
}
protected boolean
hasBinding() {
return null !=
binding;
}
/**
* <p>An override for the rendered attribute associated with our
* {@link UIComponent}.</p>
*/
private
ValueExpression rendered = null;
/**
* <p>Set an override for the rendered attribute.</p>
*
* @param rendered The new value for rendered attribute
*/
public void
setRendered(
ValueExpression rendered) {
this.
rendered =
rendered;
}
/**
* <p>Return the {@link ELContext} for the {@link FacesContext} for
* this request.</p>
*
* <p>This is a convenience for
* <code>getFacesContext().getELContext()</code>.</p>
*/
protected
ELContext getELContext() {
FacesContext fc =
getFacesContext();
ELContext result = null;
if (null !=
fc) {
result =
fc.
getELContext();
}
return
result;
}
// ------------------------------------------------------------ Tag Methods
/**
* <p>Release any resources allocated during the execution of this
* tag handler.</p>
*/
public void
release() {
this.
binding = null;
this.
rendered = null;
super.release();
}
// ------------------------------------------------------- Protected Methods
/**
* <p>Override properties and attributes of the specified component,
* if the corresponding properties of this tag handler instance were
* explicitly set. This method must be called <strong>ONLY</strong>
* if the specified {@link UIComponent} was in fact created during
* the execution of this tag handler instance, and this call will occur
* <strong>BEFORE</strong> the {@link UIComponent} is added to
* the view.</p>
*
* <p>Tag subclasses that want to support additional set properties
* must ensure that the base class <code>setProperties()</code>
* method is still called. A typical implementation that supports
* extra properties <code>foo</code> and <code>bar</code> would look
* something like this:</p>
* <pre>
* protected void setProperties(UIComponent component) {
* super.setProperties(component);
* if (foo != null) {
* component.setAttribute("foo", foo);
* }
* if (bar != null) {
* component.setAttribute("bar", bar);
* }
* }
* </pre>
*
* <p>The default implementation overrides the following properties:</p>
* <ul>
* <li><code>rendered</code> - Set if a value for the
* <code>rendered</code> property is specified for
* this tag handler instance.</li>
* <li><code>rendererType</code> - Set if the <code>getRendererType()</code>
* method returns a non-null value.</li>
* </ul>
*
* @param component {@link UIComponent} whose properties are to be
* overridden
*/
protected void
setProperties(
UIComponent component) {
// The "id" property is explicitly set when components are created
// so it does not need to be set here
if (
rendered != null) {
if (
rendered.
isLiteralText()) {
try {
component.
setRendered(
Boolean.
valueOf(
rendered.
getExpressionString())
.
booleanValue());
} catch (
ELException e) {
throw new
FacesException(
e);
}
} else {
component.
setValueExpression("rendered",
rendered);
}
}
if (
getRendererType() != null) {
component.
setRendererType(
getRendererType());
}
}
/**
* <p>Create and return a new child component of the type returned by
* calling <code>getComponentType()</code>. If this {@link UIComponentELTag}
* has a non-null <code>binding</code> attribute, this is done by
* call {@link Application#createComponent} with the {@link ValueExpression}
* created for the <code>binding</code> attribute, and the
* {@link ValueExpression} will be stored on the component. Otherwise,
* {@link Application#createComponent} is called with only
* the component type. Finally, initialize the components id
* and other properties.
* </p>
* @param context {@link FacesContext} for the current request
* @param newId id of the component
*/
protected
UIComponent createComponent(
FacesContext context,
String newId) throws
JspException {
UIComponent component;
Application application =
context.
getApplication();
if (
binding != null) {
component =
application.
createComponent(
binding,
context,
getComponentType());
component.
setValueExpression("binding",
binding);
} else {
component =
application.
createComponent(
getComponentType());
}
component.
setId(
newId);
setProperties(
component);
return
component;
}
}