org.sakaiproject.search.index.impl.FSIndexStorage.java Source code

Java tutorial

Introduction

Here is the source code for org.sakaiproject.search.index.impl.FSIndexStorage.java

Source

/**********************************************************************************
 * $URL: https://source.sakaiproject.org/svn/search/trunk/search-impl/impl/src/java/org/sakaiproject/search/index/impl/FSIndexStorage.java $
 * $Id: FSIndexStorage.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.index.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.sakaiproject.search.api.SearchService;

/**
 * A local only filestore implementation. This is a simple IndexImplementation
 * that performs all its indexing in a single, unoptimized segment on the local
 * filesystem To set the location use
 * location@org.sakaiproject.search.api.SearchService.LocalIndexStorage in
 * sakai.properties Check that the bean name is correct in the spring
 * components.xml file
 * 
 * @author ieb
 */
public class FSIndexStorage extends BaseIndexStorage {
    private static Log log = LogFactory.getLog(FSIndexStorage.class);

    protected String searchIndexDirectory = "searchindex";

    protected boolean recoverCorruptedIndex = false;

    private long lastUpdate = System.currentTimeMillis();

    public void init() {

    }

    public void doPreIndexUpdate() throws IOException {
        log.debug("Starting process List on " + searchIndexDirectory);
        File f = new File(searchIndexDirectory);
        if (!f.exists()) {
            if (!f.mkdirs()) {
                log.warn("doPreIndexUpdate() couldn't delete " + f.getPath());
            }
            log.debug("Indexing in " + f.getAbsolutePath());
        }

        if (IndexWriter.isLocked(FSDirectory.open(f))) {
            // this could be dangerous, I am assuming that
            // the locking mechanism implemented here is
            // robust and
            // already prevents multiple modifiers.
            // A more

            IndexWriter.unlock(FSDirectory.open(f));
            log.warn("Unlocked Lucene Directory for update, hope this is Ok");
        }
    }

    public IndexReader getIndexReader() throws IOException {
        File f = new File(searchIndexDirectory);
        return IndexReader.open(FSDirectory.open(f), true);
    }

    public IndexWriter getIndexWriter(boolean create) throws IOException {
        File f = new File(searchIndexDirectory);
        return new IndexWriter(FSDirectory.open(f), getAnalyzer(), create, IndexWriter.MaxFieldLength.UNLIMITED);
    }

    public void doPostIndexUpdate() throws IOException {
        lastUpdate = System.currentTimeMillis();

    }

    /**
     * @return Returns the searchIndexDirectory.
     */
    public String getSearchIndexDirectory() {
        return searchIndexDirectory;
    }

    protected IndexSearcher getIndexSearcher() throws IOException {
        IndexSearcher indexSearcher = null;
        try {
            long reloadStart = System.currentTimeMillis();
            File indexDirectoryFile = new File(searchIndexDirectory);
            if (!indexDirectoryFile.exists()) {
                if (!indexDirectoryFile.mkdirs()) {
                    log.warn("getIdexSearch couldn't create directory " + indexDirectoryFile.getPath());
                }
            }

            File f = new File(searchIndexDirectory);
            indexSearcher = new IndexSearcher(FSDirectory.open(f), false);
            if (indexSearcher == null) {
                log.warn("No search Index exists at this time");

            }
            long reloadEnd = System.currentTimeMillis();
            if (diagnostics) {
                log.info("Reload Complete " + indexSearcher.getIndexReader().numDocs() + " in "
                        + (reloadEnd - reloadStart));
            }

        } catch (FileNotFoundException e) {
            log.error("There has been a major poblem with the" + " Search Index which has become corrupted ", e);
            if (doIndexRecovery()) {
                File f = new File(searchIndexDirectory);
                indexSearcher = new IndexSearcher(FSDirectory.open(f), false);
            }
        } catch (IOException e) {
            log.error("There has been a major poblem with the " + "Search Index which has become corrupted", e);
            if (doIndexRecovery()) {
                Directory dir = FSDirectory.open(new File(searchIndexDirectory));
                indexSearcher = new IndexSearcher(dir, false);
            }
        }
        return indexSearcher;
    }

    protected boolean doIndexRecovery() throws IOException {
        if (recoverCorruptedIndex) {
            IndexWriter iw = getIndexWriter(true);
            Document doc = new Document();
            String message = "Index Recovery performed on " + (new Date()).toString();
            doc.add(new Field(SearchService.FIELD_CONTENTS, message, Field.Store.NO, Field.Index.ANALYZED));
            iw.addDocument(doc);
            iw.close();
            log.error("Sucess fully recoverd From a corrupted index, " + "the index will be empty and require a "
                    + "complete rebuild");
            return true;
        }
        return false;
    }

    public boolean indexExists() {
        Directory dir;
        try {
            dir = FSDirectory.open(new File(searchIndexDirectory));
            return IndexReader.indexExists(dir);
        } catch (IOException e) {
            return false;
        }

    }

    /**
     * @return Returns the recoverCorruptedIndex.
     */
    public boolean isRecoverCorruptedIndex() {
        return recoverCorruptedIndex;
    }

    /**
     * @param recoverCorruptedIndex
     *        The recoverCorruptedIndex to set.
     */
    public void setRecoverCorruptedIndex(boolean recoverCorruptedIndex) {
        log.info("Using FSIndexStorage, storing the index " + "on the local file system in " + searchIndexDirectory
                + " if the index is corrupted recovery will " + (recoverCorruptedIndex ? "" : "NOT ")
                + " be automatic");
        this.recoverCorruptedIndex = recoverCorruptedIndex;
    }

    public void setLocation(String location) {
        searchIndexDirectory = location;

    }

    public long getLastUpdate() {
        // not really relevant in the non cluster environment
        return lastUpdate;
    }

    public List getSegmentInfoList() {
        List<Object[]> l = new ArrayList<Object[]>();
        l.add(new Object[] { "Index Segment Info is not implemented for Local file system index stores", "", "" });
        return l;
    }

    public void closeIndexReader(IndexReader indexReader) throws IOException {
        if (indexReader != null) {
            indexReader.close();
        }
    }

    public void closeIndexWriter(IndexWriter indexWrite) throws IOException {
        if (indexWrite != null) {
            indexWrite.close();
        }

    }

    public boolean isMultipleIndexers() {
        return false;
    }

    public void closeIndexSearcher(IndexSearcher indexSearcher) {
        IndexReader indexReader = indexSearcher.getIndexReader();
        boolean closedAlready = false;
        try {
            if (indexReader != null) {
                indexReader.close();
                closedAlready = true;
            }
        } catch (Exception ex) {
            log.error("Failed to close Index Reader " + ex.getMessage());
        }
        try {
            indexSearcher.close();
        } catch (Exception ex) {
            if (closedAlready) {
                log.debug("Failed to close Index Searcher " + ex.getMessage());
            } else {
                log.error("Failed to close Index Searcher " + ex.getMessage());
            }

        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.sakaiproject.search.index.IndexStorage#centralIndexExists()
     */
    public boolean centralIndexExists() {
        return indexExists();
    }

    private Directory spellDirectory = null;

    public Directory getSpellDirectory() {
        return spellDirectory;
    }

}