This is an automated email from the ASF dual-hosted git repository.

gk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/turbine-fulcrum-pool.git

commit ab6768f9302ff44d6a0584614a71a2199d00e34c
Author: Siegfried Goeschl <[email protected]>
AuthorDate: Thu Oct 25 16:29:42 2007 +0000

    +) using fulcrum-yaafi-1.0.5
    +) getting it to run with maven 1.1
    
    git-svn-id: 
https://svn.apache.org/repos/asf/turbine/fulcrum/trunk/pool@588276 
13f79535-47bb-0310-9956-ffa450edef68
---
 .cvsignore                                         |   6 +
 maven.xml                                          |  26 +
 project.xml                                        |  55 ++
 .../apache/fulcrum/pool/ArrayCtorRecyclable.java   |  40 ++
 .../org/apache/fulcrum/pool/BoundedBuffer.java     | 151 +++++
 .../apache/fulcrum/pool/DefaultPoolService.java    | 653 +++++++++++++++++++++
 .../apache/fulcrum/pool/InitableRecyclable.java    |  44 ++
 .../fulcrum/pool/ObjectInputStreamForContext.java  |  70 +++
 .../org/apache/fulcrum/pool/PoolException.java     |  47 ++
 src/java/org/apache/fulcrum/pool/PoolService.java  | 125 ++++
 src/java/org/apache/fulcrum/pool/Recyclable.java   |  57 ++
 src/test/TestComponentConfig.xml                   |  27 +
 src/test/TestRoleConfig.xml                        |  32 +
 .../org/apache/fulcrum/pool/PoolServiceTest.java   | 112 ++++
 xdocs/changes.xml                                  |  45 ++
 xdocs/index.xml                                    | 129 ++++
 xdocs/navigation.xml                               |  37 ++
 17 files changed, 1656 insertions(+)

diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 0000000..39db54d
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,6 @@
+target
+*.log
+.classpath
+.project
+jcoverage.ser
+.merlin
diff --git a/maven.xml b/maven.xml
new file mode 100644
index 0000000..8c6e127
--- /dev/null
+++ b/maven.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project default="jar:jar" xmlns:maven="jelly:maven" xmlns:j="jelly:core" 
xmlns:util="jelly:util">
+
+  <!--preGoal name="java:compile">
+    <attainGoal name="avalon:meta"/>
+  </preGoal-->
+
+</project>
diff --git a/project.xml b/project.xml
new file mode 100644
index 0000000..bec02c5
--- /dev/null
+++ b/project.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project>
+  <extend>${basedir}/../project.xml</extend>
+  <id>fulcrum-pool</id>
+  <name>Fulcrum Pool Component</name>
+  <currentVersion>1.0.3</currentVersion>
+  <versions>
+    <version>
+      <id>1.0.3</id>
+      <name>1.0.3</name>
+      <tag>FULCRUM_POOL_1_0_3</tag>
+    </version>
+  </versions>
+  <dependencies>
+    <dependency>
+      <groupId>fulcrum</groupId>
+      <artifactId>fulcrum-factory</artifactId>
+      <version>1.0.3</version>
+    </dependency>
+
+    <!--  Needed only for testing -->
+    <dependency>
+      <groupId>fulcrum</groupId>
+      <artifactId>fulcrum-testcontainer</artifactId>
+      <version>1.0.5</version>
+    </dependency>
+
+    <dependency>
+      <groupId>fulcrum</groupId>
+      <artifactId>fulcrum-yaafi</artifactId>
+      <version>1.0.5</version>
+    </dependency>
+
+  </dependencies>
+
+</project>
+
diff --git a/src/java/org/apache/fulcrum/pool/ArrayCtorRecyclable.java 
b/src/java/org/apache/fulcrum/pool/ArrayCtorRecyclable.java
new file mode 100644
index 0000000..fd335c0
--- /dev/null
+++ b/src/java/org/apache/fulcrum/pool/ArrayCtorRecyclable.java
@@ -0,0 +1,40 @@
+package org.apache.fulcrum.pool;
+
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+/**
+ * An interface for objects that can be pooled and
+ * recycled several times by different clients.  This interface
+ * presents a recycle method that does not require introspection/reflection.
+ *
+ * @author <a href="mailto:[email protected]";>John McNally</a>
+ * @version $Id$
+ */
+public interface ArrayCtorRecyclable extends Recyclable
+{
+    /**
+     * Recycles the object for a new client. Objects implementing
+     * this interface must also provide a matching constructor.
+     * The recycle methods must call their super.
+     */
+    public void recycle(Object[] params);
+}
diff --git a/src/java/org/apache/fulcrum/pool/BoundedBuffer.java 
b/src/java/org/apache/fulcrum/pool/BoundedBuffer.java
new file mode 100644
index 0000000..40abd8d
--- /dev/null
+++ b/src/java/org/apache/fulcrum/pool/BoundedBuffer.java
@@ -0,0 +1,151 @@
+package org.apache.fulcrum.pool;
+
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+/**
+ * Efficient array-based bounded buffer class.
+ * Adapted from CPJ, chapter 8, which describes design.
+ * Originally written by Doug Lea and released into the public domain.
+ * <p>[<a 
href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html";>
 Introduction to this package. </a>] <p>
+ *
+ * @author <a href="mailto:[email protected]";>Ilkka Priha</a>
+ * @version $Id$
+ */
+public class BoundedBuffer
+{
+    /**
+     * The default capacity.
+     */
+    public static final int DEFAULT_CAPACITY = 1024;
+
+    protected final Object[]  array_;      // the elements
+
+    protected int takePtr_ = 0;            // circular indices
+    protected int putPtr_ = 0;
+
+    protected int usedSlots_ = 0;          // length
+    protected int emptySlots_;             // capacity - length
+
+    /**
+     * Creates a buffer with the given capacity.
+     *
+     * @param capacity the capacity.
+     * @throws IllegalArgumentException if capacity less or equal to zero.
+     */
+    public BoundedBuffer(int capacity)
+                         throws IllegalArgumentException
+    {
+        if (capacity <= 0)
+           throw new IllegalArgumentException();
+
+        array_ = new Object[capacity];
+        emptySlots_ = capacity;
+    }
+
+    /**
+     * Creates a buffer with the default capacity
+     */
+    public BoundedBuffer()
+    {
+        this(DEFAULT_CAPACITY);
+    }
+
+    /**
+     * Returns the number of elements in the buffer.
+     * This is only a snapshot value, that may change
+     * immediately after returning.
+     *
+     * @return the size.
+     */
+    public synchronized int size()
+    {
+        return usedSlots_;
+    }
+
+    /**
+     * Returns the capacity of the buffer.
+     *
+     * @return the capacity.
+     */
+    public int capacity()
+    {
+        return array_.length;
+    }
+
+    /**
+     * Peeks, but does not remove the top item from the buffer.
+     *
+     * @return the object or null.
+     */
+    public synchronized Object peek()
+    {
+        if (usedSlots_ > 0)
+            return array_[takePtr_];
+        else
+            return null;
+    }
+
+    /**
+     * Puts an item in the buffer only if there is capacity available.
+     *
+     * @param item the item to be inserted.
+     * @return true if accepted, else false.
+     */
+    public synchronized boolean offer(Object x)
+    {
+        if (x == null)
+            throw new IllegalArgumentException();
+
+        if (emptySlots_ > 0)
+        {
+            --emptySlots_;
+            array_[putPtr_] = x;
+            if (++putPtr_ >= array_.length)
+                putPtr_ = 0;
+            usedSlots_++;
+            return true;
+        }
+        else
+            return false;
+    }
+
+    /**
+     * Polls and removes the top item from the buffer if one is available.
+     *
+     * @return the oldest item from the buffer, or null if the buffer is empty.
+     */
+    public synchronized Object poll()
+    {
+        if (usedSlots_ > 0)
+        {
+            --usedSlots_;
+            Object old = array_[takePtr_];
+            array_[takePtr_] = null;
+            if (++takePtr_ >= array_.length)
+                takePtr_ = 0;
+            emptySlots_++;
+            return old;
+        }
+        else
+            return null;
+    }
+}
diff --git a/src/java/org/apache/fulcrum/pool/DefaultPoolService.java 
b/src/java/org/apache/fulcrum/pool/DefaultPoolService.java
new file mode 100644
index 0000000..421ffda
--- /dev/null
+++ b/src/java/org/apache/fulcrum/pool/DefaultPoolService.java
@@ -0,0 +1,653 @@
+package org.apache.fulcrum.pool;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.fulcrum.factory.FactoryException;
+import org.apache.fulcrum.factory.FactoryService;
+
+/**
+ * The Pool Service extends the Factory Service by adding support
+ * for pooling instantiated objects. When a new instance is
+ * requested, the service first checks its pool if one is available.
+ * If the the pool is empty, a new instance will be requested
+ * from the FactoryService.
+ *
+ * For objects implementing the Recyclable interface, a recycle
+ * method will be called, when they taken from the pool, and
+ * a dispose method, when they are returned to the pool.
+ *
+ * @author <a href="mailto:[email protected]";>Ilkka Priha</a>
+ * @author <a href="mailto:[email protected]";>Stephen McConnell</a>
+ * @version $Id$
+ *
+ * @avalon.component name="pool" lifestyle="transient"
+ * @avalon.service type="org.apache.fulcrum.pool.PoolService"
+ */
+public class DefaultPoolService extends AbstractLogEnabled implements 
PoolService, Serviceable, Disposable, Initializable, Configurable
+{
+    /**
+     * The property specifying the pool capacity.
+     */
+    public static final String POOL_CAPACITY = "capacity";
+    /**
+     * An inner class for class specific pools.
+     */
+    private class PoolBuffer
+    {
+        /**
+         * An inner class for cached recycle methods.
+         */
+        private class Recycler
+        {
+            /**
+             * The method.
+             */
+            private final Method recycle;
+            /**
+             * The signature.
+             */
+            private final String[] signature;
+            /**
+             * Constructs a new recycler.
+             *
+             * @param rec the recycle method.
+             * @param sign the signature.
+             */
+            public Recycler(Method rec, String[] sign)
+            {
+                recycle = rec;
+                signature = (sign != null) && (sign.length > 0) ? sign : null;
+            }
+            /**
+             * Matches the given signature against
+             * that of the recycle method of this recycler.
+             *
+             * @param sign the signature.
+             * @return the matching recycle method or null.
+             */
+            public Method match(String[] sign)
+            {
+                if ((sign != null) && (sign.length > 0))
+                {
+                    if ((signature != null) && (sign.length == 
signature.length))
+                    {
+                        for (int i = 0; i < signature.length; i++)
+                        {
+                            if (!signature[i].equals(sign[i]))
+                            {
+                                return null;
+                            }
+                        }
+                        return recycle;
+                    }
+                    else
+                    {
+                        return null;
+                    }
+                }
+                else if (signature == null)
+                {
+                    return recycle;
+                }
+                else
+                {
+                    return null;
+                }
+            }
+        }
+        /**
+         * A buffer for class instances.
+         */
+        private BoundedBuffer pool;
+        /**
+         * A flag to determine if a more efficient recycler is implemented.
+         */
+        private boolean arrayCtorRecyclable;
+        /**
+         * A cache for recycling methods.
+         */
+        private ArrayList recyclers;
+        /**
+         * Contructs a new pool buffer with a specific capacity.
+         *
+         * @param capacity a capacity.
+         */
+        public PoolBuffer(int capacity)
+        {
+            pool = new BoundedBuffer(capacity);
+        }
+        /**
+         * Tells pool that it contains objects which can be
+         * initialized using an Object array.
+         *
+         * @param isArrayCtor a <code>boolean</code> value
+         */
+        public void setArrayCtorRecyclable(boolean isArrayCtor)
+        {
+            arrayCtorRecyclable = isArrayCtor;
+        }
+        /**
+         * Polls for an instance from the pool.
+         *
+         * @return an instance or null.
+         */
+        public Object poll(Object[] params, String[] signature) throws 
PoolException
+        {
+            Object instance = pool.poll();
+            if (instance != null)
+            {
+                if (arrayCtorRecyclable)
+                {
+                    ((ArrayCtorRecyclable) instance).recycle(params);
+                }
+                else if (instance instanceof Recyclable)
+                {
+                    try
+                    {
+                        if ((signature != null) && (signature.length > 0))
+                        {
+                            /* Get the recycle method from the cache. */
+                            Method recycle = getRecycle(signature);
+                            if (recycle == null)
+                            {
+                                synchronized (this)
+                                {
+                                    /* Make a synchronized recheck. */
+                                    recycle = getRecycle(signature);
+                                    if (recycle == null)
+                                    {
+                                        Class clazz = instance.getClass();
+                                        recycle =
+                                            clazz.getMethod(
+                                                "recycle",
+                                                
getFactory().getSignature(clazz, params, signature));
+                                        ArrayList cache =
+                                            recyclers != null ? (ArrayList) 
recyclers.clone() : new ArrayList();
+                                        cache.add(new Recycler(recycle, 
signature));
+                                        recyclers = cache;
+                                    }
+                                }
+                            }
+                            recycle.invoke(instance, params);
+                        }
+                        else
+                        {
+                            ((Recyclable) instance).recycle();
+                        }
+                    }
+                    catch (Exception x)
+                    {
+                        throw new PoolException("Recycling failed for " + 
instance.getClass().getName(), x);
+                    }
+                }
+            }
+            return instance;
+        }
+        /**
+         * Offers an instance to the pool.
+         *
+         * @param instance an instance.
+         */
+        public boolean offer(Object instance)
+        {
+            if (instance instanceof Recyclable)
+            {
+                try
+                {
+                    ((Recyclable) instance).dispose();
+                }
+                catch (Exception x)
+                {
+                    return false;
+                }
+            }
+            return pool.offer(instance);
+        }
+        /**
+         * Returns the capacity of the pool.
+         *
+         * @return the capacity.
+         */
+        public int capacity()
+        {
+            return pool.capacity();
+        }
+        /**
+         * Returns the size of the pool.
+         *
+         * @return the size.
+         */
+        public int size()
+        {
+            return pool.size();
+        }
+        /**
+         * Returns a cached recycle method
+         * corresponding to the given signature.
+         *
+         * @param signature the signature.
+         * @return the recycle method or null.
+         */
+        private Method getRecycle(String[] signature)
+        {
+            ArrayList cache = recyclers;
+            if (cache != null)
+            {
+                Method recycle;
+                for (Iterator i = cache.iterator(); i.hasNext();)
+                {
+                    recycle = ((Recycler) i.next()).match(signature);
+                    if (recycle != null)
+                    {
+                        return recycle;
+                    }
+                }
+            }
+            return null;
+        }
+    }
+    /**
+     * The default capacity of pools.
+     */
+    private int poolCapacity = DEFAULT_POOL_CAPACITY;
+    /**
+     * The pool repository, one pool for each class.
+     */
+    private HashMap poolRepository = new HashMap();
+    private Map capacityMap;
+    private FactoryService factoryService;
+    private ServiceManager manager;
+    /**
+     * Constructs a Pool Service.
+     */
+    public DefaultPoolService()
+    {
+    }
+    /**
+     * Gets an instance of a named class either from the pool
+     * or by calling the Factory Service if the pool is empty.
+     *
+     * @param className the name of the class.
+     * @return the instance.
+     * @throws PoolException if recycling fails.
+     */
+    public Object getInstance(String className) throws PoolException
+    {
+        try
+        {
+            Object instance = pollInstance(className, null, null);
+            return instance == null ? getFactory().getInstance(className) : 
instance;
+        }
+        catch (FactoryException fe)
+        {
+            throw new PoolException(fe);
+        }
+    }
+    /**
+     * Gets an instance of a named class either from the pool
+     * or by calling the Factory Service if the pool is empty.
+     * The specified class loader will be passed to the Factory Service.
+     *
+     * @param className the name of the class.
+     * @param loader the class loader.
+     * @return the instance.
+     * @throws PoolException if recycling fails.
+     */
+    public Object getInstance(String className, ClassLoader loader) throws 
PoolException
+    {
+        try
+        {
+            Object instance = pollInstance(className, null, null);
+            return instance == null ? getFactory().getInstance(className, 
loader) : instance;
+        }
+        catch (FactoryException fe)
+        {
+            throw new PoolException(fe);
+        }
+    }
+    /**
+     * Gets an instance of a named class either from the pool
+     * or by calling the Factory Service if the pool is empty.
+     * Parameters for its constructor are given as an array of objects,
+     * primitive types must be wrapped with a corresponding class.
+     *
+     * @param className the name of the class.
+     * @param loader the class loader.
+     * @param params an array containing the parameters of the constructor.
+     * @param signature an array containing the signature of the constructor.
+     * @return the instance.
+     * @throws PoolException if recycling fails.
+     */
+    public Object getInstance(String className, Object[] params, String[] 
signature) throws PoolException
+    {
+        try
+        {
+            Object instance = pollInstance(className, params, signature);
+            return instance == null ? getFactory().getInstance(className, 
params, signature) : instance;
+        }
+        catch (FactoryException fe)
+        {
+            throw new PoolException(fe);
+        }
+    }
+    /**
+     * Gets an instance of a named class either from the pool
+     * or by calling the Factory Service if the pool is empty.
+     * Parameters for its constructor are given as an array of objects,
+     * primitive types must be wrapped with a corresponding class.
+     * The specified class loader will be passed to the Factory Service.
+     *
+     * @param className the name of the class.
+     * @param loader the class loader.
+     * @param params an array containing the parameters of the constructor.
+     * @param signature an array containing the signature of the constructor.
+     * @return the instance.
+     * @throws PoolException if recycling fails.
+     */
+    public Object getInstance(String className, ClassLoader loader, Object[] 
params, String[] signature)
+        throws PoolException
+    {
+        try
+        {
+            Object instance = pollInstance(className, params, signature);
+            return instance == null ? getFactory().getInstance(className, 
loader, params, signature) : instance;
+        }
+        catch (FactoryException fe)
+        {
+            throw new PoolException(fe);
+        }
+    }
+    /**
+     * Tests if specified class loaders are supported for a named class.
+     *
+     * @param className the name of the class.
+     * @return true if class loaders are supported, false otherwise.
+     * @throws PoolException if test fails.
+     */
+    public boolean isLoaderSupported(String className) throws FactoryException
+    {
+        return getFactory().isLoaderSupported(className);
+    }
+    /**
+     * Gets an instance of a specified class either from the pool
+     * or by instatiating from the class if the pool is empty.
+     *
+     * @param clazz the class.
+     * @return the instance.
+     * @throws PoolException if recycling fails.
+     */
+    public Object getInstance(Class clazz) throws PoolException
+    {
+        try
+        {
+            Object instance = pollInstance(clazz.getName(), null, null);
+            return instance == null ? factoryService.getInstance(clazz) : 
instance;
+        }
+        catch (FactoryException fe)
+        {
+            throw new PoolException(fe);
+        }
+    }
+    /**
+     * Gets an instance of a specified class either from the pool
+     * or by instatiating from the class if the pool is empty.
+     *
+     * @todo There is a whacky .toString() on the clazzz, but otherwise it
+     * won't compile..
+     * @param clazz the class.
+     * @param params an array containing the parameters of the constructor.
+     * @param signature an array containing the signature of the constructor.
+     * @return the instance.
+     * @throws PoolException if recycling fails.
+     */
+    public Object getInstance(Class clazz, Object params[], String 
signature[]) throws PoolException
+    {
+        try
+        {
+            Object instance = pollInstance(clazz.getName(), params, signature);
+            //FactoryService fs = getFactory();
+            return instance == null ? 
getFactory().getInstance(clazz.toString(), params, signature) : instance;
+        }
+        catch (FactoryException fe)
+        {
+            throw new PoolException(fe);
+        }
+    }
+    /**
+     * Puts a used object back to the pool. Objects implementing
+     * the Recyclable interface can provide a recycle method to
+     * be called when they are reused and a dispose method to be
+     * called when they are returned to the pool.
+     *
+     * @param instance the object instance to recycle.
+     * @return true if the instance was accepted.
+     */
+    public boolean putInstance(Object instance)
+    {
+        if (instance != null)
+        {
+            HashMap repository = poolRepository;
+            String className = instance.getClass().getName();
+            PoolBuffer pool = (PoolBuffer) repository.get(className);
+            if (pool == null)
+            {
+                pool = new PoolBuffer(getCapacity(className));
+                repository = (HashMap) repository.clone();
+                repository.put(className, pool);
+                poolRepository = repository;
+                if (instance instanceof ArrayCtorRecyclable)
+                {
+                    pool.setArrayCtorRecyclable(true);
+                }
+            }
+            return pool.offer(instance);
+        }
+        else
+        {
+            return false;
+        }
+    }
+    /**
+     * Gets the capacity of the pool for a named class.
+     *
+     * @param className the name of the class.
+     */
+    public int getCapacity(String className)
+    {
+        PoolBuffer pool = (PoolBuffer) poolRepository.get(className);
+        if (pool == null)
+        {
+            /* Check class specific capacity. */
+            int capacity = poolCapacity;
+            if (capacityMap != null)
+            {
+                Integer cap = (Integer) capacityMap.get(className);
+                if (cap != null)
+                {
+                    capacity = cap.intValue();
+                }
+            }
+            return capacity;
+        }
+        else
+        {
+            return pool.capacity();
+        }
+    }
+    /**
+     * Sets the capacity of the pool for a named class.
+     * Note that the pool will be cleared after the change.
+     *
+     * @param className the name of the class.
+     * @param capacity the new capacity.
+     */
+    public void setCapacity(String className, int capacity)
+    {
+        HashMap repository = poolRepository;
+        repository = repository != null ? (HashMap) repository.clone() : new 
HashMap();
+        repository.put(className, new PoolBuffer(capacity));
+        poolRepository = repository;
+    }
+    /**
+     * Gets the current size of the pool for a named class.
+     *
+     * @param className the name of the class.
+     */
+    public int getSize(String className)
+    {
+        PoolBuffer pool = (PoolBuffer) poolRepository.get(className);
+        return pool != null ? pool.size() : 0;
+    }
+    /**
+     * Clears instances of a named class from the pool.
+     *
+     * @param className the name of the class.
+     */
+    public void clearPool(String className)
+    {
+        HashMap repository = poolRepository;
+        if (repository.get(className) != null)
+        {
+            repository = (HashMap) repository.clone();
+            repository.remove(className);
+            poolRepository = repository;
+        }
+    }
+    /**
+     * Clears all instances from the pool.
+     */
+    public void clearPool()
+    {
+        poolRepository = new HashMap();
+    }
+    /**
+     * Polls and recycles an object of the named class from the pool.
+     *
+     * @param className the name of the class.
+     * @param params an array containing the parameters of the constructor.
+     * @param signature an array containing the signature of the constructor.
+     * @return the object or null.
+     * @throws PoolException if recycling fails.
+     */
+    private Object pollInstance(String className, Object[] params, String[] 
signature) throws PoolException
+    {
+        PoolBuffer pool = (PoolBuffer) poolRepository.get(className);
+        return pool != null ? pool.poll(params, signature) : null;
+    }
+    /**
+     * Gets the factory service.
+     *
+     * @return the factory service.
+     */
+    private FactoryService getFactory()
+    {
+        return factoryService;
+    }
+    // ---------------- Avalon Lifecycle Methods ---------------------
+    /**
+     * Avalon component lifecycle method
+     */
+    public void configure(Configuration conf)
+    {
+        final Configuration capacities = conf.getChild(POOL_CAPACITY, false);
+        if (capacities != null)
+        {
+            Configuration defaultConf = capacities.getChild("default");
+            int capacity = 
defaultConf.getValueAsInteger(DEFAULT_POOL_CAPACITY);
+            if (capacity <= 0)
+            {
+                throw new IllegalArgumentException("Capacity must be >0");
+            }
+            poolCapacity = capacity;
+            Configuration[] nameVal = capacities.getChildren();
+            for (int i = 0; i < nameVal.length; i++)
+            {
+                String key = nameVal[i].getName();
+                if (!"default".equals(key))
+                {
+                    capacity = nameVal[i].getValueAsInteger(poolCapacity);
+                    if (capacity < 0)
+                    {
+                        capacity = poolCapacity;
+                    }
+                    if (capacityMap == null)
+                    {
+                        capacityMap = new HashMap();
+                    }
+                    capacityMap.put(key, new Integer(capacity));
+                }
+            }
+        }
+    }
+
+    /**
+     * Avalon component lifecycle method
+     * @avalon.dependency type="org.apache.fulcrum.factory.FactoryService"
+     */
+    public void service(ServiceManager manager)
+    {
+        this.manager = manager;
+    }
+
+    /**
+     * Avalon component lifecycle method
+     * Initializes the service by loading default class loaders
+     * and customized object factories.
+     *
+     * @throws InitializationException if initialization fails.
+     */
+    public void initialize() throws Exception
+    {
+        try
+        {
+            factoryService = (FactoryService) 
manager.lookup(FactoryService.ROLE);
+        }
+        catch (Exception e)
+        {
+            throw new Exception(
+               "DefaultPoolService.initialize: Failed to get a Factory 
object", e);
+        }
+    }
+
+    /**
+     * Avalon component lifecycle method
+     */
+    public void dispose()
+    {
+        if (factoryService != null)
+        {
+            manager.release(factoryService);
+        }
+        factoryService = null;
+        manager = null;
+    }
+}
diff --git a/src/java/org/apache/fulcrum/pool/InitableRecyclable.java 
b/src/java/org/apache/fulcrum/pool/InitableRecyclable.java
new file mode 100644
index 0000000..f6683a6
--- /dev/null
+++ b/src/java/org/apache/fulcrum/pool/InitableRecyclable.java
@@ -0,0 +1,44 @@
+package org.apache.fulcrum.pool;
+
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+
+
+
+/**
+ * An interface for objects that can be pooled and recycled several times
+ * by different clients.  Pooled objects that implement this interface
+ * use no argument ctor and recycle methods.  Initialization is taken
+ * care of using the init method.  This is a way to avoid
+ * introspection/reflection when pooling an object.
+ *
+ * @author <a href="mailto:[email protected]";>John McNally</a>
+ * @version $Id$
+ */
+public interface InitableRecyclable extends Recyclable
+{
+    /**
+     * This method should be called after retrieving the object from
+     * the pool.
+     */
+    public void init(Object initObj) throws PoolException;
+}
diff --git a/src/java/org/apache/fulcrum/pool/ObjectInputStreamForContext.java 
b/src/java/org/apache/fulcrum/pool/ObjectInputStreamForContext.java
new file mode 100644
index 0000000..9683ffe
--- /dev/null
+++ b/src/java/org/apache/fulcrum/pool/ObjectInputStreamForContext.java
@@ -0,0 +1,70 @@
+package org.apache.fulcrum.pool;
+
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.io.IOException;
+
+/**
+ * A deserialization stream for a specific class loader context.
+ *
+ * @author <a href="mailto:[email protected]";>Ilkka Priha</a>
+ * @version $Id$
+ */
+public class ObjectInputStreamForContext extends ObjectInputStream
+{
+    /**
+     * The class loader of the context.
+     */
+    private ClassLoader classLoader;
+
+    // this is to make the proxy happy.
+    public ObjectInputStreamForContext()
+        throws IOException
+    {
+    }
+
+    /**
+     * Contructs a new object stream for a context.
+     *
+     * @param in the serialized input stream.
+     * @param loader the class loader of the context.
+     * @throws IOException on errors.
+     */
+    public  ObjectInputStreamForContext(InputStream in,
+                                        ClassLoader loader)
+                                        throws IOException
+    {
+        super(in);
+        classLoader = loader;
+    }
+
+    protected Class resolveClass(ObjectStreamClass v)
+                                 throws IOException,
+                                 ClassNotFoundException
+    {
+        return classLoader == null ?
+            super.resolveClass(v) : classLoader.loadClass(v.getName());
+    }
+}
diff --git a/src/java/org/apache/fulcrum/pool/PoolException.java 
b/src/java/org/apache/fulcrum/pool/PoolException.java
new file mode 100644
index 0000000..7dd5d60
--- /dev/null
+++ b/src/java/org/apache/fulcrum/pool/PoolException.java
@@ -0,0 +1,47 @@
+package org.apache.fulcrum.pool;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Exception thrown when there is a problem with the PoolException
+ *
+ * @author <a href="mailto:[email protected]";>Eric Pugh</a>
+ * @version $Id$
+ */
+public class PoolException extends Exception
+{
+    /**
+     * Serial number
+     */
+    private static final long serialVersionUID = 8192045560423973532L;
+
+    public PoolException(String msg)
+    {
+        super(msg);
+    }
+       public PoolException(Exception ex)
+         {
+                 super(ex);
+         }
+    public PoolException(String msg, Exception ex)
+    {
+        super(msg, ex);
+    }
+}
diff --git a/src/java/org/apache/fulcrum/pool/PoolService.java 
b/src/java/org/apache/fulcrum/pool/PoolService.java
new file mode 100644
index 0000000..2c0d654
--- /dev/null
+++ b/src/java/org/apache/fulcrum/pool/PoolService.java
@@ -0,0 +1,125 @@
+package org.apache.fulcrum.pool;
+
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+
+/**
+ * The Pool Service extends the Factory Service by adding support
+ * for pooling instantiated objects. When a new instance is
+ * requested, the service first checks its pool if one is available.
+ * If the the pool is empty, a new object will be instantiated
+ * from the specified class. If only class name is given, the request
+ * to create an instance will be forwarded to the Factory Service.
+ *
+ * <p>For objects implementing the Recyclable interface, a recycle
+ * method will be called, when they are taken from the pool, and
+ * a dispose method, when they are returned to the pool.
+ *
+ * @author <a href="mailto:[email protected]";>Ilkka Priha</a>
+ * @author <a href="mailto:[email protected]";>Stephen McConnell</a>
+ * @version $Id$
+ */
+public interface PoolService
+{
+    /** Avalon role - used to id the component within the manager */
+    String ROLE = PoolService.class.getName();
+
+
+    /**
+     * The default pool capacity.
+     */
+    public static final int DEFAULT_POOL_CAPACITY = 128;
+
+    /**
+     * Gets an instance of a specified class either from the pool
+     * or by instantiating from the class if the pool is empty.
+     *
+     * @param clazz the class.
+     * @return the instance.
+     * @throws PoolException if recycling fails.
+     */
+    public Object getInstance(Class clazz)
+        throws PoolException;
+
+    /**
+     * Gets an instance of a specified class either from the pool
+     * or by instantiating from the class if the pool is empty.
+     *
+     * @param clazz the class.
+     * @param params an array containing the parameters of the constructor.
+     * @param signature an array containing the signature of the constructor.
+     * @return the instance.
+     * @throws PoolException if recycling fails.
+     */
+    public Object getInstance(Class clazz,
+                              Object params[],
+                              String signature[])
+        throws PoolException;
+
+    /**
+     * Puts a used object back to the pool. Objects implementing
+     * the Recyclable interface can provide a recycle method to
+     * be called when they are reused and a dispose method to be
+     * called when they are returned to the pool.
+     *
+     * @param instance the object instance to recycle.
+     * @return true if the instance was accepted.
+     */
+    public boolean putInstance(Object instance);
+
+    /**
+     * Gets the capacity of the pool for a named class.
+     *
+     * @param className the name of the class.
+     */
+    public int getCapacity(String className);
+
+    /**
+     * Sets the capacity of the pool for a named class.
+     * Note that the pool will be cleared after the change.
+     *
+     * @param className the name of the class.
+     * @param capacity the new capacity.
+     */
+    public void setCapacity(String className,
+                            int capacity);
+
+    /**
+     * Gets the current size of the pool for a named class.
+     *
+     * @param className the name of the class.
+     */
+    public int getSize(String className);
+
+    /**
+     * Clears instances of a named class from the pool.
+     *
+     * @param className the name of the class.
+     */
+    public void clearPool(String className);
+
+    /**
+     * Clears all instances from the pool.
+     */
+    void clearPool();
+
+}
diff --git a/src/java/org/apache/fulcrum/pool/Recyclable.java 
b/src/java/org/apache/fulcrum/pool/Recyclable.java
new file mode 100644
index 0000000..762535a
--- /dev/null
+++ b/src/java/org/apache/fulcrum/pool/Recyclable.java
@@ -0,0 +1,57 @@
+package org.apache.fulcrum.pool;
+
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+/**
+ * An interface for objects that can be pooled and
+ * recycled several times by different clients.
+ *
+ * @author <a href="mailto:[email protected]";>Ilkka Priha</a>
+ * @version $Id$
+ */
+public interface Recyclable
+{
+    /**
+     * Recycles the object for a new client. Recycle methods with
+     * parameters must be added to implementing object and they will be
+     * automatically called by pool implementations when the object is
+     * taken from the pool for a new client. The parameters must
+     * correspond to the parameters of the constructors of the object.
+     * For new objects, constructors can call their corresponding recycle
+     * methods whenever applicable.
+     * The recycle methods must call their super.
+     */
+    public void recycle();
+
+    /**
+     * Disposes the object after use. The method is called
+     * when the object is returned to its pool.
+     * The dispose method must call its super.
+     */
+    public void dispose();
+
+    /**
+     * Checks whether the recyclable has been disposed.
+     * @return true, if the recyclable is disposed.
+     */
+    public boolean isDisposed();
+}
diff --git a/src/test/TestComponentConfig.xml b/src/test/TestComponentConfig.xml
new file mode 100644
index 0000000..dcb4cdd
--- /dev/null
+++ b/src/test/TestComponentConfig.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<componentConfig>
+    <pool>
+          <configuration>
+       <capacity default="256"/>
+     </configuration>
+    </pool>
+    <factory/>
+</componentConfig>
diff --git a/src/test/TestRoleConfig.xml b/src/test/TestRoleConfig.xml
new file mode 100644
index 0000000..20b744e
--- /dev/null
+++ b/src/test/TestRoleConfig.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<!-- This configuration file for Avalon components is used for testing the 
TestComponent -->
+<role-list>
+    <role
+        name="org.apache.fulcrum.factory.FactoryService"
+        shorthand="factory"
+        default-class="org.apache.fulcrum.factory.DefaultFactoryService"
+    />
+    <role
+        name="org.apache.fulcrum.pool.PoolService"
+        shorthand="pool"
+        default-class="org.apache.fulcrum.pool.DefaultPoolService"
+    />
+</role-list>
diff --git a/src/test/org/apache/fulcrum/pool/PoolServiceTest.java 
b/src/test/org/apache/fulcrum/pool/PoolServiceTest.java
new file mode 100644
index 0000000..b8c5d73
--- /dev/null
+++ b/src/test/org/apache/fulcrum/pool/PoolServiceTest.java
@@ -0,0 +1,112 @@
+package org.apache.fulcrum.pool;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.fulcrum.testcontainer.BaseUnitTest;
+
+/**
+ * @author Eric Pugh
+ * @author <a href="mailto:[email protected]";>Stephen McConnell</a>
+ *
+ * To change the template for this generated type comment go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+public class PoolServiceTest extends BaseUnitTest
+{
+    private PoolService poolService = null;
+    /**
+       * Defines the testcase name for JUnit.
+       *
+       * @param name the testcase's name.
+       */
+    public PoolServiceTest(String name)
+    {
+        super(name);
+    }
+
+    public void setUp() throws Exception
+    {
+        super.setUp();
+
+        poolService = (PoolService) this.resolve( PoolService.class.getName() 
);
+    }
+
+    /*
+     * Class to test for Object getInstance(Class)
+     */
+    public void testGetInstanceClass() throws PoolException
+    {
+        Object object = poolService.getInstance(StringBuffer.class);
+        assertTrue(object instanceof StringBuffer);
+
+    }
+
+    public void testPutInstance()
+    {
+        String s = "I am a string";
+        assertEquals(0, poolService.getSize("java.lang.String"));
+        poolService.putInstance(s);
+        assertEquals(1, poolService.getSize("java.lang.String"));
+
+    }
+    public void testGetSetCapacity()
+    {
+        assertEquals(128, poolService.getCapacity("java.lang.String"));
+        poolService.setCapacity("java.lang.String", 278);
+        assertEquals(278, poolService.getCapacity("java.lang.String"));
+
+    }
+    public void testGetSize()
+    {
+        String s = "I am a string";
+        assertEquals(0, poolService.getSize("java.lang.String"));
+        poolService.putInstance(s);
+        assertEquals(1, poolService.getSize("java.lang.String"));
+
+    }
+    /*
+     * Class to test for void clearPool(String)
+     */
+    public void testClearPoolString()
+    {
+        String s = "I am a string";
+        assertEquals(0, poolService.getSize("java.lang.String"));
+        poolService.putInstance(s);
+        assertEquals(1, poolService.getSize("java.lang.String"));
+        poolService.clearPool("java.lang.String");
+        assertEquals(0, poolService.getSize("java.lang.String"));
+
+    }
+    /*
+     * Class to test for void clearPool()
+     */
+    public void testClearPool()
+    {
+        String s = "I am a string";
+        assertEquals(0, poolService.getSize("java.lang.String"));
+        poolService.putInstance(s);
+        poolService.putInstance(new Double(32));
+        assertEquals(1, poolService.getSize("java.lang.String"));
+        poolService.clearPool();
+        assertEquals(0, poolService.getSize("java.lang.String"));
+        assertEquals(0, poolService.getSize("java.lang.Double"));
+
+    }
+}
diff --git a/xdocs/changes.xml b/xdocs/changes.xml
new file mode 100644
index 0000000..cfae165
--- /dev/null
+++ b/xdocs/changes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<document>
+  <properties>
+    <title>Fulcrum Pool Impl</title>
+    <author email="[email protected]">Eric Pugh</author>
+  </properties>
+
+  <body>
+    <release version="1.0.3" date="2004-11-24">
+      <action dev="epugh" type="update" due-to="Kostyantyn Shchekotykhin">
+        Merge api and impl jars into one project.
+      </action>
+      <action dev="epugh" type="update">
+        Clean up dependencies.  Use TestContainer.
+      </action>
+      <action dev="epugh" type="update">
+        Bump versions, clean up dependencies
+      </action>
+    </release>
+    <release version="1.0.2" date="in cvs">
+      <action dev="epugh" type="update">
+        Update to use Merlin 3.3.0
+      </action>
+    </release>
+  </body>
+</document>
+
diff --git a/xdocs/index.xml b/xdocs/index.xml
new file mode 100644
index 0000000..f50c7f1
--- /dev/null
+++ b/xdocs/index.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+  <properties>
+    <title>Pool Component</title>
+    <author email="[email protected]">Eric PUgh</author>
+  </properties>
+
+  <body>
+
+  <section name="Overview">
+
+<p>
+The Pool Service extends the functionality of the Factory Service by adding
+support for pooling objects intantiated from the given class name or
+Class object reference. Pooling of objects stabilizes memory consumption and
+reduces garbage collection making response times in server applications
+more predictable.
+</p>
+
+<p>
+When a new instance is requested from the service, it first checks its pool
+if one is available. If the the pool is empty, a new object will be 
instantiated
+from the given class. If the class is specified by its name, the request to 
create
+an instance will be forwarded to the Factory Service.
+</p>
+
+<p>
+For pooled objects implementing the Recyclable interface, a recycle method
+will be called, when they are taken from the pool, and a dispose method,
+when they are returned to the pool. Implementations of the methods should
+clear and initialize the pooled instances correspondingly. Objects
+that do not implement the interface can also be pooled, if they do not
+need to perform any specific actions during pooling. A RecyclableSupport class
+can be extended to get a minimal implementation of the interface.
+</p>
+
+<p>
+An ArrayCtorRecyclable interface extends the Recyclable interface providing
+a more efficient recycle method with less reflection for recycling frequently
+used objects having constuctors with parameters.
+</p>
+  </section>
+
+<section name="Configuration">
+
+    <p>
+      First, here is the role configuration.  This component requires the 
FactoryService
+      component.
+    </p>
+
+<source>
+<![CDATA[
+    <role
+        name="org.apache.fulcrum.pool.PoolService"
+        shorthand="pool"
+        default-class="org.apache.fulcrum.pool.DefaultPoolService"/>
+
+
+    <role
+        name="org.apache.fulcrum.factory.FactoryService"
+        shorthand="factory"
+        default-class="org.apache.fulcrum.factory.DefaultFactoryService"/>
+]]>
+</source>
+
+  <p>
+    Now comes the basic configuration of the component.  Here will will
+    configure the various bundles.
+  </p>
+<source>
+
+<![CDATA[
+    <pool>
+      <capacity default="256"/>
+    </pool>
+
+    <factory/>
+]]>
+</source>
+
+  </section>
+
+  <section name="Usage">
+
+<p>
+The Pool Service can be called instead of the Factory Service, when 
instantiating
+objects that are needed repeatedly e.g. for processing client requests. 
Intances
+of RunData implementations, ParameterParser and CookieParser implementations,
+Pull Service tools, etc, are typical examples of pooled objects. Used objects
+must be returned to the Pool Service for recycling. The TurbinePool class is a
+static accessor for common methods of the Pool Service:
+</p>
+
+<source><![CDATA[
+// Get a pooled DOM parser.
+DocumentBuilder parser =
+    TurbinePool.getInstance("javax.xml.parsers.DocumentBuilder");
+
+// Parse an XML document.
+Document doc = parser.parse(myfile);
+
+// Return the parser to the pool.
+TurbinePool.putInstance(parser);
+]]></source>
+
+  </section>
+
+</body>
+</document>
diff --git a/xdocs/navigation.xml b/xdocs/navigation.xml
new file mode 100644
index 0000000..6e7be15
--- /dev/null
+++ b/xdocs/navigation.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<!DOCTYPE project [
+<!ENTITY site-nav SYSTEM "../../incl_site_nav.xml">
+]>
+
+<project
+  name="Fulcrum Pool"
+  href="http://turbine.apache.org/fulcrum/fulcrum-pool/";>
+
+  <body>
+
+&site-nav;
+
+    <menu name="Overview">
+      <item name="Main"                 href="/index.html"/>
+    </menu>
+  </body>
+</project>

Reply via email to