| /* |
| * 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. |
| */ |
| |
| package org.apache.uima.internal.util; |
| |
| import java.util.Date; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| import org.apache.uima.UIMAFramework; |
| import org.apache.uima.resource.Resource; |
| import org.apache.uima.resource.ResourceInitializationException; |
| import org.apache.uima.resource.ResourceSpecifier; |
| import org.apache.uima.resource.Resource_ImplBase; |
| import org.apache.uima.resource.metadata.ResourceMetaData; |
| import org.apache.uima.util.Level; |
| |
| /** |
| * This class represents a simple pool of {@link Resource} instances. |
| * <p> |
| * Clients check-out Resources from the pool using the {@link #getResource()} method and check-in |
| * Resources using the {@link #releaseResource(Resource)} method. |
| * <p> |
| * This resource pool implementation does not deal with differently configured resources in the same |
| * pool. All resources are assumed to be equivalent and to share the same metadata. Therefore, the |
| * resource metadata can be retrieved via the {@link #getMetaDAta()} method without checking out a |
| * Resource instance from the pool. |
| * |
| * |
| * |
| */ |
| public class ResourcePool { |
| |
| /** |
| * resource bundle for log messages |
| */ |
| private static final String LOG_RESOURCE_BUNDLE = "org.apache.uima.impl.log_messages"; |
| |
| /** |
| * current class |
| */ |
| private static final Class CLASS_NAME = ResourcePool.class; |
| |
| /** |
| * Creates new ResourcePool_impl |
| * |
| * @param aNumInstances |
| * the number of Resource instances in the pool |
| * @param aResourceSpecifier |
| * specifier that describes how to create the Resource instances for the pool |
| * @param aResourceClass |
| * class of resource to instantiate |
| * |
| * @throws ResourceInitializationException |
| * if the Resource instances could not be created |
| */ |
| public ResourcePool(int aNumInstances, ResourceSpecifier aResourceSpecifier, Class aResourceClass) |
| throws ResourceInitializationException { |
| this(aNumInstances, aResourceSpecifier, aResourceClass, null); |
| } |
| |
| /** |
| * Creates new ResourcePool_impl |
| * |
| * @param aNumInstances |
| * the number of Resource instances in the pool |
| * @param aResourceSpecifier |
| * specifier that describes how to create the Resource instances for the pool |
| * @param aResourceClass |
| * class of resource to instantiate |
| * @param aResourceInitParams |
| * additional parameters to be passed to |
| * {@link Resource#initialize(ResourceSpecifier,Map)} methods. May be null if there are |
| * no parameters. |
| * |
| * @throws ResourceInitializationException |
| * if the Resource instances could not be created |
| */ |
| public ResourcePool(int aNumInstances, ResourceSpecifier aResourceSpecifier, |
| Class aResourceClass, Map aResourceInitParams) throws ResourceInitializationException { |
| mNumInstances = aNumInstances; |
| |
| fillPool(aResourceSpecifier, aResourceClass, aResourceInitParams); |
| } |
| |
| /** |
| * Checks out a Resource from the pool. |
| * |
| * @return a Resource for use by the client. Returns <code>null</code> if none are available (in |
| * which case the client may wait on this object in order to be notified when an instance |
| * becomes available). |
| */ |
| public synchronized Resource getResource() { |
| if (!mFreeInstances.isEmpty()) { |
| Resource r = (Resource) mFreeInstances.remove(0); |
| /* |
| * UIMAFramework.getLogger().log( "Acquired resource " + r.getMetaData().getUUID() + " from |
| * pool."); |
| */ |
| return r; |
| } else { |
| // no instances available |
| // UIMAFramework.getLogger().log("No Resource instances currently available"); |
| return null; |
| } |
| } |
| |
| /** |
| * Checks in a Resource to the pool. Also notifies other Threads that may be waiting for a |
| * connection. |
| * |
| * @param aResource |
| * the resource to release |
| */ |
| public synchronized void releaseResource(Resource aResource) { |
| // make sure this Resource was actually belongs to this pool and is checked out |
| if (!mAllInstances.contains(aResource) || mFreeInstances.contains(aResource)) { |
| UIMAFramework.getLogger(CLASS_NAME).logrb(Level.WARNING, CLASS_NAME.getName(), |
| "releaseResource", LOG_RESOURCE_BUNDLE, "UIMA_return_resource_to_pool__WARNING"); |
| } else { |
| /* |
| * UIMAFramework.getLogger().log( "Returned resource " + aResource.getMetaData().getUUID() + " |
| * to the pool."); |
| */ |
| // Add the Resource to the end of the free instances List |
| mFreeInstances.add(aResource); |
| } |
| |
| // Notify any threads waiting on this object |
| notifyAll(); |
| } |
| |
| /** |
| * Checks out a Resource from the pool. If none is currently available, wait for the specified |
| * amount of time for one to be checked in. |
| * |
| * @param aTimeout |
| * the time to wait in milliseconds. A value of <=0 will wait forever. |
| * |
| * @return a Resource for use by the client. Returns <code>null</code> if none are available (in |
| * which case the client may wait on this object in order to be notified when an instance |
| * becomes available). |
| */ |
| public synchronized Resource getResource(long aTimeout) { |
| long startTime = new Date().getTime(); |
| Resource resource; |
| while ((resource = getResource()) == null) { |
| try { |
| wait(aTimeout); |
| } catch (InterruptedException e) { |
| } |
| if (aTimeout > 0 && (new Date().getTime() - startTime) >= aTimeout) { |
| // Timeout has expired |
| return null; |
| } |
| } |
| return resource; |
| } |
| |
| /* |
| * Checks out a specific resource from the pool, waiting as long as needed until it is free |
| * @param r |
| */ |
| |
| public synchronized void checkoutSpecificResource(Resource r) { |
| while (!mFreeInstances.contains(r)) { |
| try { |
| wait(); |
| } catch (InterruptedException e) { |
| } |
| } |
| mFreeInstances.remove(r); |
| } |
| |
| /** |
| * Destroys all Resources in this pool. |
| */ |
| public synchronized void destroy() { |
| Iterator i = mAllInstances.iterator(); |
| while (i.hasNext()) { |
| Resource current = (Resource) i.next(); |
| current.destroy(); |
| } |
| mAllInstances.clear(); |
| mFreeInstances.clear(); |
| } |
| |
| /** |
| * Gets the size of this pool (the total number of instances that it can hold). |
| * |
| * @return the size of this pool |
| */ |
| public int getSize() { |
| return mNumInstances; |
| } |
| |
| /** |
| * Gets the metadata for the Resources in this pool. This pool implementation currently assumes |
| * that all Resource instances in the pool are equivalent and share the same metadata. |
| * |
| * @return the size of this pool |
| */ |
| public ResourceMetaData getMetaData() { |
| return mMetaData; |
| } |
| |
| /** |
| * Utility method used in the constructor to fill the pool with Resource instances. |
| * |
| * @param aResourceSpecifier |
| * specifier that describes how to create the Resource instances for the pool |
| * @param aResourceClass |
| * class of resource to instantiate |
| * @param aResourceInitParams |
| * initialization parameters to be passed to the |
| * {@link Resource#initialize(ResourceSpecifier,Map)} method. |
| * |
| * |
| * @throws ResourceInitializationException |
| * if the Resource instances could not be created |
| */ |
| protected void fillPool(ResourceSpecifier aResourceSpecifier, Class aResourceClass, |
| Map aResourceInitParams) throws ResourceInitializationException { |
| // fill the pool |
| for (int i = 0; i < mNumInstances; i++) { |
| Resource_ImplBase resource = (Resource_ImplBase) UIMAFramework.produceResource( |
| aResourceClass, aResourceSpecifier, aResourceInitParams); |
| |
| mAllInstances.add(resource); |
| mFreeInstances.add(resource); |
| |
| // store metadata so it can be accessed without a check-out |
| if (i == 0) { |
| mMetaData = resource.getMetaData(); |
| } |
| } |
| } |
| |
| protected Vector getAllInstances() { |
| return mAllInstances; |
| } |
| |
| protected Vector getFreeInstances() { |
| return mFreeInstances; |
| } |
| |
| private Vector mAllInstances = new Vector(); |
| |
| private Vector mFreeInstances = new Vector(); |
| |
| private int mNumInstances; |
| |
| private ResourceMetaData mMetaData; |
| } |