org.agnitas.backend.DBase.java Source code

Java tutorial

Introduction

Here is the source code for org.agnitas.backend.DBase.java

Source

/*********************************************************************************
 * The contents of this file are subject to the Common Public Attribution
 * License Version 1.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.openemm.org/cpal1.html. The License is based on the Mozilla
 * Public License Version 1.1 but Sections 14 and 15 have been added to cover
 * use of software over a computer network and provide for limited attribution
 * for the Original Developer. In addition, Exhibit A has been modified to be
 * consistent with Exhibit B.
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is OpenEMM.
 * The Original Developer is the Initial Developer.
 * The Initial Developer of the Original Code is AGNITAS AG. All portions of
 * the code written by AGNITAS AG are Copyright (c) 2007 AGNITAS AG. All Rights
 * Reserved.
 *
 * Contributor(s): AGNITAS AG.
 ********************************************************************************/
package org.agnitas.backend;

import java.sql.Blob;
import java.sql.Clob;
import java.util.Date;
import java.sql.Timestamp;
import java.sql.SQLException;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.HashSet;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.jdbc.core.JdbcOperations;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.pool.KeyedObjectPoolFactory;
import org.apache.commons.pool.impl.GenericKeyedObjectPoolFactory;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Appender;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.Level;
import org.agnitas.util.Log;

/** Database abstraction layer
 */
public class DBase {
    public final int DB_UNSET = 0;
    public final int DB_MYSQL = 1;
    public final int DB_ORACLE = 2;
    /** name for current date in database */
    public int dbType = DB_UNSET;
    public String sysdate = null;
    public String timestamp = null;
    public String measureType = null;
    public String measureRepr = null;
    /** Reference to configuration */
    private Data data = null;
    /** Reference to data source */
    protected DataSource dataSource = null;
    /** Default jdbc access instance */
    private SimpleJdbcTemplate jdbcTmpl = null;
    /** Collection of free connections */
    private ArrayList<SimpleJdbcTemplate> pool = null;

    static class DBaseFilter extends Filter {
        @Override
        public int decide(LoggingEvent e) {
            Level l = e.getLevel();

            if ((l == Level.WARN) || (l == Level.ERROR) || (l == Level.FATAL)) {
                return Filter.ACCEPT;
            }
            return Filter.NEUTRAL;
        }
    }

    static class DBaseAppender extends AppenderSkeleton {
        private Log log;

        public DBaseAppender(Log nLog) {
            super();
            log = nLog;
        }

        @Override
        public boolean requiresLayout() {
            return false;
        }

        @Override
        public void close() {
        }

        @Override
        protected void append(LoggingEvent e) {
            Level l = e.getLevel();
            int lvl = -1;

            if (l == Level.WARN) {
                lvl = Log.WARNING;
            } else if (l == Level.ERROR) {
                lvl = Log.ERROR;
            } else if (l == Level.FATAL) {
                lvl = Log.FATAL;
            }
            if (lvl != -1) {
                String name = e.getLoggerName();

                if ((name == null) || name.startsWith("org.springframework.jdbc")) {
                    log.out(lvl, "jdbc", e.getRenderedMessage());
                }
            }
        }
    }

    static class DBDatasource {
        private HashMap<String, DataSource> cache;
        private HashSet<String> seen;
        private Log log;

        public DBDatasource() {
            cache = new HashMap<String, DataSource>();
            seen = new HashSet<String>();
            log = new Log("jdbc", Log.INFO);

            Appender app = new DBaseAppender(log);

            app.addFilter(new DBaseFilter());
            BasicConfigurator.configure(app);
        }

        public DataSource newDataSource(String driver, String connect, String login, String password) {
            return new DriverManagerDataSource(connect, login, password);
        }

