1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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