/* | |
* Licensed to the Apache Software Foundation (ASF) under one or more | |
* contributor license agreements. See the NOTICE file distributed with | |
* this work for additional information regarding copyright ownership. | |
* The ASF licenses this file to You 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.apache.struts2.jasper.tagplugins.jstl.core; | |
import org.apache.struts2.jasper.compiler.tagplugin.TagPlugin; | |
import org.apache.struts2.jasper.compiler.tagplugin.TagPluginContext; | |
import org.apache.struts2.jasper.tagplugins.jstl.Util; | |
public class Import implements TagPlugin { | |
public void doTag(TagPluginContext ctxt) { | |
boolean hasContext, hasVar, hasScope, hasVarReader, hasCharEncoding; | |
//flags | |
hasContext = ctxt.isAttributeSpecified("context"); | |
hasVar = ctxt.isAttributeSpecified("var"); | |
hasScope = ctxt.isAttributeSpecified("scope"); | |
hasVarReader = ctxt.isAttributeSpecified("varReader"); | |
hasCharEncoding = ctxt.isAttributeSpecified("charEncoding"); | |
//variables' names | |
String urlName = ctxt.getTemporaryVariableName(); | |
String contextName = ctxt.getTemporaryVariableName(); | |
String iauName = ctxt.getTemporaryVariableName(); // is absolute url | |
String urlObjName = ctxt.getTemporaryVariableName(); //URL object | |
String ucName = ctxt.getTemporaryVariableName(); //URLConnection | |
String inputStreamName = ctxt.getTemporaryVariableName(); | |
String tempReaderName = ctxt.getTemporaryVariableName(); | |
String tempReaderName2 = ctxt.getTemporaryVariableName(); | |
String charSetName = ctxt.getTemporaryVariableName(); | |
String charEncodingName = ctxt.getTemporaryVariableName(); | |
String contentTypeName = ctxt.getTemporaryVariableName(); | |
String varReaderName = ctxt.getTemporaryVariableName(); | |
String servletContextName = ctxt.getTemporaryVariableName(); | |
String servletPathName = ctxt.getTemporaryVariableName(); | |
String requestDispatcherName = ctxt.getTemporaryVariableName(); | |
String irwName = ctxt.getTemporaryVariableName(); //ImportResponseWrapper name | |
String brName = ctxt.getTemporaryVariableName(); //BufferedReader name | |
String sbName = ctxt.getTemporaryVariableName(); //StringBuffer name | |
String tempStringName = ctxt.getTemporaryVariableName(); | |
//is absolute url | |
ctxt.generateJavaSource("boolean " + iauName + ";"); | |
//get the url value | |
ctxt.generateJavaSource("String " + urlName + " = "); | |
ctxt.generateAttribute("url"); | |
ctxt.generateJavaSource(";"); | |
//validate the url | |
ctxt.generateJavaSource("if(" + urlName + " == null || " + urlName + ".equals(\"\")){"); | |
ctxt.generateJavaSource(" throw new JspTagException(\"The \\\"url\\\" attribute " + | |
"illegally evaluated to \\\"null\\\" or \\\"\\\" in <import>\");"); | |
ctxt.generateJavaSource("}"); | |
//initialize the is_absolute_url | |
ctxt.generateJavaSource(iauName + " = " + | |
"org.apache.struts2.jasper.tagplugins.jstl.Util.isAbsoluteUrl(" + urlName + ");"); | |
//validate the context | |
if(hasContext){ | |
ctxt.generateJavaSource("String " + contextName + " = "); | |
ctxt.generateAttribute("context"); | |
ctxt.generateJavaSource(";"); | |
ctxt.generateJavaSource("if((!" + contextName + ".startsWith(\"/\")) " + | |
"|| (!" + urlName + ".startsWith(\"/\"))){"); | |
ctxt.generateJavaSource(" throw new JspTagException" + | |
"(\"In URL tags, when the \\\"context\\\" attribute is specified, " + | |
"values of both \\\"context\\\" and \\\"url\\\" must start with \\\"/\\\".\");"); | |
ctxt.generateJavaSource("}"); | |
} | |
//define charset | |
ctxt.generateJavaSource("String " + charSetName + " = null;"); | |
//if the charEncoding attribute is specified | |
if(hasCharEncoding){ | |
//initialize the charEncoding | |
ctxt.generateJavaSource("String " + charEncodingName + " = "); | |
ctxt.generateAttribute("charEncoding"); | |
ctxt.generateJavaSource(";"); | |
//assign appropriate value tp the charset | |
ctxt.generateJavaSource("if(null != " + charEncodingName + " " + | |
"&& !" + charEncodingName + ".equals(\"\")){"); | |
ctxt.generateJavaSource(" " + charSetName + " = " | |
+ charEncodingName + ";"); | |
ctxt.generateJavaSource("}"); | |
} | |
//reshape the url string | |
ctxt.generateJavaSource("if(!"+iauName+"){"); | |
ctxt.generateJavaSource(" if(!" + urlName + ".startsWith(\"/\")){"); | |
ctxt.generateJavaSource(" String " + servletPathName + " = " + | |
"((HttpServletRequest)pageContext.getRequest()).getServletPath();"); | |
ctxt.generateJavaSource(" " + urlName + " = " | |
+ servletPathName + ".substring(0," + servletPathName + ".lastIndexOf('/')) + '/' + " + urlName + ";"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource("}"); | |
//if the varReader attribute specified | |
if(hasVarReader){ | |
//get the String value of varReader | |
ctxt.generateJavaSource("String " + varReaderName + " = "); | |
ctxt.generateAttribute("varReader"); | |
ctxt.generateJavaSource(";"); | |
//if the url is absolute url | |
ctxt.generateJavaSource("if(" + iauName + "){"); | |
//get the content of the target | |
ctxt.generateJavaSource(" java.net.URL " + urlObjName + " = new java.net.URL(" + urlName + ");"); | |
ctxt.generateJavaSource(" java.net.URLConnection " + ucName + " = " | |
+ urlObjName + ".openConnection();"); | |
ctxt.generateJavaSource(" java.io.InputStream " + inputStreamName + " = " | |
+ ucName + ".getInputStream();"); | |
ctxt.generateJavaSource(" if(" + charSetName + " == null){"); | |
ctxt.generateJavaSource(" String " + contentTypeName + " = " | |
+ ucName + ".getContentType();"); | |
ctxt.generateJavaSource(" if(null != " + contentTypeName + "){"); | |
ctxt.generateJavaSource(" " + charSetName + " = " + | |
"org.apache.struts2.jasper.tagplugins.jstl.Util.getContentTypeAttribute(" + contentTypeName + ", \"charset\");"); | |
ctxt.generateJavaSource(" if(" + charSetName + " == null) " | |
+ charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;"); | |
ctxt.generateJavaSource(" }else{"); | |
ctxt.generateJavaSource(" " + charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" }"); | |
if(!hasCharEncoding){ | |
ctxt.generateJavaSource(" String " + contentTypeName + " = " + ucName + ".getContentType();"); | |
} | |
//define the Reader | |
ctxt.generateJavaSource(" java.io.Reader " + tempReaderName + " = null;"); | |
//initialize the Reader object | |
ctxt.generateJavaSource(" try{"); | |
ctxt.generateJavaSource(" " + tempReaderName + " = new java.io.InputStreamReader(" + inputStreamName + ", " + charSetName + ");"); | |
ctxt.generateJavaSource(" }catch(Exception ex){"); | |
ctxt.generateJavaSource(" " + tempReaderName + " = new java.io.InputStreamReader(" + inputStreamName + ", org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING);"); | |
ctxt.generateJavaSource(" }"); | |
//validate the response | |
ctxt.generateJavaSource(" if(" + ucName + " instanceof java.net.HttpURLConnection){"); | |
ctxt.generateJavaSource(" int status = ((java.net.HttpURLConnection) " + ucName + ").getResponseCode();"); | |
ctxt.generateJavaSource(" if(status < 200 || status > 299){"); | |
ctxt.generateJavaSource(" throw new JspTagException(status + \" \" + " + urlName + ");"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" }"); | |
//set attribute in the page context scope | |
ctxt.generateJavaSource(" pageContext.setAttribute(" + varReaderName + ", " + tempReaderName + ");"); | |
//if the url is relative | |
ctxt.generateJavaSource("}else{"); | |
//if the url is relative, http request is needed | |
ctxt.generateJavaSource(" if (!(pageContext.getRequest() instanceof HttpServletRequest " + | |
"&& pageContext.getResponse() instanceof HttpServletResponse)){"); | |
ctxt.generateJavaSource(" throw new JspTagException(\"Relative <import> from non-HTTP request not allowed\");"); | |
ctxt.generateJavaSource(" }"); | |
//get the servlet context of the context defined in the context attribute | |
ctxt.generateJavaSource(" ServletContext " + servletContextName + " = null;"); | |
if(hasContext){ | |
ctxt.generateJavaSource(" if(null != " + contextName + "){"); | |
ctxt.generateJavaSource(" " + servletContextName + " = pageContext.getServletContext().getContext(" + contextName + ");" ); | |
ctxt.generateJavaSource(" }else{"); | |
ctxt.generateJavaSource(" " + servletContextName + " = pageContext.getServletContext();"); | |
ctxt.generateJavaSource(" }"); | |
}else{ | |
ctxt.generateJavaSource(" " + servletContextName + " = pageContext.getServletContext();"); | |
} | |
// | |
ctxt.generateJavaSource(" if(" + servletContextName + " == null){"); | |
if(hasContext){ | |
ctxt.generateJavaSource(" throw new JspTagException(\"Unable to get RequestDispatcher for Context: \\\" \"+" + contextName + "+\" \\\" and URL: \\\" \" +" + urlName + "+ \" \\\". Verify values and/or enable cross context access.\");"); | |
}else{ | |
ctxt.generateJavaSource(" throw new JspTagException(\"Unable to get RequestDispatcher for URL: \\\" \" +" + urlName + "+ \" \\\". Verify values and/or enable cross context access.\");"); | |
} | |
ctxt.generateJavaSource(" }"); | |
//get the request dispatcher | |
ctxt.generateJavaSource(" RequestDispatcher " + requestDispatcherName + " = " + servletContextName + ".getRequestDispatcher(org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession("+urlName+"));"); | |
ctxt.generateJavaSource(" if(" + requestDispatcherName + " == null) throw new JspTagException(org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession("+urlName+"));"); | |
//initialize a ImportResponseWrapper to include the resource | |
ctxt.generateJavaSource(" org.apache.struts2.jasper.tagplugins.jstl.Util.ImportResponseWrapper " + irwName + " = new org.apache.struts2.jasper.tagplugins.jstl.Util.ImportResponseWrapper((HttpServletResponse) pageContext.getResponse());"); | |
ctxt.generateJavaSource(" if(" + charSetName + " == null){"); | |
ctxt.generateJavaSource(" " + charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" " + irwName + ".setCharEncoding(" + charSetName + ");"); | |
ctxt.generateJavaSource(" try{"); | |
ctxt.generateJavaSource(" " + requestDispatcherName + ".include(pageContext.getRequest(), " + irwName + ");"); | |
ctxt.generateJavaSource(" }catch(java.io.IOException ex){"); | |
ctxt.generateJavaSource(" throw new JspException(ex);"); | |
ctxt.generateJavaSource(" }catch(RuntimeException ex){"); | |
ctxt.generateJavaSource(" throw new JspException(ex);"); | |
ctxt.generateJavaSource(" }catch(ServletException ex){"); | |
ctxt.generateJavaSource(" Throwable rc = ex.getRootCause();"); | |
ctxt.generateJavaSource(" if (rc == null)"); | |
ctxt.generateJavaSource(" throw new JspException(ex);"); | |
ctxt.generateJavaSource(" else"); | |
ctxt.generateJavaSource(" throw new JspException(rc);"); | |
ctxt.generateJavaSource(" }"); | |
//validate the response status | |
ctxt.generateJavaSource(" if(" + irwName + ".getStatus() < 200 || " + irwName + ".getStatus() > 299){"); | |
ctxt.generateJavaSource(" throw new JspTagException(" + irwName + ".getStatus()+\" \" + org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession(" + urlName + "));"); | |
ctxt.generateJavaSource(" }"); | |
//push in the page context | |
ctxt.generateJavaSource(" java.io.Reader " + tempReaderName + " = new java.io.StringReader(" + irwName + ".getString());"); | |
ctxt.generateJavaSource(" pageContext.setAttribute(" + varReaderName + ", " + tempReaderName + ");"); | |
ctxt.generateJavaSource("}"); | |
//execute the body action | |
ctxt.generateBody(); | |
//close the reader | |
ctxt.generateJavaSource("java.io.Reader " + tempReaderName2 + " = (java.io.Reader)pageContext.getAttribute(" + varReaderName + ");"); | |
ctxt.generateJavaSource("if(" + tempReaderName2 + " != null) " + tempReaderName2 + ".close();"); | |
ctxt.generateJavaSource("pageContext.removeAttribute(" + varReaderName + ",1);"); | |
} | |
//if the varReader is not specified | |
else{ | |
ctxt.generateJavaSource("pageContext.setAttribute(\"url_without_param\"," + urlName + ");"); | |
ctxt.generateBody(); | |
ctxt.generateJavaSource(urlName + " = (String)pageContext.getAttribute(\"url_without_param\");"); | |
ctxt.generateJavaSource("pageContext.removeAttribute(\"url_without_param\");"); | |
String strScope = "page"; | |
if(hasScope){ | |
strScope = ctxt.getConstantAttribute("scope"); | |
} | |
int iScope = Util.getScope(strScope); | |
ctxt.generateJavaSource("String " + tempStringName + " = null;"); | |
ctxt.generateJavaSource("if(" + iauName + "){"); | |
//get the content of the target | |
ctxt.generateJavaSource(" java.net.URL " + urlObjName + " = new java.net.URL(" + urlName + ");"); | |
ctxt.generateJavaSource(" java.net.URLConnection " + ucName + " = " + urlObjName + ".openConnection();"); | |
ctxt.generateJavaSource(" java.io.InputStream " + inputStreamName + " = " + ucName + ".getInputStream();"); | |
ctxt.generateJavaSource(" java.io.Reader " + tempReaderName + " = null;"); | |
ctxt.generateJavaSource(" if(" + charSetName + " == null){"); | |
ctxt.generateJavaSource(" String " + contentTypeName + " = " | |
+ ucName + ".getContentType();"); | |
ctxt.generateJavaSource(" if(null != " + contentTypeName + "){"); | |
ctxt.generateJavaSource(" " + charSetName + " = " + | |
"org.apache.struts2.jasper.tagplugins.jstl.Util.getContentTypeAttribute(" + contentTypeName + ", \"charset\");"); | |
ctxt.generateJavaSource(" if(" + charSetName + " == null) " | |
+ charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;"); | |
ctxt.generateJavaSource(" }else{"); | |
ctxt.generateJavaSource(" " + charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" try{"); | |
ctxt.generateJavaSource(" " + tempReaderName + " = new java.io.InputStreamReader(" + inputStreamName + "," + charSetName + ");"); | |
ctxt.generateJavaSource(" }catch(Exception ex){"); | |
//ctxt.generateJavaSource(" throw new JspTagException(ex.toString());"); | |
ctxt.generateJavaSource(" " + tempReaderName + " = new java.io.InputStreamReader(" + inputStreamName + ",org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING);"); | |
ctxt.generateJavaSource(" }"); | |
//validate the response | |
ctxt.generateJavaSource(" if(" + ucName + " instanceof java.net.HttpURLConnection){"); | |
ctxt.generateJavaSource(" int status = ((java.net.HttpURLConnection) " + ucName + ").getResponseCode();"); | |
ctxt.generateJavaSource(" if(status < 200 || status > 299){"); | |
ctxt.generateJavaSource(" throw new JspTagException(status + \" \" + " + urlName + ");"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" java.io.BufferedReader " + brName + " = new java.io.BufferedReader(" + tempReaderName + ");"); | |
ctxt.generateJavaSource(" StringBuffer " + sbName + " = new StringBuffer();"); | |
String index = ctxt.getTemporaryVariableName(); | |
ctxt.generateJavaSource(" int " + index + ";"); | |
ctxt.generateJavaSource(" while(("+index+" = "+brName+".read()) != -1) "+sbName+".append((char)"+index+");"); | |
ctxt.generateJavaSource(" " + tempStringName + " = " +sbName + ".toString();"); | |
ctxt.generateJavaSource("}else{"); | |
//if the url is relative, http request is needed. | |
ctxt.generateJavaSource(" if (!(pageContext.getRequest() instanceof HttpServletRequest " + | |
"&& pageContext.getResponse() instanceof HttpServletResponse)){"); | |
ctxt.generateJavaSource(" throw new JspTagException(\"Relative <import> from non-HTTP request not allowed\");"); | |
ctxt.generateJavaSource(" }"); | |
//get the servlet context of the context defined in the context attribute | |
ctxt.generateJavaSource(" ServletContext " + servletContextName + " = null;"); | |
if(hasContext){ | |
ctxt.generateJavaSource(" if(null != " + contextName + "){"); | |
ctxt.generateJavaSource(" " + servletContextName + " = pageContext.getServletContext().getContext(" + contextName + ");" ); | |
ctxt.generateJavaSource(" }else{"); | |
ctxt.generateJavaSource(" " + servletContextName + " = pageContext.getServletContext();"); | |
ctxt.generateJavaSource(" }"); | |
}else{ | |
ctxt.generateJavaSource(" " + servletContextName + " = pageContext.getServletContext();"); | |
} | |
// | |
ctxt.generateJavaSource(" if(" + servletContextName + " == null){"); | |
if(hasContext){ | |
ctxt.generateJavaSource(" throw new JspTagException(\"Unable to get RequestDispatcher for Context: \\\" \" +" + contextName + "+ \" \\\" and URL: \\\" \" +" + urlName + "+ \" \\\". Verify values and/or enable cross context access.\");"); | |
}else{ | |
ctxt.generateJavaSource(" throw new JspTagException(\"Unable to get RequestDispatcher for URL: \\\" \" +" + urlName + "+ \" \\\". Verify values and/or enable cross context access.\");"); | |
} | |
ctxt.generateJavaSource(" }"); | |
//get the request dispatcher | |
ctxt.generateJavaSource(" RequestDispatcher " + requestDispatcherName + " = " + servletContextName + ".getRequestDispatcher(org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession("+urlName+"));"); | |
ctxt.generateJavaSource(" if(" + requestDispatcherName + " == null) throw new JspTagException(org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession("+urlName+"));"); | |
//initialize a ImportResponseWrapper to include the resource | |
ctxt.generateJavaSource(" org.apache.struts2.jasper.tagplugins.jstl.Util.ImportResponseWrapper " + irwName + " = new org.apache.struts2.jasper.tagplugins.jstl.Util.ImportResponseWrapper((HttpServletResponse) pageContext.getResponse());"); | |
ctxt.generateJavaSource(" if(" + charSetName + " == null){"); | |
ctxt.generateJavaSource(" " + charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" " + irwName + ".setCharEncoding(" + charSetName + ");"); | |
ctxt.generateJavaSource(" try{"); | |
ctxt.generateJavaSource(" " + requestDispatcherName + ".include(pageContext.getRequest(), " + irwName + ");"); | |
ctxt.generateJavaSource(" }catch(java.io.IOException ex){"); | |
ctxt.generateJavaSource(" throw new JspException(ex);"); | |
ctxt.generateJavaSource(" }catch(RuntimeException ex){"); | |
ctxt.generateJavaSource(" throw new JspException(ex);"); | |
ctxt.generateJavaSource(" }catch(ServletException ex){"); | |
ctxt.generateJavaSource(" Throwable rc = ex.getRootCause();"); | |
ctxt.generateJavaSource(" if (rc == null)"); | |
ctxt.generateJavaSource(" throw new JspException(ex);"); | |
ctxt.generateJavaSource(" else"); | |
ctxt.generateJavaSource(" throw new JspException(rc);"); | |
ctxt.generateJavaSource(" }"); | |
//validate the response status | |
ctxt.generateJavaSource(" if(" + irwName + ".getStatus() < 200 || " + irwName + ".getStatus() > 299){"); | |
ctxt.generateJavaSource(" throw new JspTagException(" + irwName + ".getStatus()+\" \" + org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession(" + urlName + "));"); | |
ctxt.generateJavaSource(" }"); | |
ctxt.generateJavaSource(" " + tempStringName + " = " + irwName + ".getString();"); | |
ctxt.generateJavaSource("}"); | |
if(hasVar){ | |
String strVar = ctxt.getConstantAttribute("var"); | |
ctxt.generateJavaSource("pageContext.setAttribute(\""+strVar+"\"," + tempStringName + "," + iScope + ");"); | |
}else{ | |
ctxt.generateJavaSource("pageContext.getOut().print(" + tempStringName + ");"); | |
} | |
} | |
} | |
} |