Package de.odysseus.calyxo.base.taglib.html

Source Code of de.odysseus.calyxo.base.taglib.html.AbstractTag

/*
* Copyright 2004, 2005, 2006 Odysseus Software GmbH
*
* 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 de.odysseus.calyxo.base.taglib.html;

import java.io.IOException;

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

/**
* Abstract base class for all HTML tags.
* <p/>
* Subclasses pass the tag name and a boolean indicating if the tag
* takes a body to the constructor.
* <p/>
* Subclasses may override the <code>init()</code> method, which is
* called when tag execution begins.
* <p/>
* Subclasses should override the <code>reset()</code> method to
* reset their additional fields.
* <p/>
* Subclasses will have to provide public Setters for their additional
* tag properties. Subclasses should implement <code>protected</code>
* methods to receive attributes to be rendered (at least for attributes
* that are considered to customized by subclasses).
* By convention, these methods should look like
* <pre>
* protected String getXyzAttribute() throws Exception {
*   ...
* }
* </pre>
* to get their additional attributes rendered, subclasses should then
* override the <code>appendAttributes()</code> method like this:
* <pre>
* protected void appendAttributes(StringBuffer buffer) throws Exception {
*   super.appendAttributes(buffer);
*   ...
*   append(buffer, "xyz", getXyzAttribute());
*   ...
* }
* </pre>
* That way, all attributes with a non-<code>null</code> value will get
* rendered.
*
* @author Christoph Beck
*/
public abstract class AbstractTag implements Tag {
  private String id; 

  protected PageContext pageContext;
  private Tag parent;
  private String name;
  private boolean body;

  /**
   * Constructor.
   *
   * @param name tag name
   * @param body <code>true</code> iff this tag has a body
   */
  protected AbstractTag(String name, boolean body) {
    this.name = name;
    this.body = body;
  }

  /**
   * Answer nearest <code>AbstractTag</code> ancestor
   * which is assignable to the specified class.
   */
  protected final AbstractTag findAncestor(Class type) {
    if (type == null) {
      return null;
    }
    Tag tag = parent;
    while (tag != null) {
      if (tag instanceof AbstractTag) {
        if (type.isAssignableFrom(tag.getClass())) {
          return (AbstractTag)tag;
        }
      }
      tag = tag.getParent();
    }
    return null;
  }

  /**
   * Answer nearest <code>AbstractTag</code> anchestor.
   */
  protected final AbstractTag findParent() {
    return findAncestor(AbstractTag.class);
  }

  /**
   * Escape special characters
   * <code>&lt;</code>,
   * <code>&gt;</code>,
   * <code>&amp;</code>,
   * <code>&quot;</code>.
   * Subclasses are responsible to call this method to provide
   * filtered attribute values and body content.
   */
  protected String filter(String value) {
    if (value == null)
      return null;

    char chars[] = new char[value.length()];
    value.getChars(0, value.length(), chars, 0);
    StringBuffer result = new StringBuffer(chars.length + 20);
    for (int i = 0; i < chars.length; i++) {
      switch (chars[i]) {
      case '<':
        result.append("&lt;");
        break;
      case '>':
        result.append("&gt;");
        break;
      case '&':
        result.append("&amp;");
        break;
      case '"':
        result.append("&quot;");
        break;
      default:
        result.append(chars[i]);
      }
    }
    return result.toString();
  }

  /**
   * Append a single attribute <code>" name=value"</code> (with a leading
   * blank) to specified buffer. This method may be called by
   * {@link #appendAttributes(StringBuffer)} to render attributes.
   * The attribute gets appended, iff the <code>value</code> parameter
   * is not <code>null</code>.
   * <p/>
   */
  protected final void append(StringBuffer buffer, String name, String value) {
    if (value != null) {
      buffer.append(" ");
      buffer.append(name);
      buffer.append("=\"");
      buffer.append(value);
      buffer.append("\"");
    }
  }

  /**
   * Append attributes to be rendered to the specified buffer.
   * Should be overridden by subclasses to add their additional
   * attributes.
   * By convention, the String for attribute <code>xyz</code> is
   * accessed via method <code>getXyzAttribute()</code>, which
   * might declare to throw an exception.
   */
  protected void appendAttributes(StringBuffer buffer) throws Exception {
    append(buffer, "id", getIdAttribute());
  }

  /**
   * Initialize tag execution. This method is called
   * after tag attribute properties have been populated.
   * May be overridden by subclasses.
   * This base implementation does nothing.
   * @throws Exception
   */
  protected void init() throws Exception {
  }

  /**
   * Reset fields to their initial values.
   * This method is called at the end of tag execution.
   * Should be overridden by subclasses.
   */
  protected void reset() {
    id = null;
  }

  /**
   * Get the tag body contents to be rendered.
   * May be overridden by subclasses, that specify <code>body == true</code>.
   * If this method returns <code>null</code>, the jsp tag body will be
   * evaluated and included. Otherwise, the returned string will be
   * inserted.
   */
  protected String getBodyContent() throws Exception {
    return null;
  }

  private void render(StringBuffer s) throws JspException {
    if (s.length() > 0) {
      try {
        pageContext.getOut().print(s.toString());
      } catch (IOException e) {
        throw new JspException(e);
      }
    }
  }

  /*
   * (non-Javadoc)
   * @see javax.servlet.jsp.tagext.Tag#doStartTag()
   */
  public final int doStartTag() throws JspException {
    try {
      init();
    } catch (Exception e) {
      throw new JspException(e);
    }
    StringBuffer s = new StringBuffer();
    if (name != null) {
      s.append("<");
      s.append(name);
      try {
        appendAttributes(s);
      } catch (Exception e) {
        throw new JspException(e);
      }
      s.append(body ? ">" : "/>");
    }
    if (body) {
      try {
        String content = getBodyContent();
        if (content != null) {
          s.append(content);
          render(s);
          return SKIP_BODY;
        }
      } catch (Exception e) {
        throw new JspException(e);
      }
      render(s);
      return EVAL_BODY_INCLUDE;
    } else {
      render(s);
      return SKIP_BODY;
    }
  }

  /*
   * (non-Javadoc)
   * @see javax.servlet.jsp.tagext.Tag#doEndTag()
   */
  public final int doEndTag() throws JspException {
    if (name != null && body) {
      StringBuffer s = new StringBuffer();
      s.append("</");
      s.append(name);
      s.append(">");
      render(s);
    }
    reset();
    return EVAL_PAGE;
  }

  /*
   * (non-Javadoc)
   * @see javax.servlet.jsp.tagext.Tag#release()
   */
  public void release() {
  }

  /**
   * Get id property
   */
  public final String getId() {
    return id;
  }

  /**
   * Set id property
   */
  public final void setId(String string) {
    id = string;
  }

  /**
   * Get id attribute
   */
  protected String getIdAttribute() throws Exception {
    return id;
  }

  /* (non-Javadoc)
   * @see javax.servlet.jsp.tagext.Tag#getParent()
   */
  public final Tag getParent() {
    return parent;
  }

  /* (non-Javadoc)
   * @see javax.servlet.jsp.tagext.Tag#setPageContext(javax.servlet.jsp.PageContext)
   */
  public final void setPageContext(PageContext value) {
    pageContext = value;
  }

  /* (non-Javadoc)
   * @see javax.servlet.jsp.tagext.Tag#setParent(javax.servlet.jsp.tagext.Tag)
   */
  public final void setParent(Tag value) {
    parent = value;
  }

}
TOP

Related Classes of de.odysseus.calyxo.base.taglib.html.AbstractTag

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.