/* * 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.datasource; import java.util.Collection; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import javax.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.solmix.SlxConstants; import org.solmix.api.call.DSCall; import org.solmix.api.datasource.DSRequest; import org.solmix.api.datasource.DSResponse; import org.solmix.api.datasource.DataSource; import org.solmix.api.datasource.DataSourceData; import org.solmix.api.datasource.DataSourceGenerator; import org.solmix.api.datasource.DataSourceManager; import org.solmix.api.exception.SlxException; import org.solmix.api.jaxb.Eoperation; import org.solmix.api.jaxb.EserverType; import org.solmix.api.jaxb.request.Roperation; import org.solmix.api.pool.PoolManager; import org.solmix.api.pool.PoolManagerFactory; import org.solmix.api.types.Texception; import org.solmix.api.types.Tmodule; import org.solmix.ds.context.Context; import org.solmix.fmk.SlxContext; import org.solmix.runtime.SystemContext; import org.solmix.runtime.bean.ConfiguredBeanProvider; /** * DataSourceManager service implements. * * @version 0.0.4 */ public class DefaultDataSourceManager implements DataSourceManager { private final List<DataSource> providers = new CopyOnWriteArrayList<DataSource>(); public volatile PoolManager manager; private PoolManagerFactory poolManagerFactory; private static Logger log = LoggerFactory.getLogger(DataSourceManager.class.getName()); private SystemContext sc; public DefaultDataSourceManager() { this(null); } public DefaultDataSourceManager(final SystemContext sc) { setSystemContext(sc); providers.add(new BasicDataSource(sc)); providers.add(new FileSystemDataSource(sc)); } @Resource public void setSystemContext(final SystemContext sc) { this.sc = sc; if (sc != null) { sc.setExtension(this, DataSourceManager.class); } } /** * @return the poolServiceFactory */ public synchronized PoolManagerFactory getPoolManagerFactory() { if (poolManagerFactory == null && sc != null) { poolManagerFactory = sc.getExtension(PoolManagerFactory.class); } return poolManagerFactory; } /** * @param poolServiceFactory the poolServiceFactory to set */ public void setPoolManagerFactory(PoolManagerFactory poolManagerFactory) { this.poolManagerFactory = poolManagerFactory; } public static void freeDataSource(DataSource ds) { SystemContext sc = SlxContext.getThreadSystemContext(); sc.getExtension(DataSourceManager.class).free(ds); } @Override public void free(DataSource ds) { if (ds == null) { return; } else if (ds.getContext().isWaitForFree()) { getPoolManager().returnObject(ds.getName(), ds); ds.getContext().setWaitForFree(false); } else { ds = null; } } /** * {@inheritDoc} * * @throws Exception * @see org.solmix.api.datasource.DataSourceManagerService#get(java.lang.String) */ @Override public DataSource get(String name) throws SlxException { return get(name, null); } /** * {@inheritDoc} * * @throws Exception * @see org.solmix.api.datasource.DataSourceManagerService#getUnpooledDataSource(java.lang.String) */ @Override public DataSource getUnpooledDataSource(String name) throws SlxException { return (DataSource) getPoolManager().borrowUnpooledObject(name); } @Override public synchronized PoolManager getPoolManager() { if (manager == null) { log.debug("Initial & create DataSource Pool"); manager = getPoolManagerFactory().createPoolManager(SlxConstants.MODULE_DS_NAME, new PoolableDataSourceFactory(sc)); } return manager; } /** * {@inheritDoc} * * @see org.solmix.api.datasource.DataSourceManagerService#getProviders() */ @Override public List<DataSource> getProviders() { if (sc != null) { ConfiguredBeanProvider cbp = sc.getExtension(ConfiguredBeanProvider.class); Collection<? extends DataSource> cc = cbp.getBeansOfType(DataSource.class); for (DataSource c : cc) { if (!providers.contains(c)) providers.add(c); } } return providers; } public void unregister(DataSource datasource) { providers.remove(datasource); } public void register(DataSource datasource) { String serverType = datasource.getServerType(); if (serverType == null) return; for (DataSource ds : providers) { if (serverType.equalsIgnoreCase(ds.getServerType())) providers.remove(ds); } providers.add(datasource); } public static DataSource getDataSource(String name) throws SlxException { return getDataSource(name, null); } public static DataSource getDataSource(String name, DSRequest request) throws SlxException { SystemContext sc = SlxContext.getThreadSystemContext(); return sc.getExtension(DataSourceManager.class).get(name, request); } /** * {@inheritDoc} * * @see org.solmix.api.datasource.DataSourceManagerService#get(java.lang.String, * org.solmix.api.datasource.DSRequest) */ @Override public DataSource get(String name, DSRequest request) throws SlxException { DataSource _return = null; try { _return = (DataSource) getPoolManager().borrowObject(name, request); if (_return != null) _return.getContext().setWaitForFree(true); } catch (Exception e1) { log.warn("Borrow object from pool failed, try to used unpooled object", e1); } try { // Re try. if (_return == null) return (DataSource) getPoolManager().borrowUnpooledObject(name); } catch (Exception trye) { throw new SlxException(Tmodule.POOL, Texception.POOL_BORROW_OBJECT_FAILD, "borrow unpooled Object faild ", trye); } return _return; } /** * {@inheritDoc} * * @see org.solmix.api.datasource.DataSourceManagerService#restartPoolManager() */ @Override public void restartPoolManager() { log.info("Restart DataSource Pool"); manager = getPoolManagerFactory().createPoolManager(SlxConstants.MODULE_DS_NAME, new PoolableDataSourceFactory(sc)); } /** * {@inheritDoc} * * @see org.solmix.api.datasource.DataSourceManager#createDSRequest() */ @Override public DSRequest createDSRequest() { return new DSRequestImpl(); } @Override public DSRequest createDSRequest(String dataSourceName, Eoperation opType, DSCall rpc) { return new DSRequestImpl(dataSourceName, opType, rpc); } @Override public DSRequest createDSRequest(Roperation operation, Context context) throws SlxException { return new DSRequestImpl(operation, context); } @Override public DSRequest createDSRequest(String dataSourceName, Eoperation opType) { return new DSRequestImpl(dataSourceName, opType); } /** * {@inheritDoc} * * @see org.solmix.api.datasource.DataSourceManager#createDSRequest(java.lang.String, * org.solmix.api.jaxb.Eoperation, java.lang.String) */ @Override public DSRequest createDSRequest(String dataSourceName, Eoperation opType, String operationID) { return new DSRequestImpl(dataSourceName, opType, operationID); } @Override public DSRequest createDSRequest(DataSource dataSourceName, Eoperation opType, String operationID) { return new DSRequestImpl(dataSourceName, opType, operationID); } @Override public DSRequest createDSRequest(DataSource dataSourceName, Eoperation opType) { return new DSRequestImpl(dataSourceName, opType); } @Override public DSRequest createDSRequest(DataSource dataSourceName, Eoperation opType, DSCall rpc) { return new DSRequestImpl(dataSourceName, opType, rpc); } @Override public DSResponse createDSResponse(DSRequest request) { return new DSResponseImpl(request); } /** * @param context * @return * @throws SlxException */ @Override public DataSource generateDataSource(DataSourceData context) throws SlxException { if (context == null) throw new java.lang.IllegalArgumentException("DataSourceData must be not null."); if(context.getServerType()==null) throw new java.lang.IllegalArgumentException("DataSourceData must setting serverType."); EserverType serverType = context.getServerType(); DataSourceGenerator generator=null; for (DataSource ds : getProviders()) { if (ds.getServerType().equals(serverType.value())) { generator = ds.getDataSourceGenerator(); break; } } if(generator!=null){ DataSource instance = generator.generateDataSource(context); // not from pool. instance.getContext().setWaitForFree(false); return instance; }else{ throw new SlxException(Tmodule.DATASOURCE,Texception.DS_DSCONFIG_OBJECT_TYPE_ERROR,"No found Datasource generator"); } } }