/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 

package org.apache.taglibs.standard.tlv;

import java.io.*;
import java.util.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import org.apache.taglibs.standard.lang.support.ExpressionEvaluator;
import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;
import org.apache.taglibs.standard.resources.Resources;

/**
 * <p>A SAX-based TagLibraryValidator for the core JSTL tag library.
 * Currently implements the following checks:</p>
 * 
 * <ul>
 *   <li>Expression syntax validation.
 *   <li>Choose / when / otherwise constraints</li>
 *   <li>Tag bodies that must either be empty or non-empty given
 *      particular attributes.  (E.g., <set> cannot have a body when
 *      'value' is specified; it *must* have a body otherwise.)  For
 *      these purposes, "having a body" refers to non-whitespace
 *      content inside the tag.</li>
 *   <li>Other minor constraints.</li>
 * </ul>
 * 
 * @author Shawn Bayern
 */
public class JstlCoreTLV extends JstlBaseTLV {

    //*********************************************************************
    // Implementation Overview

    /*
     * We essentially just run the page through a SAX parser, handling
     * the callbacks that interest us.  We collapse <jsp:text> elements
     * into the text they contain, since this simplifies processing
     * somewhat.  Even a quick glance at the implementation shows its
     * necessary, tree-oriented nature:  multiple Stacks, an understanding
     * of 'depth', and so on all are important as we recover necessary
     * state upon each callback.  This TLV demonstrates various techniques,
     * from the general "how do I use a SAX parser for a TLV?" to
     * "how do I read my init parameters and then validate?"  But also,
     * the specific SAX methodology was kept as general as possible to
     * allow for experimentation and flexibility.
     */


    //*********************************************************************
    // Constants

    // tag names
    private final String CHOOSE = "choose";
    private final String WHEN = "when";
    private final String OTHERWISE = "otherwise";
    private final String EXPR = "out";
    private final String SET = "set";
    private final String IMPORT = "import";
    private final String URL = "url";
    private final String REDIRECT = "redirect";
    private final String PARAM = "param";
    // private final String EXPLANG = "expressionLanguage";
    private final String TEXT = "text";

    // attribute names
    private final String EVAL = "evaluator";
    private final String VALUE = "value";
    private final String DEFAULT = "default";
    private final String VAR_READER = "varReader";

    // alternative identifiers for tags
    private final String IMPORT_WITH_READER = "import varReader=''";
    private final String IMPORT_WITHOUT_READER = "import var=''";


    //*********************************************************************
    // Contract fulfillment

    protected DefaultHandler getHandler() {
	return new Handler();
    }


    //*********************************************************************
    // SAX event handler

    /** The handler that provides the base of our implementation. */
    private class Handler extends DefaultHandler {

	// parser state
	private int depth = 0;
	private Stack chooseDepths = new Stack();
	private Stack chooseHasOtherwise = new Stack();
	private Stack chooseHasWhen = new Stack();
        private Stack urlTags = new Stack();
	private String lastElementName = null;
	private boolean bodyNecessary = false;
	private boolean bodyIllegal = false;

