001/*
002 * Copyright 2009 The Kuali Foundation
003 * 
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 * http://www.opensource.org/licenses/ecl2.php
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.ole.sys.batch.dataaccess.impl;
017
018import java.sql.PreparedStatement;
019import java.sql.ResultSet;
020import java.sql.SQLException;
021import java.util.ArrayList;
022import java.util.HashMap;
023import java.util.List;
024import java.util.Map;
025
026import org.kuali.ole.sys.batch.dataaccess.PreparedStatementCachingDao;
027import org.kuali.rice.core.framework.persistence.jdbc.dao.PlatformAwareDaoBaseJdbc;
028
029public abstract class AbstractPreparedStatementCachingDaoJdbc extends PlatformAwareDaoBaseJdbc implements PreparedStatementCachingDao {
030    protected static final String RETRIEVE_PREFIX = "retrieve-";
031    protected static final String INSERT_PREFIX = "insert-";
032    protected static final String UPDATE_PREFIX = "update-";
033
034    protected abstract class JdbcWrapper<T> {
035        protected abstract void populateStatement(PreparedStatement preparedStatement) throws SQLException;
036
037        void update(Class<T> type, PreparedStatement preparedStatement) {
038            try {
039                populateStatement(preparedStatement);
040                preparedStatement.executeUpdate();
041            }
042            catch (SQLException e) {
043                throw new RuntimeException("AbstractUpdatingPreparedStatementCachingDaoJdbc.UpdatingJdbcWrapper encountered exception during getObject method for type: " + type, e);
044            }
045        }
046    }
047
048    protected abstract class RetrievingJdbcWrapper<T> extends JdbcWrapper {
049        protected abstract T extractResult(ResultSet resultSet) throws SQLException;
050
051        public T get(Class<T> type) {
052            T value = null;
053            PreparedStatement statement = preparedStatementCache.get(RETRIEVE_PREFIX + type);
054            try {
055                populateStatement(statement);
056                ResultSet resultSet = statement.executeQuery();
057                if (resultSet.next()) {
058                    value = extractResult(resultSet);
059                    if (resultSet.next()) {
060                        throw new RuntimeException("More that one row returned when selecting by primary key in AbstractRetrievingPreparedStatementCachingDaoJdbc.RetrievingJdbcWrapper for: " + type);
061                    }
062                }
063                resultSet.close();
064            }
065            catch (SQLException e) {
066                throw new RuntimeException("AbstractRetrievingPreparedStatementCachingDaoJdbc.RetrievingJdbcWrapper encountered exception during getObject method for type: " + type, e);
067            }
068            return (T) value;
069        }
070    }
071    
072    /**
073     * Retrieve list jdbc objects 
074     */
075    protected abstract class RetrievingListJdbcWrapper<T> extends JdbcWrapper {
076        protected abstract T extractResult(ResultSet resultSet) throws SQLException;
077
078        public List<T> get(Class<T> type) {
079            List<T> resultList = new ArrayList<T>();
080            PreparedStatement statement = preparedStatementCache.get(RETRIEVE_PREFIX + type);
081            try {
082                populateStatement(statement);
083                ResultSet resultSet = statement.executeQuery();
084                while (resultSet.next()) {
085                    resultList.add(extractResult(resultSet));
086                }
087                resultSet.close();
088            }
089            catch (SQLException e) {
090                throw new RuntimeException("AbstractRetrievingPreparedStatementCachingDaoJdbc.RetrievingListJdbcWrapper encountered exception during getObject method for type: " + type, e);
091            }
092            return resultList;
093        }
094    }
095
096    protected abstract class InsertingJdbcWrapper<T> extends JdbcWrapper {
097        public void execute(Class<T> type) {
098            update(type, preparedStatementCache.get(INSERT_PREFIX + type));
099        }
100    }
101
102    protected abstract class UpdatingJdbcWrapper<T> extends JdbcWrapper {
103        public void execute(Class<T> type) {
104            update(type, preparedStatementCache.get(UPDATE_PREFIX + type));
105        }
106    }
107
108    protected Map<String, PreparedStatement> preparedStatementCache;
109
110    protected abstract Map<String, String> getSql();
111
112    public void initialize() {
113        preparedStatementCache = new HashMap<String, PreparedStatement>();
114        try {
115            for (String statementKey : getSql().keySet()) {
116                preparedStatementCache.put(statementKey, getConnection().prepareStatement(getSql().get(statementKey)));
117            }
118        }
119        catch (SQLException e) {
120            throw new RuntimeException("Caught exception preparing statements in CachingDaoJdbc initialize method", e);
121        }
122    }
123
124    public void destroy() {
125        try {
126            for (PreparedStatement preparedStatement : preparedStatementCache.values()) {
127                preparedStatement.close();
128            }
129            preparedStatementCache = null;
130        }
131        catch (SQLException e) {
132            throw new RuntimeException("Caught exception closing statements in CachingDaoJdbc destroy method", e);
133        }
134    }
135
136}