Package org.beangle.model.persist.hibernate.internal

Source Code of org.beangle.model.persist.hibernate.internal.DynamicSessionFactoryBean

/* Copyright c 2005-2012.
* Licensed under GNU  LESSER General Public License, Version 3.
* http://www.gnu.org/licenses
*/
package org.beangle.model.persist.hibernate.internal;

import java.net.URL;
import java.util.Set;

import org.beangle.commons.collection.CollectUtils;
import org.beangle.model.persist.hibernate.support.TableNameConfig;
import org.eclipse.gemini.blueprint.context.BundleContextAware;
import org.hibernate.SessionFactory;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.SynchronousBundleListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;

public class DynamicSessionFactoryBean extends LocalSessionFactoryBean implements SynchronousBundleListener,
    BundleContextAware {

  private static Logger logger = LoggerFactory.getLogger(DynamicSessionFactoryBean.class);

  private BundleContext context;

  private Set<URL> configs = CollectUtils.newHashSet();

  private ChainedClassLoader loader = null;

  private TableNameConfig tableNameConfig;

  @Override
  protected SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) {
    return new SessionFactoryWrapper(rawSf);
  }

  protected void refreshSessionFactory() {
    Set<Resource> cfgs = CollectUtils.newHashSet();
    for (URL config : configs) {
      cfgs.add(new UrlResource(config));
    }
    Resource[] configLocations = new Resource[cfgs.size()];
    cfgs.toArray(configLocations);
    setConfigLocations(configLocations);
    try {
      logger.debug("buid session from locations {}", cfgs);
      SessionFactoryWrapper wrapper = (SessionFactoryWrapper) getSessionFactory();
      // FIXME Thread.currentThread().setContextClassLoader(loader);
      setBeanClassLoader(loader);
      wrapper.setWrapped(buildSessionFactory());
      logger.debug("build new session factory success");
    } catch (Exception e) {
      throw new RuntimeException("cannot update sessionFactory ", e);
    }
  }

  public void bundleChanged(BundleEvent bundleEvent) {
    try {
      boolean changed = false;
      if (bundleEvent.getType() == BundleEvent.STARTED) {
        changed = addBundle(bundleEvent.getBundle());
      } else if (bundleEvent.getType() == BundleEvent.STOPPED) {
        changed = removeBundle(bundleEvent.getBundle());
      }
      if (changed) refreshSessionFactory();
    } catch (RuntimeException re) {
      logger.error("Error processing bundle event", re);
      throw re;
    }
  }

  private URL getConfigLocation(Bundle bundle) {
    return bundle.getResource("META-INF/hibernate.cfg.xml");
  }

  private Set<URL> getTableConfigLocation(Bundle bundle) {
    Set<URL> urls = CollectUtils.newHashSet();
    URL url = bundle.getResource("META-INF/beangle/table.properties");
    if (null != url) {
      urls.add(url);
    }
    url = bundle.getResource("beangle/table.properties");
    if (null != url) {
      urls.add(url);
    }
    return urls;
  }

  private boolean addBundle(Bundle bundle) {
    boolean added = false;
    URL location = getConfigLocation(bundle);
    if (null != location) {
      configs.add(location);
      added = true;
      logger.debug("Add hibernate configuration: {}", location);
    }

    Set<URL> locations = getTableConfigLocation(bundle);
    if (!locations.isEmpty()) {
      for (URL url : locations) {
        tableNameConfig.addConfig(url);
      }
    }
    loader.addClassLoader(BundleDelegatingClassLoader.createBundleClassLoaderFor(bundle));
    return added;
  }

  private boolean removeBundle(Bundle bundle) {
    boolean removed = false;
    URL location = getConfigLocation(bundle);
    if (null != location) {
      configs.remove(location);
      removed = true;
      logger.debug("Remove hibernate configuration: {}", location);
    }
    Set<URL> locations = getTableConfigLocation(bundle);
    if (!locations.isEmpty()) {
      // for (URL url : locations) {
      // tableNameConfig.addConfig(url);
      // }
    }
    return removed;
  }

  public void logService() {
    for (Bundle bundle : context.getBundles()) {
      if (null != bundle.getRegisteredServices() && bundle.getRegisteredServices().length > 0) {
        logger.debug("============================== in bundle {}", bundle.getSymbolicName());
        int i = 0;
        for (ServiceReference sr : bundle.getRegisteredServices()) {
          // Object s = context.getService(sr);
          logger.debug("service{} is {}", i++, sr);
        }
        logger.debug("==============================");
      }
    }
  }

  public void stop(BundleContext context) {
    context.removeBundleListener(this);
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    super.afterPropertiesSet();
    if (null != context) {
      context.addBundleListener(this);
      loader = new ChainedClassLoader(
          new ClassLoader[] { BundleDelegatingClassLoader.createBundleClassLoaderFor(context
              .getBundle()) });

      boolean added = false;
      for (Bundle bundle : context.getBundles()) {
        if (bundle.getState() == Bundle.ACTIVE) {
          added |= addBundle(bundle);
          loader.addClassLoader(BundleDelegatingClassLoader.createBundleClassLoaderFor(bundle));
        }
      }
      if (added) {
        refreshSessionFactory();
      }
    }
  }

  public void setBundleContext(BundleContext bundleContext) {
    context = bundleContext;
  }

  public void setTableNameConfig(TableNameConfig tableNameConfig) {
    this.tableNameConfig = tableNameConfig;
  }

}
TOP

Related Classes of org.beangle.model.persist.hibernate.internal.DynamicSessionFactoryBean

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.