/*
* Created on Nov 14, 2012
*
* Copyright 2013 ATPCO Confidential and Proprietary. All Rights Reserved.
*/
package net.atpco.dds.offline.filing.common.dao;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.atpco.batch.sterotype.LogIt;
import net.atpco.common.exception.ApplicationException;
import net.atpco.dds.common.DDSLogUtil;
import net.atpco.dds.offline.filing.common.model.Entity;
import net.atpco.dds.offline.filing.common.service.DataRead;
import net.atpco.dds.offline.filing.model.SearchCriteria;
import net.atpco.dds.offline.filing.model.SortCriteria;
import org.apache.log4j.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.ScoreDoc;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
/**
*
* This class provides methods to retrieve data from lucene index files. It
* implements the DataRead interface.
*
* @author Infosys
* @version 1.0
*
*/
@Repository("dataRead")
@Scope("prototype")
public class LuceneSearchDAO extends LuceneDAO implements DataRead {
/** This LOGGER is used to log information related to LuceneSearchDAO. */
private final static Logger LOGGER = DDSLogUtil.getLogger();
/**
* A constructor with one parameter.
*
* @param indexFilePath
* - String
* */
public LuceneSearchDAO(final String indexFilePath) {
super(indexFilePath);
createReaderAndSearcher();
}
/**
* This method is used to retrieve data from lucene index file based on the
* input search criteria.
*
* @param searchCriteria
* - List<SearchCriteria>
* @return list of entity - List<Entity>
* */
@LogIt
@Override
public List<Entity> retrieveData(final List<SearchCriteria> searchCriteria) {
List<Entity> searchResult = null;
BooleanQuery query = null;
List<Document> documentList = null;
// Check reader and searcher are null or not.
createReaderAndSearcher();
/*
* Instantiate query via invoking getBooleanQuery based on search
* criteria.
*/
query = getBooleanQuery(searchCriteria);
// Retrieve the data based on the query
try {
documentList = getDocumentMatchingSearchCriteria(query);
searchResult = getDesiredObject(documentList);
} catch (final IOException e) {
throw new ApplicationException(
"Some IOException occured in method retrieveData.", LOGGER,
e);
}
return searchResult;
}
/**
* This method is used to retrieve data from lucene index file based on the
* input search criteria and sort criteria.
*
* @param searchCriteria
* - List<SearchCriteria>
* @param sortCriteria
* - List<SortCriteria>
* @return list of entity - List<Entity>
* */
@LogIt
@Override
public List<Entity> retrieveData(final List<SearchCriteria> searchCriteria,
final List<SortCriteria> sortCriteria) {
List<Entity> searchResult = null;
BooleanQuery query = null;
List<Document> documentList = null;
// Check reader and searcher are null or not.
createReaderAndSearcher();
// If sort criteria is not null and empty, then instantiate searchResult.
if (sortCriteria != null && !sortCriteria.isEmpty()) {
/*
* Instantiate query via invoking getBooleanQuery based on
* search criteria.
*/
query = getBooleanQuery(searchCriteria);
try {
documentList = getDocumentMatchingSearchCriteriaWithSorting(
query, sortCriteria);
searchResult = getDesiredObject(documentList);
} catch (final IOException e) {
throw new ApplicationException(
"Some IOException occured in method retrieveData with search criteria and sort criteria.",
LOGGER, e);
}
} else {
throw new ApplicationException(
"sortCriteria is null or empty in method retrieveData with search criteria and sort criteria.",
LOGGER);
}
return searchResult;
}
/**
* This method is used to retrieve specific data from index file
* based on the input column name.
*
* @param fieldName - String
* @return column data list - List<String>
*
* */
@LogIt
@Override
public List<String> retrieveSpecificColumnData(final List<SearchCriteria> searchCriteria, final String fieldName) {
List<String> columnValues = null;
List<Document> documentList = null;
// Check reader is null or not.
createReaderAndSearcher();
// If columnName is not null then get columnValue based on it.
if (fieldName != null) {
try {
if(searchCriteria == null || searchCriteria.isEmpty()){
documentList = getAllDocuments(fieldName);
}else{
final BooleanQuery query = getBooleanQuery(searchCriteria);
documentList = getDocumentMatchingSearchCriteria(query, fieldName);
}
columnValues = getColumnValue(documentList, fieldName);
} catch (final CorruptIndexException e) {
throw new ApplicationException(
"CorruptIndexException occured.", LOGGER, e);
} catch (final IOException e) {
throw new ApplicationException("IOException occured.", LOGGER, e);
}
} else {
throw new ApplicationException("FieldName is null or empty.", LOGGER);
}
if(columnValues == null || columnValues.isEmpty()){
throw new ApplicationException("ColumnValues is null or empty.", LOGGER);
}
return columnValues;
}
/**
* This method is used to check if the data based on the search criteria
* exists in lucene index file.
*
* @param searchCriteria
* - List<SearchCriteria>
* @return boolean value - Boolean
* */
@LogIt
@Override
public Boolean checkDataExistence(final List<SearchCriteria> searchCriteria) {
BooleanQuery query = null;
List<Document> documentList = null;
// Check reader and searcher are null or not.
createReaderAndSearcher();
/*
* Instantiate query via invoking getBooleanQuery based on search
* criteria.
*/
query = getBooleanQuery(searchCriteria);
try {
documentList = getDocumentMatchingSearchCriteria(query);
if (documentList.isEmpty()) {
LOGGER.info("List of Document is empty in method checkDataExistence.");
return Boolean.FALSE;
} else {
return Boolean.TRUE;
}
} catch (final IOException e) {
throw new ApplicationException(
"Some IOException occured in method checkIfExists.",
LOGGER, e);
}
}
/**
* This method is used to get the total count of documents based on the
* search criteria exists in lucene index file.
*
* @param searchCriteria
* - List<SearchCriteria>
* @return total count - Integer
* */
@Override
public Integer retrieveDataCount(final List<SearchCriteria> searchCriteria) {
Integer totalCount = null;
BooleanQuery query = null;
// Check reader and searcher are null or not.
createReaderAndSearcher();
/*
* Instantiate query via invoking getBooleanQuery based on search
* criteria.
*/
query = getBooleanQuery(searchCriteria);
try {
// Get the total count of documents existing in lucene index file
totalCount = getScoreDocArray(query).length;
} catch (final IOException e) {
throw new ApplicationException(
"Some IOException occured in method retrieveDataCount.",
LOGGER, e);
}
return totalCount;
}
/**
* This method is used to get the total number of count in lucene index file.
*
* @return Integer
* */
@Override
public Integer retrieveAllDataCount() {
createReaderAndSearcher();
return reader.numDocs();
}
/**
* This method is used to get the specific Entity objects based on the
* search criteria,startNumber and endNumber exists in lucene index file.
*
* @param searchCriteria
* - List<SearchCriteria>
* @param startNumber
* - int
* @param endNumber
* - int
* @return Entity list
* - List<Entity>
* */
@Override
public List<Entity> retrieveDataChunk(final List<SearchCriteria> searchCriteria,
final int startNumber, final int endNumber) {
BooleanQuery query = null;
ScoreDoc[] scoreDoc = null;
final List<Document> documentList = new ArrayList<Document>();
List<Entity> searchResult = new ArrayList<Entity>();
// Check if startNumber and endNumber are valid or not
if (startNumber < 0 || endNumber < 0 || startNumber > endNumber) {
throw new ApplicationException(
"startNumber or endNumber is negative or startNumber is greater than endNumber in method retrieveDataChunk.",
LOGGER);
}
// Check reader and searcher are null or not.
createReaderAndSearcher();
/*
* Instantiate query via invoking getBooleanQuery based on search
* criteria.
*/
query = getBooleanQuery(searchCriteria);
try {
// Get the total count of documents existing in lucene index file
scoreDoc = getScoreDocArray(query);
// Check if the length of scoreDoc greater than zero and startNumber
// and endNumber are valid
if (scoreDoc.length > 0) {
if (startNumber < scoreDoc.length
&& endNumber <= scoreDoc.length) {
// Add the document into list of document
for (int i = startNumber; i <= endNumber; i++) {
documentList.add(searcher.doc(scoreDoc[i].doc));
}
// Convert the list of document into desired objects
searchResult = getDesiredObject(documentList);
} else {
throw new ApplicationException(
"startNumber or endNumber is greater than the actual account of ducments from index file in method retrieveDataChunk.",
LOGGER);
}
}
} catch (final IOException e) {
throw new ApplicationException(
"Some IOException occured in method retrieveDataChunk.",
LOGGER, e);
}
return searchResult;
}
/**
* This method is used to get the specific Entity objects based on the
* search criteria,startNumber and endNumber exists in lucene index file.
*
* @param searchCriteria
* - List<SearchCriteria>
* @param startNumber
* - int
* @param endNumber
* - int
* @param sortCriteria
* - List<SortCriteria>
* @return Entity list
* - List<Entity>
* */
@Override
public List<Entity> retrieveDataChunk(final List<SearchCriteria> searchCriteria,
final List<SortCriteria> sortCriteria, final int startNumber, final int endNumber) {
BooleanQuery query = null;
ScoreDoc[] scoreDoc = null;
final List<Document> documentList = new ArrayList<Document>();
List<Entity> searchResult = new ArrayList<Entity>();
// Check if startNumber and endNumber are valid or not
if (startNumber < 0 || endNumber < 0 || startNumber > endNumber) {
throw new ApplicationException(
"startNumber or endNumber is negative or startNumber is greater than endNumber in method retrieveDataCount.",
LOGGER);
}
// Check reader and searcher are null or not.
createReaderAndSearcher();
// If sort criteria is not null and empty, then instantiate searchResult.
if (sortCriteria != null && !sortCriteria.isEmpty()) {
// Instantiate query via invoking getBooleanQuery based on search criteria.
query = getBooleanQuery(searchCriteria);
try {
// Get the total count of documents existing in lucene index file
scoreDoc = getScoreDocArrayWithSorting(query, sortCriteria);
// Check if the length of scoreDoc greater than zero and startNumber
// and endNumber are valid
if (scoreDoc.length > 0) {
if (startNumber < scoreDoc.length
&& endNumber <= scoreDoc.length) {
// Add the document into list of document
for (int i = startNumber; i <= endNumber; i++) {
documentList.add(searcher.doc(scoreDoc[i].doc));
}
// Convert the list of document into desired objects
searchResult = getDesiredObject(documentList);
} else {
throw new ApplicationException(
"startNumber or endNumber is greater than the actual account of ducments from index file in method retrieveDataChunk.",
LOGGER);
}
}
} catch (final IOException e) {
throw new ApplicationException(
"Some IOException occured in method retrieveDataChunk.",
LOGGER, e);
}
} else {
throw new ApplicationException(
"sortCriteria is null or empty in method retrieveDataChunk with search criteria and sort criteria.",
LOGGER);
}
return searchResult;
}
/**
* Close reader, writer and searcher
*/
@Override
public void closeDataRead() {
try {
// Close searcher if it is not null.
if (searcher != null) {
searcher.close();
}
// Close reader if it is not null.
if (reader != null) {
reader.close();
}
if(directory != null){
directory.close();
}
} catch (final IOException e) {
throw new ApplicationException("Some IOException occurs in closeDataRead.", LOGGER, e);
}
}
}