1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5 *
6 * Portions Copyright Apache Software Foundation.
7 *
8 * The contents of this file are subject to the terms of either the GNU
9 * General Public License Version 2 only ("GPL") or the Common Development
10 * and Distribution License("CDDL") (collectively, the "License"). You
11 * may not use this file except in compliance with the License. You can obtain
12 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
13 * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
14 * language governing permissions and limitations under the License.
15 *
16 * When distributing the software, include this License Header Notice in each
17 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
18 * Sun designates this particular file as subject to the "Classpath" exception
19 * as provided by Sun in the GPL Version 2 section of the License file that
20 * accompanied this code. If applicable, add the following below the License
21 * Header, with the fields enclosed by brackets [] replaced by your own
22 * identifying information: "Portions Copyrighted [year]
23 * [name of copyright owner]"
24 *
25 * Contributor(s):
26 *
27 * If you wish your version of this file to be governed by only the CDDL or
28 * only the GPL Version 2, indicate your decision by adding "[Contributor]
29 * elects to include this software in this distribution under the [CDDL or GPL
30 * Version 2] license." If you don't indicate a single choice of license, a
31 * recipient has the option to distribute your version of this file under
32 * either the CDDL, the GPL Version 2 or to extend the choice of license to
33 * its licensees as provided above. However, if you add GPL Version 2 code
34 * and therefore, elected the GPL Version 2 license, then the option applies
35 * only if the new code is made subject to such option by the copyright
36 * holder.
37 */
38
39 package javax.servlet.jsp.jstl.core;
40
41 import javax.servlet.jsp.JspException;
42 import javax.servlet.jsp.JspTagException;
43 import javax.servlet.jsp.PageContext;
44 import javax.servlet.jsp.tagext.TagSupport;
45
46 /**
47 * <p>Abstract class that facilitates implementation of conditional actions
48 * where the boolean result is exposed as a JSP scoped variable. The
49 * boolean result may then be used as the test condition in a <c:when>
50 * action.</p>
51 *
52 * <p>This base class provides support for:</p>
53 *
54 * <ul>
55 * <li> Conditional processing of the action's body based on the returned value
56 * of the abstract method <tt>condition()</tt>.</li>
57 * <li> Storing the result of <tt>condition()</tt> as a <tt>Boolean</tt> object
58 * into a JSP scoped variable identified by attributes <tt>var</tt> and
59 * <tt>scope</tt>.
60 * </ul>
61 *
62 * @author Shawn Bayern
63 */
64
65 public abstract class ConditionalTagSupport
66 extends TagSupport
67 {
68 //*********************************************************************
69 // Abstract methods
70
71 /**
72 * <p>Subclasses implement this method to compute the boolean result
73 * of the conditional action. This method is invoked once per tag invocation
74 * by <tt>doStartTag()</tt>.
75 *
76 * @return a boolean representing the condition that a particular subclass
77 * uses to drive its conditional logic.
78 */
79 protected abstract boolean condition() throws JspTagException;
80
81
82 //*********************************************************************
83 // Constructor
84
85 /**
86 * Base constructor to initialize local state. As with <tt>TagSupport</tt>,
87 * subclasses should not implement constructors with arguments, and
88 * no-argument constructors implemented by subclasses must call the
89 * superclass constructor.
90 */
91 public ConditionalTagSupport() {
92 super();
93 init();
94 }
95
96
97 //*********************************************************************
98 // Lifecycle management and implementation of conditional behavior
99
100 /**
101 * Includes its body if <tt>condition()</tt> evaluates to true.
102 */
103 public int doStartTag() throws JspException {
104
105 // execute our condition() method once per invocation
106 result = condition();
107
108 // expose variables if appropriate
109 exposeVariables();
110
111 // handle conditional behavior
112 if (result)
113 return EVAL_BODY_INCLUDE;
114 else
115 return SKIP_BODY;
116 }
117
118 /**
119 * Releases any resources this ConditionalTagSupport may have (or inherit).
120 */
121 public void release() {
122 super.release();
123 init();
124 }
125
126 //*********************************************************************
127 // Private state
128
129 private boolean result; // the saved result of condition()
130 private String var; // scoped attribute name
131 private int scope; // scoped attribute scope
132
133
134 //*********************************************************************
135 // Accessors
136
137 /**
138 * Sets the 'var' attribute.
139 *
140 * @param var Name of the exported scoped variable storing the result of
141 * <tt>condition()</tt>.
142 */
143 public void setVar(String var) {
144 this.var = var;
145 }
146
147 /**
148 * Sets the 'scope' attribute.
149 *
150 * @param scope Scope of the 'var' attribute
151 */
152 public void setScope(String scope) {
153 if (scope.equalsIgnoreCase("page"))
154 this.scope = PageContext.PAGE_SCOPE;
155 else if (scope.equalsIgnoreCase("request"))
156 this.scope = PageContext.REQUEST_SCOPE;
157 else if (scope.equalsIgnoreCase("session"))
158 this.scope = PageContext.SESSION_SCOPE;
159 else if (scope.equalsIgnoreCase("application"))
160 this.scope = PageContext.APPLICATION_SCOPE;
161 // TODO: Add error handling? Needs direction from spec.
162 }
163
164
165 //*********************************************************************
166 // Utility methods
167
168 // expose attributes if we have a non-null 'var'
169 private void exposeVariables() {
170 if (var != null)
171 pageContext.setAttribute(var, Boolean.valueOf(result), scope);
172 }
173
174 // initializes internal state
175 private void init() {
176 result = false; // not really necessary
177 var = null;
178 scope = PageContext.PAGE_SCOPE;
179 }
180 }