Package org.springframework.jms.listener.serversession

Source Code of org.springframework.jms.listener.serversession.CommonsPoolServerSessionFactory

/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed 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.springframework.jms.listener.serversession;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.jms.JMSException;
import javax.jms.ServerSession;

import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;

import org.springframework.jms.listener.serversession.ListenerSessionManager;

/**
* ServerSessionFactory implementation that holds ServerSessions
* in a configurable Jakarta Commons Pool.
*
* <p>By default, an instance of <code>GenericObjectPool</code> is created.
* Subclasses may change the type of <code>ObjectPool</code> used by
* overriding the <code>createObjectPool</code> method.
*
* <p>Provides many configuration properties mirroring those of the Commons Pool
* <code>GenericObjectPool</code> class; these properties are passed to the
* <code>GenericObjectPool</code> during construction. If creating a subclass of this
* class to change the <code>ObjectPool</code> implementation type, pass in the values
* of configuration properties that are relevant to your chosen implementation.
*
* @author Juergen Hoeller
* @since 2.0
* @see GenericObjectPool
* @see #createObjectPool
* @see #setMaxSize
* @see #setMaxIdle
* @see #setMinIdle
* @see #setMaxWait
*/
public class CommonsPoolServerSessionFactory extends AbstractPoolingServerSessionFactory {

  private int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE;

  private int minIdle = GenericObjectPool.DEFAULT_MIN_IDLE;

  private long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT;

  private long timeBetweenEvictionRunsMillis = GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;

  private long minEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;

  private final Map serverSessionPools = Collections.synchronizedMap(new HashMap(1));


  /**
   * Create a CommonsPoolServerSessionFactory with default settings.
   * Default maximum size of the pool is 8.
   * @see #setMaxSize
   * @see GenericObjectPool#setMaxActive
   */
  public CommonsPoolServerSessionFactory() {
    setMaxSize(GenericObjectPool.DEFAULT_MAX_ACTIVE);
  }

  /**
   * Set the maximum number of idle ServerSessions in the pool.
   * Default is 8.
   * @see GenericObjectPool#setMaxIdle
   */
  public void setMaxIdle(int maxIdle) {
    this.maxIdle = maxIdle;
  }

  /**
   * Return the maximum number of idle ServerSessions in the pool.
   */
  public int getMaxIdle() {
    return maxIdle;
  }

  /**
   * Set the minimum number of idle ServerSessions in the pool.
   * Default is 0.
   * @see GenericObjectPool#setMinIdle
   */
  public void setMinIdle(int minIdle) {
    this.minIdle = minIdle;
  }

  /**
   * Return the minimum number of idle ServerSessions in the pool.
   */
  public int getMinIdle() {
    return minIdle;
  }

  /**
   * Set the maximum waiting time for fetching an ServerSession from the pool.
   * Default is -1, waiting forever.
   * @see GenericObjectPool#setMaxWait
   */
  public void setMaxWait(long maxWait) {
    this.maxWait = maxWait;
  }

  /**
   * Return the maximum waiting time for fetching a ServerSession from the pool.
   */
  public long getMaxWait() {
    return maxWait;
  }

