View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  
19  package org.apache.struts2.jasper.tagplugins.jstl.core;
20  
21  import org.apache.struts2.jasper.compiler.tagplugin.TagPlugin;
22  import org.apache.struts2.jasper.compiler.tagplugin.TagPluginContext;
23  import org.apache.struts2.jasper.tagplugins.jstl.Util;
24  
25  public class Import implements TagPlugin {
26  
27      public void doTag(TagPluginContext ctxt) {
28          boolean hasContext, hasVar, hasScope, hasVarReader, hasCharEncoding;
29  
30          //flags
31          hasContext = ctxt.isAttributeSpecified("context");
32          hasVar = ctxt.isAttributeSpecified("var");
33          hasScope = ctxt.isAttributeSpecified("scope");
34          hasVarReader = ctxt.isAttributeSpecified("varReader");
35          hasCharEncoding = ctxt.isAttributeSpecified("charEncoding");
36  
37          //variables' names
38          String urlName = ctxt.getTemporaryVariableName();
39          String contextName = ctxt.getTemporaryVariableName();
40          String iauName = ctxt.getTemporaryVariableName();           // is absolute url
41          String urlObjName = ctxt.getTemporaryVariableName();        //URL object
42          String ucName = ctxt.getTemporaryVariableName();            //URLConnection
43          String inputStreamName = ctxt.getTemporaryVariableName();
44          String tempReaderName = ctxt.getTemporaryVariableName();
45          String tempReaderName2 = ctxt.getTemporaryVariableName();
46          String charSetName = ctxt.getTemporaryVariableName();
47          String charEncodingName = ctxt.getTemporaryVariableName();
48          String contentTypeName = ctxt.getTemporaryVariableName();
49          String varReaderName = ctxt.getTemporaryVariableName();
50          String servletContextName = ctxt.getTemporaryVariableName();
51          String servletPathName = ctxt.getTemporaryVariableName();
52          String requestDispatcherName = ctxt.getTemporaryVariableName();
53          String irwName = ctxt.getTemporaryVariableName();           //ImportResponseWrapper name
54          String brName = ctxt.getTemporaryVariableName();            //BufferedReader name
55          String sbName = ctxt.getTemporaryVariableName();            //StringBuffer name
56          String tempStringName = ctxt.getTemporaryVariableName();
57  
58          //is absolute url
59          ctxt.generateJavaSource("boolean " + iauName + ";");
60  
61          //get the url value
62          ctxt.generateJavaSource("String " + urlName + " = ");
63          ctxt.generateAttribute("url");
64          ctxt.generateJavaSource(";");
65  
66          //validate the url
67          ctxt.generateJavaSource("if(" + urlName + " == null || " + urlName + ".equals(\"\")){");
68          ctxt.generateJavaSource("    throw new JspTagException(\"The //\"url//\" attribute " +
69                  "illegally evaluated to //\"null//\" or //\"//\" in <import>\");");
70          ctxt.generateJavaSource("}");
71  
72          //initialize the is_absolute_url
73          ctxt.generateJavaSource(iauName + " = " +
74                  "org.apache.struts2.jasper.tagplugins.jstl.Util.isAbsoluteUrl(" + urlName + ");");
75  
76          //validate the context
77          if (hasContext) {
78  
79              ctxt.generateJavaSource("String " + contextName + " = ");
80              ctxt.generateAttribute("context");
81              ctxt.generateJavaSource(";");
82  
83              ctxt.generateJavaSource("if((!" + contextName + ".startsWith(\"/\")) " +
84                      "|| (!" + urlName + ".startsWith(\"/\"))){");
85              ctxt.generateJavaSource("    throw new JspTagException" +
86                      "(\"In URL tags, when the //\"context//\" attribute is specified, " +
87                      "values of both //\"context//\" and //\"url//\" must start with //\"///\".\");");
88              ctxt.generateJavaSource("}");
89  
90          }
91  
92          //define charset
93          ctxt.generateJavaSource("String " + charSetName + " = null;");
94  
95          //if the charEncoding attribute is specified
96          if (hasCharEncoding) {
97  
98              //initialize the charEncoding
99              ctxt.generateJavaSource("String " + charEncodingName + " = ");
100             ctxt.generateAttribute("charEncoding");
101             ctxt.generateJavaSource(";");
102 
103             //assign appropriate value tp the charset
104             ctxt.generateJavaSource("if(null != " + charEncodingName + " " +
105                     "&& !" + charEncodingName + ".equals(\"\")){");
106             ctxt.generateJavaSource("    " + charSetName + " = "
107                     + charEncodingName + ";");
108             ctxt.generateJavaSource("}");
109         }
110 
111         //reshape the url string
112         ctxt.generateJavaSource("if(!" + iauName + "){");
113         ctxt.generateJavaSource("    if(!" + urlName + ".startsWith(\"/\")){");
114         ctxt.generateJavaSource("        String " + servletPathName + " = " +
115                 "((HttpServletRequest)pageContext.getRequest()).getServletPath();");
116         ctxt.generateJavaSource("        " + urlName + " = "
117                 + servletPathName + ".substring(0," + servletPathName + ".lastIndexOf('/')) + '/' + " + urlName + ";");
118         ctxt.generateJavaSource("    }");
119         ctxt.generateJavaSource("}");
120 
121         //if the varReader attribute specified
122         if (hasVarReader) {
123 
124             //get the String value of varReader
125             ctxt.generateJavaSource("String " + varReaderName + " = ");
126             ctxt.generateAttribute("varReader");
127             ctxt.generateJavaSource(";");
128 
129             //if the url is absolute url
130             ctxt.generateJavaSource("if(" + iauName + "){");
131 
132             //get the content of the target
133             ctxt.generateJavaSource("    java.net.URL " + urlObjName + " = new java.net.URL(" + urlName + ");");
134             ctxt.generateJavaSource("    java.net.URLConnection " + ucName + " = "
135                     + urlObjName + ".openConnection();");
136             ctxt.generateJavaSource("    java.io.InputStream " + inputStreamName + " = "
137                     + ucName + ".getInputStream();");
138 
139             ctxt.generateJavaSource("    if(" + charSetName + " == null){");
140             ctxt.generateJavaSource("        String " + contentTypeName + " = "
141                     + ucName + ".getContentType();");
142             ctxt.generateJavaSource("        if(null != " + contentTypeName + "){");
143             ctxt.generateJavaSource("            " + charSetName + " = " +
144                     "org.apache.struts2.jasper.tagplugins.jstl.Util.getContentTypeAttribute(" + contentTypeName + ", \"charset\");");
145             ctxt.generateJavaSource("            if(" + charSetName + " == null) "
146                     + charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;");
147             ctxt.generateJavaSource("        }else{");
148             ctxt.generateJavaSource("            " + charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;");
149             ctxt.generateJavaSource("        }");
150             ctxt.generateJavaSource("    }");
151 
152             if (!hasCharEncoding) {
153                 ctxt.generateJavaSource("    String " + contentTypeName + " = " + ucName + ".getContentType();");
154             }
155 
156             //define the Reader
157             ctxt.generateJavaSource("    java.io.Reader " + tempReaderName + " = null;");
158 
159             //initialize the Reader object
160             ctxt.generateJavaSource("    try{");
161             ctxt.generateJavaSource("        " + tempReaderName + " = new java.io.InputStreamReader(" + inputStreamName + ", " + charSetName + ");");
162             ctxt.generateJavaSource("    }catch(Exception ex){");
163             ctxt.generateJavaSource("        " + tempReaderName + " = new java.io.InputStreamReader(" + inputStreamName + ", org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING);");
164             ctxt.generateJavaSource("    }");
165 
166             //validate the response
167             ctxt.generateJavaSource("    if(" + ucName + " instanceof java.net.HttpURLConnection){");
168             ctxt.generateJavaSource("        int status = ((java.net.HttpURLConnection) " + ucName + ").getResponseCode();");
169             ctxt.generateJavaSource("        if(status < 200 || status > 299){");
170             ctxt.generateJavaSource("            throw new JspTagException(status + \" \" + " + urlName + ");");
171             ctxt.generateJavaSource("        }");
172             ctxt.generateJavaSource("    }");
173 
174             //set attribute in the page context scope
175             ctxt.generateJavaSource("    pageContext.setAttribute(" + varReaderName + ", " + tempReaderName + ");");
176 
177             //if the url is relative
178             ctxt.generateJavaSource("}else{");
179 
180             //if the url is relative, http request is needed
181             ctxt.generateJavaSource("    if (!(pageContext.getRequest() instanceof HttpServletRequest  " +
182                     "&& pageContext.getResponse() instanceof HttpServletResponse)){");
183             ctxt.generateJavaSource("        throw new JspTagException(\"Relative &lt;import&gt; from non-HTTP request not allowed\");");
184             ctxt.generateJavaSource("    }");
185 
186             //get the servlet context of the context defined in the context attribute
187             ctxt.generateJavaSource("    ServletContext " + servletContextName + " = null;");
188             if (hasContext) {
189                 ctxt.generateJavaSource("    if(null != " + contextName + "){");
190                 ctxt.generateJavaSource("        " + servletContextName + " = pageContext.getServletContext().getContext(" + contextName + ");");
191                 ctxt.generateJavaSource("    }else{");
192                 ctxt.generateJavaSource("        " + servletContextName + " = pageContext.getServletContext();");
193                 ctxt.generateJavaSource("    }");
194             } else {
195                 ctxt.generateJavaSource("    " + servletContextName + " = pageContext.getServletContext();");
196             }
197 
198             //
199             ctxt.generateJavaSource("    if(" + servletContextName + " == null){");
200             if (hasContext) {
201                 ctxt.generateJavaSource("        throw new JspTagException(\"Unable to get RequestDispatcher for Context: //\" \"+" + contextName + "+\" //\" and URL: //\" \" +" + urlName + "+ \" //\". Verify values and/or enable cross context access.\");");
202             } else {
203                 ctxt.generateJavaSource("        throw new JspTagException(\"Unable to get RequestDispatcher for  URL: //\" \" +" + urlName + "+ \" //\". Verify values and/or enable cross context access.\");");
204             }
205             ctxt.generateJavaSource("    }");
206 
207             //get the request dispatcher
208             ctxt.generateJavaSource("    RequestDispatcher " + requestDispatcherName + " = " + servletContextName + ".getRequestDispatcher(org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession(" + urlName + "));");
209             ctxt.generateJavaSource("    if(" + requestDispatcherName + " == null) throw new JspTagException(org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession(" + urlName + "));");
210 
211             //initialize a ImportResponseWrapper to include the resource
212             ctxt.generateJavaSource("    org.apache.struts2.jasper.tagplugins.jstl.Util.ImportResponseWrapper " + irwName + " = new org.apache.struts2.jasper.tagplugins.jstl.Util.ImportResponseWrapper((HttpServletResponse) pageContext.getResponse());");
213             ctxt.generateJavaSource("    if(" + charSetName + " == null){");
214             ctxt.generateJavaSource("        " + charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;");
215             ctxt.generateJavaSource("    }");
216             ctxt.generateJavaSource("    " + irwName + ".setCharEncoding(" + charSetName + ");");
217             ctxt.generateJavaSource("    try{");
218             ctxt.generateJavaSource("        " + requestDispatcherName + ".include(pageContext.getRequest(), " + irwName + ");");
219             ctxt.generateJavaSource("    }catch(java.io.IOException ex){");
220             ctxt.generateJavaSource("        throw new JspException(ex);");
221             ctxt.generateJavaSource("    }catch(RuntimeException ex){");
222             ctxt.generateJavaSource("        throw new JspException(ex);");
223             ctxt.generateJavaSource("    }catch(ServletException ex){");
224             ctxt.generateJavaSource("        Throwable rc = ex.getRootCause();");
225             ctxt.generateJavaSource("        if (rc == null)");
226             ctxt.generateJavaSource("            throw new JspException(ex);");
227             ctxt.generateJavaSource("        else");
228             ctxt.generateJavaSource("            throw new JspException(rc);");
229             ctxt.generateJavaSource("    }");
230 
231             //validate the response status
232             ctxt.generateJavaSource("    if(" + irwName + ".getStatus() < 200 || " + irwName + ".getStatus() > 299){");
233             ctxt.generateJavaSource("        throw new JspTagException(" + irwName + ".getStatus()+\" \" + org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession(" + urlName + "));");
234             ctxt.generateJavaSource("    }");
235 
236             //push in the page context
237             ctxt.generateJavaSource("    java.io.Reader " + tempReaderName + " = new java.io.StringReader(" + irwName + ".getString());");
238             ctxt.generateJavaSource("    pageContext.setAttribute(" + varReaderName + ", " + tempReaderName + ");");
239 
240             ctxt.generateJavaSource("}");
241 
242             //execute the body action
243             ctxt.generateBody();
244 
245             //close the reader
246             ctxt.generateJavaSource("java.io.Reader " + tempReaderName2 + " = (java.io.Reader)pageContext.getAttribute(" + varReaderName + ");");
247             ctxt.generateJavaSource("if(" + tempReaderName2 + " != null) " + tempReaderName2 + ".close();");
248             ctxt.generateJavaSource("pageContext.removeAttribute(" + varReaderName + ",1);");
249         }
250 
251         //if the varReader is not specified 
252         else {
253 
254             ctxt.generateJavaSource("pageContext.setAttribute(\"url_without_param\"," + urlName + ");");
255             ctxt.generateBody();
256             ctxt.generateJavaSource(urlName + " = (String)pageContext.getAttribute(\"url_without_param\");");
257             ctxt.generateJavaSource("pageContext.removeAttribute(\"url_without_param\");");
258             String strScope = "page";
259             if (hasScope) {
260                 strScope = ctxt.getConstantAttribute("scope");
261             }
262             int iScope = Util.getScope(strScope);
263 
264             ctxt.generateJavaSource("String " + tempStringName + " = null;");
265 
266             ctxt.generateJavaSource("if(" + iauName + "){");
267 
268             //get the content of the target
269             ctxt.generateJavaSource("    java.net.URL " + urlObjName + " = new java.net.URL(" + urlName + ");");
270             ctxt.generateJavaSource("    java.net.URLConnection " + ucName + " = " + urlObjName + ".openConnection();");
271             ctxt.generateJavaSource("    java.io.InputStream " + inputStreamName + " = " + ucName + ".getInputStream();");
272             ctxt.generateJavaSource("    java.io.Reader " + tempReaderName + " = null;");
273 
274             ctxt.generateJavaSource("    if(" + charSetName + " == null){");
275             ctxt.generateJavaSource("        String " + contentTypeName + " = "
276                     + ucName + ".getContentType();");
277             ctxt.generateJavaSource("        if(null != " + contentTypeName + "){");
278             ctxt.generateJavaSource("            " + charSetName + " = " +
279                     "org.apache.struts2.jasper.tagplugins.jstl.Util.getContentTypeAttribute(" + contentTypeName + ", \"charset\");");
280             ctxt.generateJavaSource("            if(" + charSetName + " == null) "
281                     + charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;");
282             ctxt.generateJavaSource("        }else{");
283             ctxt.generateJavaSource("            " + charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;");
284             ctxt.generateJavaSource("        }");
285             ctxt.generateJavaSource("    }");
286 
287             ctxt.generateJavaSource("    try{");
288             ctxt.generateJavaSource("        " + tempReaderName + " = new java.io.InputStreamReader(" + inputStreamName + "," + charSetName + ");");
289             ctxt.generateJavaSource("    }catch(Exception ex){");
290             //ctxt.generateJavaSource("        throw new JspTagException(ex.toString());");
291             ctxt.generateJavaSource("        " + tempReaderName + " = new java.io.InputStreamReader(" + inputStreamName + ",org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING);");
292             ctxt.generateJavaSource("    }");
293 
294             //validate the response
295             ctxt.generateJavaSource("    if(" + ucName + " instanceof java.net.HttpURLConnection){");
296             ctxt.generateJavaSource("        int status = ((java.net.HttpURLConnection) " + ucName + ").getResponseCode();");
297             ctxt.generateJavaSource("        if(status < 200 || status > 299){");
298             ctxt.generateJavaSource("            throw new JspTagException(status + \" \" + " + urlName + ");");
299             ctxt.generateJavaSource("        }");
300             ctxt.generateJavaSource("    }");
301 
302             ctxt.generateJavaSource("    java.io.BufferedReader " + brName + " =  new java.io.BufferedReader(" + tempReaderName + ");");
303             ctxt.generateJavaSource("    StringBuffer " + sbName + " = new StringBuffer();");
304             String index = ctxt.getTemporaryVariableName();
305             ctxt.generateJavaSource("    int " + index + ";");
306             ctxt.generateJavaSource("    while((" + index + " = " + brName + ".read()) != -1) " + sbName + ".append((char)" + index + ");");
307             ctxt.generateJavaSource("    " + tempStringName + " = " + sbName + ".toString();");
308 
309             ctxt.generateJavaSource("}else{");
310 
311             //if the url is relative, http request is needed.
312             ctxt.generateJavaSource("    if (!(pageContext.getRequest() instanceof HttpServletRequest  " +
313                     "&& pageContext.getResponse() instanceof HttpServletResponse)){");
314             ctxt.generateJavaSource("        throw new JspTagException(\"Relative &lt;import&gt; from non-HTTP request not allowed\");");
315             ctxt.generateJavaSource("    }");
316 
317             //get the servlet context of the context defined in the context attribute
318             ctxt.generateJavaSource("    ServletContext " + servletContextName + " = null;");
319             if (hasContext) {
320                 ctxt.generateJavaSource("    if(null != " + contextName + "){");
321                 ctxt.generateJavaSource("        " + servletContextName + " = pageContext.getServletContext().getContext(" + contextName + ");");
322                 ctxt.generateJavaSource("    }else{");
323                 ctxt.generateJavaSource("        " + servletContextName + " = pageContext.getServletContext();");
324                 ctxt.generateJavaSource("    }");
325             } else {
326                 ctxt.generateJavaSource("    " + servletContextName + " = pageContext.getServletContext();");
327             }
328 
329             //
330             ctxt.generateJavaSource("    if(" + servletContextName + " == null){");
331             if (hasContext) {
332                 ctxt.generateJavaSource("        throw new JspTagException(\"Unable to get RequestDispatcher for Context: //\" \" +" + contextName + "+ \" //\" and URL: //\" \" +" + urlName + "+ \" //\". Verify values and/or enable cross context access.\");");
333             } else {
334                 ctxt.generateJavaSource("        throw new JspTagException(\"Unable to get RequestDispatcher for URL: //\" \" +" + urlName + "+ \" //\". Verify values and/or enable cross context access.\");");
335             }
336             ctxt.generateJavaSource("    }");
337 
338             //get the request dispatcher
339             ctxt.generateJavaSource("    RequestDispatcher " + requestDispatcherName + " = " + servletContextName + ".getRequestDispatcher(org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession(" + urlName + "));");
340             ctxt.generateJavaSource("    if(" + requestDispatcherName + " == null) throw new JspTagException(org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession(" + urlName + "));");
341 
342             //initialize a ImportResponseWrapper to include the resource
343             ctxt.generateJavaSource("    org.apache.struts2.jasper.tagplugins.jstl.Util.ImportResponseWrapper " + irwName + " = new org.apache.struts2.jasper.tagplugins.jstl.Util.ImportResponseWrapper((HttpServletResponse) pageContext.getResponse());");
344             ctxt.generateJavaSource("    if(" + charSetName + " == null){");
345             ctxt.generateJavaSource("        " + charSetName + " = org.apache.struts2.jasper.tagplugins.jstl.Util.DEFAULT_ENCODING;");
346             ctxt.generateJavaSource("    }");
347             ctxt.generateJavaSource("    " + irwName + ".setCharEncoding(" + charSetName + ");");
348             ctxt.generateJavaSource("    try{");
349             ctxt.generateJavaSource("        " + requestDispatcherName + ".include(pageContext.getRequest(), " + irwName + ");");
350             ctxt.generateJavaSource("    }catch(java.io.IOException ex){");
351             ctxt.generateJavaSource("        throw new JspException(ex);");
352             ctxt.generateJavaSource("    }catch(RuntimeException ex){");
353             ctxt.generateJavaSource("        throw new JspException(ex);");
354             ctxt.generateJavaSource("    }catch(ServletException ex){");
355             ctxt.generateJavaSource("        Throwable rc = ex.getRootCause();");
356             ctxt.generateJavaSource("        if (rc == null)");
357             ctxt.generateJavaSource("            throw new JspException(ex);");
358             ctxt.generateJavaSource("        else");
359             ctxt.generateJavaSource("            throw new JspException(rc);");
360             ctxt.generateJavaSource("    }");
361 
362             //validate the response status
363             ctxt.generateJavaSource("    if(" + irwName + ".getStatus() < 200 || " + irwName + ".getStatus() > 299){");
364             ctxt.generateJavaSource("        throw new JspTagException(" + irwName + ".getStatus()+\" \" + org.apache.struts2.jasper.tagplugins.jstl.Util.stripSession(" + urlName + "));");
365             ctxt.generateJavaSource("    }");
366 
367             ctxt.generateJavaSource("    " + tempStringName + " = " + irwName + ".getString();");
368 
369             ctxt.generateJavaSource("}");
370 
371             if (hasVar) {
372                 String strVar = ctxt.getConstantAttribute("var");
373                 ctxt.generateJavaSource("pageContext.setAttribute(\"" + strVar + "\"," + tempStringName + "," + iScope + ");");
374             } else {
375                 ctxt.generateJavaSource("pageContext.getOut().print(" + tempStringName + ");");
376             }
377         }
378     }
379 
380 
381 }