View Javadoc

1   /*
2    * Copyright (c) 1998, 2005 Gargoyle Software Inc. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, are permitted provided that the following conditions are met:
6    *
7    * 1. Redistributions of source code must retain the above copyright notice,
8    *    this list of conditions and the following disclaimer.
9    * 2. Redistributions in binary form must reproduce the above copyright notice,
10   *    this list of conditions and the following disclaimer in the documentation
11   *    and/or other materials provided with the distribution.
12   * 3. The end-user documentation included with the redistribution, if any, must
13   *    include the following acknowledgment:
14   *
15   *       "This product includes software developed by Gargoyle Software Inc.
16   *        (http://www.GargoyleSoftware.com/)."
17   *
18   *    Alternately, this acknowledgment may appear in the software itself, if
19   *    and wherever such third-party acknowledgments normally appear.
20   * 4. The name "Gargoyle Software" must not be used to endorse or promote
21   *    products derived from this software without prior written permission.
22   *    For written permission, please contact info@GargoyleSoftware.com.
23   * 5. Products derived from this software may not be called "GSBase", nor may
24   *    "GSBase" appear in their name, without prior written permission of
25   *    Gargoyle Software Inc.
26   *
27   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
28   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
29   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
30   * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
33   * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
36   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37   */
38  package com.gargoylesoftware.base.resource;
39  
40  import com.gargoylesoftware.base.util.DetailedIllegalArgumentException;
41  import java.util.LinkedList;
42  import java.util.List;
43  
44  /***
45   *  A resource factory that provides object pooling
46   *
47   * @version  $Revision: 1.5 $
48   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
49   */
50  public class PooledResourceFactory extends ResourceFactory {
51  
52      private final ResourceFactory sourceFactory_;
53      private int preferredCacheSize_;
54      private List cache_ = new LinkedList();
55  
56  
57      /***
58       *  Create an instance
59       *
60       * @param  sourceFactory The factory that will be used to actually create
61       *      and destroy the pooled resources
62       */
63      public PooledResourceFactory( final ResourceFactory sourceFactory ) {
64          if( sourceFactory == null ) {
65              throw new NullPointerException( "sourceFactory" );
66          }
67          sourceFactory_ = sourceFactory;
68          setPreferredCacheSize( 4 );
69      }
70  
71  
72      /***
73       *  Set the preferredCacheSize
74       *
75       * @param  size The new size. May not be negative
76       */
77      public void setPreferredCacheSize( final int size ) {
78          if( size < 0 ) {
79              throw new DetailedIllegalArgumentException( "size", new Integer(size), "May not be negative" );
80          }
81          preferredCacheSize_ = size;
82      }
83  
84  
85      /***
86       *  Return the preferredCacheSize
87       *
88       * @return  The size
89       */
90      public int getPreferredCacheSize() {
91          return preferredCacheSize_;
92      }
93  
94  
95      /***
96       *  Reinitialize the resource to a known state. This is required for
97       *  resource pooling as all resources being returned from a pool must have
98       *  been initialized to a known state.
99       *
100      * @param  resource the resource to reinitialize
101      * @return  true if the resource was successfully reinitialized
102      */
103     public synchronized boolean reinitializeResourceIfPossible( final ManagedResource resource ) {
104         return sourceFactory_.reinitializeResourceIfPossible( resource );
105     }
106 
107 
108 
109     /***
110      *  Get a resource
111      *
112      * @param  resourceManager The manager that owns this factory
113      * @return  A resource
114      * @exception  Exception If an error occurs
115      */
116     protected synchronized ManagedResource getResourceImpl(
117             final ResourceManager resourceManager )
118         throws
119             Exception {
120 
121         ManagedResource resource;
122 
123         synchronized( cache_ ) {
124             if( cache_.isEmpty() == true ) {
125                 resource = sourceFactory_.getResource( resourceManager );
126             }
127             else {
128                 resource = (ManagedResource)cache_.get( 0 );
129                 cache_.remove( 0 );
130             }
131         }
132 
133         return resource;
134     }
135 
136 
137     /***
138      *  Release a resource
139      *
140      * @param  resource The resource to release
141      * @param  resourceManager The manager that owns this factory
142      * @exception  Exception If an error occurs
143      */
144     protected synchronized void releaseResourceImpl(
145             final ResourceManager resourceManager,
146             final ManagedResource resource )
147         throws
148             Exception {
149 
150         synchronized( cache_ ) {
151             if( cache_.size() < getPreferredCacheSize()
152                      && sourceFactory_.reinitializeResourceIfPossible( resource ) == true ) {
153                 cache_.add( resource );
154             }
155             else {
156                 sourceFactory_.releaseResource( resourceManager, resource );
157             }
158         }
159     }
160 }
161