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  package org.apache.struts2.jasper.runtime;
18  
19  import com.opensymphony.xwork2.util.logging.Logger;
20  import com.opensymphony.xwork2.util.logging.LoggerFactory;
21  import org.apache.struts2.jasper.util.SimplePool;
22  
23  import javax.servlet.Servlet;
24  import javax.servlet.ServletRequest;
25  import javax.servlet.ServletResponse;
26  import javax.servlet.jsp.JspEngineInfo;
27  import javax.servlet.jsp.JspFactory;
28  import javax.servlet.jsp.PageContext;
29  import java.security.AccessController;
30  import java.security.PrivilegedAction;
31  
32  /***
33   * Implementation of JspFactory.
34   *
35   * @author Anil K. Vijendran
36   */
37  public class JspFactoryImpl extends JspFactory {
38  
39      // Logger
40      private Logger log = LoggerFactory.getLogger(JspFactoryImpl.class);
41  
42      private static final String SPEC_VERSION = "2.0";
43      private static final boolean USE_POOL =
44              Boolean.valueOf(System.getProperty("org.apache.struts2.jasper.runtime.JspFactoryImpl.USE_POOL", "true")).booleanValue();
45  
46      private SimplePool pool = new SimplePool(100);
47  
48      public PageContext getPageContext(Servlet servlet,
49                                        ServletRequest request,
50                                        ServletResponse response,
51                                        String errorPageURL,
52                                        boolean needsSession,
53                                        int bufferSize,
54                                        boolean autoflush) {
55          if (System.getSecurityManager() != null) {
56              PrivilegedGetPageContext dp = new PrivilegedGetPageContext(
57                      (JspFactoryImpl) this, servlet, request, response, errorPageURL,
58                      needsSession, bufferSize, autoflush);
59              return (PageContext) AccessController.doPrivileged(dp);
60          } else {
61              return internalGetPageContext(servlet, request, response,
62                      errorPageURL, needsSession,
63                      bufferSize, autoflush);
64          }
65      }
66  
67      public void releasePageContext(PageContext pc) {
68          if (pc == null)
69              return;
70          if (System.getSecurityManager() != null) {
71              PrivilegedReleasePageContext dp = new PrivilegedReleasePageContext(
72                      (JspFactoryImpl) this, pc);
73              AccessController.doPrivileged(dp);
74          } else {
75              internalReleasePageContext(pc);
76          }
77      }
78  
79      public JspEngineInfo getEngineInfo() {
80          return new JspEngineInfo() {
81              public String getSpecificationVersion() {
82                  return SPEC_VERSION;
83              }
84          };
85      }
86  
87      private PageContext internalGetPageContext(Servlet servlet,
88                                                 ServletRequest request,
89                                                 ServletResponse response,
90                                                 String errorPageURL,
91                                                 boolean needsSession,
92                                                 int bufferSize,
93                                                 boolean autoflush) {
94          try {
95              PageContext pc;
96              if (USE_POOL) {
97                  pc = (PageContext) pool.get();
98                  if (pc == null) {
99                      pc = new PageContextImpl(this);
100                 }
101             } else {
102                 pc = new PageContextImpl(this);
103             }
104             pc.initialize(servlet, request, response, errorPageURL,
105                     needsSession, bufferSize, autoflush);
106             return pc;
107         } catch (Throwable ex) {
108             /* FIXME: need to do something reasonable here!! */
109             log.fatal("Exception initializing page context", ex);
110             return null;
111         }
112     }
113 
114     private void internalReleasePageContext(PageContext pc) {
115         pc.release();
116         if (USE_POOL && (pc instanceof PageContextImpl)) {
117             pool.put(pc);
118         }
119     }
120 
121     private class PrivilegedGetPageContext implements PrivilegedAction {
122 
123         private JspFactoryImpl factory;
124         private Servlet servlet;
125         private ServletRequest request;
126         private ServletResponse response;
127         private String errorPageURL;
128         private boolean needsSession;
129         private int bufferSize;
130         private boolean autoflush;
131 
132         PrivilegedGetPageContext(JspFactoryImpl factory,
133                                  Servlet servlet,
134                                  ServletRequest request,
135                                  ServletResponse response,
136                                  String errorPageURL,
137                                  boolean needsSession,
138                                  int bufferSize,
139                                  boolean autoflush) {
140             this.factory = factory;
141             this.servlet = servlet;
142             this.request = request;
143             this.response = response;
144             this.errorPageURL = errorPageURL;
145             this.needsSession = needsSession;
146             this.bufferSize = bufferSize;
147             this.autoflush = autoflush;
148         }
149 
150         public Object run() {
151             return factory.internalGetPageContext(servlet,
152                     request,
153                     response,
154                     errorPageURL,
155                     needsSession,
156                     bufferSize,
157                     autoflush);
158         }
159     }
160 
161     private class PrivilegedReleasePageContext implements PrivilegedAction {
162 
163         private JspFactoryImpl factory;
164         private PageContext pageContext;
165 
166         PrivilegedReleasePageContext(JspFactoryImpl factory,
167                                      PageContext pageContext) {
168             this.factory = factory;
169             this.pageContext = pageContext;
170         }
171 
172         public Object run() {
173             factory.internalReleasePageContext(pageContext);
174             return null;
175         }
176     }
177 }