1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts2.jasper.runtime;
19
20 import org.apache.struts2.jasper.Constants;
21
22 import javax.servlet.ServletConfig;
23 import javax.servlet.jsp.JspException;
24 import javax.servlet.jsp.tagext.Tag;
25
26 /***
27 * Pool of tag handlers that can be reused.
28 *
29 * @author Jan Luehe
30 */
31 public class TagHandlerPool {
32
33 private Tag[] handlers;
34
35 public static String OPTION_TAGPOOL = "tagpoolClassName";
36 public static String OPTION_MAXSIZE = "tagpoolMaxSize";
37
38
39 private int current;
40
41 public static TagHandlerPool getTagHandlerPool(ServletConfig config) {
42 TagHandlerPool result = null;
43
44 String tpClassName = getOption(config, OPTION_TAGPOOL, null);
45 if (tpClassName != null) {
46 try {
47 Class c = Class.forName(tpClassName);
48 result = (TagHandlerPool) c.newInstance();
49 } catch (Exception e) {
50 e.printStackTrace();
51 result = null;
52 }
53 }
54 if (result == null) result = new TagHandlerPool();
55 result.init(config);
56
57 return result;
58 }
59
60 protected void init(ServletConfig config) {
61 int maxSize = -1;
62 String maxSizeS = getOption(config, OPTION_MAXSIZE, null);
63 if (maxSizeS != null) {
64 try {
65 maxSize = Integer.parseInt(maxSizeS);
66 } catch (Exception ex) {
67 maxSize = -1;
68 }
69 }
70 if (maxSize < 0) {
71 maxSize = Constants.MAX_POOL_SIZE;
72 }
73 this.handlers = new Tag[maxSize];
74 this.current = -1;
75 }
76
77 /***
78 * Constructs a tag handler pool with the default capacity.
79 */
80 public TagHandlerPool() {
81
82
83 }
84
85 /***
86 * Constructs a tag handler pool with the given capacity.
87 *
88 * @param capacity Tag handler pool capacity
89 * @deprecated Use static getTagHandlerPool
90 */
91 public TagHandlerPool(int capacity) {
92 this.handlers = new Tag[capacity];
93 this.current = -1;
94 }
95
96 /***
97 * Gets the next available tag handler from this tag handler pool,
98 * instantiating one if this tag handler pool is empty.
99 *
100 * @param handlerClass Tag handler class
101 * @return Reused or newly instantiated tag handler
102 * @throws JspException if a tag handler cannot be instantiated
103 */
104 public Tag get(Class handlerClass) throws JspException {
105 Tag handler = null;
106 synchronized (this) {
107 if (current >= 0) {
108 handler = handlers[current--];
109 return handler;
110 }
111 }
112
113
114
115 try {
116 return (Tag) handlerClass.newInstance();
117 } catch (Exception e) {
118 throw new JspException(e.getMessage(), e);
119 }
120 }
121
122 /***
123 * Adds the given tag handler to this tag handler pool, unless this tag
124 * handler pool has already reached its capacity, in which case the tag
125 * handler's release() method is called.
126 *
127 * @param handler Tag handler to add to this tag handler pool
128 */
129 public void reuse(Tag handler) {
130 synchronized (this) {
131 if (current < (handlers.length - 1)) {
132 handlers[++current] = handler;
133 return;
134 }
135 }
136
137 handler.release();
138 }
139
140 /***
141 * Calls the release() method of all available tag handlers in this tag
142 * handler pool.
143 */
144 public synchronized void release() {
145 for (int i = current; i >= 0; i--) {
146 handlers[i].release();
147 }
148 }
149
150 protected static String getOption(ServletConfig config, String name, String defaultV) {
151 if (config == null) return defaultV;
152
153 String value = config.getInitParameter(name);
154 if (value != null) return value;
155 if (config.getServletContext() == null)
156 return defaultV;
157 value = config.getServletContext().getInitParameter(name);
158 if (value != null) return value;
159 return defaultV;
160 }
161
162 }
163