001: /*
002: * Copyright 2002-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.web.util;
018:
019: import javax.servlet.jsp.PageContext;
020: import javax.servlet.jsp.tagext.Tag;
021:
022: import org.springframework.util.Assert;
023:
024: /**
025: * Utility class for tag library related code, exposing functionality
026: * such as translating {@link String Strings} to web scopes.
027: *
028: * <p>
029: * <ul>
030: * <li><code>page</code> will be transformed to
031: * {@link javax.servlet.jsp.PageContext#PAGE_SCOPE PageContext.PAGE_SCOPE}
032: * <li><code>request</code> will be transformed to
033: * {@link javax.servlet.jsp.PageContext#REQUEST_SCOPE PageContext.REQUEST_SCOPE}
034: * <li><code>session</code> will be transformed to
035: * {@link javax.servlet.jsp.PageContext#SESSION_SCOPE PageContext.SESSION_SCOPE}
036: * <li><code>application</code> will be transformed to
037: * {@link javax.servlet.jsp.PageContext#APPLICATION_SCOPE PageContext.APPLICATION_SCOPE}
038: * </ul>
039: *
040: * @author Alef Arendsen
041: * @author Rob Harrop
042: * @author Juergen Hoeller
043: * @author Rick Evans
044: */
045: public abstract class TagUtils {
046:
047: /** Constant identifying the page scope */
048: public static final String SCOPE_PAGE = "page";
049:
050: /** Constant identifying the request scope */
051: public static final String SCOPE_REQUEST = "request";
052:
053: /** Constant identifying the session scope */
054: public static final String SCOPE_SESSION = "session";
055:
056: /** Constant identifying the application scope */
057: public static final String SCOPE_APPLICATION = "application";
058:
059: /**
060: * Determines the scope for a given input <code>String</code>.
061: * <p>If the <code>String</code> does not match 'request', 'session',
062: * 'page' or 'application', the method will return {@link PageContext#PAGE_SCOPE}.
063: * @param scope the <code>String</code> to inspect
064: * @return the scope found, or {@link PageContext#PAGE_SCOPE} if no scope matched
065: * @throws IllegalArgumentException if the supplied <code>scope</code> is <code>null</code>
066: */
067: public static int getScope(String scope) {
068: Assert.notNull(scope, "Scope to search for cannot be null");
069: if (scope.equals(SCOPE_REQUEST)) {
070: return PageContext.REQUEST_SCOPE;
071: } else if (scope.equals(SCOPE_SESSION)) {
072: return PageContext.SESSION_SCOPE;
073: } else if (scope.equals(SCOPE_APPLICATION)) {
074: return PageContext.APPLICATION_SCOPE;
075: } else {
076: return PageContext.PAGE_SCOPE;
077: }
078: }
079:
080: /**
081: * Determine whether the supplied {@link Tag} has any ancestor tag
082: * of the supplied type.
083: * @param tag the tag whose ancestors are to be checked
084: * @param ancestorTagClass the ancestor {@link Class} being searched for
085: * @return <code>true</code> if the supplied {@link Tag} has any ancestor tag
086: * of the supplied type
087: * @throws IllegalArgumentException if either of the supplied arguments is <code>null</code>;
088: * or if the supplied <code>ancestorTagClass</code> is not type-assignable to
089: * the {@link Tag} class
090: */
091: public static boolean hasAncestorOfType(Tag tag,
092: Class ancestorTagClass) {
093: Assert.notNull(tag, "Tag cannot be null");
094: Assert.notNull(ancestorTagClass,
095: "Ancestor tag class cannot be null");
096: if (!Tag.class.isAssignableFrom(ancestorTagClass)) {
097: throw new IllegalArgumentException("Class '"
098: + ancestorTagClass.getName()
099: + "' is not a valid Tag type");
100: }
101: Tag ancestor = tag.getParent();
102: while (ancestor != null) {
103: if (ancestorTagClass.isAssignableFrom(ancestor.getClass())) {
104: return true;
105: }
106: ancestor = ancestor.getParent();
107: }
108: return false;
109: }
110:
111: /**
112: * Determine whether the supplied {@link Tag} has any ancestor tag
113: * of the supplied type, throwing an {@link IllegalStateException}
114: * if not.
115: * @param tag the tag whose ancestors are to be checked
116: * @param ancestorTagClass the ancestor {@link Class} being searched for
117: * @param tagName the name of the <code>tag</code>; for example '<code>option</code>'
118: * @param ancestorTagName the name of the ancestor <code>tag</code>; for example '<code>select</code>'
119: * @throws IllegalStateException if the supplied <code>tag</code> does not
120: * have a tag of the supplied <code>parentTagClass</code> as an ancestor
121: * @throws IllegalArgumentException if any of the supplied arguments is <code>null</code>,
122: * or in the case of the {@link String}-typed arguments, is composed wholly
123: * of whitespace; or if the supplied <code>ancestorTagClass</code> is not
124: * type-assignable to the {@link Tag} class
125: * @see #hasAncestorOfType(javax.servlet.jsp.tagext.Tag, Class)
126: */
127: public static void assertHasAncestorOfType(Tag tag,
128: Class ancestorTagClass, String tagName,
129: String ancestorTagName) {
130: Assert.hasText(tagName, "'tagName' must not be empty");
131: Assert.hasText(ancestorTagName,
132: "'ancestorTagName' must not be empty");
133: if (!TagUtils.hasAncestorOfType(tag, ancestorTagClass)) {
134: throw new IllegalStateException("The '" + tagName
135: + "' tag can only be used inside a valid '"
136: + ancestorTagName + "' tag.");
137: }
138: }
139:
140: }
|