001: /*
002: * This file is part of the QuickServer library
003: * Copyright (C) 2003-2005 QuickServer.org
004: *
005: * Use, modification, copying and distribution of this software is subject to
006: * the terms and conditions of the GNU Lesser General Public License.
007: * You should have received a copy of the GNU LGP License along with this
008: * library; if not, you can download a copy from <http://www.quickserver.org/>.
009: *
010: * For questions, suggestions, bug-reports, enhancement-requests etc.
011: * visit http://www.quickserver.org
012: *
013: */
014:
015: package org.quickserver.util.pool;
016:
017: import java.util.*;
018: import org.apache.commons.pool.*;
019: import org.apache.commons.pool.impl.*;
020: import java.util.logging.*;
021:
022: /**
023: * This class will maintain a simple pool of object instances.
024: * It internally used a <code>HashSet</code>
025: * @author Akshathkumar Shetty
026: * @since 1.3
027: */
028: public class BasicObjectPool implements QSObjectPool {
029: private static final Logger logger = Logger
030: .getLogger(BasicObjectPool.class.getName());
031:
032: private PoolableObjectFactory factory;
033: private Config config;
034: private Set activeObjects, idleObjects;
035: private volatile boolean inMaintain = false;
036:
037: public BasicObjectPool() {
038: activeObjects = Collections.synchronizedSet(new HashSet());
039: idleObjects = Collections.synchronizedSet(new HashSet());
040: config = new Config();
041: }
042:
043: public BasicObjectPool(PoolableObjectFactory factory,
044: BasicObjectPool.Config config) {
045: this ();
046: this .factory = factory;
047: if (config != null)
048: this .config = config;
049: }
050:
051: public void addObject() throws Exception {
052: if (config.maxIdle == -1 || config.maxIdle > getNumIdle())
053: idleObjects.add(factory.makeObject());
054: else
055: maintain();
056: }
057:
058: public Object borrowObject() throws Exception {
059: if (getNumIdle() <= 0
060: && (config.maxActive == -1 || config.maxActive > getNumActive())) {
061: addObject();
062: }
063: if (getNumIdle() <= 0) {
064: throw new NoSuchElementException(
065: "No free objects! MaxActive:" + config.maxActive
066: + ", NumActive:" + getNumActive());
067: }
068:
069: Object obj = null;
070: synchronized (this ) {
071: obj = idleObjects.iterator().next();
072: idleObjects.remove(obj);
073: factory.activateObject(obj);
074: activeObjects.add(obj);
075: }
076: return obj;
077: }
078:
079: /**Clears any objects sitting idle in the pool*/
080: public synchronized void clear() {
081: Iterator iterator = idleObjects.iterator();
082: while (iterator.hasNext()) {
083: try {
084: invalidateObject(iterator.next());
085: } catch (Exception e) {
086: logger.warning("Error in BasicObjectPool.clear : " + e);
087: }
088: }
089: idleObjects.clear();
090: }
091:
092: /**Close this pool, and free any resources associated with it.*/
093: public void close() throws Exception {
094: clear();
095: /*
096: Iterator iterator = activeObjects.iterator();
097: while(iterator.hasNext()) {
098: try {
099: invalidateObject(iterator.next());
100: } catch(Exception e) {
101: logger.warning("Error in BasicObjectPool.close : "+e);
102: }
103: }
104: */
105: activeObjects.clear();
106: }
107:
108: /**Return the number of instances currently borrowed from my pool */
109: public int getNumActive() {
110: return activeObjects.size();
111: }
112:
113: /**Return the number of instances currently idle in my pool */
114: public int getNumIdle() {
115: return idleObjects.size();
116: }
117:
118: /**Invalidates an object from the pool */
119: public void invalidateObject(Object obj) throws Exception {
120: factory.destroyObject(obj);
121: }
122:
123: /**Return an instance to my pool*/
124: public synchronized void returnObject(Object obj) throws Exception {
125: activeObjects.remove(obj);
126: if (factory.validateObject(obj) == false) {
127: logger.finer("Object not good for return: " + obj);
128: return;
129: }
130: factory.passivateObject(obj);
131: idleObjects.add(obj);
132: if (config.maxIdle != -1 && config.maxIdle < getNumIdle()) {
133: maintain();
134: }
135: }
136:
137: /**Sets the factory I use to create new instances */
138: public void setFactory(PoolableObjectFactory factory) {
139: this .factory = factory;
140: }
141:
142: private void maintain() {
143: if (inMaintain == true) {
144: return;
145: }
146: inMaintain = true;
147: logger.finest("Starting maintain: " + getNumIdle());
148: while (getNumIdle() > config.maxIdle) {
149: try {
150: synchronized (idleObjects) {
151: Object obj = idleObjects.iterator().next();
152: idleObjects.remove(obj);
153: invalidateObject(obj);
154: }
155: } catch (Exception e) {
156: logger.warning("Error in BasicObjectPool.maintain : "
157: + e);
158: }
159: }
160: inMaintain = false;
161: logger.finest("Finished maintain: " + getNumIdle());
162: }
163:
164: public static class Config {
165: public int maxActive = -1;
166: public int maxIdle = 10;
167: }
168:
169: /**
170: * Returns the iterator of all active objects
171: * @since 1.3.1
172: */
173: public Iterator getAllActiveObjects() {
174: List _list = new LinkedList();
175: _list.addAll(activeObjects);
176: return _list.iterator(); //*/activeObjects.iterator();
177: }
178:
179: public Object getObjectToSynchronize() {
180: return activeObjects;
181: }
182: }
|