LuceneDataWriteDAO

/*
 * Created on Nov 15, 2012
 *
 * Copyright 2013 ATPCO Confidential and Proprietary. All Rights Reserved.
 */
package net.atpco.dds.offline.filing.common.dao;

import java.io.File;
import java.io.IOException;
import java.util.List;

import net.atpco.common.exception.ApplicationException;
import net.atpco.common.util.StringUtil;
import net.atpco.dds.common.DDSLogUtil;
import net.atpco.dds.offline.filing.common.exception.ObjectNotFoundException;
import net.atpco.dds.offline.filing.common.exception.TooManyObjectFoundException;
import net.atpco.dds.offline.filing.common.model.Entity;
import net.atpco.dds.offline.filing.common.service.DataWrite;
import net.atpco.dds.offline.filing.common.util.LuceneUtility;
import net.atpco.dds.offline.filing.model.SearchCriteria;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.SimpleAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexCommit;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.KeepOnlyLastCommitDeletionPolicy;
import org.apache.lucene.index.PersistentSnapshotDeletionPolicy;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;

/**
 *
 * This class provides methods to write data into lucene index files. It
 * implements the DataWrite interface.
 *
 * @author Infosys
 * @version 1.0
 *
 */
@Repository("dataWrite")
@Scope("prototype")
public class LuceneDataWriteDAO extends LuceneDAO implements DataWrite {

 /** This LOGGER is used to log information related to LuceneDataWriteDAO. */
 private static final Logger LOGGER = DDSLogUtil.getLogger();

 /** Variable to instantiate lucene based on memory or document.**/
 private transient boolean memoryBase = true;
 
 /**
  * A constructor with one parameter.
  *
  * @param indexFilePath - String
  * */
 public LuceneDataWriteDAO(final String indexFilePath) {
  super(indexFilePath);
  createWriter(indexFilePath, true);
 }

 /**
  * A constructor with two parameters.
  *
  * @param indexFilePath - String
  * @param isBackupRequired - boolean
  * */
 public LuceneDataWriteDAO(final String indexFilePath, final boolean isBackupRequired) {
  super(indexFilePath);
  createWriter(indexFilePath, isBackupRequired);
 }

 /**
  * A constructor with two parameters.
  *
  * @param indexFilePath - String
  * @param isBackupRequired - boolean
  * */
 public LuceneDataWriteDAO(final String indexFilePath, final boolean isBackupRequired, final boolean memoryBase) {
  super(indexFilePath);
  this.memoryBase = memoryBase;
  createWriter(indexFilePath, isBackupRequired);
 }
 /**
  * This method is used to write object to lucene index file.
  *
  * @param objectToStore
  *            - Entity
  * */
 @Override
 public void writeData(final Entity objectToStore) {
  // writer and objectToStore are not null then add document into writer.
  if (writer != null && objectToStore != null) {
   // populate document matched with objectToStore
   final Document document = createDocument(objectToStore);
   try {
    writer.addDocument(document);
   } catch (final CorruptIndexException e) {
    throw new ApplicationException(
      "CorruptIndexException in method writeData", LOGGER, e);
   } catch (final IOException e) {
    throw new ApplicationException(
      "IOException in method writeData", LOGGER, e);
   }
  } else if (writer == null) {
   throw new ApplicationException(
     "writer is null in method writeData.", LOGGER);
  } else {
   throw new ApplicationException(
     "objectToStore is null in method writeData.", LOGGER);
  }
 }

 /**
  * This method is used to close reader,searcher, writer and snapshotter.
  * */
 @Override
 public void closeDataWrite() {
  try {
   // Close searcher if it is not null.
   if (searcher != null) {
    searcher.close();
   }

   // Close writer if it is not null.
   if(writer != null){
    writer.commit();
    writer.close();
   }

   // Close reader if it is not null.
   if (reader != null) {
    reader.close();
   }
   
   // Close the directory handler
   if(directory != null){
    directory.close();
   }
  } catch (final IOException e) {
   throw new ApplicationException("Some IOException occurs in closeDataWrite.", LOGGER, e);
  }

  try {
   if (snapshotter != null) {
    snapshotter.close();
   }
   
   // Close the snapShotDir directory handler
   if(snapShotDir != null){
    snapShotDir.close();
   }
  } catch (final IOException e) {
   throw new ApplicationException(
     "Exception occured while closing the snapshotter.", LOGGER,
     e);
  }
 }

 /**
  * This method is used to update the object in lucene schema. Lucene does
  * not support the update option with the 'Query', So have to delete the
  * existing data and create the new document.
  *
  * @param searchCriteria - List<SearchCriteria>
  * @param objectToStore - Entity
  * @throws TooManyObjectFoundException
  * @throws ObjectNotFoundException
  */
 @Override
 public void updateData(final List<SearchCriteria> searchCriteria, final Entity objectToStore) throws ObjectNotFoundException, TooManyObjectFoundException {
  // delete the some specific document as per searchCriteria from index file
  deleteData(searchCriteria);
  // write the newly objectToStore into index file
  writeData(objectToStore);
 }
 