	// process under the existing context (state), then modify it
	public void startElement(
	        String ns, String ln, String qn, Attributes a) {

	    // substitute our own parsed 'ln' if it's not provided
	    if (ln == null)
		ln = getLocalPart(qn);

	    // for simplicity, we can ignore <jsp:text> for our purposes
	    // (don't bother distinguishing between it and its characters)
	    if (isJspTag(ns, ln, TEXT))
		return;

	    // check body-related constraint
	    if (bodyIllegal)
		fail(Resources.getMessage("TLV_ILLEGAL_BODY", lastElementName));

	    // validate expression syntax if we need to
	    Set expAtts;
	    if (qn.startsWith(prefix + ":")
		    && (expAtts = (Set) config.get(ln)) != null) {
		for (int i = 0; i < a.getLength(); i++) {
		    String attName = a.getLocalName(i);
		    if (expAtts.contains(attName)) {
			String vMsg =
			    validateExpression(
				ln,
				attName,
				a.getValue(i));
			if (vMsg != null)
			    fail(vMsg);
		    }
		}
	    }

            // validate attributes
            if (qn.startsWith(prefix + ":") && !hasNoInvalidScope(a))
                fail(Resources.getMessage("TLV_INVALID_ATTRIBUTE",
                    SCOPE, qn, a.getValue(SCOPE))); 
	    if (qn.startsWith(prefix + ":") && hasEmptyVar(a))
		fail(Resources.getMessage("TLV_EMPTY_VAR", qn));
	    if (qn.startsWith(prefix + ":") && hasDanglingScope(a))
		fail(Resources.getMessage("TLV_DANGLING_SCOPE", qn));

	    // check invariants for <choose>
	    if (chooseChild()) {
		// mark <choose> for the first the first <when>
		if (isCoreTag(ns, ln, WHEN)) {
		    chooseHasWhen.pop();
		    chooseHasWhen.push(new Boolean(true));
		}

		// ensure <choose> has the right children
		if(!isCoreTag(ns, ln, WHEN) && !isCoreTag(ns, ln, OTHERWISE)) {
		    fail(Resources.getMessage("TLV_ILLEGAL_CHILD_TAG",
			prefix, CHOOSE, qn));
		}

		// make sure <otherwise> is the last tag
		if (((Boolean) chooseHasOtherwise.peek()).booleanValue()) {
		   fail(Resources.getMessage("TLV_ILLEGAL_ORDER",
			qn, prefix, OTHERWISE, CHOOSE));
		}
		if (isCoreTag(ns, ln, OTHERWISE)) {
		    chooseHasOtherwise.pop();
		    chooseHasOtherwise.push(new Boolean(true));
		}

	    }

	    // check constraints for <param> vis-a-vis URL-related tags
	    if (isCoreTag(ns, ln, PARAM)) {
		// no <param> outside URL tags.
		if (urlTags.empty() || urlTags.peek().equals(PARAM))
		    fail(Resources.getMessage("TLV_ILLEGAL_ORPHAN", PARAM));

		// no <param> where the most recent <import> has a reader
		if (!urlTags.empty() &&
			urlTags.peek().equals(IMPORT_WITH_READER))
		    fail(Resources.getMessage("TLV_ILLEGAL_PARAM",
			prefix, PARAM, IMPORT, VAR_READER));
	    } else {
		// tag ISN'T <param>, so it's illegal under non-reader <import>
		if (!urlTags.empty()
			&& urlTags.peek().equals(IMPORT_WITHOUT_READER))
		    fail(Resources.getMessage("TLV_ILLEGAL_CHILD_TAG",
			prefix, IMPORT, qn));
	    }

	    // now, modify state

	    // we're a choose, so record new choose-specific state
	    if (isCoreTag(ns, ln, CHOOSE)) {
		chooseDepths.push(new Integer(depth));
		chooseHasWhen.push(new Boolean(false));
		chooseHasOtherwise.push(new Boolean(false));
	    }

	    // if we're introducing a URL-related tag, record it
	    if (isCoreTag(ns, ln, IMPORT)) {
		if (hasAttribute(a, VAR_READER))
		    urlTags.push(IMPORT_WITH_READER);
		else
		    urlTags.push(IMPORT_WITHOUT_READER);
	    } else if (isCoreTag(ns, ln, PARAM))
		urlTags.push(PARAM);
	    else if (isCoreTag(ns, ln, REDIRECT))
		urlTags.push(REDIRECT);
	    else if (isCoreTag(ns, ln, URL))
		urlTags.push(URL);

	    // set up a check against illegal attribute/body combinations
	    bodyIllegal = false;
	    bodyNecessary = false;
	    if (isCoreTag(ns, ln, EXPR)) {
		if (hasAttribute(a, DEFAULT))
		    bodyIllegal = true;
	    } else if (isCoreTag(ns, ln, SET)) {
		if (hasAttribute(a, VALUE))
		    bodyIllegal = true;
		// else
		//    bodyNecessary = true;
	    }

	    // record the most recent tag (for error reporting)
	    lastElementName = qn;
	    lastElementId = a.getValue(JSP, "id");

	    // we're a new element, so increase depth
	    depth++;
	}

	public void characters(char[] ch, int start, int length) {

	    bodyNecessary = false;		// body is no longer necessary!

	    // ignore strings that are just whitespace
	    String s = new String(ch, start, length).trim();
	    if (s.equals(""))
		return;

	    // check and update body-related constraints
	    if (bodyIllegal)
		fail(Resources.getMessage("TLV_ILLEGAL_BODY", lastElementName));
	    if (!urlTags.empty()
		    && urlTags.peek().equals(IMPORT_WITHOUT_READER)) {
		// we're in an <import> without a Reader; nothing but
		// <param> is allowed
		fail(Resources.getMessage("TLV_ILLEGAL_BODY",
		    prefix + ":" + IMPORT));
	    }

	    // make sure <choose> has no non-whitespace text
	    if (chooseChild()) {
		String msg = 
		    Resources.getMessage("TLV_ILLEGAL_TEXT_BODY",
			prefix, CHOOSE,
			(s.length() < 7 ? s : s.substring(0,7)));
		fail(msg);
	    }
	}

	public void endElement(String ns, String ln, String qn) {

	    // consistently, we ignore JSP_TEXT
	    if (isJspTag(ns, ln, TEXT))
		return;

	    // handle body-related invariant
	    if (bodyNecessary)
		fail(Resources.getMessage("TLV_MISSING_BODY",
		    lastElementName));
	    bodyIllegal = false;	// reset: we've left the tag

	    // update <choose>-related state
	    if (isCoreTag(ns, ln, CHOOSE)) {
		Boolean b = (Boolean) chooseHasWhen.pop();
		if (!b.booleanValue())
		    fail(Resources.getMessage("TLV_PARENT_WITHOUT_SUBTAG",
			CHOOSE, WHEN));
		chooseDepths.pop();
		chooseHasOtherwise.pop();
	    }

	    // update state related to URL tags
	    if (isCoreTag(ns, ln, IMPORT)
                    || isCoreTag(ns, ln, PARAM)
		    || isCoreTag(ns, ln, REDIRECT)
		    || isCoreTag(ns, ln, URL))
		urlTags.pop();

	    // update our depth
	    depth--;
	}

	// are we directly under a <choose>?
	private boolean chooseChild() {
	    return (!chooseDepths.empty()
		&& (depth - 1) == ((Integer) chooseDepths.peek()).intValue());
	}

	// returns the top int depth (peeked at) from a Stack of Integer
	private int topDepth(Stack s) {
	    if (s == null || s.empty())
		return -1;
	    else
		return ((Integer) s.peek()).intValue();
	}
	
    }
}
