DataSourceConnectionProvider.java :  » ERP-CRM-Financial » OpenXava-3.0 » org » openxava » util » Java Open Source

Java Open Source » ERP CRM Financial » OpenXava 3.0 
OpenXava 3.0 » org » openxava » util » DataSourceConnectionProvider.java
package org.openxava.util;

import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.*;

import javax.naming.*;
import javax.sql.*;
import javax.xml.parsers.*;

import org.apache.commons.logging.*;
import org.openxava.component.*;
import org.openxava.hibernate.*;
import org.openxava.jpa.*;
import org.w3c.dom.*;

/**
 * Adapter from JNDI DataSource interface to IConnectionProvider interface.
 * 
 * @author Javier Paniza
 */
public class DataSourceConnectionProvider implements IConnectionProvider, Serializable {
  
  private static final long serialVersionUID = 5262771696899604060L;
  
  private final static String DEFAULT_JPA_PERSISTENCE_UNIT="__DEFAULT__"; 
  private static Log log = LogFactory.getLog(DataSourceConnectionProvider.class);
    
  private static Properties datasourcesJNDIByPackage;
  private static Map providers;
  private static boolean useHibernateConnection = false;
  private static Map jpaDataSources; 
    
  private transient DataSource dataSource;
  private String dataSourceJNDI;  
  private String user;
  private String password;
    
  public static IConnectionProvider createByComponent(String componentName) throws XavaException {
    MetaComponent component =MetaComponent.get(componentName);         
    String jndi = null;    
    if (component.getMetaEntity().isAnnotatedEJB3()) {      
      jndi = getJPADataSource();      
      if (Is.emptyString(jndi) && !isUseHibernateConnection()) {  
        throw new XavaException("no_jpa_data_source_for_entity", componentName);  
      }
    }
    else {
      String packageName = component.getPackageNameWithSlashWithoutModel();
      jndi = getDatasourcesJNDIByPackage().getProperty(packageName);
      if (Is.emptyString(jndi)) {
        throw new XavaException("no_data_source_for_component", componentName); 
      }
    }
    DataSourceConnectionProvider provider = new DataSourceConnectionProvider();    
    provider.setDataSourceJNDI(jndi);
    return provider;
  }
    
  /**
   * Extract the JNDI of data source from JPA persistence.xml file.
   * 
   * It can be a empty string because it's possible to have a jpa unit without datasource
   * for example with direct access to data with JDBC, or so.
   */
  private static String getJPADataSource() { 
    if (jpaDataSources == null) {
      loadJPADataSources();
    }
    String result = (String) jpaDataSources.get(XPersistence.getPersistenceUnit());
    if (result != null) return result;
    return (String) jpaDataSources.get(DEFAULT_JPA_PERSISTENCE_UNIT);
  }
  
  private static String getDataSourceFromElement(Element element) { 
    String dataSource = getNodeValue(element, "non-jta-data-source");
    if (!Is.emptyString(dataSource)) return dataSource;
    return getNodeValue(element, "jta-data-source");
  }

  private static String getNodeValue(Element element, String tagName) {
    NodeList nodes = element.getElementsByTagName(tagName);
    int length = nodes.getLength();
    for (int i=0; i < length; i++) {
      String datasource = nodes.item(i).getFirstChild().getNodeValue();
      if (datasource != null) { 
        return datasource;
      }
    }
    return "";
  }  

  private static void loadJPADataSources() {
    jpaDataSources = new HashMap();
    try {
      DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      URL url = XPersistence.class.getClassLoader().getResource("META-INF/persistence.xml");
      Document doc = builder.parse(url.toExternalForm());
      NodeList units = doc.getElementsByTagName("persistence-unit");
      int unitsCount = units.getLength();
      for (int iUnits=0; iUnits<unitsCount; iUnits++) {
        Element unit = (Element) units.item(iUnits);
        String unitName = unit.getAttribute("name");
        String dataSource = getDataSourceFromElement(unit);
        if (jpaDataSources.isEmpty()) { // first time
          jpaDataSources.put(DEFAULT_JPA_PERSISTENCE_UNIT, dataSource); // The first is the default one
        }
        jpaDataSources.put(unitName, dataSource);
      }      
    }
    catch (Exception ex) {
      jpaDataSources = null;
      log.error(ex.getMessage(), ex); 
    }    
  }

  public static IConnectionProvider getByComponent(String componentName) throws XavaException {
    if (providers == null) providers = new HashMap();
    IConnectionProvider provider = (IConnectionProvider) providers.get(componentName);
    if (provider == null) {
      provider = createByComponent(componentName);
      providers.put(componentName, provider);
    }    
    return provider;
  }
  
  /**
   * DataSource to wrap
   * @throws NamingException
   */  
  public DataSource getDataSource() throws NamingException {
    if (dataSource == null) {      
      Context ctx = new InitialContext();
      dataSource = (DataSource) ctx.lookup(getDataSourceJNDI());      
    }
    return dataSource;
  }
    
  /**
   * JNDI of DataSource to wrap. <p>
   * Only works if datasource == null 
   */
  public String getDataSourceJNDI() {
    return dataSourceJNDI;
  }

  /**
   * JNDI of DataSource to wrap. <p>
   * Only works if datasource == null 
   */  
  public void setDataSourceJNDI(String dataSourceJDNI) {
    this.dataSourceJNDI = dataSourceJDNI;
  }
  
  public Connection getConnection() throws SQLException {
    if (isUseHibernateConnection()) {    
      return XHibernate.getSession().connection();
    }    
    try {
      if (Is.emptyString(getUser())) {
        return getDataSource().getConnection();
      }
      else {
        return getDataSource().getConnection(getUser(), getPassword());
      }
    }
    catch (NamingException ex) {
      throw new SQLException(ex.getLocalizedMessage());      
    }
  }
  
  public Connection getConnection(String dataSourceName) throws SQLException {
    return getConnection();
  }
  public void setPassword(String password) {
    this.password = password;
  }
  public void setUser(String user) {
    this.user = user;
  }
  public String getPassword() {
    return password;
  }
  public String getUser() {
    return user;
  }
  
  public void setDefaultDataSource(String dataSourceName) {
  }
    
  private static Properties getDatasourcesJNDIByPackage() throws XavaException {
    if (datasourcesJNDIByPackage == null) {
      try {
        PropertiesReader reader = new PropertiesReader(DataSourceConnectionProvider.class, "datasource.properties");         
        datasourcesJNDIByPackage = reader.get();        
      }
      catch (IOException ex) {
        log.error(ex.getMessage(), ex);
        throw new XavaException(ex.getLocalizedMessage());
      }
    }    
    return datasourcesJNDIByPackage;
  }

  /**
   * If <code>true</code> then all intances use hibernate connection for obtain 
   * connection, instead of data source connection pool. <p>
   * 
   * Useful for using outside an application server, for example, in a
   * junit test. 
   */  
  public static boolean isUseHibernateConnection() {
    return useHibernateConnection;
  }

  /**
   * If <code>true</code> then all intances use hibernate connection for obtain 
   * connection, instead of data source connection pool. <p>
   * 
   * Useful for using outside an application server, for example, in a
   * junit test. 
   */
  public static void setUseHibernateConnection(boolean useHibernateConnection) {
    DataSourceConnectionProvider.useHibernateConnection = useHibernateConnection;
  }
  
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.