org.opoo.oqs.core.AbstractQueryFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.opoo.oqs.core.AbstractQueryFactory.java

Source

/*
 * $Id$
 *
 * Copyright 2006-2008 Alex Lin. All rights reserved.
 *
 * 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.opoo.oqs.core;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.opoo.oqs.CannotCreateQueryException;
import org.opoo.oqs.CannotCreateQueryFactoryException;
import org.opoo.oqs.Criteria;
import org.opoo.oqs.Oqs;
import org.opoo.oqs.QueryException;
import org.opoo.oqs.QueryFactory;
import org.opoo.oqs.dialect.Dialect;
import org.opoo.oqs.dialect.HibernateDialectWrapper;
import org.opoo.oqs.jdbc.ConnectionManager;
import org.opoo.oqs.jdbc.DataSourceAware;
import org.opoo.util.ClassUtils;

/**
 * <tt>QueryFactory</tt>
 *
 * @author Alex Lin(alex@opoo.org)
 * @version 1.0
 * @since OQS1.0
 */
public abstract class AbstractQueryFactory implements QueryFactory, DataSourceAware {
    private static Log log = LogFactory.getLog(QueryFactory.class);
    private DataSource dataSource;
    private ConnectionManager connectionManager;

    /**
     * Dialect
     */
    Dialect dialect;
    int debugLevel = 0;
    ClassLoader beanClassLoader = null;

    static {
        log.info("Initializing " + Oqs.getSpecificationTitle() + ": " + Oqs.getSpecificationVersion());
        System.out.println(Oqs.getOqsInfo());
    }

    public AbstractQueryFactory() {
        log.info("OQS QueryFactory: " + getClass().getName());
    }

    public AbstractQueryFactory(DataSource dataSource) {
        setDataSource(dataSource);
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
        //setConnectionManager(new TransactionSupportConnectionManager(dataSource));
        this.connectionManager = createConnectionManager(dataSource);
    }

