14c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/*
24c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
34c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * or more contributor license agreements. See the NOTICE file
44c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed with this work for additional information
54c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * regarding copyright ownership. The ASF licenses this file
64c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
74c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * you may not use this file except in compliance with the License.
84c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * You may obtain a copy of the License at
94c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson *
104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson *
124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Unless required by applicable law or agreed to in writing, software
134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * See the License for the specific language governing permissions and
164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * limitations under the License.
174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */
184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/*
194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * $Id: ObjectPool.java 475981 2006-11-16 23:35:53Z minchau $
204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */
214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpackage org.apache.xml.utils;
224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport java.util.ArrayList;
244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.res.XMLErrorResources;
264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.res.XMLMessages;
274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/**
304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Pool of object of a given type to pick from to help memory usage
314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @xsl.usage internal
324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */
334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic class ObjectPool implements java.io.Serializable
344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson{
354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    static final long serialVersionUID = -8519013691660936643L;
364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /** Type of objects in this pool.
384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *  @serial          */
394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  private final Class objectType;
404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /** Stack of given objects this points to.
424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *  @serial          */
434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  private final ArrayList freeStack;
444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Constructor ObjectPool
474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param type Type of objects for this pool
494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public ObjectPool(Class type)
514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    objectType = type;
534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    freeStack = new ArrayList();
544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Constructor ObjectPool
584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param className Fully qualified name of the type of objects for this pool.
604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public ObjectPool(String className)
624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    try
644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      objectType = ObjectFactory.findProviderClass(
664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        className, ObjectFactory.findClassLoader(), true);
674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    catch(ClassNotFoundException cnfe)
694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw new WrappedRuntimeException(cnfe);
714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    freeStack = new ArrayList();
734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Constructor ObjectPool
784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param type Type of objects for this pool
814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param size Size of vector to allocate
824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public ObjectPool(Class type, int size)
844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    objectType = type;
864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    freeStack = new ArrayList(size);
874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Constructor ObjectPool
914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public ObjectPool()
944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    objectType = null;
964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    freeStack = new ArrayList();
974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Get an instance of the given object in this pool if available
1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return an instance of the given object if available or null
1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public synchronized Object getInstanceIfFree()
1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // Check if the pool is empty.
1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (!freeStack.isEmpty())
1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // Remove object from end of free pool.
1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      Object result = freeStack.remove(freeStack.size() - 1);
1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return result;
1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    return null;
1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Get an instance of the given object in this pool
1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @return An instance of the given object
1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public synchronized Object getInstance()
1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // Check if the pool is empty.
1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    if (freeStack.isEmpty())
1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // Create a new object if so.
1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      try
1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      {
1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson        return objectType.newInstance();
1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      }
1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      catch (InstantiationException ex){}
1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      catch (IllegalAccessException ex){}
1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // Throw unchecked exception for error in pool configuration.
1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      throw new RuntimeException(XMLMessages.createXMLMessage(XMLErrorResources.ER_EXCEPTION_CREATING_POOL, null)); //"exception creating new instance for pool");
1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    else
1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    {
1464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      // Remove object from end of free pool.
1484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      Object result = freeStack.remove(freeStack.size() - 1);
1494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson      return result;
1514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    }
1524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
1534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  /**
1554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * Add an instance of the given object to the pool
1564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   *
1584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   * @param obj Object to add.
1594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson   */
1604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  public synchronized void freeInstance(Object obj)
1614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  {
1624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson
1634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // Make sure the object is of the correct type.
1644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // Remove safety.  -sb
1654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // if (objectType.isInstance(obj))
1664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // {
1674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    freeStack.add(obj);
1684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // }
1694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // else
1704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // {
1714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    //  throw new IllegalArgumentException("argument type invalid for pool");
1724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson    // }
1734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson  }
1744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson}
175