package com.cyster.taglib.test;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletContext;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.ServletRequest;
import javax.servlet.jsp.PageContext;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;

public class PageContextTag extends BodyTagSupport {
  private String url = null;

  public void setUrl(String url) {
    this.url = url;
  }

  private void init() {
    url = null;
  }

  public void addParameter(String name, String value) {
    // handle this ...
  }

  public int doStartTag() throws JspException {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();

    try {
       pageContext.getOut().println(getTemplateUrl() + "<br />");

      pageContext.setAttribute("page_value", "testing testing 012",
        PageContext.PAGE_SCOPE);

      pageContext.setAttribute("request_value", "testing testing 123",
        PageContext.REQUEST_SCOPE);

      pageContext.setAttribute("session_value", "testing testing 234",
        PageContext.SESSION_SCOPE);

      PrintWriter writer = new PrintWriter(stream);
      pageContext.pushBody(writer);

      pageContext.include(getTemplateUrl());
      pageContext.popBody();

      writer.flush();
      pageContext.getOut().println("XXXXX<br/>");
      pageContext.getOut().println(stream.toString());
      pageContext.getOut().println("YYYYY<br/>");
 
    } catch (IOException e)  {
      throw new JspException(e);
    } catch (RuntimeException e) {
      throw new JspException(e);
    } catch (ServletException e) {
      Throwable rootCause = e.getRootCause();
      if (rootCause == null) {
        throw new JspException(e);
      } else {
        throw new JspException(rootCause);
      }
    }

    return EVAL_BODY_INCLUDE;
  }

  public int doEndTag() throws JspException {
    return EVAL_PAGE;
  }

  public void doFinally() {  
  }

  private String getTemplateUrl() {
    String templateUrl = this.url;

    if (!templateUrl.startsWith("/")) {
      String servletPath = (
        (HttpServletRequest)pageContext.getRequest()).getServletPath();
      templateUrl = servletPath.substring(0, servletPath.lastIndexOf('/'))
         + '/' + templateUrl;
     }

    return stripSession(templateUrl);
  }

 /**
  * Strips a servlet session ID from <tt>url</tt>.  The session ID
  * is encoded as a URL "path parameter" beginning with "jsessionid=".
  * We thus remove anything we find between ";jsessionid=" (inclusive)
  * and either EOS or a subsequent ';' (exclusive).
  */
  private String stripSession(String url) {
    StringBuffer result = new StringBuffer(url);
    int sessionStart;

    while ((sessionStart = result.toString().indexOf(";jsessionid=")) != -1) {
      int sessionEnd = result.toString().indexOf(";", sessionStart + 1);
      if (sessionEnd == -1) {
        sessionEnd = result.toString().indexOf("?", sessionStart + 1);
      }
      if (sessionEnd == -1) {  // still
        sessionEnd = result.length();
      }
      result.delete(sessionStart, sessionEnd);
    }

    return result.toString();
  }

}
