com.bluedragon.search.collection.Collection.java Source code

Java tutorial

Introduction

Here is the source code for com.bluedragon.search.collection.Collection.java

Source

/* 
 *  Copyright (C) 2000 - 2013 TagServlet Ltd
 *
 *  This file is part of Open BlueDragon (OpenBD) CFML Server Engine.
 *  
 *  OpenBD is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  Free Software Foundation,version 3.
 *  
 *  OpenBD is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with OpenBD.  If not, see http://www.gnu.org/licenses/
 *  
 *  Additional permission under GNU GPL version 3 section 7
 *  
 *  If you modify this Program, or any covered work, by linking or combining 
 *  it with any of the JARS listed in the README.txt (or a modified version of 
 *  (that library), containing parts covered by the terms of that JAR, the 
 *  licensors of this Program grant you additional permission to convey the 
 *  resulting work. 
 *  README.txt @ http://openbd.org/license/README.txt
 *  
 *  http://openbd.org/
 *  
 *  $Id: Collection.java 2523 2015-02-22 16:23:11Z alan $
 */

package com.bluedragon.search.collection;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.nio.file.FileSystems;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.NIOFSDirectory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Constants;

import com.bluedragon.search.AnalyzerFactory;
import com.bluedragon.search.DocumentWrap;
import com.bluedragon.search.index.DocumentWriter;
import com.nary.io.FileUtils;

public class Collection extends Object {

    private String name;
    private long created;
    private boolean bStoreBody;
    private String language, collectionpath;

    // Lucene specific variables
    private Directory directory = null;
    private IndexSearcher indexsearcher = null;
    private IndexWriter indexwriter = null;
    private int totalDocs = -1;
    private DocumentWriter documentwriter = null;
    private long lastUsed = System.currentTimeMillis();

    public String toString() {
        return "[Collection name=" + name + "; path=" + collectionpath + "]";
    }

    public long getTimeSinceLastUsed() {
        return System.currentTimeMillis() - lastUsed;
    }

    public void setName(String string) throws Exception {
        this.name = string;

        if (this.name == null || this.name.length() == 0)
            throw new Exception("invalid collection name");
    }

    public void setLanguage(String string) {
        this.language = string;
    }

    public String getLanguage() {
        return this.language;
    }

    public void setStoreBody(boolean boolean1) {
        bStoreBody = boolean1;
    }

    public boolean bStoreBody() {
        return bStoreBody;
    }

    public String getName() {
        return name;
    }

    public long getLastModified() {
        return lastUsed;
    }

    public long getCreated() {
        return created;
    }

    public String getPath() {
        return collectionpath;
    }

    public void setDirectory(String path) throws Exception {
        File filePath;
        if (!path.endsWith(name))
            filePath = new File(path, name);
        else
            filePath = new File(path);

        if (!filePath.exists() || !filePath.isDirectory())
            throw new Exception("invalid collection path: " + path);

        collectionpath = filePath.getCanonicalPath();
    }

    public void close() {
        closeReader();

        if (indexwriter != null) {
            try {
                indexwriter.close();
            } catch (IOException e) {
            }
            indexwriter = null;
        }
    }

    public void closeReader() {
        if (indexsearcher != null) {
            try {
                indexsearcher.getIndexReader().close();
            } catch (IOException ignoreThisException) {
            }
            indexsearcher = null;
        }
    }

    /**
     * Retrieves the IndexSearcher object.  This object is cached against this collection and is intended
     * to be used amongst several threads.   This is the recommended approach.
     * 
     * If new content is added to this collection then it won't be available for searching until a new
     * indexsearcher is created
     * 
     * @return
     * @throws CorruptIndexException
     * @throws IOException
     */
    public synchronized IndexSearcher getIndexSearcher() throws CorruptIndexException, IOException {
        lastUsed = System.currentTimeMillis();

        if (indexsearcher != null)
            return indexsearcher;

        setDirectory();
        indexsearcher = new IndexSearcher(DirectoryReader.open(directory));

        totalDocs = indexsearcher.getIndexReader().numDocs();

        return indexsearcher;
    }

    public int getTotalDocs() {
        return totalDocs;
    }

    public int size() {
        int size = 0;
        try {
            setDirectory();

            String[] files = directory.listAll();
            for (int i = 0; i < files.length; i++) {
                try {
                    size += directory.fileLength(files[i]);
                } catch (IOException e) {
                }
            }
        } catch (IOException e1) {
        }

        return size;
    }

    private void setDirectory() throws IOException {
        if (directory != null)
            return;

        if (Constants.WINDOWS) {
            directory = new SimpleFSDirectory(FileSystems.getDefault().getPath(collectionpath));
        } else {
            directory = new NIOFSDirectory(FileSystems.getDefault().getPath(collectionpath));
        }

        File touchFile = new File(collectionpath, "openbd.created");
        if (touchFile.exists())
            created = touchFile.lastModified();
        else
            created = System.currentTimeMillis();
    }

    /**
     * Creates an empty collection to get it up and running
     */
    public synchronized void create(boolean _errorOnExists) throws IOException {
        setDirectory();

        if (directory.listAll().length > 2) {
            if (_errorOnExists) {
                throw new IOException("directory not empty; possible collection already present");
            } else {
                if (DirectoryReader.indexExists(directory)) {
                    return;
                } // otherwise an index doesn't exist so allow the creation code to execute
            }
        }

        IndexWriterConfig iwc = new IndexWriterConfig(AnalyzerFactory.get(language));
        iwc.setOpenMode(OpenMode.CREATE);

        indexwriter = new IndexWriter(directory, iwc);
        indexwriter.commit();
        indexwriter.close();
        indexwriter = null;

        // throw an openbd.create file in there so we know when it was created
        created = System.currentTimeMillis();
        File touchFile = new File(collectionpath, "openbd.created");
        Writer fw = new FileWriter(touchFile);
        fw.close();
    }

    /**
     * Deletes this collection, removing all files
     * @throws IOException 
     */
    public synchronized void delete() throws IOException {
        close();

        // delete the file
        File f = new File(collectionpath);
        if (f.exists() && f.isDirectory())
            FileUtils.recursiveDelete(f, true);
    }

    public synchronized DocumentWriter getDocumentWriter()
            throws CorruptIndexException, LockObtainFailedException, IOException {
        if (documentwriter != null)
            return documentwriter;

        documentwriter = new DocumentWriter(this);
        return documentwriter;
    }

    private void setIndexWriter() throws IOException {
        if (indexwriter != null)
            return;

        setDirectory();
        IndexWriterConfig iwc = new IndexWriterConfig(AnalyzerFactory.get(language));
        iwc.setOpenMode(OpenMode.CREATE_OR_APPEND);
        indexwriter = new IndexWriter(directory, iwc);
    }

    public synchronized void addDocuments(java.util.Collection<Document> pageCollection)
            throws CorruptIndexException, IOException {
        setIndexWriter();
        indexwriter.addDocuments(pageCollection);
        closeWriter();
        close();
    }

    public synchronized void deleteDocument(DocumentWrap docwrap, boolean closeOptimize) throws IOException {
        setIndexWriter();
        indexwriter.deleteDocuments(new Term(DocumentWrap.ID, docwrap.getId()));

        if (closeOptimize) {
            closeWriter();
        }
    }

    public synchronized void closeWriter() throws CorruptIndexException, IOException {
        indexwriter.commit();
        indexwriter.close();
        indexwriter = null;
    }

    public synchronized void deleteAll() throws IOException {
        setIndexWriter();
        indexwriter.deleteAll();
        closeWriter();
        close();
    }
}