Open Source Repository

Home /spring/spring-web-3.0.5 | Repository Home



org/springframework/web/util/TagUtils.java
/*
 * Copyright 2002-2006 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.util;

import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;

import org.springframework.util.Assert;

/**
 * Utility class for tag library related code, exposing functionality
 * such as translating {@link String Strings} to web scopes.
 *
 <p>
 <ul>
 <li><code>page</code> will be transformed to
 {@link javax.servlet.jsp.PageContext#PAGE_SCOPE PageContext.PAGE_SCOPE}
 <li><code>request</code> will be transformed to
 {@link javax.servlet.jsp.PageContext#REQUEST_SCOPE PageContext.REQUEST_SCOPE}
 <li><code>session</code> will be transformed to
 {@link javax.servlet.jsp.PageContext#SESSION_SCOPE PageContext.SESSION_SCOPE}
 <li><code>application</code> will be transformed to
 {@link javax.servlet.jsp.PageContext#APPLICATION_SCOPE PageContext.APPLICATION_SCOPE}
 </ul>
 *
 @author Alef Arendsen
 @author Rob Harrop
 @author Juergen Hoeller
 @author Rick Evans
 */
public abstract class TagUtils {

  /** Constant identifying the page scope */
  public static final String SCOPE_PAGE = "page";

  /** Constant identifying the request scope */
  public static final String SCOPE_REQUEST = "request";

  /** Constant identifying the session scope */
  public static final String SCOPE_SESSION = "session";

  /** Constant identifying the application scope */
  public static final String SCOPE_APPLICATION = "application";


  /**
   * Determines the scope for a given input <code>String</code>.
   <p>If the <code>String</code> does not match 'request', 'session',
   * 'page' or 'application', the method will return {@link PageContext#PAGE_SCOPE}.
   @param scope the <code>String</code> to inspect
   @return the scope found, or {@link PageContext#PAGE_SCOPE} if no scope matched
   @throws IllegalArgumentException if the supplied <code>scope</code> is <code>null</code> 
   */
  public static int getScope(String scope) {
    Assert.notNull(scope, "Scope to search for cannot be null");
    if (scope.equals(SCOPE_REQUEST)) {
      return PageContext.REQUEST_SCOPE;
    }
    else if (scope.equals(SCOPE_SESSION)) {
      return PageContext.SESSION_SCOPE;
    }
    else if (scope.equals(SCOPE_APPLICATION)) {
      return PageContext.APPLICATION_SCOPE;
    }
    else {
      return PageContext.PAGE_SCOPE;
    }
  }

  /**
   * Determine whether the supplied {@link Tag} has any ancestor tag
   * of the supplied type.
   @param tag the tag whose ancestors are to be checked
   @param ancestorTagClass the ancestor {@link Class} being searched for
   @return <code>true</code> if the supplied {@link Tag} has any ancestor tag
   * of the supplied type
   @throws IllegalArgumentException if either of the supplied arguments is <code>null</code>;
   * or if the supplied <code>ancestorTagClass</code> is not type-assignable to
   * the {@link Tag} class 
   */
  public static boolean hasAncestorOfType(Tag tag, Class ancestorTagClass) {
    Assert.notNull(tag, "Tag cannot be null");
    Assert.notNull(ancestorTagClass, "Ancestor tag class cannot be null");
    if (!Tag.class.isAssignableFrom(ancestorTagClass)) {
      throw new IllegalArgumentException(
          "Class '" + ancestorTagClass.getName() "' is not a valid Tag type");
    }
    Tag ancestor = tag.getParent();
    while (ancestor != null) {
      if (ancestorTagClass.isAssignableFrom(ancestor.getClass())) {
        return true;
      }
      ancestor = ancestor.getParent();
    }
    return false;
  }

  /**
   * Determine whether the supplied {@link Tag} has any ancestor tag
   * of the supplied type, throwing an {@link IllegalStateException}
   * if not.
   @param tag the tag whose ancestors are to be checked
   @param ancestorTagClass the ancestor {@link Class} being searched for
   @param tagName the name of the <code>tag</code>; for example '<code>option</code>'
   @param ancestorTagName the name of the ancestor <code>tag</code>; for example '<code>select</code>'
   @throws IllegalStateException if the supplied <code>tag</code> does not
   * have a tag of the supplied <code>parentTagClass</code> as an ancestor
   @throws IllegalArgumentException if any of the supplied arguments is <code>null</code>,
   * or in the case of the {@link String}-typed arguments, is composed wholly
   * of whitespace; or if the supplied <code>ancestorTagClass</code> is not
   * type-assignable to the {@link Tag} class 
   @see #hasAncestorOfType(javax.servlet.jsp.tagext.Tag, Class)
   */
  public static void assertHasAncestorOfType(Tag tag, Class ancestorTagClass, String tagName, String ancestorTagName) {
    Assert.hasText(tagName, "'tagName' must not be empty");
    Assert.hasText(ancestorTagName, "'ancestorTagName' must not be empty");
    if (!TagUtils.hasAncestorOfType(tag, ancestorTagClass)) {
      throw new IllegalStateException("The '" + tagName + "' tag can only be used inside a valid '" + ancestorTagName + "' tag.");
    }
  }

}