001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: IteratorPool.java 475981 2006-11-16 23:35:53Z minchau $
020     */
021    package org.apache.xpath.axes;
022    
023    import java.util.ArrayList;
024    
025    import org.apache.xml.dtm.DTMIterator;
026    import org.apache.xml.utils.WrappedRuntimeException;
027    
028    /**
029     * Pool of object of a given type to pick from to help memory usage
030     * @xsl.usage internal
031     */
032    public final class IteratorPool implements java.io.Serializable
033    {
034        static final long serialVersionUID = -460927331149566998L;
035    
036      /** 
037       * Type of objects in this pool.
038       */
039      private final DTMIterator m_orig;
040    
041      /** 
042       * Stack of given objects this points to.
043       */
044      private final ArrayList m_freeStack;
045    
046      /**
047       * Constructor IteratorPool
048       *
049       * @param original The original iterator from which all others will be cloned.
050       */
051      public IteratorPool(DTMIterator original)
052      {
053        m_orig = original;
054        m_freeStack = new ArrayList();
055      }
056      
057      /**
058       * Get an instance of the given object in this pool 
059       *
060       * @return An instance of the given object
061       */
062      public synchronized DTMIterator getInstanceOrThrow()
063        throws CloneNotSupportedException
064      {
065        // Check if the pool is empty.
066        if (m_freeStack.isEmpty())
067        {
068    
069          // Create a new object if so.
070          return (DTMIterator)m_orig.clone();
071        }
072        else
073        {
074          // Remove object from end of free pool.
075          DTMIterator result = (DTMIterator)m_freeStack.remove(m_freeStack.size() - 1);
076          return result;
077        }
078      }
079      
080      /**
081       * Get an instance of the given object in this pool 
082       *
083       * @return An instance of the given object
084       */
085      public synchronized DTMIterator getInstance()
086      {
087        // Check if the pool is empty.
088        if (m_freeStack.isEmpty())
089        {
090    
091          // Create a new object if so.
092          try
093          {
094            return (DTMIterator)m_orig.clone();
095          }
096          catch (Exception ex)
097          {
098            throw new WrappedRuntimeException(ex);
099          }
100        }
101        else
102        {
103          // Remove object from end of free pool.
104          DTMIterator result = (DTMIterator)m_freeStack.remove(m_freeStack.size() - 1);
105          return result;
106        }
107      }
108    
109      /**
110       * Add an instance of the given object to the pool  
111       *
112       *
113       * @param obj Object to add.
114       */
115      public synchronized void freeInstance(DTMIterator obj)
116      {
117        m_freeStack.add(obj);
118      }
119    }