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 */
21package org.apache.xml.utils;
22
23import java.util.ArrayList;
24
25import org.apache.xml.res.XMLErrorResources;
26import 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 */
33public 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   */
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   */
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   */
83  public ObjectPool(Class type, int size)
84  {
85    objectType = type;
86    freeStack = new ArrayList(size);
87  }
88
89  /**
90   * Constructor ObjectPool
91   *
92   */
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   */
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   */
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   */
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