001: /*
002: * Copyright 1999-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.commons.pool.impl;
018:
019: import java.lang.ref.SoftReference;
020: import java.util.ArrayList;
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.NoSuchElementException;
024:
025: import org.apache.commons.pool.BaseObjectPool;
026: import org.apache.commons.pool.ObjectPool;
027: import org.apache.commons.pool.PoolableObjectFactory;
028:
029: /**
030: * A {@link java.lang.ref.SoftReference SoftReference} based
031: * {@link ObjectPool}.
032: *
033: * @author Rodney Waldhoff
034: * @version $Revision: 383290 $ $Date: 2006-03-05 02:00:15 -0500 (Sun, 05 Mar 2006) $
035: */
036: public class SoftReferenceObjectPool extends BaseObjectPool implements
037: ObjectPool {
038: public SoftReferenceObjectPool() {
039: _pool = new ArrayList();
040: _factory = null;
041: }
042:
043: public SoftReferenceObjectPool(PoolableObjectFactory factory) {
044: _pool = new ArrayList();
045: _factory = factory;
046: }
047:
048: public SoftReferenceObjectPool(PoolableObjectFactory factory,
049: int initSize) throws Exception {
050: _pool = new ArrayList();
051: _factory = factory;
052: if (null != _factory) {
053: for (int i = 0; i < initSize; i++) {
054: Object obj = _factory.makeObject();
055: _factory.passivateObject(obj);
056: _pool.add(new SoftReference(obj));
057: }
058: }
059: }
060:
061: public synchronized Object borrowObject() throws Exception {
062: assertOpen();
063: Object obj = null;
064: while (null == obj) {
065: if (_pool.isEmpty()) {
066: if (null == _factory) {
067: throw new NoSuchElementException();
068: } else {
069: obj = _factory.makeObject();
070: }
071: } else {
072: SoftReference ref = (SoftReference) (_pool.remove(_pool
073: .size() - 1));
074: obj = ref.get();
075: }
076: if (null != _factory && null != obj) {
077: _factory.activateObject(obj);
078: }
079: if (null != _factory && null != obj
080: && !_factory.validateObject(obj)) {
081: _factory.destroyObject(obj);
082: obj = null;
083: }
084: }
085: _numActive++;
086: return obj;
087: }
088:
089: public synchronized void returnObject(Object obj) throws Exception {
090: assertOpen();
091: boolean success = true;
092: if (!(_factory.validateObject(obj))) {
093: success = false;
094: } else {
095: try {
096: _factory.passivateObject(obj);
097: } catch (Exception e) {
098: success = false;
099: }
100: }
101:
102: boolean shouldDestroy = !success;
103: _numActive--;
104: if (success) {
105: _pool.add(new SoftReference(obj));
106: }
107: notifyAll(); // _numActive has changed
108:
109: if (shouldDestroy) {
110: try {
111: _factory.destroyObject(obj);
112: } catch (Exception e) {
113: // ignored
114: }
115: }
116:
117: }
118:
119: public synchronized void invalidateObject(Object obj)
120: throws Exception {
121: assertOpen();
122: _numActive--;
123: _factory.destroyObject(obj);
124: notifyAll(); // _numActive has changed
125: }
126:
127: /**
128: * Create an object, and place it into the pool.
129: * addObject() is useful for "pre-loading" a pool with idle objects.
130: */
131: public synchronized void addObject() throws Exception {
132: assertOpen();
133: Object obj = _factory.makeObject();
134: _numActive++; // A little slimy - must do this because returnObject decrements it.
135: returnObject(obj);
136: }
137:
138: /** Returns an approximation not less than the of the number of idle instances in the pool. */
139: public synchronized int getNumIdle() {
140: assertOpen();
141: return _pool.size();
142: }
143:
144: public synchronized int getNumActive() {
145: assertOpen();
146: return _numActive;
147: }
148:
149: public synchronized void clear() {
150: assertOpen();
151: if (null != _factory) {
152: Iterator iter = _pool.iterator();
153: while (iter.hasNext()) {
154: try {
155: Object obj = ((SoftReference) iter.next()).get();
156: if (null != obj) {
157: _factory.destroyObject(obj);
158: }
159: } catch (Exception e) {
160: // ignore error, keep destroying the rest
161: }
162: }
163: }
164: _pool.clear();
165: }
166:
167: public synchronized void close() throws Exception {
168: clear();
169: _pool = null;
170: _factory = null;
171: super .close();
172: }
173:
174: public synchronized void setFactory(PoolableObjectFactory factory)
175: throws IllegalStateException {
176: assertOpen();
177: if (0 < getNumActive()) {
178: throw new IllegalStateException(
179: "Objects are already active");
180: } else {
181: clear();
182: _factory = factory;
183: }
184: }
185:
186: /** My pool. */
187: private List _pool = null;
188:
189: /** My {@link PoolableObjectFactory}. */
190: private PoolableObjectFactory _factory = null;
191:
192: /** Number of active objects. */
193: private int _numActive = 0;
194: }
|