/* * Copyright 2012 The Solmix Project * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.fmk.pool; import java.util.HashMap; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.solmix.api.datasource.DSRequest; import org.solmix.api.exception.SlxException; import org.solmix.api.pool.IPoolableObjectFactory; import org.solmix.api.pool.PoolManager; import org.solmix.api.pool.SlxKeyedPoolableObjectFactory; import org.solmix.api.pool.SlxPoolableObjectFactory; import org.solmix.api.types.Texception; import org.solmix.api.types.Tmodule; import org.solmix.commons.collections.DataTypeMap; import org.solmix.commons.util.DataUtils; /** * {@link org.solmix.api.pool.PoolService PoolService} implement. * * @version 0.0.4 * @since 0.0.1 * @author solmix.f@gmail.com */ @SuppressWarnings({ "rawtypes", "unchecked" }) public class PoolManagerImpl implements PoolManager { private final Logger log = LoggerFactory.getLogger(PoolManagerImpl.class.getName()); protected IPoolableObjectFactory factory; protected String symbolicName; protected Object source; protected Map sources; private final Map config; protected String name; protected boolean enablePool; // private static final String FILTER = SlxConstants.SERVICE_CM_NAME + "=" + SlxConstants.MODULE_DS_NAME; // // @Inject // @Reference(id = "ds-config", serviceInterface = ConfigRealm.class, timeout = 100, filter = FILTER) public PoolManagerImpl(String name, IPoolableObjectFactory factory, Map config) { sources = new HashMap(); this.name = name; this.factory = factory; this.config = config; symbolicName = getClass().getName(); } @Override public Object borrowObject(Object key) throws SlxException { return borrowObject(key, null); } /** * This method only used for datasource pool. * * @param name * @param request {@link org.solmix.api.datasource.DSRequest} * @return * @throws SlxException */ @Override public Object borrowObject(Object key, DSRequest request) throws SlxException { Object objectSource = getObjectSource(key); if (objectSource instanceof SlxKeyedObjectPool) try { return ((SlxKeyedObjectPool) objectSource).borrowObject(key); } catch (Exception e) { throw new SlxException(Tmodule.POOL, Texception.POOL_BORROW_OBJECT_FAILD, "borrow Object faild", e); } if (objectSource instanceof SlxObjectPool) try { return ((SlxObjectPool) objectSource).borrowObject(); } catch (Exception e) { throw new SlxException(Tmodule.POOL, Texception.POOL_BORROW_OBJECT_FAILD, "borrow Object faild", e); } if (objectSource instanceof SlxPoolableObjectFactory) try { return ((SlxPoolableObjectFactory) objectSource).makeObject(); } catch (Exception e) { throw new SlxException(Tmodule.POOL, Texception.POOL_BORROW_OBJECT_FAILD, "borrow Object faild", e); } if (objectSource instanceof SlxKeyedPoolableObjectFactory) try { SlxKeyedPoolableObjectFactory source = (SlxKeyedPoolableObjectFactory) objectSource; // if (source instanceof PoolableDataSourceFactory) // ((PoolableDataSourceFactory) source).setDsRequest(request); return source.makeObject(key); } catch (Exception e) { throw new SlxException(Tmodule.POOL, Texception.POOL_BORROW_OBJECT_FAILD, "borrow Object faild", e); } else throw new SlxException(Tmodule.POOL, Texception.POOL_INVALID_OBJECT_TYPE, "Invalid objectSource type:" + objectSource.getClass().getName(), new IllegalArgumentException()); } @Override public Object borrowUnpooledObject(Object key) throws SlxException { Object objectSource = getObjectSource(key); if (objectSource instanceof SlxKeyedObjectPool) try { return ((SlxKeyedObjectPool) objectSource).getObjectFactory().makeUnpooledObject(key); } catch (Exception e) { throw new SlxException(Tmodule.POOL, Texception.POOL_BORROW_OBJECT_FAILD, "borrow Unpool Object faild", e); } if (objectSource instanceof SlxObjectPool) try { return ((SlxObjectPool) objectSource).getObjectFactory().makeUnpooledObject(); } catch (Exception e) { throw new SlxException(Tmodule.POOL, Texception.POOL_BORROW_OBJECT_FAILD, "borrow Unpool Object faild", e); } if (objectSource instanceof SlxPoolableObjectFactory) try { return ((SlxPoolableObjectFactory) objectSource).makeUnpooledObject(); } catch (Exception e) { throw new SlxException(Tmodule.POOL, Texception.POOL_BORROW_OBJECT_FAILD, "borrow Unpool Object faild", e); } if (objectSource instanceof SlxKeyedPoolableObjectFactory) try { return ((SlxKeyedPoolableObjectFactory) objectSource).makeUnpooledObject(key); } catch (Exception e) { throw new SlxException(Tmodule.POOL, Texception.POOL_BORROW_OBJECT_FAILD, "borrow Unpool Object faild", e); } else throw new SlxException(Tmodule.POOL, Texception.POOL_INVALID_OBJECT_TYPE, "Invalid objectSource type:" + objectSource.getClass().getName(), new IllegalArgumentException()); } @Override public Object borrowNewObject(Object key) throws Exception { Object objectSource = getObjectSource(key); if (objectSource instanceof SlxKeyedObjectPool) return ((SlxKeyedObjectPool) objectSource).getObjectFactory().makeObject(key); if (objectSource instanceof SlxObjectPool) return ((SlxObjectPool) objectSource).getObjectFactory().makeObject(); if (objectSource instanceof SlxPoolableObjectFactory) return ((SlxPoolableObjectFactory) objectSource).makeObject(); if (objectSource instanceof SlxKeyedPoolableObjectFactory) return ((SlxKeyedPoolableObjectFactory) objectSource).makeObject(key); else throw new Exception((new StringBuilder()).append("Invalid objectSource type: ").append(objectSource.getClass().getName()).toString()); } @Override public void returnObject(Object key, Object obj) { try { Object objectSource = getObjectSource(key); if (objectSource instanceof SlxObjectPool) ((SlxObjectPool) objectSource).returnObject(obj); else if (objectSource instanceof SlxKeyedObjectPool) ((SlxKeyedObjectPool) objectSource).returnObject(key, obj); else if (objectSource instanceof SlxPoolableObjectFactory) ((SlxPoolableObjectFactory) objectSource).destroyObject(obj); else if (objectSource instanceof SlxKeyedPoolableObjectFactory) ((SlxKeyedPoolableObjectFactory) objectSource).destroyObject(key, obj); } catch (Exception e) { log.error("Error while freeing object - ignored.", e); } } public synchronized Object getObjectSource(Object key) throws SlxException { if (factory instanceof SlxKeyedPoolableObjectFactory) { if (this.source == null) this.source = makeSource(key); return this.source; } Object source = sources.get(key); if (source == null) { source = makeSource(key); sources.put(key, source); } return source; } protected Object makeSource(Object key) throws SlxException { DataTypeMap mergConfig = new DataTypeMap(config); IPoolableObjectFactory factory = this.factory.newInstance(key); source = factory; SlxPoolableObjectFactory iscFactory = null; if (factory instanceof SlxPoolableObjectFactory) iscFactory = (SlxPoolableObjectFactory) factory; if (mergConfig.getBoolean("enabled", false) && (iscFactory == null || !iscFactory.poolDisabled)) { enablePool = DataUtils.asBoolean(mergConfig.remove("enabled")); Object pool; if (factory instanceof SlxKeyedPoolableObjectFactory) pool = new SlxKeyedObjectPool((SlxKeyedPoolableObjectFactory) factory, mergConfig); else pool = new SlxObjectPool((SlxPoolableObjectFactory) factory, mergConfig); factory.setPool(pool); source = pool; } else { log.info((new StringBuilder()).append("Disabled for pooling '").append(key.toString()).append("' objects").toString()); } if (source == null) throw new SlxException(Tmodule.POOL, Texception.POOL_UNABLE_BIND_OBJECT, "Unable to bind Object for key:" + key); else return source; } @Override public void destroy() { if (source == null) return; try { if (this.source instanceof SlxKeyedObjectPool) { ((SlxKeyedObjectPool) source).close(); } else { ((SlxObjectPool) source).close(); } } catch (Exception e) { // ignored. } } @Override public boolean isEnablePool() { return enablePool; } @Override public Object getPool() { if (isEnablePool()) { return source; } return null; } }