package moreservlets;

import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.util.StringTokenizer;

/** A SAX handler that returns an exception if either of
 *  the following two situations occurs:
 *  <UL>
 *    <LI>The designated outer tag is directly or indirectly
 *        nested within the outer tag (i.e., itself).
 *    <LI>The designated inner tag is <I>not</I> directly
 *        or indirectly nested within the outer tag.
 *  </UL>
 *  
 *  Taken from More Servlets and JavaServer Pages
 *  from Prentice Hall and Sun Microsystems Press,
 *  http://www.moreservlets.com/.
 *  &copy; 2002 Marty Hall; may be freely used or adapted.
 */

public class NestingHandler extends DefaultHandler {
  private String outerTagName = "outerTag";
  private String innerTagName = "innerTag";
  private boolean inOuterTag = false;

  public void startElement(String namespaceUri,
                           String localName,
                           String qualifiedName,
                           Attributes attributes)
      throws SAXException {
    String tagName = mainTagName(qualifiedName);
    if (tagName.equals(outerTagName)) {
      if (inOuterTag) {
        throw new SAXException("\nCannot nest " + outerTagName);
      }
      inOuterTag = true;
    } else if (tagName.equals(innerTagName) && !inOuterTag) {
      throw new SAXException("\n" + innerTagName +
                             " can only appear within " +
                             outerTagName);
    }
  }

  public void endElement(String namespaceUri,
                         String localName,
                         String qualifiedName)
      throws SAXException {
    String tagName = mainTagName(qualifiedName);
    if (tagName.equals(outerTagName)) {
      inOuterTag = false;
    }
  }

  private String mainTagName(String qualifiedName) {
    StringTokenizer tok =
      new StringTokenizer(qualifiedName, ":");
    tok.nextToken();
    return(tok.nextToken());
  }
}