    public void afterPropertiesSet() {
        String databaseName = null;
        int databaseMajorVersion = 0;
        Connection conn = null;
        try {
            conn = connectionManager.getConnection();
            DatabaseMetaData meta = conn.getMetaData();
            databaseName = meta.getDatabaseProductName();
            databaseMajorVersion = getDatabaseMajorVersion(meta);
            log.info("RDBMS: " + databaseName + ", version: " + meta.getDatabaseProductVersion());
            log.info("JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion());
        } catch (SQLException sqle) {
            log.warn("Could not obtain connection metadata", sqle);
        } catch (UnsupportedOperationException uoe) {
            // user supplied JDBC connections
        } finally {
            connectionManager.releaseConnection(conn);
        }
        if (dialect == null) {
            dialect = this.determineDialect(databaseName, databaseMajorVersion);
        }
    }

    /**
       * ConnectionManager
       * @param ds DataSource
       * @return ConnectionManager
       */
    protected abstract ConnectionManager createConnectionManager(DataSource ds);

    public ConnectionManager getConnectionManager() {
        return connectionManager;
    }

    /**
     * SQL<br>
     * <ul>
     * <li>1 show sql only
     * <li>2 show sql and middle processing query string
     * <li>0 nothing
     * </ul>
     * QueryFactoryQuerySQL
     * @param debugLevel int
     */
    public void setShowSql(int debugLevel) {
        this.debugLevel = debugLevel;
    }

    /**
     * Dialect
     * @param classname String
     */
    public void setDialectClassName(String classname) {
        try {
            Object object = ClassUtils.newInstance(classname);
            if (object.getClass().getName().startsWith("org.hibernate.dialect.")) {
                //if (object instanceof org.hibernate.dialect.Dialect) {
                dialect = new HibernateDialectWrapper((org.hibernate.dialect.Dialect) object);
            } else {
                dialect = (Dialect) object;
            }
        } catch (Exception ex) {
            throw new QueryException("Can not create Dialect for " + classname, ex);
        }
    }

    public void setDialect(String dialectClassName) {
        setDialectClassName(dialectClassName);
    }

    public void setBeanClassLoader(ClassLoader classLoader) {
        this.beanClassLoader = classLoader;
    }

    public void setBeanImports(String[] packages) {
        this.beanClassLoader = new BeanClassLoader(packages);
    }

    /**
     *
     * @param queryString String
     * @return Criteria
     * @throws CannotCreateQueryException
     */
    public Criteria createCriteria(String queryString) throws CannotCreateQueryException {
        return new DefaultCriteria(this, queryString);
    }

    private static AbstractQueryFactory createQueryFactory(String factoryClassName)
            throws CannotCreateQueryFactoryException {
        try {
            Class clazz = ClassUtils.forName(factoryClassName, AbstractQuery.class.getClassLoader());
            return (AbstractQueryFactory) clazz.newInstance();
        } catch (Exception ex) {
            log.error("CacheFactory.createFactory", ex);
            throw new CannotCreateQueryFactoryException("Cannot create QueryFactory, " + factoryClassName, ex);
        }
    }

    /**
     * <tt>QueryFactory</tt>- Map
     * <tt>QueryFactory</tt>createQueryFactory(DataSource)
     * <pre>
     * Sample:
     *  DataSource dataSource = ...;
     *  String className = "org.opoo.oqs.spring.SpringQueryFactoryImpl";
     *  Map map = new HashMap();
     *  map.put("dataSource", dataSource);
     *  *** ConnectionManagermap.put("connectionManager",
     *  *** youConnectionManager)dataSource
     *  map.put("dialectClass", "org.opoo.oqs.dialect.MySQLDialect");
     *  map.put("showSql", new Integer(2));
     *  QueryFactory qf = AbstractQueryFactory.createQueryFactory(className, map);
     *
     * </pre>
     *
     * @param factoryClassName String
     * @param properties Map
     * @return QueryFactory
     * @throws CannotCreateQueryFactoryException
     */
    public static QueryFactory createQueryFactory(String factoryClassName, Map properties)
            throws CannotCreateQueryFactoryException {

        try {
            AbstractQueryFactory qf = AbstractQueryFactory.createQueryFactory(factoryClassName);
            if (qf != null) {
                ClassUtils.populate(qf, properties);
                if (log.isDebugEnabled()) {
                    log.debug("QueryFactory " + factoryClassName + " created.");
                }
                return qf;
            }
        } catch (Exception ex) {
            throw new CannotCreateQueryFactoryException("Create QueryFactory " + factoryClassName, ex);
        }
        return null;
    }

    /**
     * Hibernate3Hibernate3SQL Dialect.
     * classpathnull
     *
     * @param databaseName String
     * @param databaseMajorVersion int
     * @return Dialect
     */
    private Dialect determineDialect(String databaseName, int databaseMajorVersion) {
        String className = "org.hibernate.dialect.DialectFactory";
        if (ClassUtils.isPresent(className)) {
            String methodName = "determineDialect";
            Class[] types = { String.class, int.class };
            org.hibernate.dialect.Dialect d = null;
            try {
                d = (org.hibernate.dialect.Dialect) ClassUtils.forName(className).getMethod(methodName, types)
                        .invoke(null, new Object[] { databaseName, Integer.valueOf(databaseMajorVersion) });
            } catch (Exception ex) {
                log.debug("cannot determine hibernate dialect", ex);
            }
            if (d != null) {
                log.debug("Find proper dialect for " + databaseName + ": " + d.getClass().getName());
                return new HibernateDialectWrapper(d);
            }
        }
        return null;
    }

    private int getDatabaseMajorVersion(DatabaseMetaData meta) {
        try {
            Method gdbmvMethod = DatabaseMetaData.class.getMethod("getDatabaseMajorVersion", (Class[]) null);
            return ((Integer) gdbmvMethod.invoke(meta, (Object[]) null)).intValue();
        } catch (NoSuchMethodException nsme) {
            return 0;
        } catch (Throwable t) {
            log.debug("could not get database version from JDBC metadata");
            return 0;
        }
    }

}