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  
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      // index of next available tag handler
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          // Nothing - jasper generated servlets call the other constructor,
82          // this should be used in future + init .
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         // Out of sync block - there is no need for other threads to
114         // wait for us to construct a tag for this thread.
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         // There is no need for other threads to wait for us to release
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