1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * @LastModified: Oct 2017
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.xpath.internal.axes;
  23 
  24 import com.sun.org.apache.xml.internal.dtm.DTMIterator;
  25 import com.sun.org.apache.xml.internal.utils.WrappedRuntimeException;
  26 import java.util.ArrayList;
  27 import java.util.List;
  28 
  29 /**
  30  * Pool of object of a given type to pick from to help memory usage
  31  * @xsl.usage internal
  32  */
  33 public final class IteratorPool implements java.io.Serializable
  34 {
  35     static final long serialVersionUID = -460927331149566998L;
  36 
  37   /**
  38    * Type of objects in this pool.
  39    */
  40   private final DTMIterator m_orig;
  41 
  42   /**
  43    * Stack of given objects this points to.
  44    */
  45   private final List<DTMIterator> m_freeStack;
  46 
  47   /**
  48    * Constructor IteratorPool
  49    *
  50    * @param original The original iterator from which all others will be cloned.
  51    */
  52   public IteratorPool(DTMIterator original)
  53   {
  54     m_orig = original;
  55     m_freeStack = new ArrayList<>();
  56   }
  57 
  58   /**
  59    * Get an instance of the given object in this pool
  60    *
  61    * @return An instance of the given object
  62    */
  63   public synchronized DTMIterator getInstanceOrThrow()
  64     throws CloneNotSupportedException
  65   {
  66     // Check if the pool is empty.
  67     if (m_freeStack.isEmpty())
  68     {
  69 
  70       // Create a new object if so.
  71       return (DTMIterator)m_orig.clone();
  72     }
  73     else
  74     {
  75       // Remove object from end of free pool.
  76       DTMIterator result = m_freeStack.remove(m_freeStack.size() - 1);
  77       return result;
  78     }
  79   }
  80 
  81   /**
  82    * Get an instance of the given object in this pool
  83    *
  84    * @return An instance of the given object
  85    */
  86   public synchronized DTMIterator getInstance()
  87   {
  88     // Check if the pool is empty.
  89     if (m_freeStack.isEmpty())
  90     {
  91 
  92       // Create a new object if so.
  93       try
  94       {
  95         return (DTMIterator)m_orig.clone();
  96       }
  97       catch (Exception ex)
  98       {
  99         throw new WrappedRuntimeException(ex);
 100       }
 101     }
 102     else
 103     {
 104       // Remove object from end of free pool.
 105       DTMIterator result = m_freeStack.remove(m_freeStack.size() - 1);
 106       return result;
 107     }
 108   }
 109 
 110   /**
 111    * Add an instance of the given object to the pool
 112    *
 113    *
 114    * @param obj Object to add.
 115    */
 116   public synchronized void freeInstance(DTMIterator obj)
 117   {
 118     m_freeStack.add(obj);
 119   }
 120 }