001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jasper.runtime;
018:
019: import java.security.AccessController;
020: import java.security.PrivilegedAction;
021:
022: import javax.servlet.Servlet;
023: import javax.servlet.ServletContext;
024: import javax.servlet.ServletRequest;
025: import javax.servlet.ServletResponse;
026: import javax.servlet.jsp.JspApplicationContext;
027: import javax.servlet.jsp.JspEngineInfo;
028: import javax.servlet.jsp.JspFactory;
029: import javax.servlet.jsp.PageContext;
030:
031: import org.apache.jasper.Constants;
032: import org.apache.juli.logging.Log;
033: import org.apache.juli.logging.LogFactory;
034:
035: /**
036: * Implementation of JspFactory.
037: *
038: * @author Anil K. Vijendran
039: */
040: public class JspFactoryImpl extends JspFactory {
041:
042: // Logger
043: private Log log = LogFactory.getLog(JspFactoryImpl.class);
044:
045: private static final String SPEC_VERSION = "2.1";
046: private static final boolean USE_POOL = Boolean
047: .valueOf(
048: System
049: .getProperty(
050: "org.apache.jasper.runtime.JspFactoryImpl.USE_POOL",
051: "true")).booleanValue();
052: private static final int POOL_SIZE = Integer
053: .valueOf(
054: System
055: .getProperty(
056: "org.apache.jasper.runtime.JspFactoryImpl.POOL_SIZE",
057: "8")).intValue();
058:
059: private ThreadLocal<PageContextPool> localPool = new ThreadLocal<PageContextPool>();
060:
061: public PageContext getPageContext(Servlet servlet,
062: ServletRequest request, ServletResponse response,
063: String errorPageURL, boolean needsSession, int bufferSize,
064: boolean autoflush) {
065:
066: if (Constants.IS_SECURITY_ENABLED) {
067: PrivilegedGetPageContext dp = new PrivilegedGetPageContext(
068: (JspFactoryImpl) this , servlet, request, response,
069: errorPageURL, needsSession, bufferSize, autoflush);
070: return (PageContext) AccessController.doPrivileged(dp);
071: } else {
072: return internalGetPageContext(servlet, request, response,
073: errorPageURL, needsSession, bufferSize, autoflush);
074: }
075: }
076:
077: public void releasePageContext(PageContext pc) {
078: if (pc == null)
079: return;
080: if (Constants.IS_SECURITY_ENABLED) {
081: PrivilegedReleasePageContext dp = new PrivilegedReleasePageContext(
082: (JspFactoryImpl) this , pc);
083: AccessController.doPrivileged(dp);
084: } else {
085: internalReleasePageContext(pc);
086: }
087: }
088:
089: public JspEngineInfo getEngineInfo() {
090: return new JspEngineInfo() {
091: public String getSpecificationVersion() {
092: return SPEC_VERSION;
093: }
094: };
095: }
096:
097: private PageContext internalGetPageContext(Servlet servlet,
098: ServletRequest request, ServletResponse response,
099: String errorPageURL, boolean needsSession, int bufferSize,
100: boolean autoflush) {
101: try {
102: PageContext pc;
103: if (USE_POOL) {
104: PageContextPool pool = localPool.get();
105: if (pool == null) {
106: pool = new PageContextPool();
107: localPool.set(pool);
108: }
109: pc = pool.get();
110: if (pc == null) {
111: pc = new PageContextImpl();
112: }
113: } else {
114: pc = new PageContextImpl();
115: }
116: pc.initialize(servlet, request, response, errorPageURL,
117: needsSession, bufferSize, autoflush);
118: return pc;
119: } catch (Throwable ex) {
120: /* FIXME: need to do something reasonable here!! */
121: log.fatal("Exception initializing page context", ex);
122: return null;
123: }
124: }
125:
126: private void internalReleasePageContext(PageContext pc) {
127: pc.release();
128: if (USE_POOL && (pc instanceof PageContextImpl)) {
129: localPool.get().put(pc);
130: }
131: }
132:
133: private class PrivilegedGetPageContext implements PrivilegedAction {
134:
135: private JspFactoryImpl factory;
136: private Servlet servlet;
137: private ServletRequest request;
138: private ServletResponse response;
139: private String errorPageURL;
140: private boolean needsSession;
141: private int bufferSize;
142: private boolean autoflush;
143:
144: PrivilegedGetPageContext(JspFactoryImpl factory,
145: Servlet servlet, ServletRequest request,
146: ServletResponse response, String errorPageURL,
147: boolean needsSession, int bufferSize, boolean autoflush) {
148: this .factory = factory;
149: this .servlet = servlet;
150: this .request = request;
151: this .response = response;
152: this .errorPageURL = errorPageURL;
153: this .needsSession = needsSession;
154: this .bufferSize = bufferSize;
155: this .autoflush = autoflush;
156: }
157:
158: public Object run() {
159: return factory.internalGetPageContext(servlet, request,
160: response, errorPageURL, needsSession, bufferSize,
161: autoflush);
162: }
163: }
164:
165: private class PrivilegedReleasePageContext implements
166: PrivilegedAction {
167:
168: private JspFactoryImpl factory;
169: private PageContext pageContext;
170:
171: PrivilegedReleasePageContext(JspFactoryImpl factory,
172: PageContext pageContext) {
173: this .factory = factory;
174: this .pageContext = pageContext;
175: }
176:
177: public Object run() {
178: factory.internalReleasePageContext(pageContext);
179: return null;
180: }
181: }
182:
183: protected final class PageContextPool {
184:
185: private PageContext[] pool;
186:
187: private int current = -1;
188:
189: public PageContextPool() {
190: this .pool = new PageContext[POOL_SIZE];
191: }
192:
193: public void put(PageContext o) {
194: if (current < (POOL_SIZE - 1)) {
195: current++;
196: pool[current] = o;
197: }
198: }
199:
200: public PageContext get() {
201: PageContext item = null;
202: if (current >= 0) {
203: item = pool[current];
204: current--;
205: }
206: return item;
207: }
208:
209: }
210:
211: public JspApplicationContext getJspApplicationContext(
212: ServletContext context) {
213: return JspApplicationContextImpl.getInstance(context);
214: }
215: }
|