it.doqui.index.ecmengine.business.personalization.multirepository.index.lucene.fts.RepositoryAwareFullTextSearchIndexerImpl.java Source code

Java tutorial

Introduction

Here is the source code for it.doqui.index.ecmengine.business.personalization.multirepository.index.lucene.fts.RepositoryAwareFullTextSearchIndexerImpl.java

Source

/* Index ECM Engine - A system for managing the capture (when created
 * or received), classification (cataloguing), storage, retrieval,
 * revision, sharing, reuse and disposition of documents.
 *
 * Copyright (C) 2008 Regione Piemonte
 * Copyright (C) 2008 Provincia di Torino
 * Copyright (C) 2008 Comune di Torino
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2,
 * or (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 */

package it.doqui.index.ecmengine.business.personalization.multirepository.index.lucene.fts;

import it.doqui.index.ecmengine.business.personalization.multirepository.RepositoryManager;
import it.doqui.index.ecmengine.business.personalization.multirepository.index.RepositoryAwareIndexerAndSearcher;
import it.doqui.index.ecmengine.business.personalization.multirepository.index.RepositoryAwareSupportsBackgroundIndexing;
import it.doqui.index.ecmengine.business.personalization.multirepository.index.RepositoryBackgroundIndexerAware;
import it.doqui.index.ecmengine.business.personalization.multirepository.util.EcmEngineMultirepositoryConstants;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

import org.alfresco.repo.search.Indexer;
import org.alfresco.repo.search.impl.lucene.fts.FTSIndexerException;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class RepositoryAwareFullTextSearchIndexerImpl
        implements RepositoryFTSIndexerAware, RepositoryAwareFullTextSearchIndexer {

    private static Set<Pair<String, StoreRef>> requiresIndex = new LinkedHashSet<Pair<String, StoreRef>>();
    private static Set<Pair<String, StoreRef>> indexing = new HashSet<Pair<String, StoreRef>>();

    private RepositoryAwareIndexerAndSearcher indexerAndSearcherFactory;

    private int pauseCount = 0;

    private boolean paused = false;

    private static Log logger = LogFactory
            .getLog(EcmEngineMultirepositoryConstants.MULTIREPOSITORY_INDEX_LOG_CATEGORY);

    private RetryingTransactionHelper retryingTransactionHelper;

    public RepositoryAwareFullTextSearchIndexerImpl() {
        super();
    }

    public synchronized void requiresIndex(StoreRef storeRef, String repository) {
        logger.debug("[RepositoryAwareFullTextSearchIndexerImpl::requiresIndex] Requested index of: " + storeRef
                + " - " + repository);
        requiresIndex.add(new Pair<String, StoreRef>(repository, storeRef));
    }

    public synchronized void indexCompleted(StoreRef storeRef, String repository, int remaining, Exception e) {
        try {
            Pair<String, StoreRef> pair = new Pair<String, StoreRef>(repository, storeRef);

            indexing.remove(pair);
            if ((remaining > 0) || (e != null)) {
                requiresIndex(storeRef, repository);
            }

            if (e != null) {
                throw new FTSIndexerException(e);
            }
        } finally {
            this.notifyAll();
        }
    }

    public synchronized void pause() throws InterruptedException {
        pauseCount++;
        while ((!indexing.isEmpty())) {
            this.wait();
        }
        pauseCount--;
        if (pauseCount == 0) {
            paused = true;
            this.notifyAll(); // only resumers
        }
    }

    public synchronized void resume() throws InterruptedException {
        if (pauseCount == 0) {
            paused = false;
        } else {
            while (pauseCount > 0) {
                this.wait();
            }
            paused = false;
        }
    }

    @SuppressWarnings("unused")
    private synchronized boolean isPaused() throws InterruptedException {
        if (pauseCount == 0) {
            return paused;
        } else {
            while (pauseCount > 0) {
                this.wait();
            }
            return paused;
        }
    }

    public void index() {
        // Use the calling thread to index
        // Parallel indexing via multiple Quartz thread initiating indexing
        final RepositoryFTSIndexerAware ftsIndexer = this;

        int done = 0;
        while (done == 0) {
            Pair<String, StoreRef> toIndex = getNextPair();
            if (toIndex != null) {

                logger.debug("[RepositoryAwareFullTextSearchIndexer::getNextPair] "
                        + "Retrieving Indexer for Pair: " + toIndex.getFirst() + " - " + toIndex.getSecond());

                final String repository = toIndex.getFirst();
                final StoreRef storeRef = toIndex.getSecond();

                final String origRepo = RepositoryManager.getCurrentRepository();

                RetryingTransactionCallback<Long> callback = new RetryingTransactionCallback<Long>() {
                    public Long execute() {
                        long myDone = 0;
                        final Indexer indexer = indexerAndSearcherFactory.getIndexer(storeRef, repository);

                        if (indexer instanceof RepositoryBackgroundIndexerAware) {
                            RepositoryBackgroundIndexerAware backgroundIndexerAware = (RepositoryBackgroundIndexerAware) indexer;
                            backgroundIndexerAware.registerCallBack(ftsIndexer);
                            myDone = backgroundIndexerAware.updateFullTextSearch(1000);
                        }
                        return myDone;
                    }
                };

                RepositoryManager.setCurrentRepository(repository);
                try {
                    done += retryingTransactionHelper.doInTransaction(callback, false, true);
                } finally {
                    RepositoryManager.setCurrentRepository(origRepo);
                }
            } else {
                break;
            }
        }
    }

    private synchronized Pair<String, StoreRef> getNextPair() {
        if (paused || (pauseCount > 0)) {
            return null;
        }

        Pair<String, StoreRef> nextPair = null;

        logger.debug(
                "[RepositoryAwareFullTextSearchIndexer::getNextPair] Looking for next pair in: " + requiresIndex);

        for (Pair<String, StoreRef> pair : requiresIndex) {
            if (!indexing.contains(pair)) {
                nextPair = pair;

                // FIFO
                break;
            } else {
                logger.debug("[RepositoryAwareFullTextSearchIndexer::getNextPair] Already indexing: "
                        + pair.getFirst() + " - " + pair.getSecond());
            }
        }

        if (nextPair != null) {
            logger.debug("[RepositoryAwareFullTextSearchIndexer::getNextPair] Next to index: " + nextPair.getFirst()
                    + " - " + nextPair.getSecond());
            requiresIndex.remove(nextPair);
            indexing.add(nextPair);
        }

        return nextPair;
    }

    /**
     * @param indexerAndSearcherFactory
     */
    public void setIndexerAndSearcherFactory(RepositoryAwareIndexerAndSearcher indexerAndSearcherFactory) {
        this.indexerAndSearcherFactory = indexerAndSearcherFactory;
    }

    /**
     * @param beanFactory
     * @throws InterruptedException
     */
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // Find bean implementing RepositoryAwareSupportsBackgroundIndexing and register
        for (Object bgindexable : beanFactory.getBeansOfType(RepositoryAwareSupportsBackgroundIndexing.class)
                .values()) {
            if (bgindexable instanceof RepositoryAwareSupportsBackgroundIndexing) {
                ((RepositoryAwareSupportsBackgroundIndexing) bgindexable).setFullTextSearchIndexer(this);
            }
        }
    }

    public RetryingTransactionHelper getRetryingTransactionHelper() {
        return retryingTransactionHelper;
    }

    public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper) {
        this.retryingTransactionHelper = retryingTransactionHelper;
    }
}