1
17 package org.apache.jasper.runtime;
18
19 import java.io.IOException;
20 import java.security.AccessController;
21 import java.security.PrivilegedAction;
22
23 import javax.servlet.Servlet;
24 import javax.servlet.ServletContext;
25 import javax.servlet.ServletRequest;
26 import javax.servlet.ServletResponse;
27 import javax.servlet.jsp.JspApplicationContext;
28 import javax.servlet.jsp.JspEngineInfo;
29 import javax.servlet.jsp.JspFactory;
30 import javax.servlet.jsp.PageContext;
31
32 import org.apache.jasper.Constants;
33
34
39 public class JspFactoryImpl extends JspFactory {
40
41 private static final boolean USE_POOL =
42 Boolean.parseBoolean(System.getProperty("org.apache.jasper.runtime.JspFactoryImpl.USE_POOL", "true"));
43 private static final int POOL_SIZE =
44 Integer.parseInt(System.getProperty("org.apache.jasper.runtime.JspFactoryImpl.POOL_SIZE", "8"));
45
46 private final ThreadLocal<PageContextPool> localPool = new ThreadLocal<>();
47
48 @Override
49 public PageContext getPageContext(Servlet servlet, ServletRequest request,
50 ServletResponse response, String errorPageURL, boolean needsSession,
51 int bufferSize, boolean autoflush) {
52
53 if( Constants.IS_SECURITY_ENABLED ) {
54 PrivilegedGetPageContext dp = new PrivilegedGetPageContext(
55 this, servlet, request, response, errorPageURL,
56 needsSession, bufferSize, autoflush);
57 return AccessController.doPrivileged(dp);
58 } else {
59 return internalGetPageContext(servlet, request, response,
60 errorPageURL, needsSession,
61 bufferSize, autoflush);
62 }
63 }
64
65 @Override
66 public void releasePageContext(PageContext pc) {
67 if( pc == null )
68 return;
69 if( Constants.IS_SECURITY_ENABLED ) {
70 PrivilegedReleasePageContext dp = new PrivilegedReleasePageContext(
71 this,pc);
72 AccessController.doPrivileged(dp);
73 } else {
74 internalReleasePageContext(pc);
75 }
76 }
77
78 @Override
79 public JspEngineInfo getEngineInfo() {
80 return new JspEngineInfo() {
81 @Override
82 public String getSpecificationVersion() {
83 return Constants.SPEC_VERSION;
84 }
85 };
86 }
87
88 private PageContext internalGetPageContext(Servlet servlet, ServletRequest request,
89 ServletResponse response, String errorPageURL, boolean needsSession,
90 int bufferSize, boolean autoflush) {
91
92 PageContext pc;
93 if (USE_POOL) {
94 PageContextPool pool = localPool.get();
95 if (pool == null) {
96 pool = new PageContextPool();
97 localPool.set(pool);
98 }
99 pc = pool.get();
100 if (pc == null) {
101 pc = new PageContextImpl();
102 }
103 } else {
104 pc = new PageContextImpl();
105 }
106
107 try {
108 pc.initialize(servlet, request, response, errorPageURL,
109 needsSession, bufferSize, autoflush);
110 } catch (IOException ioe) {
111
112
113 }
114
115 return pc;
116 }
117
118 private void internalReleasePageContext(PageContext pc) {
119 pc.release();
120 if (USE_POOL && (pc instanceof PageContextImpl)) {
121 localPool.get().put(pc);
122 }
123 }
124
125 private static class PrivilegedGetPageContext
126 implements PrivilegedAction<PageContext> {
127
128 private JspFactoryImpl factory;
129 private Servlet servlet;
130 private ServletRequest request;
131 private ServletResponse response;
132 private String errorPageURL;
133 private boolean needsSession;
134 private int bufferSize;
135 private boolean autoflush;
136
137 PrivilegedGetPageContext(JspFactoryImpl factory, Servlet servlet,
138 ServletRequest request, ServletResponse response, String errorPageURL,
139 boolean needsSession, int bufferSize, 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 @Override
151 public PageContext run() {
152 return factory.internalGetPageContext(servlet, request, response,
153 errorPageURL, needsSession, bufferSize, autoflush);
154 }
155 }
156
157 private static class PrivilegedReleasePageContext
158 implements PrivilegedAction<Void> {
159
160 private JspFactoryImpl factory;
161 private PageContext pageContext;
162
163 PrivilegedReleasePageContext(JspFactoryImpl factory,
164 PageContext pageContext) {
165 this.factory = factory;
166 this.pageContext = pageContext;
167 }
168
169 @Override
170 public Void run() {
171 factory.internalReleasePageContext(pageContext);
172 return null;
173 }
174 }
175
176 private static final class PageContextPool {
177
178 private final PageContext[] pool;
179
180 private int current = -1;
181
182 public PageContextPool() {
183 this.pool = new PageContext[POOL_SIZE];
184 }
185
186 public void put(PageContext o) {
187 if (current < (POOL_SIZE - 1)) {
188 current++;
189 pool[current] = o;
190 }
191 }
192
193 public PageContext get() {
194 PageContext item = null;
195 if (current >= 0) {
196 item = pool[current];
197 current--;
198 }
199 return item;
200 }
201
202 }
203
204 @Override
205 public JspApplicationContext getJspApplicationContext(
206 final ServletContext context) {
207 if (Constants.IS_SECURITY_ENABLED) {
208 return AccessController.doPrivileged(
209 new PrivilegedAction<JspApplicationContext>() {
210 @Override
211 public JspApplicationContext run() {
212 return JspApplicationContextImpl.getInstance(context);
213 }
214 });
215 } else {
216 return JspApplicationContextImpl.getInstance(context);
217 }
218 }
219 }
220