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 java.util.ArrayList;
41  import java.util.HashMap;
42  import java.util.List;
43  import java.util.Map;
44  
45  /***
46   *  A class that can create instances of specific types of resources, such as
47   *  JDBC connections.
48   *
49   * @version  $Revision: 1.4 $
50   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
51   */
52  public abstract class ResourceFactory {
53  
54      private final Map resourceManagerToResourceListMap_ = new HashMap( 89 );
55  
56  
57      /***
58       *  Create a factory
59       */
60      public ResourceFactory() {
61      }
62  
63  
64      /***
65       *  Allocate a resource for the specified store
66       *
67       * @param  resourceManager The object that is managing the resource
68       *      allocation
69       * @return  The new resource
70       * @exception  ResourceException If an error occurs
71       */
72      public final synchronized ManagedResource getResource(
73              final ResourceManager resourceManager )
74          throws
75              ResourceException {
76  
77          if( resourceManager == null ) {
78              throw new NullPointerException( "resourceManager" );
79          }
80  
81          final ManagedResource resource;
82          try {
83              resource = getResourceImpl( resourceManager );
84          }
85          catch( final Exception e ) {
86              throw new ResourceException( e );
87          }
88  
89          registerResource( resourceManager, resource );
90          return resource;
91      }
92  
93  
94      /***
95       *  Release the specified resource. It must have been allocated by the
96       *  specified store
97       *
98       * @param  resource The resource that we are releasing
99       * @param  resourceManager The object that is managing the resource
100      *      allocation
101      * @exception  ResourceException If an error occurs
102      */
103     public final synchronized void releaseResource(
104             final ResourceManager resourceManager,
105             final ManagedResource resource )
106         throws
107             ResourceException {
108 
109         if( resourceManager == null ) {
110             throw new NullPointerException( "resourceManager" );
111         }
112         if( resource == null ) {
113             throw new NullPointerException( "resource" );
114         }
115 
116         deregisterResource( resourceManager, resource );
117 
118         try {
119             releaseResourceImpl( resourceManager, resource );
120         }
121         catch( final Exception e ) {
122             throw new ResourceException( e );
123         }
124     }
125 
126 
127     /***
128      *  Release all the resources that had been allocated by the specified
129      *  store.
130      *
131      * @param  resourceManager The object that is managing the resource
132      *      allocation
133      * @exception  ResourceException If an error occurs
134      */
135     public synchronized void releaseAllResources(
136             final ResourceManager resourceManager )
137         throws
138             ResourceException {
139 
140         final List list = ( List )resourceManagerToResourceListMap_.get( resourceManager );
141         if( list != null ) {
142             while( list.size() != 0 ) {
143                 releaseResource( resourceManager, ( ManagedResource )list.get( 0 ) );
144             }
145         }
146     }
147 
148 
149     /***
150      *  Reinitialize the resource to a known state. This is required for
151      *  resource pooling as all resources being returned from a pool must have
152      *  been initialized to a known state.
153      *
154      * @param  resource the resource to reinitialize
155      * @return  true if the resource was successfully reinitialized
156      */
157     public abstract boolean reinitializeResourceIfPossible( final ManagedResource resource );
158 
159 
160     /***
161      *  Subclasses will override this to perform the actual allocation of the
162      *  resource.
163      *
164      * @param  resourceManager The object that is managing the resource
165      *      allocation
166      * @return  The new resource
167      * @exception  Exception If an error occurs
168      */
169     protected abstract ManagedResource getResourceImpl(
170             final ResourceManager resourceManager )
171         throws
172             Exception;
173 
174 
175     /***
176      *  Subclasses will override this to perform the actual release of the
177      *  resource.
178      *
179      * @param  resource The resource to release
180      * @param  resourceManager The object that is managing the resource
181      *      allocation
182      * @exception  Exception If an error occurs
183      */
184     protected abstract void releaseResourceImpl(
185             final ResourceManager resourceManager,
186             final ManagedResource resource )
187         throws
188             Exception;
189 
190 
191     private synchronized void registerResource(
192             final ResourceManager resourceManager,
193             final ManagedResource resource ) {
194 
195         List list = ( List )resourceManagerToResourceListMap_.get( resourceManager );
196         if( list == null ) {
197             list = new ArrayList();
198             resourceManagerToResourceListMap_.put( resourceManager, list );
199         }
200 
201         list.add( resource );
202     }
203 
204 
205     private synchronized void deregisterResource(
206             final ResourceManager resourceManager,
207             final ManagedResource resource )
208         throws
209             ResourceException {
210 
211         final List list = ( List )resourceManagerToResourceListMap_.get( resourceManager );
212         if( list == null ) {
213             throw new ResourceException(
214                     "Resource was not allocated by this resource manager: resource=["
215                      + resource
216                      + "] resourceManager=[" + resourceManager
217                      + "]: No resources are being managed by this manager" );
218         }
219 
220         if( list.contains( resource ) == false ) {
221             throw new ResourceException(
222                     "Resource was not allocated by this resource manager: resource=["
223                      + resource + "] resourceManager=[" + resourceManager
224                      + "]: Resources that are being managed by this manager are ["
225                      + list + "]" );
226         }
227 
228         list.remove( resource );
229         if( list.size() == 0 ) {
230             resourceManagerToResourceListMap_.remove( resourceManager );
231         }
232     }
233 }
234