org.sakaiproject.search.indexer.impl.test.TDataSource.java Source code

Java tutorial

Introduction

Here is the source code for org.sakaiproject.search.indexer.impl.test.TDataSource.java

Source

/**********************************************************************************
 * $URL: https://source.sakaiproject.org/svn/search/trunk/search-impl/impl/src/test/org/sakaiproject/search/indexer/impl/test/TDataSource.java $
 * $Id: TDataSource.java 105078 2012-02-24 23:00:38Z ottenhoff@longsight.com $
 ***********************************************************************************
 *
 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 The Sakai Foundation
 *
 * Licensed under the Educational Community 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.opensource.org/licenses/ECL-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.sakaiproject.search.indexer.impl.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.dbcp.cpdsadapter.DriverAdapterCPDS;
import org.apache.commons.dbcp.datasources.SharedPoolDataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.document.CompressionTools;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.sakaiproject.search.api.SearchService;
import org.sakaiproject.search.jdbc.WrappingConnection;
import org.sakaiproject.search.jdbc.WrappingDataSource;
import org.sakaiproject.search.model.SearchBuilderItem;
import org.sakaiproject.search.model.impl.SearchBuilderItemImpl;

/**
 * @author ieb
 */
public class TDataSource {
    private static final Log log = LogFactory.getLog(TDataSource.class);

    private SharedPoolDataSource tds;

    private DataSource wds;

    protected int nopen = 0;

    private DriverAdapterCPDS cpds;

    public TDataSource(int poolSize, final boolean logging) throws Exception {
        super();

        cpds = new DriverAdapterCPDS();
        /*
         * try { // can we test against mysql
         * Class.forName("com.mysql.jdbc.Driver");
         * cpds.setDriver("com.mysql.jdbc.Driver"); cpds
         * .setUrl("jdbc:mysql://127.0.0.1:3306/sakai22?useUnicode=true&characterEncoding=UTF-8");
         * cpds.setUser("sakai22"); cpds.setPassword("sakai22"); } catch
         * (ClassNotFoundException cnfe) { }
         */
        // we need to use derby db because HSQL only has read_uncommitted
        // transaction
        // isolation

        log.info("Using Derby DB");
        cpds.setDriver("org.apache.derby.jdbc.EmbeddedDriver");
        cpds.setUrl("jdbc:derby:target/testdb;create=true");
        cpds.setUser("sa");
        cpds.setPassword("manager");

        tds = new SharedPoolDataSource();
        tds.setConnectionPoolDataSource(cpds);
        tds.setMaxActive(poolSize);
        tds.setMaxWait(5);
        tds.setDefaultAutoCommit(false);

        wds = new WrappingDataSource(tds) {

            public Connection getConnection() throws SQLException {
                final Connection c = super.getConnection();
                nopen++;
                if (logging)
                    log.info("+++++++++++Opened " + nopen);
                Exception ex = new Exception();
                StackTraceElement[] ste = ex.getStackTrace();
                log.debug("Stack Trace " + ste[1].toString());
                return new WrappingConnection(c) {

                    public void close() throws SQLException {
                        c.close();
                        nopen--;
                        if (logging)
                            log.info("--------------Closed " + nopen);
                    }

                };
            }

        };

        Connection connection = tds.getConnection();
        Statement s = connection.createStatement();
        try {
            s.execute("DROP TABLE search_transaction");
        } catch (Exception ex) {
            log.warn("Drop Table Said :" + ex.getMessage());
        }
        try {
            s.execute("create table search_transaction ( txname varchar(36), txid bigint )");
        } catch (Exception ex) {
            log.warn("Create Table Said :" + ex.getMessage());
        }
        try {
            s.execute("DROP TABLE searchbuilderitem");
        } catch (Exception ex) {
            log.warn("Drop Table Said :" + ex.getMessage());
        }
        try {
            s.execute("CREATE TABLE searchbuilderitem ( \n" + " id varchar(64) NOT NULL, \n"
                    + " version timestamp NOT NULL, \n" + " name varchar(255) NOT NULL, \n"
                    + " context varchar(255) NOT NULL, \n" + " searchaction int default NULL, \n"
                    + " searchstate int default NULL, \n" + " itemscope int default NULL, \n"
                    + " PRIMARY KEY  (id), \n" + " UNIQUE (name) \n" + ")");
        } catch (Exception ex) {
            log.warn("Create Table Said :" + ex.getMessage());
        }
        try {
            s.execute("DROP TABLE search_journal");
        } catch (Exception ex) {
            log.warn("Drop Table Said :" + ex.getMessage());
        }
        try {
            s.execute("CREATE TABLE search_journal ( " + " txid bigint NOT NULL, "
                    + " txts bigint NOT NULL, indexwriter varchar(255) NOT NULL, status varchar(36) NOT NULL, "
                    + " PRIMARY KEY  (txid) )");
        } catch (Exception ex) {
            log.warn("Create Table Said :" + ex.getMessage());
        }

        try {
            s.execute("DROP TABLE search_node_status");
        } catch (Exception ex) {
            log.warn("Drop Table Said :" + ex.getMessage());
        }
        try {
            s.execute("CREATE TABLE search_node_status ( " + " jid bigint NOT NULL, " + " jidts bigint NOT NULL, "
                    + " serverid varchar(255) NOT NULL, " + " PRIMARY KEY  (serverid) )");
        } catch (Exception ex) {
            log.warn("Create Table Said :" + ex.getMessage());
        }
        s.close();
        connection.commit();
        connection.close();
    }