        public synchronized DataSource request(String driver, String connect, String login, String password)
                throws ClassNotFoundException {
            DataSource rc;
            String key = driver + ";" + connect + ";" + login + ";*";
            ArrayList<DataSource> cur;

            if (cache.containsKey(key)) {
                rc = cache.get(key);
                log.out(Log.DEBUG, "rq", "Got exitsing DS for " + key);
            } else {
                if (!seen.contains(driver)) {
                    try {
                        Class.forName(driver);
                        seen.add(driver);
                        log.out(Log.DEBUG, "rq", "Installed new driver for " + driver);
                    } catch (ClassNotFoundException e) {
                        log.out(Log.ERROR, "rq", "Failed to install driver " + driver);
                        throw e;
                    }
                }
                rc = newDataSource(driver, connect, login, password);
                cache.put(key, rc);
                log.out(Log.DEBUG, "rq", "Created new DS for " + key);
            }
            return rc;
        }
    }

    static class DBDatasourcePooled extends DBDatasource {
        private int dsPoolsize = 12;
        private boolean dsPoolgrow = true;

        public void setup(int poolsize, boolean poolgrow) {
            dsPoolsize = poolsize;
            dsPoolgrow = poolgrow;
        }

        public DataSource newDataSource(String driver, String connect, String login, String password) {
            ObjectPool connectionPool = new GenericObjectPool(null, dsPoolsize,
                    (dsPoolgrow ? GenericObjectPool.WHEN_EXHAUSTED_GROW : GenericObjectPool.WHEN_EXHAUSTED_BLOCK),
                    0);
            ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(connect, login, password);
            //            KeyedObjectPoolFactory      statementPoolFactory = new GenericKeyedObjectPoolFactory (null);
            PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,
                    connectionPool, null /*statementPoolFactory*/, null, false, true);