  /**
   * Set the time between eviction runs that check idle ServerSessions
   * whether they have been idle for too long or have become invalid.
   * Default is -1, not performing any eviction.
   * @see GenericObjectPool#setTimeBetweenEvictionRunsMillis
   */
  public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
    this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
  }

  /**
   * Return the time between eviction runs that check idle ServerSessions.
   */
  public long getTimeBetweenEvictionRunsMillis() {
    return timeBetweenEvictionRunsMillis;
  }

  /**
   * Set the minimum time that an idle ServerSession can sit in the pool
   * before it becomes subject to eviction. Default is 1800000 (30 minutes).
   * <p>Note that eviction runs need to be performed to take this
   * setting into effect.
   * @see #setTimeBetweenEvictionRunsMillis
   * @see GenericObjectPool#setMinEvictableIdleTimeMillis
   */
  public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
    this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
  }

  /**
   * Return the minimum time that an idle ServerSession can sit in the pool.
   */
  public long getMinEvictableIdleTimeMillis() {
    return minEvictableIdleTimeMillis;
  }


  /**
   * Returns a ServerSession from the pool, creating a new pool for the given
   * session manager if necessary.
   * @see #createObjectPool
   */
  public ServerSession getServerSession(ListenerSessionManager sessionManager) throws JMSException {
    ObjectPool pool = null;
    synchronized (this.serverSessionPools) {
      pool = (ObjectPool) this.serverSessionPools.get(sessionManager);
      if (pool == null) {
        if (logger.isInfoEnabled()) {
          logger.info("Creating Commons ServerSession pool for: " + sessionManager);
        }
        pool = createObjectPool(sessionManager);
        this.serverSessionPools.put(sessionManager, pool);
      }
    }
    try {
      return (ServerSession) pool.borrowObject();
    }
    catch (Exception ex) {
      JMSException jmsEx = new JMSException("Failed to borrow ServerSession from pool");
      jmsEx.setLinkedException(ex);
      throw jmsEx;
    }
  }

  /**
   * Subclasses can override this if they want to return a specific Commons pool.
   * They should apply any configuration properties to the pool here.
   * <p>Default is a GenericObjectPool instance with the given pool size.
   * @param sessionManager the session manager to use for
   * creating and executing new listener sessions
   * @return an empty Commons <code>ObjectPool</code>.
   * @see org.apache.commons.pool.impl.GenericObjectPool
   * @see #setMaxSize
   */
  protected ObjectPool createObjectPool(ListenerSessionManager sessionManager) {
    GenericObjectPool pool = new GenericObjectPool(createPoolableObjectFactory(sessionManager));
    pool.setMaxActive(getMaxSize());
    pool.setMaxIdle(getMaxIdle());
    pool.setMinIdle(getMinIdle());
    pool.setMaxWait(getMaxWait());
    pool.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis());
    pool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
    return pool;
  }

  /**
   * Create a Commons PoolableObjectFactory adapter for the given session manager.
   * Calls <code>createServerSession</code> and <code>destroyServerSession</code>
   * as defined by the AbstractPoolingServerSessionFactory class.
   * @param sessionManager the session manager to use for
   * creating and executing new listener sessions
   * @return the Commons PoolableObjectFactory
   * @see #createServerSession
   * @see #destroyServerSession
   */
  protected PoolableObjectFactory createPoolableObjectFactory(final ListenerSessionManager sessionManager) {
    return new PoolableObjectFactory() {
      public Object makeObject() throws JMSException {
        return createServerSession(sessionManager);
      }
      public void destroyObject(Object obj) {
        destroyServerSession((ServerSession) obj);
      }
      public boolean validateObject(Object obj) {
        return true;
      }
      public void activateObject(Object obj) {
      }
      public void passivateObject(Object obj) {
      }
    };
  }

  /**
   * Returns the given ServerSession, which just finished an execution
   * of its listener, back to the pool.
   */
  protected void serverSessionFinished(ServerSession serverSession, ListenerSessionManager sessionManager) {
    ObjectPool pool = (ObjectPool) this.serverSessionPools.get(sessionManager);
    try {
      pool.returnObject(serverSession);
    }
    catch (Exception ex) {
      logger.error("Failed to return ServerSession to pool", ex);
    }
  }

  /**
   * Closes all pools held by this ServerSessionFactory.
   */
  public void close(ListenerSessionManager sessionManager) {
    synchronized (this.serverSessionPools) {
      for (Iterator it = this.serverSessionPools.values().iterator(); it.hasNext();) {
        ObjectPool pool = (ObjectPool) it.next();
        try {
          pool.close();
        }
        catch (Exception ex) {
          logger.error("Failed to close ServerSession pool", ex);
        }
      }
    }
  }

}
TOP

Related Classes of org.springframework.jms.listener.serversession.CommonsPoolServerSessionFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.