    /**
     * @return
     */
    public DataSource getDataSource() {
        return wds;

    }

    /**
     * @throws Exception
     */
    public void close() throws Exception {
        tds.close();

    }

    public List<SearchBuilderItem> populateDocuments(long targetItems, String prefix) throws SQLException {
        int nitems = 0;

        Connection connection = null;
        PreparedStatement insertPST = null;
        List<SearchBuilderItem> items = new ArrayList<SearchBuilderItem>();
        try {
            connection = getDataSource().getConnection();
            insertPST = connection.prepareStatement("insert into searchbuilderitem "
                    + "(id,version,name,context,searchaction,searchstate,itemscope) values " + "(?,?,?,?,?,?,?)");
            for (int i = 0; i < targetItems; i++) {
                int state = i % SearchBuilderItem.states.length;
                String name = SearchBuilderItem.states[state];
                int action = i % 3;
                if (state == SearchBuilderItem.STATE_PENDING && action == SearchBuilderItem.ACTION_ADD) {
                    nitems++;
                }
                SearchBuilderItemImpl sbi = new SearchBuilderItemImpl();
                sbi.setContext("/" + name + prefix + "/at/a");
                sbi.setName("/" + name + prefix + "/at/a/location/" + i);
                sbi.setVersion(new Date(System.currentTimeMillis()));
                sbi.setId(String.valueOf(System.currentTimeMillis()) + String.valueOf(i));
                sbi.setItemscope(SearchBuilderItem.ITEM);
                sbi.setSearchaction(action);
                sbi.setSearchstate(state);

                insertPST.clearParameters();
                insertPST.setString(1, sbi.getId());
                insertPST.setTimestamp(2, new Timestamp(sbi.getVersion().getTime()));
                insertPST.setString(3, sbi.getName());
                insertPST.setString(4, sbi.getContext());
                insertPST.setInt(5, sbi.getSearchaction());
                insertPST.setInt(6, sbi.getSearchstate());
                insertPST.setInt(7, sbi.getItemscope());
                insertPST.execute();

                items.add(sbi);
            }
            connection.commit();
        } finally {
            try {
                insertPST.close();
            } catch (Exception ex2) {
                log.debug(ex2);
            }
            try {
                connection.close();
            } catch (Exception ex2) {
                log.debug(ex2);
            }
        }
        return items;

    }