            return new PoolingDataSource(connectionPool);
        }
    }

    private static DBDatasourcePooled dsPool = new DBDatasourcePooled();

    public DBase(Data nData) throws Exception {
        data = nData;

        dsPool.setup(data.dbPoolsize(), data.dbPoolgrow());
        dataSource = dsPool.request(data.dbDriver(), data.dbConnect(), data.dbLogin(), data.dbPassword());
        jdbcTmpl = new SimpleJdbcTemplate(dataSource);
        pool = new ArrayList<SimpleJdbcTemplate>();
    }

    public void setup() throws Exception {
        dbType = DB_MYSQL;
        sysdate = "current_timestamp";
        timestamp = "change_date";
        measureType = "MEASURE_TYPE";
        measureRepr = "MEASURE_TYPE";
    }

    /**
     * Cleanup, close open statements and database connection
     */
    public void done() throws Exception {
        pool.clear();
        pool = null;
        jdbcTmpl = null;
        dataSource = null;
    }

    private void show(String what, String query, HashMap<String, Object> param) {
        if ((query != null) && data.islog(Log.DEBUG)) {
            String m = what + ": " + query;

            if ((param != null) && (param.size() > 0)) {
                String sep = " { ";

                for (String key : param.keySet()) {
                    Object val = param.get(key);
                    String disp;

                    if (val == null) {
                        disp = "null";
                    } else {
                        try {
                            Class cls = val.getClass();

                            if ((cls == String.class) || (cls == StringBuffer.class)) {
                                disp = "\"" + val.toString() + "\"";
                            } else if (cls == Character.class) {
                                disp = "'" + val.toString() + "'";
                            } else if (cls == Boolean.class) {
                                disp = ((Boolean) val).booleanValue() ? "true" : "false";
                            } else {
                                disp = val.toString();
                            }
                        } catch (Exception e) {
                            disp = "???";
                        }
                    }
                    m += sep + key + "=" + disp;
                    sep = ", ";
                }
                m += " }";
            }
            data.logging(Log.DEBUG, "dbase", m);
        }
    }

    public SimpleJdbcTemplate jdbc() {
        return jdbcTmpl;
    }

    public SimpleJdbcTemplate jdbc(String query, HashMap<String, Object> param) {
        show("DB", query, param);
        return jdbc();
    }

    public SimpleJdbcTemplate jdbc(String query) {
        return jdbc(query, null);
    }

    public JdbcOperations op() {
        return jdbc().getJdbcOperations();
    }

    public JdbcOperations op(String query, HashMap<String, Object> param) {
        show("OP", query, param);
        return op();
    }

    public JdbcOperations op(String query) {
        return op(query, null);
    }

    public SimpleJdbcTemplate request() {
        SimpleJdbcTemplate temp;

        if (pool.isEmpty()) {
            temp = new SimpleJdbcTemplate(dataSource);
        } else {
            temp = pool.remove(0);
        }
        return temp;
    }

    public SimpleJdbcTemplate request(String query, HashMap<String, Object> param) {
        show("RQ", query, param);
        return request();
    }

    public SimpleJdbcTemplate request(String query) {
        return request(query, null);
    }

    public SimpleJdbcTemplate release(SimpleJdbcTemplate temp) {
        if ((temp != null) && (!pool.contains(temp))) {
            pool.add(temp);
        }
        return null;
    }

    public SimpleJdbcTemplate release(SimpleJdbcTemplate temp, String query, HashMap<String, Object> param) {
        show("RL", query, param);
        return release(temp);
    }

    public SimpleJdbcTemplate release(SimpleJdbcTemplate temp, String query) {
        return release(temp, query, null);
    }

    private HashMap<String, Object> pack(Object[] param) {
        HashMap<String, Object> input = new HashMap<String, Object>(param.length / 2);

        for (int n = 0; n < param.length; n += 2) {
            input.put((String) param[n], param[n + 1]);
        }
        return input;
    }

    private Exception failure(String q, Exception e) {
        data.logging(Log.ERROR, "dbase", "DB Failed: " + q + ": " + e.toString());
        return e;
    }

    private int doQueryInt(SimpleJdbcTemplate jdbc, String q, HashMap<String, Object> packed) throws Exception {
        try {
            return jdbc.queryForInt(q, packed);
        } catch (Exception e) {
            throw failure(q, e);
        }
    }

    public int queryInt(SimpleJdbcTemplate jdbc, String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doQueryInt(jdbc, q, packed);
    }

    public int queryInt(String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doQueryInt(jdbc(q, packed), q, packed);
    }

    private long doQueryLong(SimpleJdbcTemplate jdbc, String q, HashMap<String, Object> packed) throws Exception {
        try {
            return jdbc.queryForLong(q, packed);
        } catch (Exception e) {
            throw failure(q, e);
        }
    }

    public long queryLong(SimpleJdbcTemplate jdbc, String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doQueryLong(jdbc, q, packed);
    }

    public long queryLong(String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doQueryLong(jdbc(q, packed), q, packed);
    }

    private String doQueryString(SimpleJdbcTemplate jdbc, String q, HashMap<String, Object> packed)
            throws Exception {
        try {
            return jdbc.queryForObject(q, String.class, packed);
        } catch (Exception e) {
            throw failure(q, e);
        }
    }

    public String queryString(SimpleJdbcTemplate jdbc, String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doQueryString(jdbc, q, packed);
    }

    public String queryString(String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doQueryString(jdbc(q, packed), q, packed);
    }

    private Map<String, Object> doQuerys(SimpleJdbcTemplate jdbc, String q, HashMap<String, Object> packed)
            throws Exception {
        try {
            return jdbc.queryForMap(q, packed);
        } catch (Exception e) {
            throw failure(q, e);
        }
    }

    public Map<String, Object> querys(SimpleJdbcTemplate jdbc, String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doQuerys(jdbc, q, packed);
    }

    public Map<String, Object> querys(String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doQuerys(jdbc(q, packed), q, packed);
    }

    private List<Map<String, Object>> doQuery(SimpleJdbcTemplate jdbc, String q, HashMap<String, Object> packed)
            throws Exception {
        try {
            return jdbc.queryForList(q, packed);
        } catch (Exception e) {
            throw failure(q, e);
        }
    }

    public List<Map<String, Object>> query(SimpleJdbcTemplate jdbc, String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doQuery(jdbc, q, packed);
    }

    public List<Map<String, Object>> query(String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doQuery(jdbc(q, packed), q, packed);
    }

    private int doUpdate(SimpleJdbcTemplate jdbc, String q, HashMap<String, Object> packed) throws Exception {
        try {
            return jdbc.update(q, packed);
        } catch (Exception e) {
            throw failure(q, e);
        }
    }

    public int update(SimpleJdbcTemplate jdbc, String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doUpdate(jdbc, q, packed);
    }

    public int update(String q, Object... param) throws Exception {
        HashMap<String, Object> packed = pack(param);

        return doUpdate(jdbc(q, packed), q, packed);
    }

    private void doExecute(SimpleJdbcTemplate jdbc, String q) throws Exception {
        try {
            jdbc.getJdbcOperations().execute(q);
        } catch (Exception e) {
            throw failure(q, e);
        }
    }

    public void execute(SimpleJdbcTemplate jdbc, String q) throws Exception {
        doExecute(jdbc, q);
    }

    public void execute(String q) throws Exception {
        doExecute(jdbc(q), q);
    }

    /**
     * Check the string for a minimum length or not all spaces,
     * otherwise set it to null
     * @param s the string to validate
     * @param minLength the minimal length required for the string
     * @return the modified string
     */
    public String validate(String s, int minLength) {
        if (s != null) {
            int len = s.length();

            if (len < minLength) {
                s = null;
            } else {
                int n;

                for (n = 0; n < len; ++n) {
                    if (s.charAt(n) != ' ') {
                        break;
                    }
                }
                if (n == len) {
                    s = null;
                }
            }
        }
        return s;
    }

    public String validate(String s) {
        return validate(s, 1);
    }

    public int asInt(Object o, int ifNull) {
        return o != null ? ((Number) o).intValue() : ifNull;
    }

    public int asInt(Object o) {
        return asInt(o, 0);
    }

    public long asLong(Object o, long ifNull) {
        return o != null ? ((Number) o).longValue() : ifNull;
    }

    public long asLong(Object o) {
        return asLong(o, 0L);
    }

    public String asString(Object o, int minLength, String ifNull) {
        String s = validate((String) o, minLength);

        return s != null ? s : ifNull;
    }

    public String asString(Object o, int minLength) {
        return asString(o, minLength, null);
    }

    public String asString(Object o, String ifNull) {
        return asString(o, 1, ifNull);
    }

    public String asString(Object o) {
        return asString(o, 1, null);
    }

    public String asClob(Object o) {
        if (o == null) {
            return null;
        } else if (o.getClass() == String.class) {
            return (String) o;
        } else {
            Clob clob = (Clob) o;

            try {
                return clob == null ? null : clob.getSubString(1, (int) clob.length());
            } catch (SQLException e) {
                failure("clob parse", e);
            }
            return null;
        }
    }

    public byte[] asBlob(Object o) {
        if (o == null) {
            return null;
        } else if (o.getClass().getName().equals("[B")) {
            return (byte[]) o;
        } else {
            Blob blob = (Blob) o;

            try {
                return blob == null ? null : blob.getBytes(1, (int) blob.length());
            } catch (SQLException e) {
                failure("blob parse", e);
            }
            return null;
        }
    }

    public Date asDate(Object o, Date ifNull) {
        return o != null ? (Date) o : ifNull;
    }

    public Date asDate(Object o) {
        return asDate(o, null);
    }

    public Timestamp asTimestamp(Object o, Timestamp ifNull) {
        return o != null ? (Timestamp) o : ifNull;
    }

    public Timestamp asTimestamp(Object o) {
        return asTimestamp(o, null);
    }
}