1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 /*
19  * $Id: ObjectPool.java 475981 2006-11-16 23:35:53Z minchau $
20  */
21 package org.apache.xml.utils;
22 
23 import java.util.ArrayList;
24 
25 import org.apache.xml.res.XMLErrorResources;
26 import org.apache.xml.res.XMLMessages;
27 
28 
29 /**
30  * Pool of object of a given type to pick from to help memory usage
31  * @xsl.usage internal
32  */
33 public class ObjectPool implements java.io.Serializable
34 {
35     static final long serialVersionUID = -8519013691660936643L;
36 
37   /** Type of objects in this pool.
38    *  @serial          */
39   private final Class objectType;
40 
41   /** Stack of given objects this points to.
42    *  @serial          */
43   private final ArrayList freeStack;
44 
45   /**
46    * Constructor ObjectPool
47    *
48    * @param type Type of objects for this pool
49    */
ObjectPool(Class type)50   public ObjectPool(Class type)
51   {
52     objectType = type;
53     freeStack = new ArrayList();
54   }
55 
56   /**
57    * Constructor ObjectPool
58    *
59    * @param className Fully qualified name of the type of objects for this pool.
60    */
ObjectPool(String className)61   public ObjectPool(String className)
62   {
63     try
64     {
65       objectType = ObjectFactory.findProviderClass(
66         className, ObjectFactory.findClassLoader(), true);
67     }
68     catch(ClassNotFoundException cnfe)
69     {
70       throw new WrappedRuntimeException(cnfe);
71     }
72     freeStack = new ArrayList();
73   }
74 
75 
76   /**
77    * Constructor ObjectPool
78    *
79    *
80    * @param type Type of objects for this pool
81    * @param size Size of vector to allocate
82    */
ObjectPool(Class type, int size)83   public ObjectPool(Class type, int size)
84   {
85     objectType = type;
86     freeStack = new ArrayList(size);
87   }
88 
89   /**
90    * Constructor ObjectPool
91    *
92    */
ObjectPool()93   public ObjectPool()
94   {
95     objectType = null;
96     freeStack = new ArrayList();
97   }
98 
99   /**
100    * Get an instance of the given object in this pool if available
101    *
102    *
103    * @return an instance of the given object if available or null
104    */
getInstanceIfFree()105   public synchronized Object getInstanceIfFree()
106   {
107 
108     // Check if the pool is empty.
109     if (!freeStack.isEmpty())
110     {
111 
112       // Remove object from end of free pool.
113       Object result = freeStack.remove(freeStack.size() - 1);
114       return result;
115     }
116 
117     return null;
118   }
119 
120   /**
121    * Get an instance of the given object in this pool
122    *
123    *
124    * @return An instance of the given object
125    */
getInstance()126   public synchronized Object getInstance()
127   {
128 
129     // Check if the pool is empty.
130     if (freeStack.isEmpty())
131     {
132 
133       // Create a new object if so.
134       try
135       {
136         return objectType.newInstance();
137       }
138       catch (InstantiationException ex){}
139       catch (IllegalAccessException ex){}
140 
141       // Throw unchecked exception for error in pool configuration.
142       throw new RuntimeException(XMLMessages.createXMLMessage(XMLErrorResources.ER_EXCEPTION_CREATING_POOL, null)); //"exception creating new instance for pool");
143     }
144     else
145     {
146 
147       // Remove object from end of free pool.
148       Object result = freeStack.remove(freeStack.size() - 1);
149 
150       return result;
151     }
152   }
153 
154   /**
155    * Add an instance of the given object to the pool
156    *
157    *
158    * @param obj Object to add.
159    */
freeInstance(Object obj)160   public synchronized void freeInstance(Object obj)
161   {
162 
163     // Make sure the object is of the correct type.
164     // Remove safety.  -sb
165     // if (objectType.isInstance(obj))
166     // {
167     freeStack.add(obj);
168     // }
169     // else
170     // {
171     //  throw new IllegalArgumentException("argument type invalid for pool");
172     // }
173   }
174 }
175