    /**
     * @param items
     * @param indexSearcher
     * @return
     */
    public int checkIndexContents(List<SearchBuilderItem> items, IndexSearcher indexSearcher) {
        int errors = 0;
        try {
            Map<String, SearchBuilderItem> finalState = new HashMap<String, SearchBuilderItem>();

            for (SearchBuilderItem sbi : items) {
                if (sbi.getSearchstate().equals(SearchBuilderItem.STATE_PENDING)) {
                    finalState.put(sbi.getId(), sbi);
                }
            }
            for (SearchBuilderItem sbi : finalState.values()) {
                TermQuery tq = new TermQuery(new Term(SearchService.FIELD_REFERENCE, sbi.getName()));

                TopDocs topDocs = indexSearcher.search(tq, 1000000);
                if (sbi.getSearchaction().equals(SearchBuilderItem.ACTION_ADD)) {
                    log.info("====== ADD CHECKING =====");
                    if (topDocs.totalHits != 1) {
                        log.error("Didnt find " + sbi.getName() + " got " + topDocs.totalHits);
                        errors++;
                    } else {
                        Document doc = indexSearcher.doc(topDocs.scoreDocs[0].doc);
                        byte[] binValue = doc.getBinaryValue(SearchService.FIELD_REFERENCE);
                        String value = null;
                        if (binValue == null) {
                            log.warn("Binary Value not found!");
                            value = doc.get(SearchService.FIELD_REFERENCE);
                        } else {
                            value = CompressionTools.decompressString(binValue);
                        }

                        if (!sbi.getName().equals(value)) {
                            log.error("Ids Dont Match " + sbi.getName() + ":" + value);
                            errors++;
                        } else {
                            log.debug("Ok " + sbi.getName());
                        }
                    }
                } else {
                    log.info("====== DELETE CHECKING =====");
                    if (topDocs.totalHits != 0) {
                        Document doc = indexSearcher.doc(0);
                        String value = CompressionTools
                                .decompressString(doc.getBinaryValue(SearchService.FIELD_REFERENCE));
                        log.error("Found " + sbi.getName() + " when should have not  " + value + " "
                                + SearchBuilderItem.actions[sbi.getSearchaction()] + " "
                                + (sbi.isLocked() ? "Locked to " + sbi.getLock()
                                        : SearchBuilderItem.states[sbi.getSearchstate()])
                                + "");
                        errors++;
                    } else {
                        log.debug("Ok " + sbi.getName());
                    }

                }

            }
            return errors;
        } catch (Exception ex) {
            log.error("Searching Exception ", ex);
            return -1;
        }
    }

    /**
     * @param items
     * @return
     * @throws SQLException 
     */
    public List<SearchBuilderItem> deleteSomeItems(List<SearchBuilderItem> items) throws SQLException {
        int nitems = 0;

        Connection connection = null;
        PreparedStatement updatePST = null;
        try {
            connection = getDataSource().getConnection();
            updatePST = connection.prepareStatement(
                    "update searchbuilderitem  set searchaction = ?, searchstate = ? where id = ?");
            int i = 0;
            for (SearchBuilderItem sbi : items) {
                if (sbi.getSearchaction().equals(SearchBuilderItem.ACTION_ADD)) {
                    i++;
                    if (i % 3 == 0) {
                        sbi.setSearchaction(SearchBuilderItem.ACTION_DELETE);
                        sbi.setSearchstate(SearchBuilderItem.STATE_PENDING);
                        updatePST.clearParameters();
                        updatePST.setInt(1, sbi.getSearchaction());
                        updatePST.setInt(2, sbi.getSearchstate());
                        updatePST.setString(3, sbi.getId());
                        if (updatePST.executeUpdate() != 1) {
                            throw new SQLException("Failed to update for delete " + sbi.getId());
                        }
                        log.info("Marked " + sbi.getName() + " for deletion ");
                    }
                }
            }
            connection.commit();
        } finally {
            try {
                updatePST.close();
            } catch (Exception ex2) {
                log.debug(ex2);
            }
            try {
                connection.close();
            } catch (Exception ex2) {
                log.debug(ex2);
            }
        }
        return items;
    }

}