Suppose you're writing a set of java.io.Reader utilities, and would like to
provide a method for dumping the contents of a Reader to a String.
Here's the code for the ReaderUtil, implemented without an ObjectPool:
import java.io.Reader;
import java.io.IOException;
public class ReaderUtil {
public ReaderUtil() {
}
/**
* Dumps the contents of the {@link Reader} to a
* String, closing the {@link Reader} when done.
*/
public String readToString(Reader in) throws IOException {
StringBuffer buf = new StringBuffer();
try {
for(int c = in.read(); c != -1; c = in.read()) {
buf.append((char)c);
}
return buf.toString();
} catch(IOException e) {
throw e;
} finally {
try {
in.close();
} catch(Exception e) {
// ignored
}
}
}
}
For the sake of this example, let's assume we want to to pool the StringBuffers
used to buffer the Reader's contents. (A pool of StringBuffers
may or may not be useful in practice. We're just using it as a simple example here.)
Let's further assume that a complete pool implementation will be provided via
a constructor. (We'll show you how to create such an implementation in just a moment.)
Then to use the pool we simply call borrowObject to obtain the buffer, and
then call returnObject when we're done with it.
Then a ReaderUtil implementation using a pool of StringBuffers might look
like this (changed code is in bold face):
import org.apache.commons.pool.ObjectPool;
import java.io.Reader;
import java.io.IOException;
public class ReaderUtil {
private ObjectPool pool;
public ReaderUtil(ObjectPool pool) {
this.pool = pool;
}
/**
* Dumps the contents of the {@link Reader} to a
* String, closing the {@link Reader} when done.
*/
public String readToString(Reader in) throws IOException {
StringBuffer buf = null;
try {
buf = (StringBuffer)(pool.borrowObject());
for(int c = in.read(); c != -1; c = in.read()) {
buf.append((char)c);
}
return buf.toString();
} catch(IOException e) {
throw e;
} catch(Exception e) {
throw new RuntimeException("Unable to borrow buffer from pool" +
e.toString());
} finally {
try {
in.close();
} catch(Exception e) {
// ignored
}
try {
if(null != buf) {
pool.returnObject(buf);
}
} catch(Exception e) {
// ignored
}
}
}
}
Since we've constrained ourselves to the ObjectPool interface, an arbitrary pool
implementation (returning, in our case, StringBuffers) can be used. When a different
or "better" pool implemenatation comes along, we can simply drop it into our ReaderUtil
without changing a line of code.