 /**
  * This method is used to delete the object from lucene schema.
  *
  * @param searchCriterias - List<SearchCriteria>
  * @throws ObjectNotFoundException
  * @throws TooManyObjectFoundException
  */
 private void deleteData(final List<SearchCriteria> searchCriterias) throws ObjectNotFoundException, TooManyObjectFoundException {
  BooleanQuery bQuery = null;
  try {
   // Check reader and searcher are null or not.
   createReaderAndSearcher();
   // Form the query
   bQuery = getExpressBooleanQuery(searchCriterias);
   writer.deleteDocuments(bQuery);
   
//   // Before deletion, check whether record exist for the filter criteria
//   final TopDocs topDocs = searcher.search(bQuery, LuceneConstants.LUCENE_SEARCH_MAX);
//   
//   //If the length of topDocs is zero then throw object not found exception
//   if (topDocs.scoreDocs.length == 0) {
//    throw new ObjectNotFoundException("No matching record was  found in method deleteData");
//   }else if(topDocs.scoreDocs.length > 1){
//    //If the length of topDocs is greater than one then throw too many object found exception
//    throw new TooManyObjectFoundException("More than one record was found in method deleteData");
//   }else {
//    writer.deleteDocuments(bQuery);
//   }
   
  } catch (final IOException e) {
   throw new ApplicationException("Some IOException occured in method deleteData.", LOGGER, e);
  }
 }

 /**
  * Take a snapshot of current data. The backup data will be uniquely
  * identified using the snapshotname
  *
  * @param backupName
  */
 @Override
 public void backup(final String backupName) throws ApplicationException {
  if (backupName == null || StringUtil.isEmpty(backupName)) {
   throw new ApplicationException("Backup name is null or empty", LOGGER);
  }
  try {
   writer.commit();
   snapshotter.snapshot(backupName);
  } catch (final IOException e) {
   throw new ApplicationException(
     "IO Exception occurred while taking backup for the snapshot "
       + backupName, LOGGER, e);
  } catch (final Exception ex) {
   throw new ApplicationException(
     "Exception occurred while doing restore for the snapshot ", LOGGER, ex);
  } finally {
   closeDataWrite();
   LuceneUtility.close(snapShotDir);
  }
 }

 /**
  * Restore the data from the backup to original index file
  *
  * @param backupName
  */
 @Override
 public void restore(final String backupName) throws ApplicationException {
  IndexReader reader = null;
  if (backupName == null && StringUtil.isEmpty(backupName)) {
   throw new ApplicationException("Backup name is null or empty", LOGGER);
  }
  try {
   // Get the commit point reference for the snapshot
   final IndexCommit commit = snapshotter.getSnapshot(backupName);

   // Read the data
   reader = IndexReader.open(commit);

   // Delete the current index file from the source schema
   writer.deleteAll();

   // Restore the data from commit point reference to the original
   // index files
   writer.addIndexes(reader);

   // Commit the data
   writer.commit();
  } catch (final IOException e) {
   throw new ApplicationException(
     "IO Exception occurred while doing restore for the snapshot "
       + backupName, LOGGER, e);
  } catch (final Exception ex) {
   throw new ApplicationException(
     "Exception occurred while doing restore for the snapshot "
       + backupName, LOGGER, ex);
  } finally {
   closeDataWrite();
   LuceneUtility.close(snapShotDir);
   LuceneUtility.close(directory);
   LuceneUtility.close(reader);
  }
 }

 /**
  * Check if the backup exists already
  * @param snapshotName
  */
 @Override
 public boolean isBackupExist(final String snapshotName) throws ApplicationException {
  boolean hasBackup;
  if(snapshotter!=null && snapshotter.isSnapshotted(snapshotName)) {
   hasBackup = true;
  } else {
   hasBackup = false;
  }
  return hasBackup;
 }

 private void createWriter(final String indexFilePath, final boolean isBackupRequired) {
  if (indexFilePath == null) {
   throw new ApplicationException("Index Path shouldn't be null.", LOGGER);
  }

  try {
   this.indexFilePath = indexFilePath;
   final File indexFile = new File(indexFilePath);

   // Open the indexFile which is used to write data.
   directory = FSDirectory.open(indexFile);

   // Define the configuration for this writer.
   final IndexWriterConfig indexWriterConfig = new IndexWriterConfig(
     Version.LUCENE_36, new SimpleAnalyzer(Version.LUCENE_36));

   // Set the write mode of writer to CREATE_OR_APPEND.
   indexWriterConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
   
   // Fix GI-1543 Start at 08 Apr, 2014
   if(memoryBase){
    // Set the RAM Buffer size, the default value is 16MB
    indexWriterConfig.setRAMBufferSizeMB(48.0);
    LOGGER.debug("Memory based Lucene write");
   }else{
    // Set the Buffered document
    indexWriterConfig.setMaxBufferedDeleteTerms(50);
    indexWriterConfig.setMaxBufferedDocs(50);
    LOGGER.debug("Term based Lucene write");
   }
   // Fix GI-1543 End
   
   // Generate the backup path based on the schema path
   if (isBackupRequired) {
    final String backupFile = LuceneUtility.generateBackupPath(indexFilePath);
    if (backupFile != null) {
     final File bFile = new File(backupFile);
     snapShotDir = FSDirectory.open(bFile);
     snapshotter = new PersistentSnapshotDeletionPolicy(
       new KeepOnlyLastCommitDeletionPolicy(),
       snapShotDir, OpenMode.CREATE_OR_APPEND,
       Version.LUCENE_36);
     // Set the snapshot policy
     indexWriterConfig.setIndexDeletionPolicy(snapshotter);
    } else {
     LOGGER.warn("User Requested to take backup but the file location did not match");
    }
   }

   // Make an instance of writer with the pre-defiend configuration.
   writer = new IndexWriter(directory, indexWriterConfig);
  } catch (final Exception e) {
   throw new ApplicationException(
     "Some IOException occured in method createWriter.", LOGGER,
     e);
  }
 }
}

你可能感兴趣的:(DAO,write,LuceneData)