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:
018: package org.apache.jasper.runtime;
019:
020: import java.util.Enumeration;
021: import java.util.Vector;
022:
023: import javax.servlet.ServletConfig;
024: import javax.servlet.jsp.JspException;
025: import javax.servlet.jsp.tagext.Tag;
026:
027: import org.apache.jasper.Constants;
028:
029: /**
030: * Thread-local based pool of tag handlers that can be reused.
031: *
032: * @author Jan Luehe
033: * @author Costin Manolache
034: */
035: public class PerThreadTagHandlerPool extends TagHandlerPool {
036:
037: private int maxSize;
038:
039: // For cleanup
040: private Vector perThreadDataVector;
041:
042: private ThreadLocal perThread;
043:
044: private static class PerThreadData {
045: Tag handlers[];
046: int current;
047: }
048:
049: /**
050: * Constructs a tag handler pool with the default capacity.
051: */
052: public PerThreadTagHandlerPool() {
053: super ();
054: perThreadDataVector = new Vector();
055: }
056:
057: protected void init(ServletConfig config) {
058: maxSize = Constants.MAX_POOL_SIZE;
059: String maxSizeS = getOption(config, OPTION_MAXSIZE, null);
060: if (maxSizeS != null) {
061: maxSize = Integer.parseInt(maxSizeS);
062: if (maxSize < 0) {
063: maxSize = Constants.MAX_POOL_SIZE;
064: }
065: }
066:
067: perThread = new ThreadLocal() {
068: protected Object initialValue() {
069: PerThreadData ptd = new PerThreadData();
070: ptd.handlers = new Tag[maxSize];
071: ptd.current = -1;
072: perThreadDataVector.addElement(ptd);
073: return ptd;
074: }
075: };
076: }
077:
078: /**
079: * Gets the next available tag handler from this tag handler pool,
080: * instantiating one if this tag handler pool is empty.
081: *
082: * @param handlerClass Tag handler class
083: *
084: * @return Reused or newly instantiated tag handler
085: *
086: * @throws JspException if a tag handler cannot be instantiated
087: */
088: public Tag get(Class handlerClass) throws JspException {
089: PerThreadData ptd = (PerThreadData) perThread.get();
090: if (ptd.current >= 0) {
091: return ptd.handlers[ptd.current--];
092: } else {
093: try {
094: return (Tag) handlerClass.newInstance();
095: } catch (Exception e) {
096: throw new JspException(e.getMessage(), e);
097: }
098: }
099: }
100:
101: /**
102: * Adds the given tag handler to this tag handler pool, unless this tag
103: * handler pool has already reached its capacity, in which case the tag
104: * handler's release() method is called.
105: *
106: * @param handler Tag handler to add to this tag handler pool
107: */
108: public void reuse(Tag handler) {
109: PerThreadData ptd = (PerThreadData) perThread.get();
110: if (ptd.current < (ptd.handlers.length - 1)) {
111: ptd.handlers[++ptd.current] = handler;
112: } else {
113: handler.release();
114: }
115: }
116:
117: /**
118: * Calls the release() method of all tag handlers in this tag handler pool.
119: */
120: public void release() {
121: Enumeration enumeration = perThreadDataVector.elements();
122: while (enumeration.hasMoreElements()) {
123: PerThreadData ptd = (PerThreadData) enumeration
124: .nextElement();
125: if (ptd.handlers != null) {
126: for (int i = ptd.current; i >= 0; i--) {
127: if (ptd.handlers[i] != null) {
128: ptd.handlers[i].release();
129: }
130: }
131: }
132: }
133: }
134: }
|