diff --git a/source/java/org/alfresco/repo/node/ConcurrentNodeServiceSearchTest.java b/source/java/org/alfresco/repo/node/ConcurrentNodeServiceSearchTest.java index 14a32afe4f..582ed0aa81 100644 --- a/source/java/org/alfresco/repo/node/ConcurrentNodeServiceSearchTest.java +++ b/source/java/org/alfresco/repo/node/ConcurrentNodeServiceSearchTest.java @@ -130,7 +130,8 @@ public class ConcurrentNodeServiceSearchTest extends TestCase public void testConcurrent() throws Exception { luceneFTS.pause(); - IndexWriter.COMMIT_LOCK_TIMEOUT = 100000; + // TODO: LUCENE UPDATE ISSUE fix commit lock timeout here + // IndexWriter.COMMIT_LOCK_TIMEOUT = 100000; int count = 10; int repeats = 10; diff --git a/source/java/org/alfresco/repo/node/ConcurrentNodeServiceTest.java b/source/java/org/alfresco/repo/node/ConcurrentNodeServiceTest.java index be65145b23..2534bcd048 100644 --- a/source/java/org/alfresco/repo/node/ConcurrentNodeServiceTest.java +++ b/source/java/org/alfresco/repo/node/ConcurrentNodeServiceTest.java @@ -126,7 +126,8 @@ public class ConcurrentNodeServiceTest extends TestCase public void testConcurrent() throws Exception { luceneFTS.pause(); - IndexWriter.COMMIT_LOCK_TIMEOUT = 100000; + // TODO: LUCENE UPDATE ISSUE fix commit lock time out + // IndexWriter.COMMIT_LOCK_TIMEOUT = 100000; int count = 10; int repeats = 10; diff --git a/source/java/org/alfresco/repo/node/index/MissingContentReindexComponent.java b/source/java/org/alfresco/repo/node/index/MissingContentReindexComponent.java index 3080244605..7f176d4321 100644 --- a/source/java/org/alfresco/repo/node/index/MissingContentReindexComponent.java +++ b/source/java/org/alfresco/repo/node/index/MissingContentReindexComponent.java @@ -18,7 +18,7 @@ package org.alfresco.repo.node.index; import java.util.List; -import org.alfresco.repo.search.impl.lucene.LuceneIndexerImpl; +import org.alfresco.repo.search.impl.lucene.LuceneIndexerImpl2; import org.alfresco.repo.transaction.TransactionUtil; import org.alfresco.repo.transaction.TransactionUtil.TransactionWork; import org.alfresco.service.cmr.repository.NodeRef; @@ -92,7 +92,7 @@ public class MissingContentReindexComponent extends AbstractReindexComponent // search for it in the index, sorting with youngest first sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("TEXT:" + LuceneIndexerImpl.NOT_INDEXED_CONTENT_MISSING); + sp.setQuery("TEXT:" + LuceneIndexerImpl2.NOT_INDEXED_CONTENT_MISSING); sp.addSort(SearchParameters.SORT_IN_DOCUMENT_ORDER_DESCENDING); ResultSet results = null; try diff --git a/source/java/org/alfresco/repo/node/index/MissingContentReindexComponentTest.java b/source/java/org/alfresco/repo/node/index/MissingContentReindexComponentTest.java index 04e3830c63..dec79827a5 100644 --- a/source/java/org/alfresco/repo/node/index/MissingContentReindexComponentTest.java +++ b/source/java/org/alfresco/repo/node/index/MissingContentReindexComponentTest.java @@ -23,7 +23,7 @@ import org.alfresco.repo.content.AbstractContentStore; import org.alfresco.repo.content.ContentStore; import org.alfresco.repo.node.db.NodeDaoService; import org.alfresco.repo.search.Indexer; -import org.alfresco.repo.search.impl.lucene.LuceneIndexerImpl; +import org.alfresco.repo.search.impl.lucene.LuceneIndexerImpl2; import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.transaction.TransactionComponent; @@ -126,7 +126,7 @@ public class MissingContentReindexComponentTest extends TestCase SearchParameters sp = new SearchParameters(); sp.addStore(rootNodeRef.getStoreRef()); sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("TEXT:" + LuceneIndexerImpl.NOT_INDEXED_CONTENT_MISSING); + sp.setQuery("TEXT:" + LuceneIndexerImpl2.NOT_INDEXED_CONTENT_MISSING); sp.addSort(SearchParameters.SORT_IN_DOCUMENT_ORDER_DESCENDING); ResultSet results = null; try diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneBase.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneBase.java deleted file mode 100644 index e5ecfae529..0000000000 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneBase.java +++ /dev/null @@ -1,1029 +0,0 @@ -/* - * Copyright (C) 2005 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * 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.alfresco.repo.search.impl.lucene; - -import java.io.File; -import java.io.IOException; -import java.util.Set; - -import org.alfresco.repo.search.IndexerException; -import org.alfresco.repo.search.transaction.LuceneIndexLock; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.apache.log4j.Logger; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.MultiReader; -import org.apache.lucene.index.Term; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Searcher; -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.FSDirectory; - -/** - * Common support for abstracting the lucene indexer from its configuration and management requirements. - * - *

- * This class defines where the indexes are stored. This should be via a configurable Bean property in Spring. - * - *

- * The default file structure is - *

    - *
  1. "base"/"protocol"/"name"/ for the main index - *
  2. "base"/"protocol"/"name"/deltas/"id" for transactional updates - *
  3. "base"/"protocol"/"name"/undo/"id" undo information - *
- * - *

- * The IndexWriter and IndexReader for a given index are toggled (one should be used for delete and the other for write). These are reused/closed/initialised as required. - * - *

- * The index deltas are buffered to memory and persisted in the file system as required. - * - * @author Andy Hind - * - */ - -public abstract class LuceneBase implements Lockable -{ - private static Logger s_logger = Logger.getLogger(LuceneBase.class); - - /** - * The base directory for the index (on file) - */ - - private File baseDir; - - /** - * The directory for deltas (on file) - */ - - private File deltaDir; - - /** - * The directory for undo information (on file) - */ - - private File undoDir; - - /** - * The index reader for the on file delta. (This should no coexist with the writer) - */ - - private IndexReader deltaReader; - - /** - * The writer for the delta to file. (This should no coexist with the reader) - */ - - private IndexWriter deltaWriter; - - /** - * The writer for the main index. (This should no coexist with the reader) - */ - - private IndexWriter mainWriter; - - /* - * TODO: The main indexer operations need to be serialised to the main index - */ - - /** - * The reader for the main index. (This should no coexist with the writer) - */ - - private IndexReader mainReader; - - /** - * The identifier for the store - */ - - protected StoreRef store; - - /** - * The identifier for the delta - */ - - protected String deltaId; - - private LuceneIndexLock luceneIndexLock; - - private LuceneConfig config; - - // "lucene-indexes"; - - /** - * Initialise the configuration elements of the lucene store indexers and searchers. - * - * @param store - * @param deltaId - * @throws IOException - */ - protected void initialise(StoreRef store, String deltaId, boolean createMain, boolean createDelta) - throws LuceneIndexException - { - this.store = store; - this.deltaId = deltaId; - - String basePath = getMainPath(); - baseDir = new File(basePath); - if (createMain) - { - getWriteLock(); - } - try - { - try - { - initialiseFSDirectory(basePath, false, createMain).close(); - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to close directory after initialisation " + basePath); - } - if (deltaId != null) - { - String deltaPath = getDeltaPath(); - deltaDir = new File(deltaPath); - try - { - initialiseFSDirectory(deltaPath, createDelta, createDelta).close(); - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to close directory after initialisation " + deltaPath); - } - // undoDir = initialiseFSDirectory(basePath + File.separator + - // "undo" + File.separator + deltaId + File.separator, true, - // true); - } - } - finally - { - if (createMain) - { - releaseWriteLock(); - } - } - } - - /** - * Utility method to find the path to the transactional store for this index delta - * - * @return - */ - private String getDeltaPath() - { - String deltaPath = getBasePath() + File.separator + "delta" + File.separator + this.deltaId + File.separator; - return deltaPath; - } - - private String getMainPath() - { - String mainPath = getBasePath() + File.separator + "index" + File.separator; - return mainPath; - } - - /** - * Utility method to find the path to the base index - * - * @return - */ - private String getBasePath() - { - if (config.getIndexRootLocation() == null) - { - throw new IndexerException("No configuration for index location"); - } - String basePath = config.getIndexRootLocation() - + File.separator + store.getProtocol() + File.separator + store.getIdentifier() + File.separator; - return basePath; - } - - /** - * Utility method to initiliase a lucene FSDirectorya at a given location. We may try and delete the directory when the JVM exits. - * - * @param path - * @param temp - * @return - * @throws IOException - */ - private Directory initialiseFSDirectory(String path, boolean deleteOnExit, boolean overwrite) - throws LuceneIndexException - { - try - { - File file = new File(path); - if (overwrite) - { - // deleteDirectory(file); - } - if (!file.exists()) - { - file.mkdirs(); - if (deleteOnExit) - { - file.deleteOnExit(); - } - - return FSDirectory.getDirectory(file, true); - } - else - { - return FSDirectory.getDirectory(file, overwrite); - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Filed to initialise lucene file directory " + path, e); - } - } - - /** - * Get a searcher for the main index TODO: Split out support for the main index. We really only need this if we want to search over the changing index before it is committed - * - * @return - * @throws IOException - */ - - protected IndexSearcher getSearcher() throws LuceneIndexException - { - try - { - return new IndexSearcher(getMainPath()); - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to open IndexSarcher for " + getMainPath(), e); - } - } - - protected Searcher getSearcher(LuceneIndexer luceneIndexer) throws LuceneIndexException - { - // If we know the delta id we should do better - try - { - if (mainIndexExists()) - { - if (luceneIndexer == null) - { - return new IndexSearcher(getMainPath()); - } - else - { - // TODO: Create appropriate reader that lies about deletions - // from the first - // - luceneIndexer.flushPending(); - return new ClosingIndexSearcher(new MultiReader(new IndexReader[] { - new FilterIndexReaderByNodeRefs(IndexReader.open(getMainPath()), luceneIndexer - .getDeletions()), IndexReader.open(getDeltaPath()) })); - } - } - else - { - if (luceneIndexer == null) - { - return null; - } - else - { - luceneIndexer.flushPending(); - return new IndexSearcher(getDeltaPath()); - } - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to open IndexSarcher for " + getMainPath(), e); - } - } - - /** - * Get a reader for the on file portion of the delta - * - * @return - * @throws IOException - */ - - protected IndexReader getDeltaReader() throws LuceneIndexException - { - if (deltaReader == null) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Trying to get index delta reader for tx " + deltaDir); - } - // Readers and writes can not exists at the same time so we swap - // between them. - closeDeltaWriter(); - - if (!indexExists(deltaDir)) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("... index does not already exist for " + deltaDir + " creating ..."); - } - try - { - // Make sure there is something we can read - IndexWriter writer = new IndexWriter(deltaDir, new LuceneAnalyser(dictionaryService), true); - writer.setUseCompoundFile(true); - writer.close(); - if (s_logger.isDebugEnabled()) - { - s_logger.debug("... index created " + deltaDir); - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to create empty index for delta reader: " + deltaDir, e); - } - } - - try - { - deltaReader = IndexReader.open(deltaDir); - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Opened delta reader for " + deltaDir); - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to open delta reader: " + deltaDir, e); - } - - } - return deltaReader; - } - - private boolean indexExists(File dir) - { - return IndexReader.indexExists(dir); - } - - /** - * Close the on file reader for the delta if it is open - * - * @throws IOException - */ - - protected void closeDeltaReader() throws LuceneIndexException - { - if (deltaReader != null) - { - try - { - try - { - deltaReader.close(); - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Closed delta read for " + deltaDir); - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Filed to close delta reader " + deltaDir, e); - } - } - finally - { - deltaReader = null; - } - } - - } - - /** - * Get the on file writer for the delta - * - * @return - * @throws IOException - */ - protected IndexWriter getDeltaWriter() throws LuceneIndexException - { - if (deltaWriter == null) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Trying to create delta writer " + deltaDir); - } - // Readers and writes can not exists at the same time so we swap - // between them. - closeDeltaReader(); - - try - { - boolean create = !IndexReader.indexExists(deltaDir); - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Creating delta writer " + deltaDir + " " + (create ? "CREATE" : "OPEN")); - } - deltaWriter = new IndexWriter(deltaDir, new LuceneAnalyser(dictionaryService), create); - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new IndexerException("Failed to get delta writer for " + deltaDir, e); - } - } - deltaWriter.setUseCompoundFile(true); - deltaWriter.minMergeDocs = config.getIndexerMinMergeDocs(); - deltaWriter.mergeFactor = config.getIndexerMergeFactor(); - deltaWriter.maxMergeDocs = config.getIndexerMaxMergeDocs(); - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Created delta writer " + deltaDir); - } - return deltaWriter; - } - - /** - * Close the on disk delta writer - * - * @throws IOException - */ - - protected void closeDeltaWriter() throws LuceneIndexException - { - if (deltaWriter != null) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Trying to close delta writer... " + deltaDir); - } - try - { - // deltaWriter.optimize(); - deltaWriter.close(); - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Closed delta writer " + deltaDir); - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to close delta writer " + deltaDir, e); - } - finally - { - deltaWriter = null; - } - } - - } - - /** - * Save the in memory delta to the disk, make sure there is nothing held in memory - * - * @throws IOException - */ - protected void saveDelta() throws LuceneIndexException - { - // Only one should exist so we do not need error trapping to execute the - // other - closeDeltaReader(); - closeDeltaWriter(); - } - - /** - * Get all the locks so we can expect a merge to succeed - * - * The delta should be thread local so we do not have to worry about contentention TODO: Worry about main index contentention of readers and writers @ - * @throws IOException - */ - protected void prepareToMergeIntoMain() throws LuceneIndexException - { - if (mainWriter != null) - { - throw new IndexerException("Can not merge as main writer is active"); - } - if (mainReader != null) - { - throw new IndexerException("Can not merge as main reader is active"); - } - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Getting write lock for " + baseDir + " for " + deltaDir); - } - getWriteLock(); - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Got write lock for " + baseDir + " for " + deltaDir); - } - try - { - getDeltaReader(); // Flush any deletes - closeDeltaReader(); - } - catch (LuceneIndexException e) - { - s_logger.error("Error", e); - releaseWriteLock(); - throw e; - } - - } - - /** - * Merge the delta in the main index. The delta still exists on disk. - * - * @param terms - * A list of terms that identifiy documents to be deleted from the main index before the delta os merged in. - * - * @throws IOException - */ - protected void mergeDeltaIntoMain(Set terms) throws LuceneIndexException - { - if (writeLockCount < 1) - { - throw new LuceneIndexException("Must hold the write lock to merge"); - } - - try - { - if (!indexExists(baseDir)) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Creating base index " + baseDir); - } - try - { - mainWriter = new IndexWriter(baseDir, new LuceneAnalyser(dictionaryService), true); - mainWriter.setUseCompoundFile(true); - mainWriter.close(); - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Created base index " + baseDir); - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to create empty base index at " + baseDir, e); - } - } - try - { - mainReader = IndexReader.open(baseDir); - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Opened base index for deletes " + baseDir); - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to create base index reader at " + baseDir, e); - } - - // Do the deletions - try - { - if ((mainReader.numDocs() > 0) && (terms.size() > 0)) - { - for (Term term : terms) - { - try - { - mainReader.delete(term); - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to delete term from main index at " + baseDir, e); - } - } - } - } - finally - { - try - { - try - { - mainReader.close(); - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Completed index deletes on " + baseDir + " for " + deltaDir); - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to close from main index reader at " + baseDir, e); - } - } - finally - { - mainReader = null; - } - } - - // Do the append - - try - { - mainWriter = new IndexWriter(baseDir, new LuceneAnalyser(dictionaryService), false); - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Opened index for append " + baseDir + " for " + deltaDir); - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to open main index for append at " + baseDir, e); - } - mainWriter.setUseCompoundFile(true); - - mainWriter.minMergeDocs = config.getIndexerMinMergeDocs(); - mainWriter.mergeFactor = config.getIndexerMergeFactor(); - mainWriter.maxMergeDocs = config.getIndexerMaxMergeDocs(); - - try - { - IndexReader reader = getDeltaReader(); - if (reader.numDocs() > 0) - { - IndexReader[] readers = new IndexReader[] { reader }; - try - { - mainWriter.mergeIndexes(readers); - // mainWriter.addIndexes(readers); - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to merge indexes into the main index for " - + baseDir + " merging in " + deltaDir, e); - } - // mainWriter.optimize(); - closeDeltaReader(); - } - else - { - closeDeltaReader(); - } - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Closed index after append " + baseDir + " for " + deltaDir); - } - } - finally - { - try - { - try - { - mainWriter.close(); - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to cloase main index after append at " + baseDir, e); - } - } - finally - { - mainWriter = null; - } - } - } - finally - { - releaseWriteLock(); - } - } - - /** - * Delete the delta and make this instance unusable - * - * This tries to tidy up all it can. It is possible some stuff will remain if errors are throws else where - * - * TODO: Support for cleaning up transactions - need to support recovery and knowing of we are prepared - * - */ - protected void deleteDelta() throws LuceneIndexException - { - try - { - // Try and close everything - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Deleting delta " + deltaDir); - } - try - { - closeDeltaReader(); - } - catch (LuceneIndexException e) - { - s_logger.warn(e); - } - try - { - closeDeltaWriter(); - } - catch (LuceneIndexException e) - { - s_logger.warn(e); - } - - // try - // { - // deltaDir.close(); - // } - // catch (IOException e) - // { - // s_logger.warn("Failed to close delta dir", e); - // } - deltaDir = null; - - // Close the main stuff - if (mainReader != null) - { - try - { - mainReader.close(); - } - catch (IOException e) - { - s_logger.warn("Failed to close main reader", e); - } - } - mainReader = null; - - if (mainWriter != null) - { - try - { - mainWriter.close(); - } - catch (IOException e) - { - s_logger.warn("Failed to close main writer", e); - } - } - mainWriter = null; - // try - // { - // baseDir.close(); - // } - // catch (IOException e) - // { - // s_logger.warn("Failed to close base dir", e); - // } - - // Delete the delta directories - String deltaPath = getDeltaPath(); - File file = new File(deltaPath); - - deleteDirectory(file); - } - finally - { - releaseWriteLock(); - } - } - - /** - * Support to help deleting directories - * - * @param file - */ - private void deleteDirectory(File file) - { - File[] children = file.listFiles(); - if (children != null) - { - for (int i = 0; i < children.length; i++) - { - File child = children[i]; - if (child.isDirectory()) - { - deleteDirectory(child); - } - else - { - if (child.exists() && !child.delete() && child.exists()) - { - s_logger.warn("Failed to delete " + child); - } - } - } - } - if (file.exists() && !file.delete() && file.exists()) - { - s_logger.warn("Failed to delete " + file); - } - } - - public LuceneIndexLock getLuceneIndexLock() - { - return luceneIndexLock; - } - - public void setLuceneIndexLock(LuceneIndexLock luceneIndexLock) - { - this.luceneIndexLock = luceneIndexLock; - } - - public void getReadLock() - { - getLuceneIndexLock().getReadLock(store); - } - - public static boolean isWriteLocked(String directory) throws IOException - { - Directory dir = FSDirectory.getDirectory(directory, false); - boolean result = isWriteLocked(dir); - dir.close(); - return result; - } - - public static boolean isWriteLocked(Directory directory) throws IOException - { - return directory.makeLock(IndexWriter.WRITE_LOCK_NAME).isLocked(); - - } - - private int writeLockCount = 0; - - public void getWriteLock() throws LuceneIndexException - { - getLuceneIndexLock().getWriteLock(store); - writeLockCount++; - // Check the main index is not locked and release if it is - // We must have the lock - try - { - if (((writeLockCount == 1) && IndexReader.indexExists(baseDir) && (LuceneBase.isWriteLocked(baseDir - .getPath())))) - { - Directory dir = FSDirectory.getDirectory(baseDir, false); - try - { - dir.makeLock(IndexWriter.WRITE_LOCK_NAME).release(); - } - finally - { - dir.close(); - } - s_logger.warn("Releasing unexpected lucene index write lock for " + baseDir); - StackTraceElement[] trace = Thread.currentThread().getStackTrace(); - for (StackTraceElement el : trace) - { - s_logger.warn(el.toString()); - } - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Write lock failed to check or clear any existing lucene locks", e); - } - } - - public void releaseReadLock() - { - getLuceneIndexLock().releaseReadLock(store); - } - - public void releaseWriteLock() - { - - if (writeLockCount > 0) - { - try - { - if (((writeLockCount == 1) && IndexReader.indexExists(baseDir) && (LuceneBase.isWriteLocked(baseDir - .getPath())))) - { - Directory dir = FSDirectory.getDirectory(baseDir, false); - try - { - dir.makeLock(IndexWriter.WRITE_LOCK_NAME).release(); - } - finally - { - dir.close(); - } - } - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Write lock failed to check or clear any existing lucene locks", e); - } - getLuceneIndexLock().releaseWriteLock(store); - writeLockCount--; - - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Released write lock " + baseDir + " for " + deltaDir); - } - } - } - - private DictionaryService dictionaryService; - - public boolean mainIndexExists() - { - return IndexReader.indexExists(baseDir); - } - - protected IndexReader getReader() throws LuceneIndexException - { - - if (!indexExists(baseDir)) - { - getWriteLock(); - try - { - if (!indexExists(baseDir)) - { - try - { - mainWriter = new IndexWriter(baseDir, new LuceneAnalyser(dictionaryService), true); - mainWriter.setUseCompoundFile(true); - mainWriter.close(); - mainWriter = null; - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to create empty main index", e); - } - } - } - finally - { - releaseWriteLock(); - } - } - - try - { - return IndexReader.open(baseDir); - } - catch (IOException e) - { - s_logger.error("Error", e); - throw new LuceneIndexException("Failed to open main index reader", e); - } - - } - - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - public DictionaryService getDictionaryService() - { - return dictionaryService; - } - - public void setLuceneConfig(LuceneConfig config) - { - this.config = config; - } - - public LuceneConfig getLuceneConfig() - { - return config; - } - - public String getDeltaId() - { - return deltaId; - } - -} diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryTest.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryTest.java deleted file mode 100644 index f8bf082963..0000000000 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryTest.java +++ /dev/null @@ -1,672 +0,0 @@ -/* - * Copyright (C) 2005 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * 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.alfresco.repo.search.impl.lucene; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Random; - -import javax.transaction.UserTransaction; - -import junit.framework.TestCase; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.dictionary.DictionaryDAO; -import org.alfresco.repo.dictionary.M2Aspect; -import org.alfresco.repo.dictionary.M2Model; -import org.alfresco.repo.dictionary.M2Property; -import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer; -import org.alfresco.repo.search.transaction.LuceneIndexLock; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.search.CategoryService; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.ResultSetRow; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.DynamicNamespacePrefixResolver; -import org.alfresco.service.namespace.NamespacePrefixResolver; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.transaction.TransactionService; -import org.alfresco.util.ApplicationContextHelper; -import org.springframework.context.ApplicationContext; - -public class LuceneCategoryTest extends TestCase -{ - private ServiceRegistry serviceRegistry; - - static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(); - NodeService nodeService; - DictionaryService dictionaryService; - LuceneIndexLock luceneIndexLock; - private NodeRef rootNodeRef; - private NodeRef n1; - private NodeRef n2; - private NodeRef n3; - private NodeRef n4; - private NodeRef n6; - private NodeRef n5; - private NodeRef n7; - private NodeRef n8; - private NodeRef n9; - private NodeRef n10; - private NodeRef n11; - private NodeRef n12; - private NodeRef n13; - private NodeRef n14; - - private NodeRef catContainer; - private NodeRef catRoot; - private NodeRef catACBase; - private NodeRef catACOne; - private NodeRef catACTwo; - private NodeRef catACThree; - private FullTextSearchIndexer luceneFTS; - private DictionaryDAO dictionaryDAO; - private String TEST_NAMESPACE = "http://www.alfresco.org/test/lucenecategorytest"; - private QName regionCategorisationQName; - private QName assetClassCategorisationQName; - private QName investmentRegionCategorisationQName; - private QName marketingRegionCategorisationQName; - private NodeRef catRBase; - private NodeRef catROne; - private NodeRef catRTwo; - private NodeRef catRThree; - private SearchService searcher; - private LuceneIndexerAndSearcher indexerAndSearcher; - - private CategoryService categoryService; - - public LuceneCategoryTest() - { - super(); - } - - public LuceneCategoryTest(String arg0) - { - super(arg0); - } - - public void setUp() throws Exception - { - nodeService = (NodeService)ctx.getBean("dbNodeService"); - luceneIndexLock = (LuceneIndexLock)ctx.getBean("luceneIndexLock"); - dictionaryService = (DictionaryService)ctx.getBean("dictionaryService"); - luceneFTS = (FullTextSearchIndexer) ctx.getBean("LuceneFullTextSearchIndexer"); - dictionaryDAO = (DictionaryDAO) ctx.getBean("dictionaryDAO"); - searcher = (SearchService) ctx.getBean("searchService"); - indexerAndSearcher = (LuceneIndexerAndSearcher) ctx.getBean("luceneIndexerAndSearcherFactory"); - categoryService = (CategoryService) ctx.getBean("categoryService"); - serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); - - createTestTypes(); - - TransactionService transactionService = serviceRegistry.getTransactionService(); - UserTransaction tx = transactionService.getUserTransaction(); - tx.begin(); - - StoreRef storeRef = nodeService.createStore( - StoreRef.PROTOCOL_WORKSPACE, - "Test_" + System.currentTimeMillis()); - rootNodeRef = nodeService.getRootNode(storeRef); - - n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}one"), ContentModel.TYPE_CONTAINER).getChildRef(); - nodeService.setProperty(n1, QName.createQName("{namespace}property-1"), "value-1"); - n2 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}two"), ContentModel.TYPE_CONTAINER).getChildRef(); - nodeService.setProperty(n2, QName.createQName("{namespace}property-1"), "value-1"); - nodeService.setProperty(n2, QName.createQName("{namespace}property-2"), "value-2"); - n3 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}three"), ContentModel.TYPE_CONTAINER).getChildRef(); - n4 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}four"), ContentModel.TYPE_CONTAINER).getChildRef(); - n5 = nodeService.createNode(n1, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}five"), ContentModel.TYPE_CONTAINER).getChildRef(); - n6 = nodeService.createNode(n1, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}six"), ContentModel.TYPE_CONTAINER).getChildRef(); - n7 = nodeService.createNode(n2, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}seven"), ContentModel.TYPE_CONTAINER).getChildRef(); - n8 = nodeService.createNode(n2, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}eight-2"), ContentModel.TYPE_CONTAINER).getChildRef(); - n9 = nodeService.createNode(n5, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}nine"), ContentModel.TYPE_CONTAINER).getChildRef(); - n10 = nodeService.createNode(n5, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}ten"), ContentModel.TYPE_CONTAINER).getChildRef(); - n11 = nodeService.createNode(n5, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}eleven"), ContentModel.TYPE_CONTAINER).getChildRef(); - n12 = nodeService.createNode(n5, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}twelve"), ContentModel.TYPE_CONTAINER).getChildRef(); - n13 = nodeService.createNode(n12, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}thirteen"), ContentModel.TYPE_CONTAINER).getChildRef(); - n14 = nodeService.createNode(n13, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}fourteen"), ContentModel.TYPE_CONTAINER).getChildRef(); - - nodeService.addChild(rootNodeRef, n8, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}eight-0")); - nodeService.addChild(n1, n8, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}eight-1")); - nodeService.addChild(n2, n13, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}link")); - - nodeService.addChild(n1, n14, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}common")); - nodeService.addChild(n2, n14, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}common")); - nodeService.addChild(n5, n14, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}common")); - nodeService.addChild(n6, n14, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}common")); - nodeService.addChild(n12, n14, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}common")); - nodeService.addChild(n13, n14, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}common")); - - // Categories - - catContainer = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "categoryContainer"), ContentModel.TYPE_CONTAINER).getChildRef(); - catRoot = nodeService.createNode(catContainer, ContentModel.ASSOC_CHILDREN, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "categoryRoot"), ContentModel.TYPE_CATEGORYROOT).getChildRef(); - - - - catRBase = nodeService.createNode(catRoot, ContentModel.ASSOC_CATEGORIES, QName.createQName(TEST_NAMESPACE, "Region"), ContentModel.TYPE_CATEGORY).getChildRef(); - catROne = nodeService.createNode(catRBase, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(TEST_NAMESPACE, "Europe"), ContentModel.TYPE_CATEGORY).getChildRef(); - catRTwo = nodeService.createNode(catRBase, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(TEST_NAMESPACE, "RestOfWorld"), ContentModel.TYPE_CATEGORY).getChildRef(); - catRThree = nodeService.createNode(catRTwo, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(TEST_NAMESPACE, "US"), ContentModel.TYPE_CATEGORY).getChildRef(); - - nodeService.addChild(catRoot, catRBase, ContentModel.ASSOC_CATEGORIES, QName.createQName(TEST_NAMESPACE, "InvestmentRegion")); - nodeService.addChild(catRoot, catRBase, ContentModel.ASSOC_CATEGORIES, QName.createQName(TEST_NAMESPACE, "MarketingRegion")); - - - catACBase = nodeService.createNode(catRoot, ContentModel.ASSOC_CATEGORIES, QName.createQName(TEST_NAMESPACE, "AssetClass"), ContentModel.TYPE_CATEGORY).getChildRef(); - catACOne = nodeService.createNode(catACBase, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(TEST_NAMESPACE, "Fixed"), ContentModel.TYPE_CATEGORY).getChildRef(); - catACTwo = nodeService.createNode(catACBase, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(TEST_NAMESPACE, "Equity"), ContentModel.TYPE_CATEGORY).getChildRef(); - catACThree = nodeService.createNode(catACTwo, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(TEST_NAMESPACE, "SpecialEquity"), ContentModel.TYPE_CATEGORY).getChildRef(); - - - - nodeService.addAspect(n1, assetClassCategorisationQName, createMap("assetClass", catACBase)); - nodeService.addAspect(n1, regionCategorisationQName, createMap("region", catRBase)); - - nodeService.addAspect(n2, assetClassCategorisationQName, createMap("assetClass", catACOne)); - nodeService.addAspect(n3, assetClassCategorisationQName, createMap("assetClass", catACOne)); - nodeService.addAspect(n4, assetClassCategorisationQName, createMap("assetClass", catACOne)); - nodeService.addAspect(n5, assetClassCategorisationQName, createMap("assetClass", catACOne)); - nodeService.addAspect(n6, assetClassCategorisationQName, createMap("assetClass", catACOne)); - - nodeService.addAspect(n7, assetClassCategorisationQName, createMap("assetClass", catACTwo)); - nodeService.addAspect(n8, assetClassCategorisationQName, createMap("assetClass", catACTwo)); - nodeService.addAspect(n9, assetClassCategorisationQName, createMap("assetClass", catACTwo)); - nodeService.addAspect(n10, assetClassCategorisationQName, createMap("assetClass", catACTwo)); - nodeService.addAspect(n11, assetClassCategorisationQName, createMap("assetClass", catACTwo)); - - nodeService.addAspect(n12, assetClassCategorisationQName, createMap("assetClass", catACOne, catACTwo)); - nodeService.addAspect(n13, assetClassCategorisationQName, createMap("assetClass", catACOne, catACTwo, catACThree)); - nodeService.addAspect(n14, assetClassCategorisationQName, createMap("assetClass", catACOne, catACTwo)); - - nodeService.addAspect(n2, regionCategorisationQName, createMap("region", catROne)); - nodeService.addAspect(n3, regionCategorisationQName, createMap("region", catROne)); - nodeService.addAspect(n4, regionCategorisationQName, createMap("region", catRTwo)); - nodeService.addAspect(n5, regionCategorisationQName, createMap("region", catRTwo)); - - nodeService.addAspect(n5, investmentRegionCategorisationQName, createMap("investmentRegion", catRBase)); - nodeService.addAspect(n5, marketingRegionCategorisationQName, createMap("marketingRegion", catRBase)); - nodeService.addAspect(n6, investmentRegionCategorisationQName, createMap("investmentRegion", catRBase)); - nodeService.addAspect(n7, investmentRegionCategorisationQName, createMap("investmentRegion", catRBase)); - nodeService.addAspect(n8, investmentRegionCategorisationQName, createMap("investmentRegion", catRBase)); - nodeService.addAspect(n9, investmentRegionCategorisationQName, createMap("investmentRegion", catRBase)); - nodeService.addAspect(n10, marketingRegionCategorisationQName, createMap("marketingRegion", catRBase)); - nodeService.addAspect(n11, marketingRegionCategorisationQName, createMap("marketingRegion", catRBase)); - nodeService.addAspect(n12, marketingRegionCategorisationQName, createMap("marketingRegion", catRBase)); - nodeService.addAspect(n13, marketingRegionCategorisationQName, createMap("marketingRegion", catRBase)); - nodeService.addAspect(n14, marketingRegionCategorisationQName, createMap("marketingRegion", catRBase)); - - tx.commit(); - } - - private HashMap createMap(String name, NodeRef[] nodeRefs) - { - HashMap map = new HashMap(); - Serializable value = (Serializable) Arrays.asList(nodeRefs); - map.put(QName.createQName(TEST_NAMESPACE, name), value); - return map; - } - - private HashMap createMap(String name, NodeRef nodeRef) - { - return createMap(name, new NodeRef[]{nodeRef}); - } - - private HashMap createMap(String name, NodeRef nodeRef1, NodeRef nodeRef2) - { - return createMap(name, new NodeRef[]{nodeRef1, nodeRef2}); - } - - private HashMap createMap(String name, NodeRef nodeRef1, NodeRef nodeRef2, NodeRef nodeRef3) - { - return createMap(name, new NodeRef[]{nodeRef1, nodeRef2, nodeRef3}); - } - - private void createTestTypes() - { - M2Model model = M2Model.createModel("test:lucenecategory"); - model.createNamespace(TEST_NAMESPACE, "test"); - model.createImport(NamespaceService.DICTIONARY_MODEL_1_0_URI, NamespaceService.DICTIONARY_MODEL_PREFIX); - model.createImport(NamespaceService.CONTENT_MODEL_1_0_URI, NamespaceService.CONTENT_MODEL_PREFIX); - - regionCategorisationQName = QName.createQName(TEST_NAMESPACE, "Region"); - M2Aspect generalCategorisation = model.createAspect("test:" + regionCategorisationQName.getLocalName()); - generalCategorisation.setParentName("cm:" + ContentModel.ASPECT_CLASSIFIABLE.getLocalName()); - M2Property genCatProp = generalCategorisation.createProperty("test:region"); - genCatProp.setIndexed(true); - genCatProp.setIndexedAtomically(true); - genCatProp.setMandatory(true); - genCatProp.setMultiValued(true); - genCatProp.setStoredInIndex(true); - genCatProp.setTokenisedInIndex(true); - genCatProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName()); - - assetClassCategorisationQName = QName.createQName(TEST_NAMESPACE, "AssetClass"); - M2Aspect assetClassCategorisation = model.createAspect("test:" + assetClassCategorisationQName.getLocalName()); - assetClassCategorisation.setParentName("cm:" + ContentModel.ASPECT_CLASSIFIABLE.getLocalName()); - M2Property acProp = assetClassCategorisation.createProperty("test:assetClass"); - acProp.setIndexed(true); - acProp.setIndexedAtomically(true); - acProp.setMandatory(true); - acProp.setMultiValued(true); - acProp.setStoredInIndex(true); - acProp.setTokenisedInIndex(true); - acProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName()); - - investmentRegionCategorisationQName = QName.createQName(TEST_NAMESPACE, "InvestmentRegion"); - M2Aspect investmentRegionCategorisation = model.createAspect("test:" + investmentRegionCategorisationQName.getLocalName()); - investmentRegionCategorisation.setParentName("cm:" + ContentModel.ASPECT_CLASSIFIABLE.getLocalName()); - M2Property irProp = investmentRegionCategorisation.createProperty("test:investmentRegion"); - irProp.setIndexed(true); - irProp.setIndexedAtomically(true); - irProp.setMandatory(true); - irProp.setMultiValued(true); - irProp.setStoredInIndex(true); - irProp.setTokenisedInIndex(true); - irProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName()); - - marketingRegionCategorisationQName = QName.createQName(TEST_NAMESPACE, "MarketingRegion"); - M2Aspect marketingRegionCategorisation = model.createAspect("test:" + marketingRegionCategorisationQName.getLocalName()); - marketingRegionCategorisation.setParentName("cm:" + ContentModel.ASPECT_CLASSIFIABLE.getLocalName()); - M2Property mrProp = marketingRegionCategorisation.createProperty("test:marketingRegion"); - mrProp.setIndexed(true); - mrProp.setIndexedAtomically(true); - mrProp.setMandatory(true); - mrProp.setMultiValued(true); - mrProp.setStoredInIndex(true); - mrProp.setTokenisedInIndex(true); - mrProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName()); - - dictionaryDAO.putModel(model); - } - - private void buildBaseIndex() - { - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" + System.currentTimeMillis() + "_" + (new Random().nextInt()), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - //indexer.clearIndex(); - indexer.createNode(new ChildAssociationRef(null, null, null, rootNodeRef)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName.createQName("{namespace}one"), n1)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName.createQName("{namespace}two"), n2)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName.createQName("{namespace}three"), n3)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName.createQName("{namespace}four"), n4)); - - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName.createQName("{namespace}categoryContainer"), catContainer)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, catContainer, QName.createQName("{cat}categoryRoot"), catRoot)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, catRoot, QName.createQName(TEST_NAMESPACE, "AssetClass"), catACBase)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_SUBCATEGORIES, catACBase, QName.createQName(TEST_NAMESPACE, "Fixed"), catACOne)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_SUBCATEGORIES, catACBase, QName.createQName(TEST_NAMESPACE, "Equity"), catACTwo)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_SUBCATEGORIES, catACTwo, QName.createQName(TEST_NAMESPACE, "SpecialEquity"), catACThree)); - - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, catRoot, QName.createQName(TEST_NAMESPACE, "Region"), catRBase)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_SUBCATEGORIES, catRBase, QName.createQName(TEST_NAMESPACE, "Europe"), catROne)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_SUBCATEGORIES, catRBase, QName.createQName(TEST_NAMESPACE, "RestOfWorld"), catRTwo)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_SUBCATEGORIES, catRTwo, QName.createQName(TEST_NAMESPACE, "US"), catRThree)); - - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, n1, QName.createQName("{namespace}five"), n5)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, n1, QName.createQName("{namespace}six"), n6)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, n2, QName.createQName("{namespace}seven"), n7)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, n2, QName.createQName("{namespace}eight"), n8)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, n5, QName.createQName("{namespace}nine"), n9)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, n5, QName.createQName("{namespace}ten"), n10)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, n5, QName.createQName("{namespace}eleven"), n11)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, n5, QName.createQName("{namespace}twelve"), n12)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, n12, QName.createQName("{namespace}thirteen"), n13)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CATEGORIES, n13, QName.createQName("{namespace}fourteen"), n14)); - indexer.prepare(); - indexer.commit(); - } - - - public void testMulti() throws Exception - { - TransactionService transactionService = serviceRegistry.getTransactionService(); - UserTransaction tx = transactionService.getUserTransaction(); - tx.begin(); - buildBaseIndex(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("")); - ResultSet results; - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*\" AND (PATH:\"/test:AssetClass/test:Equity/member\" PATH:\"/test:MarketingRegion/member\")", null, null); - //printPaths(results); - assertEquals(9, results.length()); - results.close(); - tx.rollback(); - } - - public void testBasic() throws Exception - { - TransactionService transactionService = serviceRegistry.getTransactionService(); - UserTransaction tx = transactionService.getUserTransaction(); - tx.begin(); - buildBaseIndex(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("")); - ResultSet results; - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:MarketingRegion\"", null, null); - //printPaths(results); - assertEquals(1, results.length()); - results.close(); - - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:MarketingRegion//member\"", null, null); - //printPaths(results); - assertEquals(6, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/cm:categoryContainer\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/cm:categoryContainer/cm:categoryRoot\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/cm:categoryContainer/cm:categoryRoot\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/cm:categoryContainer/cm:categoryRoot/test:AssetClass\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/cm:categoryContainer/cm:categoryRoot/test:AssetClass/member\" ", null, null); - assertEquals(1, results.length()); - results.close(); - - - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/cm:categoryContainer/cm:categoryRoot/test:AssetClass/test:Fixed\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/cm:categoryContainer/cm:categoryRoot/test:AssetClass/test:Equity\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass/test:Fixed\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass/test:Equity\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass/test:*\"", null, null); - assertEquals(2, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass//test:*\"", null, null); - assertEquals(3, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass/test:Fixed/member\"", null, null); - //printPaths(results); - assertEquals(8, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass/test:Equity/member\"", null, null); - //printPaths(results); - assertEquals(8, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass/test:Equity/test:SpecialEquity/member//.\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass/test:Equity/test:SpecialEquity/member//*\"", null, null); - assertEquals(0, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass/test:Equity/test:SpecialEquity/member\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "+PATH:\"/test:AssetClass/test:Equity/member\" AND +PATH:\"/test:AssetClass/test:Fixed/member\"", null, null); - //printPaths(results); - assertEquals(3, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass/test:Equity/member\" PATH:\"/test:AssetClass/test:Fixed/member\"", null, null); - //printPaths(results); - assertEquals(13, results.length()); - results.close(); - - // Region - - assertEquals(4, nodeService.getChildAssocs(catRoot).size()); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:Region\"", null, null); - //printPaths(results); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:Region/member\"", null, null); - //printPaths(results); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:Region/test:Europe/member\"", null, null); - //printPaths(results); - assertEquals(2, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:Region/test:RestOfWorld/member\"", null, null); - //printPaths(results); - assertEquals(2, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:Region//member\"", null, null); - //printPaths(results); - assertEquals(5, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:InvestmentRegion//member\"", null, null); - //printPaths(results); - assertEquals(5, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:MarketingRegion//member\"", null, null); - //printPaths(results); - assertEquals(6, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "+PATH:\"/test:AssetClass/test:Fixed/member\" AND +PATH:\"/test:Region/test:Europe/member\"", null, null); - //printPaths(results); - assertEquals(2, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "+PATH:\"/cm:categoryContainer/cm:categoryRoot/test:AssetClass/test:Fixed/member\" AND +PATH:\"/cm:categoryContainer/cm:categoryRoot/test:Region/test:Europe/member\"", null, null); - //printPaths(results); - assertEquals(2, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/test:AssetClass/test:Equity/member\" PATH:\"/test:MarketingRegion/member\"", null, null); - //printPaths(results); - assertEquals(9, results.length()); - results.close(); - tx.rollback(); - } - - public void testCategoryServiceImpl() throws Exception - { - TransactionService transactionService = serviceRegistry.getTransactionService(); - UserTransaction tx = transactionService.getUserTransaction(); - tx.begin(); - buildBaseIndex(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("")); - - ResultSet - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/cm:categoryContainer/cm:categoryRoot/test:AssetClass/*\" ", null, null); - assertEquals(3, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/cm:categoryContainer/cm:categoryRoot/test:AssetClass/member\" ", null, null); - assertEquals(1, results.length()); - results.close(); - - LuceneCategoryServiceImpl impl = new LuceneCategoryServiceImpl(); - impl.setNodeService(nodeService); - impl.setNamespacePrefixResolver(getNamespacePrefixReolsver("")); - impl.setIndexerAndSearcher(indexerAndSearcher); - impl.setDictionaryService(dictionaryService); - - Collection - result = impl.getChildren(catACBase , CategoryService.Mode.MEMBERS, CategoryService.Depth.IMMEDIATE); - assertEquals(1, result.size()); - - - result = impl.getChildren(catACBase , CategoryService.Mode.ALL, CategoryService.Depth.IMMEDIATE); - assertEquals(3, result.size()); - - - result = impl.getChildren(catACBase , CategoryService.Mode.SUB_CATEGORIES, CategoryService.Depth.IMMEDIATE); - assertEquals(2, result.size()); - - - result = impl.getChildren(catACBase , CategoryService.Mode.MEMBERS, CategoryService.Depth.ANY); - assertEquals(18, result.size()); - - - result = impl.getChildren(catACBase , CategoryService.Mode.ALL, CategoryService.Depth.ANY); - assertEquals(21, result.size()); - - - result = impl.getChildren(catACBase , CategoryService.Mode.SUB_CATEGORIES, CategoryService.Depth.ANY); - assertEquals(3, result.size()); - - - result = impl.getClassifications(rootNodeRef.getStoreRef()); - assertEquals(4, result.size()); - - - result = impl.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.IMMEDIATE); - assertEquals(2, result.size()); - - - Collection aspects = impl.getClassificationAspects(); - assertEquals(6, aspects.size()); - - tx.rollback(); - } - - private NamespacePrefixResolver getNamespacePrefixReolsver(String defaultURI) - { - DynamicNamespacePrefixResolver nspr = new DynamicNamespacePrefixResolver(null); - nspr.registerNamespace(NamespaceService.CONTENT_MODEL_PREFIX, NamespaceService.CONTENT_MODEL_1_0_URI); - nspr.registerNamespace("namespace", "namespace"); - nspr.registerNamespace("test", TEST_NAMESPACE); - nspr.registerNamespace(NamespaceService.DEFAULT_PREFIX, defaultURI); - return nspr; - } - - public void testCategoryService() throws Exception - { - TransactionService transactionService = serviceRegistry.getTransactionService(); - UserTransaction tx = transactionService.getUserTransaction(); - tx.begin(); - buildBaseIndex(); - assertEquals(1, categoryService.getChildren(catACBase , CategoryService.Mode.MEMBERS, CategoryService.Depth.IMMEDIATE).size()); - assertEquals(2, categoryService.getChildren(catACBase , CategoryService.Mode.SUB_CATEGORIES, CategoryService.Depth.IMMEDIATE).size()); - assertEquals(3, categoryService.getChildren(catACBase , CategoryService.Mode.ALL, CategoryService.Depth.IMMEDIATE).size()); - assertEquals(18, categoryService.getChildren(catACBase , CategoryService.Mode.MEMBERS, CategoryService.Depth.ANY).size()); - assertEquals(3, categoryService.getChildren(catACBase , CategoryService.Mode.SUB_CATEGORIES, CategoryService.Depth.ANY).size()); - assertEquals(21, categoryService.getChildren(catACBase , CategoryService.Mode.ALL, CategoryService.Depth.ANY).size()); - assertEquals(4, categoryService.getClassifications(rootNodeRef.getStoreRef()).size()); - assertEquals(2, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.IMMEDIATE).size()); - assertEquals(3, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.ANY).size()); - assertEquals(6, categoryService.getClassificationAspects().size()); - assertEquals(2, categoryService.getRootCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass")).size()); - - NodeRef newRoot = categoryService.createRootCategory(rootNodeRef.getStoreRef(),QName.createQName(TEST_NAMESPACE, "AssetClass"), "Fruit"); - tx.commit(); - tx = transactionService.getUserTransaction(); - tx.begin(); - assertEquals(3, categoryService.getRootCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass")).size()); - assertEquals(3, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.IMMEDIATE).size()); - assertEquals(4, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.ANY).size()); - - NodeRef newCat = categoryService.createCategory(newRoot, "Banana"); - tx.commit(); - tx = transactionService.getUserTransaction(); - tx.begin(); - assertEquals(3, categoryService.getRootCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass")).size()); - assertEquals(3, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.IMMEDIATE).size()); - assertEquals(5, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.ANY).size()); - - categoryService.deleteCategory(newCat); - tx.commit(); - tx = transactionService.getUserTransaction(); - tx.begin(); - assertEquals(3, categoryService.getRootCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass")).size()); - assertEquals(3, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.IMMEDIATE).size()); - assertEquals(4, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.ANY).size()); - - categoryService.deleteCategory(newRoot); - tx.commit(); - tx = transactionService.getUserTransaction(); - tx.begin(); - assertEquals(2, categoryService.getRootCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass")).size()); - assertEquals(2, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.IMMEDIATE).size()); - assertEquals(3, categoryService.getCategories(rootNodeRef.getStoreRef(), QName.createQName(TEST_NAMESPACE, "AssetClass"), CategoryService.Depth.ANY).size()); - - - tx.rollback(); - } - - private int getTotalScore(ResultSet results) - { - int totalScore = 0; - for(ResultSetRow row: results) - { - totalScore += row.getScore(); - } - return totalScore; - } -} diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexBackupComponentTest.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexBackupComponentTest.java index dc05e51163..8b090cd007 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexBackupComponentTest.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexBackupComponentTest.java @@ -20,7 +20,7 @@ import java.io.File; import junit.framework.TestCase; -import org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcherFactory.LuceneIndexBackupComponent; +import org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcherFactory2.LuceneIndexBackupComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.transaction.TransactionService; diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcherFactory.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcherFactory.java deleted file mode 100644 index a181147115..0000000000 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcherFactory.java +++ /dev/null @@ -1,1140 +0,0 @@ -/* - * Copyright (C) 2005 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * 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.alfresco.repo.search.impl.lucene; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.transaction.RollbackException; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.xa.XAException; -import javax.transaction.xa.XAResource; -import javax.transaction.xa.Xid; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.repo.search.IndexerException; -import org.alfresco.repo.search.QueryRegisterComponent; -import org.alfresco.repo.search.SearcherException; -import org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcher.WithAllWriteLocksWork; -import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer; -import org.alfresco.repo.search.transaction.LuceneIndexLock; -import org.alfresco.repo.search.transaction.SimpleTransaction; -import org.alfresco.repo.search.transaction.SimpleTransactionManager; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; -import org.alfresco.repo.transaction.TransactionUtil; -import org.alfresco.repo.transaction.TransactionUtil.TransactionWork; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.transaction.TransactionService; -import org.alfresco.util.GUID; -import org.apache.commons.io.FileUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.store.Lock; -import org.quartz.Job; -import org.quartz.JobDataMap; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; - -/** - * This class is resource manager LuceneIndexers and LuceneSearchers. - * - * It supports two phase commit inside XA transactions and outside transactions it provides thread local transaction support. - * - * TODO: Provide pluggable support for a transaction manager TODO: Integrate with Spring transactions - * - * @author andyh - * - */ - -public class LuceneIndexerAndSearcherFactory implements LuceneIndexerAndSearcher, XAResource -{ - private static Log logger = LogFactory.getLog(LuceneIndexerAndSearcherFactory.class); - - private DictionaryService dictionaryService; - - private NamespaceService nameSpaceService; - - private int queryMaxClauses; - - private int indexerBatchSize; - - private int indexerMinMergeDocs; - - private int indexerMergeFactor; - - private int indexerMaxMergeDocs; - - private String lockDirectory; - - /** - * A map of active global transactions . It contains all the indexers a transaction has used, with at most one indexer for each store within a transaction - */ - - private static Map> activeIndexersInGlobalTx = new HashMap>(); - - /** - * Suspended global transactions. - */ - private static Map> suspendedIndexersInGlobalTx = new HashMap>(); - - /** - * Thread local indexers - used outside a global transaction - */ - - private static ThreadLocal> threadLocalIndexers = new ThreadLocal>(); - - /** - * The dafault timeout for transactions TODO: Respect this - */ - - private int timeout = DEFAULT_TIMEOUT; - - /** - * Default time out value set to 10 minutes. - */ - private static final int DEFAULT_TIMEOUT = 600000; - - /** - * The node service we use to get information about nodes - */ - - private NodeService nodeService; - - private LuceneIndexLock luceneIndexLock; - - private FullTextSearchIndexer luceneFullTextSearchIndexer; - - private String indexRootLocation; - - private ContentService contentService; - - private QueryRegisterComponent queryRegister; - - /** the maximum transformation time to allow atomically, defaulting to 20ms */ - private long maxAtomicTransformationTime = 20; - - private int indexerMaxFieldLength; - - /** - * Private constructor for the singleton TODO: FIt in with IOC - */ - - public LuceneIndexerAndSearcherFactory() - { - super(); - } - - /** - * Setter for getting the node service via IOC Used in the Spring container - * - * @param nodeService - */ - - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - public void setNameSpaceService(NamespaceService nameSpaceService) - { - this.nameSpaceService = nameSpaceService; - } - - public void setLuceneIndexLock(LuceneIndexLock luceneIndexLock) - { - this.luceneIndexLock = luceneIndexLock; - } - - public void setLuceneFullTextSearchIndexer(FullTextSearchIndexer luceneFullTextSearchIndexer) - { - this.luceneFullTextSearchIndexer = luceneFullTextSearchIndexer; - } - - public void setIndexRootLocation(String indexRootLocation) - { - this.indexRootLocation = indexRootLocation; - } - - public void setQueryRegister(QueryRegisterComponent queryRegister) - { - this.queryRegister = queryRegister; - } - - /** - * Set the maximum average transformation time allowed to a transformer in order to have the transformation performed in the current transaction. The default is 20ms. - * - * @param maxAtomicTransformationTime - * the maximum average time that a text transformation may take in order to be performed atomically. - */ - public void setMaxAtomicTransformationTime(long maxAtomicTransformationTime) - { - this.maxAtomicTransformationTime = maxAtomicTransformationTime; - } - - /** - * Check if we are in a global transactoin according to the transaction manager - * - * @return - */ - - private boolean inGlobalTransaction() - { - try - { - return SimpleTransactionManager.getInstance().getTransaction() != null; - } - catch (SystemException e) - { - return false; - } - } - - /** - * Get the local transaction - may be null oif we are outside a transaction. - * - * @return - * @throws IndexerException - */ - private SimpleTransaction getTransaction() throws IndexerException - { - try - { - return SimpleTransactionManager.getInstance().getTransaction(); - } - catch (SystemException e) - { - throw new IndexerException("Failed to get transaction", e); - } - } - - /** - * Get an indexer for the store to use in the current transaction for this thread of control. - * - * @param storeRef - - * the id of the store - */ - public LuceneIndexer getIndexer(StoreRef storeRef) throws IndexerException - { - // register to receive txn callbacks - // TODO: make this conditional on whether the XA stuff is being used - // directly on not - AlfrescoTransactionSupport.bindLucene(this); - - if (inGlobalTransaction()) - { - SimpleTransaction tx = getTransaction(); - // Only find indexers in the active list - Map indexers = activeIndexersInGlobalTx.get(tx); - if (indexers == null) - { - if (suspendedIndexersInGlobalTx.containsKey(tx)) - { - throw new IndexerException("Trying to obtain an index for a suspended transaction."); - } - indexers = new HashMap(); - activeIndexersInGlobalTx.put(tx, indexers); - try - { - tx.enlistResource(this); - } - // TODO: what to do in each case? - catch (IllegalStateException e) - { - throw new IndexerException("", e); - } - catch (RollbackException e) - { - throw new IndexerException("", e); - } - catch (SystemException e) - { - throw new IndexerException("", e); - } - } - LuceneIndexer indexer = indexers.get(storeRef); - if (indexer == null) - { - indexer = createIndexer(storeRef, getTransactionId(tx, storeRef)); - indexers.put(storeRef, indexer); - } - return indexer; - } - else - // A thread local transaction - { - return getThreadLocalIndexer(storeRef); - } - - } - - private LuceneIndexer getThreadLocalIndexer(StoreRef storeRef) - { - Map indexers = threadLocalIndexers.get(); - if (indexers == null) - { - indexers = new HashMap(); - threadLocalIndexers.set(indexers); - } - LuceneIndexer indexer = indexers.get(storeRef); - if (indexer == null) - { - indexer = createIndexer(storeRef, GUID.generate()); - indexers.put(storeRef, indexer); - } - return indexer; - } - - /** - * Get the transaction identifier uised to store it in the transaction map. - * - * @param tx - * @return - */ - private static String getTransactionId(Transaction tx, StoreRef storeRef) - { - if (tx instanceof SimpleTransaction) - { - SimpleTransaction simpleTx = (SimpleTransaction) tx; - return simpleTx.getGUID(); - } - else - { - Map indexers = threadLocalIndexers.get(); - if (indexers != null) - { - LuceneIndexer indexer = indexers.get(storeRef); - if (indexer != null) - { - return indexer.getDeltaId(); - } - } - return null; - } - } - - /** - * Encapsulate creating an indexer - * - * @param storeRef - * @param deltaId - * @return - */ - private LuceneIndexerImpl createIndexer(StoreRef storeRef, String deltaId) - { - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(storeRef, deltaId, this); - indexer.setNodeService(nodeService); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setLuceneFullTextSearchIndexer(luceneFullTextSearchIndexer); - indexer.setContentService(contentService); - indexer.setMaxAtomicTransformationTime(maxAtomicTransformationTime); - return indexer; - } - - /** - * Encapsulate creating a searcher over the main index - */ - public LuceneSearcher getSearcher(StoreRef storeRef, boolean searchDelta) throws SearcherException - { - String deltaId = null; - LuceneIndexer indexer = null; - if (searchDelta) - { - deltaId = getTransactionId(getTransaction(), storeRef); - if (deltaId != null) - { - indexer = getIndexer(storeRef); - } - } - LuceneSearcher searcher = getSearcher(storeRef, indexer); - return searcher; - } - - /** - * Get a searcher over the index and the current delta - * - * @param storeRef - * @param deltaId - * @return - * @throws SearcherException - */ - private LuceneSearcher getSearcher(StoreRef storeRef, LuceneIndexer indexer) throws SearcherException - { - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(storeRef, indexer, this); - searcher.setNamespacePrefixResolver(nameSpaceService); - searcher.setLuceneIndexLock(luceneIndexLock); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setQueryRegister(queryRegister); - return searcher; - } - - /* - * XAResource implementation - */ - - public void commit(Xid xid, boolean onePhase) throws XAException - { - try - { - // TODO: Should be remembering overall state - // TODO: Keep track of prepare responses - Map indexers = activeIndexersInGlobalTx.get(xid); - if (indexers == null) - { - if (suspendedIndexersInGlobalTx.containsKey(xid)) - { - throw new XAException("Trying to commit indexes for a suspended transaction."); - } - else - { - // nothing to do - return; - } - } - - if (onePhase) - { - if (indexers.size() == 0) - { - return; - } - else if (indexers.size() == 1) - { - for (LuceneIndexer indexer : indexers.values()) - { - indexer.commit(); - } - return; - } - else - { - throw new XAException("Trying to do one phase commit on more than one index"); - } - } - else - // two phase - { - for (LuceneIndexer indexer : indexers.values()) - { - indexer.commit(); - } - return; - } - } - finally - { - activeIndexersInGlobalTx.remove(xid); - } - } - - public void end(Xid xid, int flag) throws XAException - { - Map indexers = activeIndexersInGlobalTx.get(xid); - if (indexers == null) - { - if (suspendedIndexersInGlobalTx.containsKey(xid)) - { - throw new XAException("Trying to commit indexes for a suspended transaction."); - } - else - { - // nothing to do - return; - } - } - if (flag == XAResource.TMSUSPEND) - { - activeIndexersInGlobalTx.remove(xid); - suspendedIndexersInGlobalTx.put(xid, indexers); - } - else if (flag == TMFAIL) - { - activeIndexersInGlobalTx.remove(xid); - suspendedIndexersInGlobalTx.remove(xid); - } - else if (flag == TMSUCCESS) - { - activeIndexersInGlobalTx.remove(xid); - } - } - - public void forget(Xid xid) throws XAException - { - activeIndexersInGlobalTx.remove(xid); - suspendedIndexersInGlobalTx.remove(xid); - } - - public int getTransactionTimeout() throws XAException - { - return timeout; - } - - public boolean isSameRM(XAResource xar) throws XAException - { - return (xar instanceof LuceneIndexerAndSearcherFactory); - } - - public int prepare(Xid xid) throws XAException - { - // TODO: Track state OK, ReadOnly, Exception (=> rolled back?) - Map indexers = activeIndexersInGlobalTx.get(xid); - if (indexers == null) - { - if (suspendedIndexersInGlobalTx.containsKey(xid)) - { - throw new XAException("Trying to commit indexes for a suspended transaction."); - } - else - { - // nothing to do - return XAResource.XA_OK; - } - } - boolean isPrepared = true; - boolean isModified = false; - for (LuceneIndexer indexer : indexers.values()) - { - try - { - isModified |= indexer.isModified(); - indexer.prepare(); - } - catch (IndexerException e) - { - isPrepared = false; - } - } - if (isPrepared) - { - if (isModified) - { - return XAResource.XA_OK; - } - else - { - return XAResource.XA_RDONLY; - } - } - else - { - throw new XAException("Failed to prepare: requires rollback"); - } - } - - public Xid[] recover(int arg0) throws XAException - { - // We can not rely on being able to recover at the moment - // Avoiding for performance benefits at the moment - // Assume roll back and no recovery - in the worst case we get an unused - // delta - // This should be there to avoid recovery of partial commits. - // It is difficult to see how we can mandate the same conditions. - return new Xid[0]; - } - - public void rollback(Xid xid) throws XAException - { - // TODO: What to do if all do not roll back? - try - { - Map indexers = activeIndexersInGlobalTx.get(xid); - if (indexers == null) - { - if (suspendedIndexersInGlobalTx.containsKey(xid)) - { - throw new XAException("Trying to commit indexes for a suspended transaction."); - } - else - { - // nothing to do - return; - } - } - for (LuceneIndexer indexer : indexers.values()) - { - indexer.rollback(); - } - } - finally - { - activeIndexersInGlobalTx.remove(xid); - } - } - - public boolean setTransactionTimeout(int timeout) throws XAException - { - this.timeout = timeout; - return true; - } - - public void start(Xid xid, int flag) throws XAException - { - Map active = activeIndexersInGlobalTx.get(xid); - Map suspended = suspendedIndexersInGlobalTx.get(xid); - if (flag == XAResource.TMJOIN) - { - // must be active - if ((active != null) && (suspended == null)) - { - return; - } - else - { - throw new XAException("Trying to rejoin transaction in an invalid state"); - } - - } - else if (flag == XAResource.TMRESUME) - { - // must be suspended - if ((active == null) && (suspended != null)) - { - suspendedIndexersInGlobalTx.remove(xid); - activeIndexersInGlobalTx.put(xid, suspended); - return; - } - else - { - throw new XAException("Trying to rejoin transaction in an invalid state"); - } - - } - else if (flag == XAResource.TMNOFLAGS) - { - if ((active == null) && (suspended == null)) - { - return; - } - else - { - throw new XAException("Trying to start an existing or suspended transaction"); - } - } - else - { - throw new XAException("Unkown flags for start " + flag); - } - - } - - /* - * Thread local support for transactions - */ - - /** - * Commit the transaction - */ - - public void commit() throws IndexerException - { - try - { - Map indexers = threadLocalIndexers.get(); - if (indexers != null) - { - for (LuceneIndexer indexer : indexers.values()) - { - try - { - indexer.commit(); - } - catch (IndexerException e) - { - rollback(); - throw e; - } - } - } - } - finally - { - if (threadLocalIndexers.get() != null) - { - threadLocalIndexers.get().clear(); - threadLocalIndexers.set(null); - } - } - } - - /** - * Prepare the transaction TODO: Store prepare results - * - * @return - */ - public int prepare() throws IndexerException - { - boolean isPrepared = true; - boolean isModified = false; - Map indexers = threadLocalIndexers.get(); - if (indexers != null) - { - for (LuceneIndexer indexer : indexers.values()) - { - try - { - isModified |= indexer.isModified(); - indexer.prepare(); - } - catch (IndexerException e) - { - isPrepared = false; - throw new IndexerException("Failed to prepare: requires rollback", e); - } - } - } - if (isPrepared) - { - if (isModified) - { - return XAResource.XA_OK; - } - else - { - return XAResource.XA_RDONLY; - } - } - else - { - throw new IndexerException("Failed to prepare: requires rollback"); - } - } - - /** - * Roll back the transaction - */ - public void rollback() - { - Map indexers = threadLocalIndexers.get(); - - if (indexers != null) - { - for (LuceneIndexer indexer : indexers.values()) - { - try - { - indexer.rollback(); - } - catch (IndexerException e) - { - - } - } - } - - if (threadLocalIndexers.get() != null) - { - threadLocalIndexers.get().clear(); - threadLocalIndexers.set(null); - } - - } - - public void flush() - { - // TODO: Needs fixing if we expose the indexer in JTA - Map indexers = threadLocalIndexers.get(); - - if (indexers != null) - { - for (LuceneIndexer indexer : indexers.values()) - { - indexer.flushPending(); - } - } - } - - public void setContentService(ContentService contentService) - { - this.contentService = contentService; - } - - public String getIndexRootLocation() - { - return indexRootLocation; - } - - public int getIndexerBatchSize() - { - return indexerBatchSize; - } - - public void setIndexerBatchSize(int indexerBatchSize) - { - this.indexerBatchSize = indexerBatchSize; - } - - public int getIndexerMaxMergeDocs() - { - return indexerMaxMergeDocs; - } - - public void setIndexerMaxMergeDocs(int indexerMaxMergeDocs) - { - this.indexerMaxMergeDocs = indexerMaxMergeDocs; - } - - public int getIndexerMergeFactor() - { - return indexerMergeFactor; - } - - public void setIndexerMergeFactor(int indexerMergeFactor) - { - this.indexerMergeFactor = indexerMergeFactor; - } - - public int getIndexerMinMergeDocs() - { - return indexerMinMergeDocs; - } - - public void setIndexerMinMergeDocs(int indexerMinMergeDocs) - { - this.indexerMinMergeDocs = indexerMinMergeDocs; - } - - public String getLockDirectory() - { - return lockDirectory; - } - - public void setLockDirectory(String lockDirectory) - { - this.lockDirectory = lockDirectory; - // Set the lucene lock file via System property - // org.apache.lucene.lockdir - System.setProperty("org.apache.lucene.lockdir", lockDirectory); - // Make sure the lock directory exists - File lockDir = new File(lockDirectory); - if (!lockDir.exists()) - { - lockDir.mkdirs(); - } - // clean out any existing locks when we start up - - File[] children = lockDir.listFiles(); - if (children != null) - { - for (int i = 0; i < children.length; i++) - { - File child = children[i]; - if (child.isFile()) - { - if (child.exists() && !child.delete() && child.exists()) - { - throw new IllegalStateException("Failed to delete " + child); - } - } - } - } - } - - public int getQueryMaxClauses() - { - return queryMaxClauses; - } - - public void setQueryMaxClauses(int queryMaxClauses) - { - this.queryMaxClauses = queryMaxClauses; - BooleanQuery.setMaxClauseCount(this.queryMaxClauses); - } - - public void setWriteLockTimeout(long timeout) - { - IndexWriter.WRITE_LOCK_TIMEOUT = timeout; - } - - public void setCommitLockTimeout(long timeout) - { - IndexWriter.COMMIT_LOCK_TIMEOUT = timeout; - } - - public void setLockPollInterval(long time) - { - Lock.LOCK_POLL_INTERVAL = time; - } - - public int getIndexerMaxFieldLength() - { - return indexerMaxFieldLength; - } - - public void setIndexerMaxFieldLength(int indexerMaxFieldLength) - { - this.indexerMaxFieldLength = indexerMaxFieldLength; - System.setProperty("org.apache.lucene.maxFieldLength", "" + indexerMaxFieldLength); - } - - /** - * This component is able to safely perform backups of the Lucene indexes while the server is running. - *

- * It can be run directly by calling the {@link #backup() } method, but the convenience {@link LuceneIndexBackupJob} can be used to call it as well. - * - * @author Derek Hulley - */ - public static class LuceneIndexBackupComponent - { - private TransactionService transactionService; - - private LuceneIndexerAndSearcher factory; - - private NodeService nodeService; - - private String targetLocation; - - public LuceneIndexBackupComponent() - { - } - - /** - * Provides transactions in which to perform the work - * - * @param transactionService - */ - public void setTransactionService(TransactionService transactionService) - { - this.transactionService = transactionService; - } - - /** - * Set the Lucene index factory that will be used to control the index locks - * - * @param factory - * the index factory - */ - public void setFactory(LuceneIndexerAndSearcher factory) - { - this.factory = factory; - } - - /** - * Used to retrieve the stores - * - * @param nodeService - * the node service - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * Set the directory to which the backup will be copied - * - * @param targetLocation - * the backup directory - */ - public void setTargetLocation(String targetLocation) - { - this.targetLocation = targetLocation; - } - - /** - * Backup the Lucene indexes - */ - public void backup() - { - TransactionWork backupWork = new TransactionWork() - { - public Object doWork() throws Exception - { - backupImpl(); - return null; - } - }; - TransactionUtil.executeInUserTransaction(transactionService, backupWork); - } - - private void backupImpl() - { - // create the location to copy to - final File targetDir = new File(targetLocation); - if (targetDir.exists() && !targetDir.isDirectory()) - { - throw new AlfrescoRuntimeException("Target location is a file and not a directory: " + targetDir); - } - final File targetParentDir = targetDir.getParentFile(); - if (targetParentDir == null) - { - throw new AlfrescoRuntimeException("Target location may not be a root directory: " + targetDir); - } - final File tempDir = new File(targetParentDir, "indexbackup_temp"); - - factory.doWithAllWriteLocks(new WithAllWriteLocksWork () - { - public Object doWork() - { - try - { - File indexRootDir = new File(factory.getIndexRootLocation()); - // perform the copy - backupDirectory(indexRootDir, tempDir, targetDir); - return null; - } - catch (Throwable e) - { - throw new AlfrescoRuntimeException( - "Failed to copy Lucene index root: \n" - + " Index root: " + factory.getIndexRootLocation() + "\n" + " Target: " - + targetDir, e); - } - } - }); - - if (logger.isDebugEnabled()) - { - logger.debug("Backed up Lucene indexes: \n" + " Target directory: " + targetDir); - } - } - - /** - * Makes a backup of the source directory via a temporary folder - * - * @param storeRef - */ - private void backupDirectory(File sourceDir, File tempDir, File targetDir) throws Exception - { - if (!sourceDir.exists()) - { - // there is nothing to copy - return; - } - // delete the files from the temp directory - if (tempDir.exists()) - { - FileUtils.deleteDirectory(tempDir); - if (tempDir.exists()) - { - throw new AlfrescoRuntimeException("Temp directory exists and cannot be deleted: " + tempDir); - } - } - // copy to the temp directory - FileUtils.copyDirectory(sourceDir, tempDir, true); - // check that the temp directory was created - if (!tempDir.exists()) - { - throw new AlfrescoRuntimeException("Copy to temp location failed"); - } - // delete the target directory - FileUtils.deleteDirectory(targetDir); - if (targetDir.exists()) - { - throw new AlfrescoRuntimeException("Failed to delete older files from target location"); - } - // rename the temp to be the target - tempDir.renameTo(targetDir); - // make sure the rename worked - if (!targetDir.exists()) - { - throw new AlfrescoRuntimeException("Failed to rename temporary directory to target backup directory"); - } - } - } - - /** - * Job that lock uses the {@link LuceneIndexBackupComponent} to perform safe backups of the Lucene indexes. - * - * @author Derek Hulley - */ - public static class LuceneIndexBackupJob implements Job - { - /** KEY_LUCENE_INDEX_BACKUP_COMPONENT = 'luceneIndexBackupComponent' */ - public static final String KEY_LUCENE_INDEX_BACKUP_COMPONENT = "luceneIndexBackupComponent"; - - /** - * Locks the Lucene indexes and copies them to a backup location - */ - public void execute(JobExecutionContext context) throws JobExecutionException - { - JobDataMap jobData = context.getJobDetail().getJobDataMap(); - LuceneIndexBackupComponent backupComponent = (LuceneIndexBackupComponent) jobData - .get(KEY_LUCENE_INDEX_BACKUP_COMPONENT); - if (backupComponent == null) - { - throw new JobExecutionException("Missing job data: " + KEY_LUCENE_INDEX_BACKUP_COMPONENT); - } - // perform the backup - backupComponent.backup(); - } - } - - public R doWithAllWriteLocks(WithAllWriteLocksWork lockWork) - { - // get all the available stores - List storeRefs = nodeService.getStores(); - - // lock all the stores - List lockedStores = new ArrayList(storeRefs.size()); - try - { - for (StoreRef storeRef : storeRefs) - { - luceneIndexLock.getWriteLock(storeRef); - lockedStores.add(storeRef); - } - - try - { - return lockWork.doWork(); - } - catch (Throwable exception) - { - - // Re-throw the exception - if (exception instanceof RuntimeException) - { - throw (RuntimeException) exception; - } - else - { - throw new RuntimeException("Error during run with lock.", exception); - } - } - } - finally - { - for (StoreRef storeRef : lockedStores) - { - try - { - luceneIndexLock.releaseWriteLock(storeRef); - } - catch (Throwable e) - { - logger.error("Failed to release index lock for store " + storeRef, e); - } - } - } - } -} diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcherFactory2.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcherFactory2.java index 622a0f9a07..eeef925e30 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcherFactory2.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcherFactory2.java @@ -138,6 +138,10 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche private int indexerMaxFieldLength; + private long writeLockTimeout; + + private long commitLockTimeout; + /** * Private constructor for the singleton TODO: FIt in with IOC */ @@ -831,8 +835,8 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche { this.lockDirectory = lockDirectory; // Set the lucene lock file via System property - // org.apache.lucene.lockdir - System.setProperty("org.apache.lucene.lockdir", lockDirectory); + // org.apache.lucene.lockDir + System.setProperty("org.apache.lucene.lockDir", lockDirectory); // Make sure the lock directory exists File lockDir = new File(lockDirectory); if (!lockDir.exists()) @@ -871,12 +875,22 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche public void setWriteLockTimeout(long timeout) { - IndexWriter.WRITE_LOCK_TIMEOUT = timeout; + this.writeLockTimeout = timeout; } public void setCommitLockTimeout(long timeout) { - IndexWriter.COMMIT_LOCK_TIMEOUT = timeout; + this.commitLockTimeout = timeout; + } + + public long getCommitLockTimeout() + { + return commitLockTimeout; + } + + public long getWriteLockTimeout() + { + return writeLockTimeout; } public void setLockPollInterval(long time) diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl.java deleted file mode 100644 index 91310ecfcd..0000000000 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl.java +++ /dev/null @@ -1,1912 +0,0 @@ -/* - * Copyright (C) 2005 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * 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.alfresco.repo.search.impl.lucene; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Set; - -import javax.transaction.Status; -import javax.transaction.xa.XAResource; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.content.MimetypeMap; -import org.alfresco.repo.content.transform.ContentTransformer; -import org.alfresco.repo.search.IndexerException; -import org.alfresco.repo.search.impl.lucene.fts.FTSIndexerAware; -import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer; -import org.alfresco.service.cmr.dictionary.AspectDefinition; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.dictionary.PropertyDefinition; -import org.alfresco.service.cmr.dictionary.TypeDefinition; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.ContentIOException; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.cmr.repository.InvalidNodeRefException; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.Path; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; -import org.alfresco.service.cmr.search.ResultSetRow; -import org.alfresco.service.cmr.search.SearchParameters; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.EqualsHelper; -import org.alfresco.util.ISO9075; -import org.apache.log4j.Logger; -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.index.Term; -import org.apache.lucene.index.TermDocs; -import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.search.Hits; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Searcher; -import org.apache.lucene.search.TermQuery; - -/** - * The implementation of the lucene based indexer. Supports basic transactional behaviour if used on its own. - * - * @author andyh - * - */ -public class LuceneIndexerImpl extends LuceneBase implements LuceneIndexer -{ - public static final String NOT_INDEXED_NO_TRANSFORMATION = "nint"; - - public static final String NOT_INDEXED_TRANSFORMATION_FAILED = "nitf"; - - public static final String NOT_INDEXED_CONTENT_MISSING = "nicm"; - - private static Logger s_logger = Logger.getLogger(LuceneIndexerImpl.class); - - /** - * Enum for indexing actions against a node - */ - private enum Action - { - INDEX, REINDEX, DELETE, CASCADEREINDEX - }; - - /** - * The node service we use to get information about nodes - */ - private NodeService nodeService; - - /** - * Content service to get content for indexing. - */ - private ContentService contentService; - - /** the maximum transformation time to allow atomically, defaulting to 20ms */ - private long maxAtomicTransformationTime = 20; - - /** - * A list of all deletions we have made - at merge these deletions need to be made against the main index. - * - * TODO: Consider if this information needs to be persisted for recovery - */ - private Set deletions = new LinkedHashSet(); - - /** - * The status of this index - follows javax.transaction.Status - */ - - private int status = Status.STATUS_UNKNOWN; - - /** - * Has this index been modified? - */ - - private boolean isModified = false; - - /** - * Flag to indicte if we are doing an in transactional delta or a batch update to the index. If true, we are just fixing up non atomically indexed things from one or more other - * updates. - */ - - private Boolean isFTSUpdate = null; - - /** - * List of pending indexing commands. - */ - private List commandList = new ArrayList(10000); - - /** - * Call back to make after doing non atomic indexing - */ - private FTSIndexerAware callBack; - - /** - * Count of remaining items to index non atomically - */ - private int remainingCount = 0; - - /** - * A list of stuff that requires non atomic indexing - */ - private ArrayList toFTSIndex = new ArrayList(); - - /** - * Default construction - * - */ - LuceneIndexerImpl() - { - super(); - } - - /** - * IOC setting of dictionary service - */ - - public void setDictionaryService(DictionaryService dictionaryService) - { - super.setDictionaryService(dictionaryService); - } - - /** - * Setter for getting the node service via IOC Used in the Spring container - * - * @param nodeService - */ - - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * IOC setting of the content service - * - * @param contentService - */ - public void setContentService(ContentService contentService) - { - this.contentService = contentService; - } - - public void setMaxAtomicTransformationTime(long maxAtomicTransformationTime) - { - this.maxAtomicTransformationTime = maxAtomicTransformationTime; - } - - /*=========================== - * Indexer Implementation - ============================*/ - - /** - * Utility method to check we are in the correct state to do work Also keeps track of the dirty flag. - * - */ - - private void checkAbleToDoWork(boolean isFTS, boolean isModified) - { - if (isFTSUpdate == null) - { - isFTSUpdate = Boolean.valueOf(isFTS); - } - else - { - if (isFTS != isFTSUpdate.booleanValue()) - { - throw new IndexerException("Can not mix FTS and transactional updates"); - } - } - - switch (status) - { - case Status.STATUS_UNKNOWN: - status = Status.STATUS_ACTIVE; - break; - case Status.STATUS_ACTIVE: - // OK - break; - default: - // All other states are a problem - throw new IndexerException(buildErrorString()); - } - this.isModified = isModified; - } - - /** - * Utility method to report errors about invalid state. - * - * @return - */ - private String buildErrorString() - { - StringBuilder buffer = new StringBuilder(128); - buffer.append("The indexer is unable to accept more work: "); - switch (status) - { - case Status.STATUS_COMMITTED: - buffer.append("The indexer has been committed"); - break; - case Status.STATUS_COMMITTING: - buffer.append("The indexer is committing"); - break; - case Status.STATUS_MARKED_ROLLBACK: - buffer.append("The indexer is marked for rollback"); - break; - case Status.STATUS_PREPARED: - buffer.append("The indexer is prepared to commit"); - break; - case Status.STATUS_PREPARING: - buffer.append("The indexer is preparing to commit"); - break; - case Status.STATUS_ROLLEDBACK: - buffer.append("The indexer has been rolled back"); - break; - case Status.STATUS_ROLLING_BACK: - buffer.append("The indexer is rolling back"); - break; - case Status.STATUS_UNKNOWN: - buffer.append("The indexer is in an unknown state"); - break; - default: - break; - } - return buffer.toString(); - } - - /* - * Indexer Implementation - */ - - public void createNode(ChildAssociationRef relationshipRef) throws LuceneIndexException - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Create node " + relationshipRef.getChildRef()); - } - checkAbleToDoWork(false, true); - try - { - NodeRef childRef = relationshipRef.getChildRef(); - // If we have the root node we delete all other root nodes first - if ((relationshipRef.getParentRef() == null) - && childRef.equals(nodeService.getRootNode(childRef.getStoreRef()))) - { - addRootNodesToDeletionList(); - s_logger.warn("Detected root node addition: deleting all nodes from the index"); - } - index(childRef); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Create node failed", e); - } - } - - private void addRootNodesToDeletionList() - { - IndexReader mainReader = null; - try - { - try - { - mainReader = getReader(); - TermDocs td = mainReader.termDocs(new Term("ISROOT", "T")); - while (td.next()) - { - int doc = td.doc(); - Document document = mainReader.document(doc); - String id = document.get("ID"); - NodeRef ref = new NodeRef(id); - deleteImpl(ref, false, true, mainReader); - } - } - catch (IOException e) - { - throw new LuceneIndexException("Failed to delete all primary nodes", e); - } - } - finally - { - if (mainReader != null) - { - try - { - mainReader.close(); - } - catch (IOException e) - { - throw new LuceneIndexException("Filed to close main reader", e); - } - } - } - } - - public void updateNode(NodeRef nodeRef) throws LuceneIndexException - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Update node " + nodeRef); - } - checkAbleToDoWork(false, true); - try - { - reindex(nodeRef, false); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Update node failed", e); - } - } - - public void deleteNode(ChildAssociationRef relationshipRef) throws LuceneIndexException - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Delete node " + relationshipRef.getChildRef()); - } - checkAbleToDoWork(false, true); - try - { - delete(relationshipRef.getChildRef()); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Delete node failed", e); - } - } - - public void createChildRelationship(ChildAssociationRef relationshipRef) throws LuceneIndexException - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Create child " + relationshipRef); - } - checkAbleToDoWork(false, true); - try - { - // TODO: Optimise - // reindex(relationshipRef.getParentRef()); - reindex(relationshipRef.getChildRef(), true); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Failed to create child relationship", e); - } - } - - public void updateChildRelationship(ChildAssociationRef relationshipBeforeRef, - ChildAssociationRef relationshipAfterRef) throws LuceneIndexException - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Update child " + relationshipBeforeRef + " to " + relationshipAfterRef); - } - checkAbleToDoWork(false, true); - try - { - // TODO: Optimise - if (relationshipBeforeRef.getParentRef() != null) - { - // reindex(relationshipBeforeRef.getParentRef()); - } - reindex(relationshipBeforeRef.getChildRef(), true); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Failed to update child relationship", e); - } - } - - public void deleteChildRelationship(ChildAssociationRef relationshipRef) throws LuceneIndexException - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Delete child " + relationshipRef); - } - checkAbleToDoWork(false, true); - try - { - // TODO: Optimise - if (relationshipRef.getParentRef() != null) - { - // reindex(relationshipRef.getParentRef()); - } - reindex(relationshipRef.getChildRef(), true); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Failed to delete child relationship", e); - } - } - - /** - * Generate an indexer - * - * @param storeRef - * @param deltaId - * @return - */ - public static LuceneIndexerImpl getUpdateIndexer(StoreRef storeRef, String deltaId, LuceneConfig config) - throws LuceneIndexException - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Creating indexer"); - } - LuceneIndexerImpl indexer = new LuceneIndexerImpl(); - indexer.setLuceneConfig(config); - indexer.initialise(storeRef, deltaId, false, true); - return indexer; - } - - /* - * Transactional support Used by the resource manager for indexers. - */ - - /** - * Commit this index - */ - - public void commit() throws LuceneIndexException - { - switch (status) - { - case Status.STATUS_COMMITTING: - throw new LuceneIndexException("Unable to commit: Transaction is committing"); - case Status.STATUS_COMMITTED: - throw new LuceneIndexException("Unable to commit: Transaction is commited "); - case Status.STATUS_ROLLING_BACK: - throw new LuceneIndexException("Unable to commit: Transaction is rolling back"); - case Status.STATUS_ROLLEDBACK: - throw new LuceneIndexException("Unable to commit: Transaction is aleady rolled back"); - case Status.STATUS_MARKED_ROLLBACK: - throw new LuceneIndexException("Unable to commit: Transaction is marked for roll back"); - case Status.STATUS_PREPARING: - throw new LuceneIndexException("Unable to commit: Transaction is preparing"); - case Status.STATUS_ACTIVE: - // special case - commit from active - prepare(); - // drop through to do the commit; - default: - if (status != Status.STATUS_PREPARED) - { - throw new LuceneIndexException("Index must be prepared to commit"); - } - status = Status.STATUS_COMMITTING; - try - { - if (isModified()) - { - if (isFTSUpdate.booleanValue()) - { - doFTSIndexCommit(); - // FTS does not trigger indexing request - } - else - { - // Build the deletion terms - Set terms = new LinkedHashSet(); - for (NodeRef nodeRef : deletions) - { - terms.add(new Term("ID", nodeRef.toString())); - } - // Merge - mergeDeltaIntoMain(terms); - luceneFullTextSearchIndexer.requiresIndex(store); - } - } - status = Status.STATUS_COMMITTED; - if (callBack != null) - { - callBack.indexCompleted(store, remainingCount, null); - } - } - catch (LuceneIndexException e) - { - // If anything goes wrong we try and do a roll back - rollback(); - throw new LuceneIndexException("Commit failed", e); - } - finally - { - // Make sure we tidy up - deleteDelta(); - } - break; - } - } - - private void doFTSIndexCommit() throws LuceneIndexException - { - IndexReader mainReader = null; - IndexReader deltaReader = null; - IndexSearcher mainSearcher = null; - IndexSearcher deltaSearcher = null; - - try - { - try - { - mainReader = getReader(); - deltaReader = getDeltaReader(); - mainSearcher = new IndexSearcher(mainReader); - deltaSearcher = new IndexSearcher(deltaReader); - - for (Helper helper : toFTSIndex) - { - BooleanQuery query = new BooleanQuery(); - query.add(new TermQuery(new Term("ID", helper.nodeRef.toString())), true, false); - query.add(new TermQuery(new Term("TX", helper.tx)), true, false); - query.add(new TermQuery(new Term("ISNODE", "T")), false, false); - - try - { - Hits hits = mainSearcher.search(query); - if (hits.length() > 0) - { - // No change - for (int i = 0; i < hits.length(); i++) - { - mainReader.delete(hits.id(i)); - } - } - else - { - hits = deltaSearcher.search(query); - for (int i = 0; i < hits.length(); i++) - { - deltaReader.delete(hits.id(i)); - } - } - } - catch (IOException e) - { - throw new LuceneIndexException("Failed to delete an FTS update from the original index", e); - } - } - - } - finally - { - if (deltaSearcher != null) - { - try - { - deltaSearcher.close(); - } - catch (IOException e) - { - s_logger.warn("Failed to close delta searcher", e); - } - } - if (mainSearcher != null) - { - try - { - mainSearcher.close(); - } - catch (IOException e) - { - s_logger.warn("Failed to close main searcher", e); - } - } - try - { - closeDeltaReader(); - } - catch (LuceneIndexException e) - { - s_logger.warn("Failed to close delta reader", e); - } - if (mainReader != null) - { - try - { - mainReader.close(); - } - catch (IOException e) - { - s_logger.warn("Failed to close main reader", e); - } - } - } - - mergeDeltaIntoMain(new LinkedHashSet()); - } - catch (LuceneIndexException e) - { - // If anything goes wrong we try and do a roll back - rollback(); - throw new LuceneIndexException("Commit failed", e); - } - finally - { - // Make sure we tidy up - deleteDelta(); - } - - } - - /** - * Prepare to commit - * - * At the moment this makes sure we have all the locks - * - * TODO: This is not doing proper serialisation against the index as would a data base transaction. - * - * @return - */ - public int prepare() throws LuceneIndexException - { - - switch (status) - { - case Status.STATUS_COMMITTING: - throw new IndexerException("Unable to prepare: Transaction is committing"); - case Status.STATUS_COMMITTED: - throw new IndexerException("Unable to prepare: Transaction is commited "); - case Status.STATUS_ROLLING_BACK: - throw new IndexerException("Unable to prepare: Transaction is rolling back"); - case Status.STATUS_ROLLEDBACK: - throw new IndexerException("Unable to prepare: Transaction is aleady rolled back"); - case Status.STATUS_MARKED_ROLLBACK: - throw new IndexerException("Unable to prepare: Transaction is marked for roll back"); - case Status.STATUS_PREPARING: - throw new IndexerException("Unable to prepare: Transaction is already preparing"); - case Status.STATUS_PREPARED: - throw new IndexerException("Unable to prepare: Transaction is already prepared"); - default: - status = Status.STATUS_PREPARING; - try - { - if (isModified()) - { - saveDelta(); - flushPending(); - prepareToMergeIntoMain(); - } - status = Status.STATUS_PREPARED; - return isModified ? XAResource.XA_OK : XAResource.XA_RDONLY; - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Index failed to prepare", e); - } - } - } - - /** - * Has this index been modified? - * - * @return - */ - public boolean isModified() - { - return isModified; - } - - /** - * Return the javax.transaction.Status integer status code - * - * @return - */ - public int getStatus() - { - return status; - } - - /** - * Roll back the index changes (this just means they are never added) - * - */ - - public void rollback() throws LuceneIndexException - { - switch (status) - { - - case Status.STATUS_COMMITTED: - throw new IndexerException("Unable to roll back: Transaction is committed "); - case Status.STATUS_ROLLING_BACK: - throw new IndexerException("Unable to roll back: Transaction is rolling back"); - case Status.STATUS_ROLLEDBACK: - throw new IndexerException("Unable to roll back: Transaction is already rolled back"); - case Status.STATUS_COMMITTING: - // Can roll back during commit - default: - status = Status.STATUS_ROLLING_BACK; - if (isModified()) - { - deleteDelta(); - } - status = Status.STATUS_ROLLEDBACK; - if (callBack != null) - { - callBack.indexCompleted(store, 0, null); - } - break; - } - } - - /** - * Mark this index for roll back only. This action can not be reversed. It will reject all other work and only allow roll back. - * - */ - - public void setRollbackOnly() - { - switch (status) - { - case Status.STATUS_COMMITTING: - throw new IndexerException("Unable to mark for rollback: Transaction is committing"); - case Status.STATUS_COMMITTED: - throw new IndexerException("Unable to mark for rollback: Transaction is committed"); - default: - status = Status.STATUS_MARKED_ROLLBACK; - break; - } - } - - /* - * Implementation - */ - - private void index(NodeRef nodeRef) throws LuceneIndexException - { - addCommand(new Command(nodeRef, Action.INDEX)); - } - - private void reindex(NodeRef nodeRef, boolean cascadeReindexDirectories) throws LuceneIndexException - { - addCommand(new Command(nodeRef, cascadeReindexDirectories ? Action.CASCADEREINDEX : Action.REINDEX)); - } - - private void delete(NodeRef nodeRef) throws LuceneIndexException - { - addCommand(new Command(nodeRef, Action.DELETE)); - } - - private void addCommand(Command command) - { - if (commandList.size() > 0) - { - Command last = commandList.get(commandList.size() - 1); - if ((last.action == command.action) && (last.nodeRef.equals(command.nodeRef))) - { - return; - } - } - purgeCommandList(command); - commandList.add(command); - - if (commandList.size() > getLuceneConfig().getIndexerBatchSize()) - { - flushPending(); - } - } - - private void purgeCommandList(Command command) - { - if (command.action == Action.DELETE) - { - removeFromCommandList(command, false); - } - else if (command.action == Action.REINDEX) - { - removeFromCommandList(command, true); - } - else if (command.action == Action.INDEX) - { - removeFromCommandList(command, true); - } - else if (command.action == Action.CASCADEREINDEX) - { - removeFromCommandList(command, true); - } - } - - private void removeFromCommandList(Command command, boolean matchExact) - { - for (ListIterator it = commandList.listIterator(commandList.size()); it.hasPrevious(); /**/) - { - Command current = it.previous(); - if (matchExact) - { - if ((current.action == command.action) && (current.nodeRef.equals(command.nodeRef))) - { - it.remove(); - return; - } - } - else - { - if (current.nodeRef.equals(command.nodeRef)) - { - it.remove(); - } - } - } - } - - public void flushPending() throws LuceneIndexException - { - IndexReader mainReader = null; - try - { - mainReader = getReader(); - Set forIndex = new LinkedHashSet(); - - for (Command command : commandList) - { - if (command.action == Action.INDEX) - { - // Indexing just requires the node to be added to the list - forIndex.add(command.nodeRef); - } - else if (command.action == Action.REINDEX) - { - // Reindex is a delete and then and index - Set set = deleteImpl(command.nodeRef, true, false, mainReader); - - // Deleting any pending index actions - // - make sure we only do at most one index - forIndex.removeAll(set); - // Add the nodes for index - forIndex.addAll(set); - } - else if (command.action == Action.CASCADEREINDEX) - { - // Reindex is a delete and then and index - Set set = deleteImpl(command.nodeRef, true, true, mainReader); - - // Deleting any pending index actions - // - make sure we only do at most one index - forIndex.removeAll(set); - // Add the nodes for index - forIndex.addAll(set); - } - else if (command.action == Action.DELETE) - { - // Delete the nodes - Set set = deleteImpl(command.nodeRef, false, true, mainReader); - // Remove any pending indexes - forIndex.removeAll(set); - } - } - commandList.clear(); - indexImpl(forIndex, false); - } - finally - { - if (mainReader != null) - { - try - { - mainReader.close(); - } - catch (IOException e) - { - throw new LuceneIndexException("Filed to close main reader", e); - } - } - // Make sure deletes are sent - closeDeltaReader(); - // Make sure writes and updates are sent. - closeDeltaWriter(); - } - } - - private Set deleteImpl(NodeRef nodeRef, boolean forReindex, boolean cascade, IndexReader mainReader) - throws LuceneIndexException - { - // startTimer(); - getDeltaReader(); - // outputTime("Delete "+nodeRef+" size = "+getDeltaWriter().docCount()); - Set refs = new LinkedHashSet(); - - refs.addAll(deleteContainerAndBelow(nodeRef, getDeltaReader(), true, cascade)); - refs.addAll(deleteContainerAndBelow(nodeRef, mainReader, false, cascade)); - - if (!forReindex) - { - Set leafrefs = new LinkedHashSet(); - - leafrefs.addAll(deletePrimary(refs, getDeltaReader(), true)); - leafrefs.addAll(deletePrimary(refs, mainReader, false)); - - leafrefs.addAll(deleteReference(refs, getDeltaReader(), true)); - leafrefs.addAll(deleteReference(refs, mainReader, false)); - - refs.addAll(leafrefs); - } - - deletions.addAll(refs); - - return refs; - - } - - private Set deletePrimary(Collection nodeRefs, IndexReader reader, boolean delete) - throws LuceneIndexException - { - - Set refs = new LinkedHashSet(); - - for (NodeRef nodeRef : nodeRefs) - { - - try - { - TermDocs td = reader.termDocs(new Term("PRIMARYPARENT", nodeRef.toString())); - while (td.next()) - { - int doc = td.doc(); - Document document = reader.document(doc); - String id = document.get("ID"); - NodeRef ref = new NodeRef(id); - refs.add(ref); - if (delete) - { - reader.delete(doc); - } - } - } - catch (IOException e) - { - throw new LuceneIndexException("Failed to delete node by primary parent for " + nodeRef.toString(), e); - } - } - - return refs; - - } - - private Set deleteReference(Collection nodeRefs, IndexReader reader, boolean delete) - throws LuceneIndexException - { - - Set refs = new LinkedHashSet(); - - for (NodeRef nodeRef : nodeRefs) - { - - try - { - TermDocs td = reader.termDocs(new Term("PARENT", nodeRef.toString())); - while (td.next()) - { - int doc = td.doc(); - Document document = reader.document(doc); - String id = document.get("ID"); - NodeRef ref = new NodeRef(id); - refs.add(ref); - if (delete) - { - reader.delete(doc); - } - } - } - catch (IOException e) - { - throw new LuceneIndexException("Failed to delete node by parent for " + nodeRef.toString(), e); - } - } - - return refs; - - } - - private Set deleteContainerAndBelow(NodeRef nodeRef, IndexReader reader, boolean delete, boolean cascade) - throws LuceneIndexException - { - Set refs = new LinkedHashSet(); - - try - { - if (delete) - { - reader.delete(new Term("ID", nodeRef.toString())); - } - refs.add(nodeRef); - if (cascade) - { - TermDocs td = reader.termDocs(new Term("ANCESTOR", nodeRef.toString())); - while (td.next()) - { - int doc = td.doc(); - Document document = reader.document(doc); - String id = document.get("ID"); - NodeRef ref = new NodeRef(id); - refs.add(ref); - if (delete) - { - reader.delete(doc); - } - } - } - } - catch (IOException e) - { - throw new LuceneIndexException("Failed to delete container and below for " + nodeRef.toString(), e); - } - return refs; - } - - private void indexImpl(Set nodeRefs, boolean isNew) throws LuceneIndexException - { - for (NodeRef ref : nodeRefs) - { - indexImpl(ref, isNew); - } - } - - private void indexImpl(NodeRef nodeRef, boolean isNew) throws LuceneIndexException - { - IndexWriter writer = getDeltaWriter(); - - // avoid attempting to index nodes that don't exist - - try - { - List docs = createDocuments(nodeRef, isNew, false, true); - for (Document doc : docs) - { - try - { - writer.addDocument(doc /* - * TODO: Select the language based analyser - */); - } - catch (IOException e) - { - throw new LuceneIndexException("Failed to add document to index", e); - } - } - } - catch (InvalidNodeRefException e) - { - // The node does not exist - return; - } - - } - - static class Counter - { - int countInParent = 0; - - int count = -1; - - int getCountInParent() - { - return countInParent; - } - - int getRepeat() - { - return (count / countInParent) + 1; - } - - void incrementParentCount() - { - countInParent++; - } - - void increment() - { - count++; - } - - } - - private class Pair - { - private F first; - - private S second; - - public Pair(F first, S second) - { - this.first = first; - this.second = second; - } - - public F getFirst() - { - return first; - } - - public S getSecond() - { - return second; - } - } - - private List createDocuments(NodeRef nodeRef, boolean isNew, boolean indexAllProperties, - boolean includeDirectoryDocuments) - { - Map nodeCounts = getNodeCounts(nodeRef); - List docs = new ArrayList(); - ChildAssociationRef qNameRef = null; - Map properties = nodeService.getProperties(nodeRef); - NodeRef.Status nodeStatus = nodeService.getNodeStatus(nodeRef); - - Collection directPaths = nodeService.getPaths(nodeRef, false); - Collection> categoryPaths = getCategoryPaths(nodeRef, properties); - Collection> paths = new ArrayList>(directPaths.size() - + categoryPaths.size()); - for (Path path : directPaths) - { - paths.add(new Pair(path, null)); - } - paths.addAll(categoryPaths); - - Document xdoc = new Document(); - xdoc.add(new Field("ID", nodeRef.toString(), true, true, false)); - xdoc.add(new Field("TX", nodeStatus.getChangeTxnId(), true, true, false)); - boolean isAtomic = true; - for (QName propertyName : properties.keySet()) - { - Serializable value = properties.get(propertyName); - if (indexAllProperties) - { - indexProperty(nodeRef, propertyName, value, xdoc, false); - } - else - { - isAtomic &= indexProperty(nodeRef, propertyName, value, xdoc, true); - } - } - - boolean isRoot = nodeRef.equals(nodeService.getRootNode(nodeRef.getStoreRef())); - - StringBuilder qNameBuffer = new StringBuilder(64); - - for (Iterator> it = paths.iterator(); it.hasNext(); /**/) - { - Pair pair = it.next(); - // Lucene flags in order are: Stored, indexed, tokenised - - qNameRef = getLastRefOrNull(pair.getFirst()); - - String pathString = pair.getFirst().toString(); - if ((pathString.length() > 0) && (pathString.charAt(0) == '/')) - { - pathString = pathString.substring(1); - } - - if (isRoot) - { - // Root node - } - else if (pair.getFirst().size() == 1) - { - // Pseudo root node ignore - } - else - // not a root node - { - Counter counter = nodeCounts.get(qNameRef); - // If we have something in a container with root aspect we will - // not find it - - if ((counter == null) || (counter.getRepeat() < counter.getCountInParent())) - { - if ((qNameRef != null) && (qNameRef.getParentRef() != null) && (qNameRef.getQName() != null)) - { - if (qNameBuffer.length() > 0) - { - qNameBuffer.append(";/"); - } - qNameBuffer.append(ISO9075.getXPathName(qNameRef.getQName())); - xdoc.add(new Field("PARENT", qNameRef.getParentRef().toString(), true, true, false)); - xdoc.add(new Field("ASSOCTYPEQNAME", ISO9075.getXPathName(qNameRef.getTypeQName()), true, - false, false)); - xdoc.add(new Field("LINKASPECT", (pair.getSecond() == null) ? "" : ISO9075.getXPathName(pair - .getSecond()), true, true, false)); - } - } - - if (counter != null) - { - counter.increment(); - } - - // TODO: DC: Should this also include aspect child definitions? - QName nodeTypeRef = nodeService.getType(nodeRef); - TypeDefinition nodeTypeDef = getDictionaryService().getType(nodeTypeRef); - // check for child associations - - if (includeDirectoryDocuments) - { - if (nodeTypeDef.getChildAssociations().size() > 0) - { - if (directPaths.contains(pair.getFirst())) - { - Document directoryEntry = new Document(); - directoryEntry.add(new Field("ID", nodeRef.toString(), true, true, false)); - directoryEntry.add(new Field("PATH", pathString, true, true, true)); - for (NodeRef parent : getParents(pair.getFirst())) - { - directoryEntry.add(new Field("ANCESTOR", parent.toString(), false, true, false)); - } - directoryEntry.add(new Field("ISCONTAINER", "T", true, true, false)); - - if (isCategory(getDictionaryService().getType(nodeService.getType(nodeRef)))) - { - directoryEntry.add(new Field("ISCATEGORY", "T", true, true, false)); - } - - docs.add(directoryEntry); - } - } - } - } - } - - // Root Node - if (isRoot) - { - // TODO: Does the root element have a QName? - xdoc.add(new Field("ISCONTAINER", "T", true, true, false)); - xdoc.add(new Field("PATH", "", true, true, true)); - xdoc.add(new Field("QNAME", "", true, true, true)); - xdoc.add(new Field("ISROOT", "T", false, true, false)); - xdoc.add(new Field("PRIMARYASSOCTYPEQNAME", ISO9075.getXPathName(ContentModel.ASSOC_CHILDREN), true, false, - false)); - xdoc.add(new Field("ISNODE", "T", false, true, false)); - docs.add(xdoc); - - } - else - // not a root node - { - xdoc.add(new Field("QNAME", qNameBuffer.toString(), true, true, true)); - // xdoc.add(new Field("PARENT", parentBuffer.toString(), true, true, - // true)); - - ChildAssociationRef primary = nodeService.getPrimaryParent(nodeRef); - xdoc.add(new Field("PRIMARYPARENT", primary.getParentRef().toString(), true, true, false)); - xdoc.add(new Field("PRIMARYASSOCTYPEQNAME", ISO9075.getXPathName(primary.getTypeQName()), true, false, - false)); - QName typeQName = nodeService.getType(nodeRef); - - xdoc.add(new Field("TYPE", ISO9075.getXPathName(typeQName), true, true, false)); - for (QName classRef : nodeService.getAspects(nodeRef)) - { - xdoc.add(new Field("ASPECT", ISO9075.getXPathName(classRef), true, true, false)); - } - - xdoc.add(new Field("ISROOT", "F", false, true, false)); - xdoc.add(new Field("ISNODE", "T", false, true, false)); - if (isAtomic || indexAllProperties) - { - xdoc.add(new Field("FTSSTATUS", "Clean", false, true, false)); - } - else - { - if (isNew) - { - xdoc.add(new Field("FTSSTATUS", "New", false, true, false)); - } - else - { - xdoc.add(new Field("FTSSTATUS", "Dirty", false, true, false)); - } - } - - // { - docs.add(xdoc); - // } - } - - return docs; - } - - private ArrayList getParents(Path path) - { - ArrayList parentsInDepthOrderStartingWithSelf = new ArrayList(8); - for (Iterator elit = path.iterator(); elit.hasNext(); /**/) - { - Path.Element element = elit.next(); - if (!(element instanceof Path.ChildAssocElement)) - { - throw new IndexerException("Confused path: " + path); - } - Path.ChildAssocElement cae = (Path.ChildAssocElement) element; - parentsInDepthOrderStartingWithSelf.add(0, cae.getRef().getChildRef()); - - } - return parentsInDepthOrderStartingWithSelf; - } - - private ChildAssociationRef getLastRefOrNull(Path path) - { - if (path.last() instanceof Path.ChildAssocElement) - { - Path.ChildAssocElement cae = (Path.ChildAssocElement) path.last(); - return cae.getRef(); - } - else - { - return null; - } - } - - /** - * @param indexAtomicPropertiesOnly true to ignore all properties that must be indexed - * non-atomically - * @return Returns true if the property was indexed atomically, or false if it - * should be done asynchronously - */ - private boolean indexProperty( - NodeRef nodeRef, QName propertyName, Serializable value, Document doc, - boolean indexAtomicPropertiesOnly) - { - String attributeName = "@" + QName.createQName( - propertyName.getNamespaceURI(), - ISO9075.encode(propertyName.getLocalName())); - - boolean store = true; - boolean index = true; - boolean tokenise = true; - boolean atomic = true; - boolean isContent = false; - - PropertyDefinition propertyDef = getDictionaryService().getProperty(propertyName); - if (propertyDef != null) - { - index = propertyDef.isIndexed(); - store = propertyDef.isStoredInIndex(); - tokenise = propertyDef.isTokenisedInIndex(); - atomic = propertyDef.isIndexedAtomically(); - isContent = propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT); - } - if (value == null) - { - // the value is null - return true; - } - else if (indexAtomicPropertiesOnly && !atomic) - { - // we are only doing atomic properties and the property is definitely non-atomic - return false; - } - - if (!indexAtomicPropertiesOnly) - { - doc.removeFields(propertyName.toString()); - } - boolean wereAllAtomic = true; - // convert value to String - for (String strValue : DefaultTypeConverter.INSTANCE.getCollection(String.class, value)) - { - if (strValue == null) - { - // nothing to index - continue; - } - // String strValue = ValueConverter.convert(String.class, value); - // TODO: Need to add with the correct language based analyser - - if (isContent) - { - ContentData contentData = DefaultTypeConverter.INSTANCE.convert(ContentData.class, value); - if (!index || contentData.getMimetype() == null) - { - // no mimetype or property not indexed - continue; - } - // store mimetype in index - even if content does not index it is useful - doc.add(new Field( - attributeName + ".mimetype", - contentData.getMimetype(), - false, true, false)); - - ContentReader reader = contentService.getReader(nodeRef, propertyName); - if (reader != null && reader.exists()) - { - boolean readerReady = true; - // transform if necessary (it is not a UTF-8 text document) - if (!EqualsHelper.nullSafeEquals(reader.getMimetype(), MimetypeMap.MIMETYPE_TEXT_PLAIN) - || !EqualsHelper.nullSafeEquals(reader.getEncoding(), "UTF-8")) - { - // get the transformer - ContentTransformer transformer = contentService.getTransformer( - reader.getMimetype(), - MimetypeMap.MIMETYPE_TEXT_PLAIN); - // is this transformer good enough? - if (transformer == null) - { - // log it - if (s_logger.isDebugEnabled()) - { - s_logger.debug( - "Not indexed: No transformation: \n" + - " source: " + reader + "\n" + - " target: " + MimetypeMap.MIMETYPE_TEXT_PLAIN); - } - // don't index from the reader - readerReady = false; - // not indexed: no transformation - doc.add(Field.Text("TEXT", NOT_INDEXED_NO_TRANSFORMATION)); - doc.add(Field.Text(attributeName, NOT_INDEXED_NO_TRANSFORMATION)); - } - else if (indexAtomicPropertiesOnly && transformer.getTransformationTime() > maxAtomicTransformationTime) - { - // only indexing atomic properties - // indexing will take too long, so push it to the background - wereAllAtomic = false; - } - else - { - // We have a transformer that is fast enough - ContentWriter writer = contentService.getTempWriter(); - writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - // this is what the analyzers expect on the stream - writer.setEncoding("UTF-8"); - try - { - - transformer.transform(reader, writer); - // point the reader to the new-written content - reader = writer.getReader(); - } - catch (ContentIOException e) - { - // log it - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Not indexed: Transformation failed", e); - } - // don't index from the reader - readerReady = false; - // not indexed: transformation - // failed - doc.add(Field.Text("TEXT", NOT_INDEXED_TRANSFORMATION_FAILED)); - doc.add(Field.Text(attributeName, NOT_INDEXED_TRANSFORMATION_FAILED)); - } - } - } - // add the text field using the stream from the - // reader, but only if the reader is valid - if (readerReady) - { - InputStreamReader isr = null; - InputStream ris = reader.getContentInputStream(); - try - { - isr = new InputStreamReader(ris, "UTF-8"); - } - catch (UnsupportedEncodingException e) - { - isr = new InputStreamReader(ris); - } - doc.add(Field.Text("TEXT", isr)); - - ris = reader.getReader().getContentInputStream(); - try - { - isr = new InputStreamReader(ris, "UTF-8"); - } - catch (UnsupportedEncodingException e) - { - isr = new InputStreamReader(ris); - } - - doc.add(Field.Text("@" + QName.createQName( - propertyName.getNamespaceURI(), - ISO9075.encode(propertyName.getLocalName())), isr)); - } - } - else - // URL not present (null reader) or no content at the URL (file missing) - { - // log it - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Not indexed: Content Missing \n" - + " node: " + nodeRef + "\n" + " reader: " + reader + "\n" - + " content exists: " - + (reader == null ? " --- " : Boolean.toString(reader.exists()))); - } - // not indexed: content missing - doc.add(Field.Text("TEXT", NOT_INDEXED_CONTENT_MISSING)); - doc.add(Field.Text(attributeName, NOT_INDEXED_CONTENT_MISSING)); - } - } - else - { - doc.add(new Field(attributeName, strValue, store, index, tokenise)); - } - } - - return wereAllAtomic; - } - - private Map getNodeCounts(NodeRef nodeRef) - { - Map nodeCounts = new HashMap(5); - List parentAssocs = nodeService.getParentAssocs(nodeRef); - // count the number of times the association is duplicated - for (ChildAssociationRef assoc : parentAssocs) - { - Counter counter = nodeCounts.get(assoc); - if (counter == null) - { - counter = new Counter(); - nodeCounts.put(assoc, counter); - } - counter.incrementParentCount(); - - } - return nodeCounts; - } - - private Collection> getCategoryPaths(NodeRef nodeRef, Map properties) - { - ArrayList> categoryPaths = new ArrayList>(); - Set aspects = nodeService.getAspects(nodeRef); - - for (QName classRef : aspects) - { - AspectDefinition aspDef = getDictionaryService().getAspect(classRef); - if (isCategorised(aspDef)) - { - LinkedList> aspectPaths = new LinkedList>(); - for (PropertyDefinition propDef : aspDef.getProperties().values()) - { - if (propDef.getDataType().getName().equals(DataTypeDefinition.CATEGORY)) - { - for (NodeRef catRef : DefaultTypeConverter.INSTANCE.getCollection(NodeRef.class, properties - .get(propDef.getName()))) - { - if (catRef != null) - { - for (Path path : nodeService.getPaths(catRef, false)) - { - if ((path.size() > 1) && (path.get(1) instanceof Path.ChildAssocElement)) - { - Path.ChildAssocElement cae = (Path.ChildAssocElement) path.get(1); - boolean isFakeRoot = true; - for (ChildAssociationRef car : nodeService.getParentAssocs(cae.getRef() - .getChildRef())) - { - if (cae.getRef().equals(car)) - { - isFakeRoot = false; - break; - } - } - if (isFakeRoot) - { - if (path.toString().indexOf(aspDef.getName().toString()) != -1) - { - aspectPaths.add(new Pair(path, aspDef.getName())); - } - } - } - } - - } - } - } - } - categoryPaths.addAll(aspectPaths); - } - } - // Add member final element - for (Pair pair : categoryPaths) - { - if (pair.getFirst().last() instanceof Path.ChildAssocElement) - { - Path.ChildAssocElement cae = (Path.ChildAssocElement) pair.getFirst().last(); - ChildAssociationRef assocRef = cae.getRef(); - pair.getFirst().append( - new Path.ChildAssocElement(new ChildAssociationRef(assocRef.getTypeQName(), assocRef - .getChildRef(), QName.createQName("member"), nodeRef))); - } - } - - return categoryPaths; - } - - private boolean isCategorised(AspectDefinition aspDef) - { - AspectDefinition current = aspDef; - while (current != null) - { - if (current.getName().equals(ContentModel.ASPECT_CLASSIFIABLE)) - { - return true; - } - else - { - QName parentName = current.getParentName(); - if (parentName == null) - { - break; - } - current = getDictionaryService().getAspect(parentName); - } - } - return false; - } - - private boolean isCategory(TypeDefinition typeDef) - { - if (typeDef == null) - { - return false; - } - TypeDefinition current = typeDef; - while (current != null) - { - if (current.getName().equals(ContentModel.TYPE_CATEGORY)) - { - return true; - } - else - { - QName parentName = current.getParentName(); - if (parentName == null) - { - break; - } - current = getDictionaryService().getType(parentName); - } - } - return false; - } - - public int updateFullTextSearch(int size) throws LuceneIndexException - { - checkAbleToDoWork(true, false); - if (!mainIndexExists()) - { - remainingCount = size; - return 0; - } - try - { - NodeRef lastId = null; - - toFTSIndex = new ArrayList(size); - BooleanQuery booleanQuery = new BooleanQuery(); - booleanQuery.add(new TermQuery(new Term("FTSSTATUS", "Dirty")), false, false); - booleanQuery.add(new TermQuery(new Term("FTSSTATUS", "New")), false, false); - - int count = 0; - Searcher searcher = null; - LuceneResultSet results = null; - try - { - searcher = getSearcher(null); - // commit on another thread - appears like there is no index ...try later - if(searcher == null) - { - remainingCount = size; - return 0; - } - Hits hits; - try - { - hits = searcher.search(booleanQuery); - } - catch (IOException e) - { - throw new LuceneIndexException( - "Failed to execute query to find content which needs updating in the index", e); - } - results = new LuceneResultSet(hits, searcher, nodeService, null, new SearchParameters()); - - for (ResultSetRow row : results) - { - LuceneResultSetRow lrow = (LuceneResultSetRow) row; - Helper helper = new Helper(lrow.getNodeRef(), lrow.getDocument().getField("TX").stringValue()); - toFTSIndex.add(helper); - if (++count >= size) - { - break; - } - } - count = results.length(); - } - finally - { - if (results != null) - { - results.close(); // closes the searcher - } - else if (searcher != null) - { - try - { - searcher.close(); - } - catch (IOException e) - { - throw new LuceneIndexException("Failed to close searcher", e); - } - } - } - - if (toFTSIndex.size() > 0) - { - checkAbleToDoWork(true, true); - - IndexWriter writer = null; - try - { - writer = getDeltaWriter(); - for (Helper helper : toFTSIndex) - { - // Document document = helper.document; - NodeRef ref = helper.nodeRef; - // bypass nodes that have disappeared - if (!nodeService.exists(ref)) - { - continue; - } - - List docs = createDocuments(ref, false, true, false); - for (Document doc : docs) - { - try - { - writer.addDocument(doc /* - * TODO: Select the language based analyser - */); - } - catch (IOException e) - { - throw new LuceneIndexException("Failed to add document while updating fts index", e); - } - } - - // Need to do all the current id in the TX - should all - // be - // together so skip until id changes - if (writer.docCount() > size) - { - if (lastId == null) - { - lastId = ref; - } - if (!lastId.equals(ref)) - { - break; - } - } - } - - int done = writer.docCount(); - remainingCount = count - done; - return done; - } - catch (LuceneIndexException e) - { - if (writer != null) - { - closeDeltaWriter(); - } - return 0; - } - } - else - { - return 0; - } - - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Failed FTS update", e); - } - } - - public void registerCallBack(FTSIndexerAware callBack) - { - this.callBack = callBack; - } - - private static class Helper - { - NodeRef nodeRef; - - String tx; - - Helper(NodeRef nodeRef, String tx) - { - this.nodeRef = nodeRef; - this.tx = tx; - } - } - - private static class Command - { - NodeRef nodeRef; - - Action action; - - Command(NodeRef nodeRef, Action action) - { - this.nodeRef = nodeRef; - this.action = action; - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - if (action == Action.INDEX) - { - buffer.append("Index "); - } - else if (action == Action.DELETE) - { - buffer.append("Delete "); - } - else if (action == Action.REINDEX) - { - buffer.append("Reindex "); - } - else - { - buffer.append("Unknown ... "); - } - buffer.append(nodeRef); - return buffer.toString(); - } - - } - - private FullTextSearchIndexer luceneFullTextSearchIndexer; - - public void setLuceneFullTextSearchIndexer(FullTextSearchIndexer luceneFullTextSearchIndexer) - { - this.luceneFullTextSearchIndexer = luceneFullTextSearchIndexer; - } - - public Set getDeletions() - { - return Collections.unmodifiableSet(deletions); - } -} diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl2.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl2.java index 3ea070e565..bebec65083 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl2.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl2.java @@ -77,6 +77,7 @@ import org.apache.lucene.search.Hits; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Searcher; import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.BooleanClause.Occur; /** * The implementation of the lucene based indexer. Supports basic transactional behaviour if used on its own. @@ -1043,7 +1044,7 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 refs.add(ref); if (delete) { - reader.delete(doc); + reader.deleteDocument(doc); } } } @@ -1078,7 +1079,7 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 refs.add(ref); if (delete) { - reader.delete(doc); + reader.deleteDocument(doc); } } } @@ -1101,7 +1102,7 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 { if (delete) { - reader.delete(new Term("ID", nodeRef.toString())); + reader.deleteDocuments(new Term("ID", nodeRef.toString())); } refs.add(nodeRef); if (cascade) @@ -1116,7 +1117,7 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 refs.add(ref); if (delete) { - reader.delete(doc); + reader.deleteDocument(doc); } } } @@ -1238,8 +1239,8 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 paths.addAll(categoryPaths); Document xdoc = new Document(); - xdoc.add(new Field("ID", nodeRef.toString(), true, true, false)); - xdoc.add(new Field("TX", nodeStatus.getChangeTxnId(), true, true, false)); + xdoc.add(new Field("ID", nodeRef.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("TX", nodeStatus.getChangeTxnId(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); boolean isAtomic = true; for (QName propertyName : properties.keySet()) { @@ -1295,11 +1296,10 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 qNameBuffer.append(";/"); } qNameBuffer.append(ISO9075.getXPathName(qNameRef.getQName())); - xdoc.add(new Field("PARENT", qNameRef.getParentRef().toString(), true, true, false)); - xdoc.add(new Field("ASSOCTYPEQNAME", ISO9075.getXPathName(qNameRef.getTypeQName()), true, - false, false)); + xdoc.add(new Field("PARENT", qNameRef.getParentRef().toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("ASSOCTYPEQNAME", ISO9075.getXPathName(qNameRef.getTypeQName()), Field.Store.YES, Field.Index.NO, Field.TermVector.NO)); xdoc.add(new Field("LINKASPECT", (pair.getSecond() == null) ? "" : ISO9075.getXPathName(pair - .getSecond()), true, true, false)); + .getSecond()), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } } @@ -1320,17 +1320,17 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 if (directPaths.contains(pair.getFirst())) { Document directoryEntry = new Document(); - directoryEntry.add(new Field("ID", nodeRef.toString(), true, true, false)); - directoryEntry.add(new Field("PATH", pathString, true, true, true)); + directoryEntry.add(new Field("ID", nodeRef.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + directoryEntry.add(new Field("PATH", pathString, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); for (NodeRef parent : getParents(pair.getFirst())) { - directoryEntry.add(new Field("ANCESTOR", parent.toString(), false, true, false)); + directoryEntry.add(new Field("ANCESTOR", parent.toString(), Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } - directoryEntry.add(new Field("ISCONTAINER", "T", true, true, false)); + directoryEntry.add(new Field("ISCONTAINER", "T", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); if (isCategory(getDictionaryService().getType(nodeService.getType(nodeRef)))) { - directoryEntry.add(new Field("ISCATEGORY", "T", true, true, false)); + directoryEntry.add(new Field("ISCATEGORY", "T", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } docs.add(directoryEntry); @@ -1344,50 +1344,48 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 if (isRoot) { // TODO: Does the root element have a QName? - xdoc.add(new Field("ISCONTAINER", "T", true, true, false)); - xdoc.add(new Field("PATH", "", true, true, true)); - xdoc.add(new Field("QNAME", "", true, true, true)); - xdoc.add(new Field("ISROOT", "T", false, true, false)); - xdoc.add(new Field("PRIMARYASSOCTYPEQNAME", ISO9075.getXPathName(ContentModel.ASSOC_CHILDREN), true, false, - false)); - xdoc.add(new Field("ISNODE", "T", false, true, false)); + xdoc.add(new Field("ISCONTAINER", "T", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("PATH", "", Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("QNAME", "", Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("ISROOT", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("PRIMARYASSOCTYPEQNAME", ISO9075.getXPathName(ContentModel.ASSOC_CHILDREN), Field.Store.YES, Field.Index.NO, Field.TermVector.NO)); + xdoc.add(new Field("ISNODE", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); docs.add(xdoc); } else // not a root node { - xdoc.add(new Field("QNAME", qNameBuffer.toString(), true, true, true)); + xdoc.add(new Field("QNAME", qNameBuffer.toString(),Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); // xdoc.add(new Field("PARENT", parentBuffer.toString(), true, true, // true)); ChildAssociationRef primary = nodeService.getPrimaryParent(nodeRef); - xdoc.add(new Field("PRIMARYPARENT", primary.getParentRef().toString(), true, true, false)); - xdoc.add(new Field("PRIMARYASSOCTYPEQNAME", ISO9075.getXPathName(primary.getTypeQName()), true, false, - false)); + xdoc.add(new Field("PRIMARYPARENT", primary.getParentRef().toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("PRIMARYASSOCTYPEQNAME", ISO9075.getXPathName(primary.getTypeQName()), Field.Store.YES, Field.Index.NO, Field.TermVector.NO)); QName typeQName = nodeService.getType(nodeRef); - xdoc.add(new Field("TYPE", ISO9075.getXPathName(typeQName), true, true, false)); + xdoc.add(new Field("TYPE", ISO9075.getXPathName(typeQName), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); for (QName classRef : nodeService.getAspects(nodeRef)) { - xdoc.add(new Field("ASPECT", ISO9075.getXPathName(classRef), true, true, false)); + xdoc.add(new Field("ASPECT", ISO9075.getXPathName(classRef), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } - xdoc.add(new Field("ISROOT", "F", false, true, false)); - xdoc.add(new Field("ISNODE", "T", false, true, false)); + xdoc.add(new Field("ISROOT", "F", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); + xdoc.add(new Field("ISNODE", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); if (isAtomic || indexAllProperties) { - xdoc.add(new Field("FTSSTATUS", "Clean", false, true, false)); + xdoc.add(new Field("FTSSTATUS", "Clean", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } else { if (isNew) { - xdoc.add(new Field("FTSSTATUS", "New", false, true, false)); + xdoc.add(new Field("FTSSTATUS", "New", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } else { - xdoc.add(new Field("FTSSTATUS", "Dirty", false, true, false)); + xdoc.add(new Field("FTSSTATUS", "Dirty", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } } @@ -1491,7 +1489,7 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 continue; } // store mimetype in index - even if content does not index it is useful - doc.add(new Field(attributeName + ".mimetype", contentData.getMimetype(), false, true, false)); + doc.add(new Field(attributeName + ".mimetype", contentData.getMimetype(), Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); ContentReader reader = contentService.getReader(nodeRef, propertyName); if (reader != null && reader.exists()) @@ -1517,8 +1515,8 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 // don't index from the reader readerReady = false; // not indexed: no transformation - doc.add(Field.Text("TEXT", NOT_INDEXED_NO_TRANSFORMATION)); - doc.add(Field.Text(attributeName, NOT_INDEXED_NO_TRANSFORMATION)); + doc.add(new Field("TEXT", NOT_INDEXED_NO_TRANSFORMATION, Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO)); + doc.add(new Field(attributeName, NOT_INDEXED_NO_TRANSFORMATION, Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO)); } else if (indexAtomicPropertiesOnly && transformer.getTransformationTime() > maxAtomicTransformationTime) @@ -1552,8 +1550,8 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 readerReady = false; // not indexed: transformation // failed - doc.add(Field.Text("TEXT", NOT_INDEXED_TRANSFORMATION_FAILED)); - doc.add(Field.Text(attributeName, NOT_INDEXED_TRANSFORMATION_FAILED)); + doc.add(new Field("TEXT", NOT_INDEXED_TRANSFORMATION_FAILED, Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO)); + doc.add(new Field(attributeName, NOT_INDEXED_TRANSFORMATION_FAILED, Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO)); } } } @@ -1571,7 +1569,7 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 { isr = new InputStreamReader(ris); } - doc.add(Field.Text("TEXT", isr)); + doc.add(new Field("TEXT", isr, Field.TermVector.NO)); ris = reader.getReader().getContentInputStream(); try @@ -1583,9 +1581,9 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 isr = new InputStreamReader(ris); } - doc.add(Field.Text("@" + doc.add(new Field("@" + QName.createQName(propertyName.getNamespaceURI(), ISO9075.encode(propertyName - .getLocalName())), isr)); + .getLocalName())), isr, Field.TermVector.NO)); } } else @@ -1599,13 +1597,31 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 + (reader == null ? " --- " : Boolean.toString(reader.exists()))); } // not indexed: content missing - doc.add(Field.Text("TEXT", NOT_INDEXED_CONTENT_MISSING)); - doc.add(Field.Text(attributeName, NOT_INDEXED_CONTENT_MISSING)); + doc.add(new Field("TEXT", NOT_INDEXED_CONTENT_MISSING, Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO)); + doc.add(new Field(attributeName, NOT_INDEXED_CONTENT_MISSING, Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO)); } } else { - doc.add(new Field(attributeName, strValue, store, index, tokenise)); + Field.Store fieldStore = store ? Field.Store.YES : Field.Store.NO; + Field.Index fieldIndex; + if(index ) + { + if(tokenise) + { + fieldIndex = Field.Index.TOKENIZED; + } + else + { + fieldIndex = Field.Index.UN_TOKENIZED; + } + } + else + { + fieldIndex = Field.Index.NO; + } + + doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO)); } } @@ -1761,8 +1777,8 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2 toFTSIndex = new ArrayList(size); BooleanQuery booleanQuery = new BooleanQuery(); - booleanQuery.add(new TermQuery(new Term("FTSSTATUS", "Dirty")), false, false); - booleanQuery.add(new TermQuery(new Term("FTSSTATUS", "New")), false, false); + booleanQuery.add(new TermQuery(new Term("FTSSTATUS", "Dirty")), Occur.SHOULD); + booleanQuery.add(new TermQuery(new Term("FTSSTATUS", "New")), Occur.SHOULD); int count = 0; Searcher searcher = null; diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java index aa7315956f..1901290807 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java @@ -37,6 +37,7 @@ import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.RangeQuery; import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.BooleanClause.Occur; import org.saxpath.SAXPathException; import com.werken.saxpath.XPathReader; @@ -198,7 +199,7 @@ public class LuceneQueryParser extends QueryParser for (QName qname : subclasses) { TermQuery termQuery = new TermQuery(new Term(field, qname.toString())); - booleanQuery.add(termQuery, false, false); + booleanQuery.add(termQuery, Occur.SHOULD); } return booleanQuery; } @@ -244,7 +245,7 @@ public class LuceneQueryParser extends QueryParser for (QName qname : subclasses) { TermQuery termQuery = new TermQuery(new Term(field, qname.toString())); - booleanQuery.add(termQuery, false, false); + booleanQuery.add(termQuery, Occur.SHOULD); } return booleanQuery; } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcherImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcherImpl.java deleted file mode 100644 index d9cfcb15b2..0000000000 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcherImpl.java +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Copyright (C) 2005 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * 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.alfresco.repo.search.impl.lucene; - -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Set; - -import org.alfresco.repo.search.CannedQueryDef; -import org.alfresco.repo.search.EmptyResultSet; -import org.alfresco.repo.search.Indexer; -import org.alfresco.repo.search.QueryRegisterComponent; -import org.alfresco.repo.search.SearcherException; -import org.alfresco.repo.search.impl.NodeSearcher; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.InvalidNodeRefException; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.Path; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.repository.XPathException; -import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; -import org.alfresco.service.cmr.search.QueryParameter; -import org.alfresco.service.cmr.search.QueryParameterDefinition; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.SearchParameters; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.NamespacePrefixResolver; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.ISO9075; -import org.alfresco.util.SearchLanguageConversion; -import org.apache.lucene.search.Hits; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.Searcher; -import org.apache.lucene.search.Sort; -import org.apache.lucene.search.SortField; -import org.saxpath.SAXPathException; - -import com.werken.saxpath.XPathReader; - -/** - * The Lucene implementation of Searcher At the moment we support only lucene - * based queries. - * - * TODO: Support for other query languages - * - * @author andyh - * - */ -public class LuceneSearcherImpl extends LuceneBase implements LuceneSearcher -{ - /** - * Default field name - */ - private static final String DEFAULT_FIELD = "TEXT"; - - private NamespacePrefixResolver namespacePrefixResolver; - - private NodeService nodeService; - - private DictionaryService dictionaryService; - - private QueryRegisterComponent queryRegister; - - private LuceneIndexer indexer; - - /* - * Searcher implementation - */ - - /** - * Get an initialised searcher for the store and transaction Normally we do - * not search against a a store and delta. Currently only gets the searcher - * against the main index. - * - * @param storeRef - * @param deltaId - * @return - */ - public static LuceneSearcherImpl getSearcher(StoreRef storeRef, LuceneIndexer indexer, LuceneConfig config) - { - LuceneSearcherImpl searcher = new LuceneSearcherImpl(); - searcher.setLuceneConfig(config); - try - { - searcher.initialise(storeRef, indexer == null ? null : indexer.getDeltaId(), false, false); - searcher.indexer = indexer; - } - catch (LuceneIndexException e) - { - throw new SearcherException(e); - } - return searcher; - } - - /** - * Get an intialised searcher for the store. No transactional ammendsmends - * are searched. - * - * - * @param storeRef - * @return - */ - public static LuceneSearcherImpl getSearcher(StoreRef storeRef, LuceneConfig config) - { - return getSearcher(storeRef, null, config); - } - - public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver) - { - this.namespacePrefixResolver = namespacePrefixResolver; - } - - public boolean indexExists() - { - return mainIndexExists(); - } - - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - public void setQueryRegister(QueryRegisterComponent queryRegister) - { - this.queryRegister = queryRegister; - } - - public ResultSet query(StoreRef store, String language, String queryString, Path[] queryOptions, - QueryParameterDefinition[] queryParameterDefinitions) throws SearcherException - { - SearchParameters sp = new SearchParameters(); - sp.addStore(store); - sp.setLanguage(language); - sp.setQuery(queryString); - if (queryOptions != null) - { - for (Path path : queryOptions) - { - sp.addAttrbutePath(path); - } - } - if (queryParameterDefinitions != null) - { - for (QueryParameterDefinition qpd : queryParameterDefinitions) - { - sp.addQueryParameterDefinition(qpd); - } - } - sp.excludeDataInTheCurrentTransaction(true); - - return query(sp); - } - - public ResultSet query(SearchParameters searchParameters) - { - if (searchParameters.getStores().size() != 1) - { - throw new IllegalStateException("Only one store can be searched at present"); - } - - String parameterisedQueryString; - if (searchParameters.getQueryParameterDefinitions().size() > 0) - { - Map map = new HashMap(); - - for (QueryParameterDefinition qpd : searchParameters.getQueryParameterDefinitions()) - { - map.put(qpd.getQName(), qpd); - } - - parameterisedQueryString = parameterise(searchParameters.getQuery(), map, null, namespacePrefixResolver); - } - else - { - parameterisedQueryString = searchParameters.getQuery(); - } - - if (searchParameters.getLanguage().equalsIgnoreCase(SearchService.LANGUAGE_LUCENE)) - { - try - { - - int defaultOperator; - if (searchParameters.getDefaultOperator() == SearchParameters.AND) - { - defaultOperator = LuceneQueryParser.DEFAULT_OPERATOR_AND; - } - else - { - defaultOperator = LuceneQueryParser.DEFAULT_OPERATOR_OR; - } - - Query query = LuceneQueryParser.parse(parameterisedQueryString, DEFAULT_FIELD, new LuceneAnalyser( - dictionaryService), namespacePrefixResolver, dictionaryService, defaultOperator); - Searcher searcher = getSearcher(indexer); - if (searcher == null) - { - // no index return an empty result set - return new EmptyResultSet(); - } - - Hits hits; - - if (searchParameters.getSortDefinitions().size() > 0) - { - int index = 0; - SortField[] fields = new SortField[searchParameters.getSortDefinitions().size()]; - for (SearchParameters.SortDefinition sd : searchParameters.getSortDefinitions()) - { - switch (sd.getSortType()) - { - case FIELD: - fields[index++] = new SortField(sd.getField(), SortField.STRING, !sd.isAscending()); - break; - case DOCUMENT: - fields[index++] = new SortField(null, SortField.DOC, !sd.isAscending()); - break; - case SCORE: - fields[index++] = new SortField(null, SortField.SCORE, !sd.isAscending()); - break; - } - - } - hits = searcher.search(query, new Sort(fields)); - } - else - { - hits = searcher.search(query); - } - - return new LuceneResultSet(hits, searcher, nodeService, searchParameters.getAttributePaths().toArray( - new Path[0]), searchParameters); - - } - catch (ParseException e) - { - throw new SearcherException("Failed to parse query: " + parameterisedQueryString, e); - } - catch (IOException e) - { - throw new SearcherException("IO exception during search", e); - } - } - else if (searchParameters.getLanguage().equalsIgnoreCase(SearchService.LANGUAGE_XPATH)) - { - try - { - XPathReader reader = new XPathReader(); - LuceneXPathHandler handler = new LuceneXPathHandler(); - handler.setNamespacePrefixResolver(namespacePrefixResolver); - handler.setDictionaryService(dictionaryService); - // TODO: Handler should have the query parameters to use in - // building its lucene query - // At the moment xpath style parameters in the PATH - // expression are not supported. - reader.setXPathHandler(handler); - reader.parse(parameterisedQueryString); - Query query = handler.getQuery(); - Searcher searcher = getSearcher(null); - if (searcher == null) - { - // no index return an empty result set - return new EmptyResultSet(); - } - Hits hits = searcher.search(query); - return new LuceneResultSet(hits, searcher, nodeService, searchParameters.getAttributePaths().toArray( - new Path[0]), searchParameters); - } - catch (SAXPathException e) - { - throw new SearcherException("Failed to parse query: " + searchParameters.getQuery(), e); - } - catch (IOException e) - { - throw new SearcherException("IO exception during search", e); - } - } - else - { - throw new SearcherException("Unknown query language: " + searchParameters.getLanguage()); - } - } - - public ResultSet query(StoreRef store, String language, String query) - { - return query(store, language, query, null, null); - } - - public ResultSet query(StoreRef store, String language, String query, - QueryParameterDefinition[] queryParameterDefintions) - { - return query(store, language, query, null, queryParameterDefintions); - } - - public ResultSet query(StoreRef store, String language, String query, Path[] attributePaths) - { - return query(store, language, query, attributePaths, null); - } - - public ResultSet query(StoreRef store, QName queryId, QueryParameter[] queryParameters) - { - CannedQueryDef definition = queryRegister.getQueryDefinition(queryId); - - // Do parameter replacement - // As lucene phrases are tokensied it is correct to just do straight - // string replacement. - // The string will be formatted by the tokeniser. - // - // For non phrase queries this is incorrect but string replacement is - // probably the best we can do. - // As numbers and text are indexed specially, direct term queries only - // make sense against textual data - - checkParameters(definition, queryParameters); - - String queryString = parameterise(definition.getQuery(), definition.getQueryParameterMap(), queryParameters, - definition.getNamespacePrefixResolver()); - - return query(store, definition.getLanguage(), queryString, null, null); - } - - /** - * The definitions must provide a default value, or of not there must be a - * parameter to provide the value - * - * @param definition - * @param queryParameters - * @throws QueryParameterisationException - */ - private void checkParameters(CannedQueryDef definition, QueryParameter[] queryParameters) - throws QueryParameterisationException - { - List missing = new ArrayList(); - - Set parameterQNameSet = new HashSet(); - if (queryParameters != null) - { - for (QueryParameter parameter : queryParameters) - { - parameterQNameSet.add(parameter.getQName()); - } - } - - for (QueryParameterDefinition parameterDefinition : definition.getQueryParameterDefs()) - { - if (!parameterDefinition.hasDefaultValue()) - { - if (!parameterQNameSet.contains(parameterDefinition.getQName())) - { - missing.add(parameterDefinition.getQName()); - } - } - } - - if (missing.size() > 0) - { - StringBuilder buffer = new StringBuilder(128); - buffer.append("The query is missing values for the following parameters: "); - for (QName qName : missing) - { - buffer.append(qName); - buffer.append(", "); - } - buffer.delete(buffer.length() - 1, buffer.length() - 1); - buffer.delete(buffer.length() - 1, buffer.length() - 1); - throw new QueryParameterisationException(buffer.toString()); - } - } - - /* - * Parameterise the query string - not sure if it is required to escape - * lucence spacials chars The parameters could be used to build the query - - * the contents of parameters should alread have been escaped if required. - * ... mush better to provide the parameters and work out what to do TODO: - * conditional query escapement - may be we should have a parameter type - * that is not escaped - */ - private String parameterise(String unparameterised, Map map, - QueryParameter[] queryParameters, NamespacePrefixResolver nspr) throws QueryParameterisationException - { - - Map> valueMap = new HashMap>(); - - if (queryParameters != null) - { - for (QueryParameter parameter : queryParameters) - { - List list = valueMap.get(parameter.getQName()); - if (list == null) - { - list = new ArrayList(); - valueMap.put(parameter.getQName(), list); - } - list.add(parameter.getValue()); - } - } - - Map> iteratorMap = new HashMap>(); - - List missing = new ArrayList(1); - StringBuilder buffer = new StringBuilder(unparameterised); - int index = 0; - while ((index = buffer.indexOf("${", index)) != -1) - { - int endIndex = buffer.indexOf("}", index); - String qNameString = buffer.substring(index + 2, endIndex); - QName key = QName.createQName(qNameString, nspr); - QueryParameterDefinition parameterDefinition = map.get(key); - if (parameterDefinition == null) - { - missing.add(key); - buffer.replace(index, endIndex + 1, ""); - } - else - { - ListIterator it = iteratorMap.get(key); - if ((it == null) || (!it.hasNext())) - { - List list = valueMap.get(key); - if ((list != null) && (list.size() > 0)) - { - it = list.listIterator(); - } - if (it != null) - { - iteratorMap.put(key, it); - } - } - String value; - if (it == null) - { - value = parameterDefinition.getDefault(); - } - else - { - value = DefaultTypeConverter.INSTANCE.convert(String.class, it.next()); - } - buffer.replace(index, endIndex + 1, value); - } - } - if (missing.size() > 0) - { - StringBuilder error = new StringBuilder(); - error.append("The query uses the following parameters which are not defined: "); - for (QName qName : missing) - { - error.append(qName); - error.append(", "); - } - error.delete(error.length() - 1, error.length() - 1); - error.delete(error.length() - 1, error.length() - 1); - throw new QueryParameterisationException(error.toString()); - } - return buffer.toString(); - } - - /** - * @see org.alfresco.repo.search.impl.NodeSearcher - */ - public List selectNodes(NodeRef contextNodeRef, String xpath, QueryParameterDefinition[] parameters, - NamespacePrefixResolver namespacePrefixResolver, boolean followAllParentLinks, String language) - throws InvalidNodeRefException, XPathException - { - NodeSearcher nodeSearcher = new NodeSearcher(nodeService, dictionaryService, this); - return nodeSearcher.selectNodes(contextNodeRef, xpath, parameters, namespacePrefixResolver, - followAllParentLinks, language); - } - - /** - * @see org.alfresco.repo.search.impl.NodeSearcher - */ - public List selectProperties(NodeRef contextNodeRef, String xpath, - QueryParameterDefinition[] parameters, NamespacePrefixResolver namespacePrefixResolver, - boolean followAllParentLinks, String language) throws InvalidNodeRefException, XPathException - { - NodeSearcher nodeSearcher = new NodeSearcher(nodeService, dictionaryService, this); - return nodeSearcher.selectProperties(contextNodeRef, xpath, parameters, namespacePrefixResolver, - followAllParentLinks, language); - } - - /** - * @return Returns true if the pattern is present, otherwise false. - */ - public boolean contains(NodeRef nodeRef, QName propertyQName, String googleLikePattern) - { - return contains(nodeRef, propertyQName, googleLikePattern, SearchParameters.Operator.OR); - } - - /** - * @return Returns true if the pattern is present, otherwise false. - */ - public boolean contains(NodeRef nodeRef, QName propertyQName, String googleLikePattern, - SearchParameters.Operator defaultOperator) - { - ResultSet resultSet = null; - try - { - // build Lucene search string specific to the node - StringBuilder sb = new StringBuilder(); - sb.append("+ID:\"").append(nodeRef.toString()).append("\" +(TEXT:(") - .append(googleLikePattern.toLowerCase()).append(") "); - if (propertyQName != null) - { - sb.append(" OR @").append( - LuceneQueryParser.escape(QName.createQName(propertyQName.getNamespaceURI(), - ISO9075.encode(propertyQName.getLocalName())).toString())); - sb.append(":(").append(googleLikePattern.toLowerCase()).append(")"); - } - else - { - for (QName key : nodeService.getProperties(nodeRef).keySet()) - { - sb.append(" OR @").append( - LuceneQueryParser.escape(QName.createQName(key.getNamespaceURI(), - ISO9075.encode(key.getLocalName())).toString())); - sb.append(":(").append(googleLikePattern.toLowerCase()).append(")"); - } - } - sb.append(")"); - - SearchParameters sp = new SearchParameters(); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery(sb.toString()); - sp.setDefaultOperator(defaultOperator); - sp.addStore(nodeRef.getStoreRef()); - - resultSet = this.query(sp); - boolean answer = resultSet.length() > 0; - return answer; - } - finally - { - if (resultSet != null) - { - resultSet.close(); - } - } - } - - /** - * @return Returns true if the pattern is present, otherwise false. - * - * @see #setIndexer(Indexer) - * @see #setSearcher(SearchService) - */ - public boolean like(NodeRef nodeRef, QName propertyQName, String sqlLikePattern, boolean includeFTS) - { - if (propertyQName == null) - { - throw new IllegalArgumentException("Property QName is mandatory for the like expression"); - } - - StringBuilder sb = new StringBuilder(sqlLikePattern.length() * 3); - - if (includeFTS) - { - // convert the SQL-like pattern into a Lucene-compatible string - String pattern = SearchLanguageConversion.convertXPathLikeToLucene(sqlLikePattern.toLowerCase()); - - // build Lucene search string specific to the node - sb = new StringBuilder(); - sb.append("+ID:\"").append(nodeRef.toString()).append("\" +("); - // FTS or attribute matches - if (includeFTS) - { - sb.append("TEXT:(").append(pattern).append(") "); - } - if (propertyQName != null) - { - sb.append(" @").append( - LuceneQueryParser.escape(QName.createQName(propertyQName.getNamespaceURI(), - ISO9075.encode(propertyQName.getLocalName())).toString())).append(":(").append(pattern) - .append(")"); - } - sb.append(")"); - - ResultSet resultSet = null; - try - { - resultSet = this.query(nodeRef.getStoreRef(), "lucene", sb.toString()); - boolean answer = resultSet.length() > 0; - return answer; - } - finally - { - if (resultSet != null) - { - resultSet.close(); - } - } - } - else - { - // convert the SQL-like pattern into a Lucene-compatible string - String pattern = SearchLanguageConversion.convertXPathLikeToRegex(sqlLikePattern.toLowerCase()); - - Serializable property = nodeService.getProperty(nodeRef, propertyQName); - if (property == null) - { - return false; - } - else - { - String propertyString = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty( - nodeRef, propertyQName)); - return propertyString.toLowerCase().matches(pattern); - } - } - } - - public List selectNodes(NodeRef contextNodeRef, String xpath, QueryParameterDefinition[] parameters, - NamespacePrefixResolver namespacePrefixResolver, boolean followAllParentLinks) - throws InvalidNodeRefException, XPathException - { - return selectNodes(contextNodeRef, xpath, parameters, namespacePrefixResolver, followAllParentLinks, - SearchService.LANGUAGE_XPATH); - } - - public List selectProperties(NodeRef contextNodeRef, String xpath, - QueryParameterDefinition[] parameters, NamespacePrefixResolver namespacePrefixResolver, - boolean followAllParentLinks) throws InvalidNodeRefException, XPathException - { - return selectProperties(contextNodeRef, xpath, parameters, namespacePrefixResolver, followAllParentLinks, - SearchService.LANGUAGE_XPATH); - } -} diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneTest.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneTest.java deleted file mode 100644 index a30e255203..0000000000 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneTest.java +++ /dev/null @@ -1,3468 +0,0 @@ -/* - * Copyright (C) 2005 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * 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.alfresco.repo.search.impl.lucene; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Random; - -import javax.transaction.Status; -import javax.transaction.UserTransaction; - -import junit.framework.TestCase; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.dictionary.DictionaryDAO; -import org.alfresco.repo.dictionary.M2Model; -import org.alfresco.repo.node.BaseNodeServiceTest; -import org.alfresco.repo.search.QueryParameterDefImpl; -import org.alfresco.repo.search.QueryRegisterComponent; -import org.alfresco.repo.search.impl.lucene.analysis.NumericEncoder; -import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer; -import org.alfresco.repo.search.results.ChildAssocRefResultSet; -import org.alfresco.repo.search.results.DetachedResultSet; -import org.alfresco.repo.search.transaction.LuceneIndexLock; -import org.alfresco.repo.security.authentication.AuthenticationComponent; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.Path; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; -import org.alfresco.service.cmr.repository.datatype.Duration; -import org.alfresco.service.cmr.search.QueryParameter; -import org.alfresco.service.cmr.search.QueryParameterDefinition; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.ResultSetRow; -import org.alfresco.service.cmr.search.SearchParameters; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.DynamicNamespacePrefixResolver; -import org.alfresco.service.namespace.NamespacePrefixResolver; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.transaction.TransactionService; -import org.alfresco.util.ApplicationContextHelper; -import org.alfresco.util.CachingDateFormat; -import org.alfresco.util.ISO9075; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.context.ApplicationContext; - -/** - * @author andyh - * - */ -@SuppressWarnings("unused") -public class LuceneTest extends TestCase -{ - - private static final String TEST_NAMESPACE = "http://www.alfresco.org/test/lucenetest"; - - private static final QName ASSOC_TYPE_QNAME = QName.createQName(TEST_NAMESPACE, "assoc"); - - private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(); - - private static Log logger = LogFactory.getLog(LuceneTest.class); - - QName createdDate = QName.createQName(TEST_NAMESPACE, "createdDate"); - - QName orderDouble = QName.createQName(TEST_NAMESPACE, "orderDouble"); - - QName orderFloat = QName.createQName(TEST_NAMESPACE, "orderFloat"); - - QName orderLong = QName.createQName(TEST_NAMESPACE, "orderLong"); - - QName orderInt = QName.createQName(TEST_NAMESPACE, "orderInt"); - - TransactionService transactionService; - - NodeService nodeService; - - DictionaryService dictionaryService; - - LuceneIndexLock luceneIndexLock; - - private NodeRef rootNodeRef; - - private NodeRef n1; - - private NodeRef n2; - - private NodeRef n3; - - private NodeRef n4; - - private NodeRef n5; - - private NodeRef n6; - - private NodeRef n7; - - private NodeRef n8; - - private NodeRef n9; - - private NodeRef n10; - - private NodeRef n11; - - private NodeRef n12; - - private NodeRef n13; - - private NodeRef n14; - - private DictionaryDAO dictionaryDAO; - - private FullTextSearchIndexer luceneFTS; - - private QName testType = QName.createQName(TEST_NAMESPACE, "testType"); - - private QName testSuperType = QName.createQName(TEST_NAMESPACE, "testSuperType"); - - private QName testAspect = QName.createQName(TEST_NAMESPACE, "testAspect"); - - private QName testSuperAspect = QName.createQName(TEST_NAMESPACE, "testSuperAspect"); - - private ContentService contentService; - - private QueryRegisterComponent queryRegisterComponent; - - private NamespacePrefixResolver namespacePrefixResolver; - - private LuceneIndexerAndSearcher indexerAndSearcher; - - private ServiceRegistry serviceRegistry; - - private UserTransaction testTX; - - private AuthenticationComponent authenticationComponent; - - private NodeRef[] documentOrder; - - public LuceneTest() - { - super(); - } - - public void setUp() throws Exception - { - nodeService = (NodeService) ctx.getBean("dbNodeService"); - luceneIndexLock = (LuceneIndexLock) ctx.getBean("luceneIndexLock"); - dictionaryService = (DictionaryService) ctx.getBean("dictionaryService"); - dictionaryDAO = (DictionaryDAO) ctx.getBean("dictionaryDAO"); - luceneFTS = (FullTextSearchIndexer) ctx.getBean("LuceneFullTextSearchIndexer"); - contentService = (ContentService) ctx.getBean("contentService"); - queryRegisterComponent = (QueryRegisterComponent) ctx.getBean("queryRegisterComponent"); - namespacePrefixResolver = (NamespacePrefixResolver) ctx.getBean("namespaceService"); - indexerAndSearcher = (LuceneIndexerAndSearcher) ctx.getBean("luceneIndexerAndSearcherFactory"); - transactionService = (TransactionService) ctx.getBean("transactionComponent"); - serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); - - this.authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent"); - - queryRegisterComponent.loadQueryCollection("testQueryRegister.xml"); - - assertEquals(true, ctx.isSingleton("luceneIndexLock")); - assertEquals(true, ctx.isSingleton("LuceneFullTextSearchIndexer")); - - testTX = transactionService.getUserTransaction(); - testTX.begin(); - this.authenticationComponent.setSystemUserAsCurrentUser(); - - // load in the test model - ClassLoader cl = BaseNodeServiceTest.class.getClassLoader(); - InputStream modelStream = cl.getResourceAsStream("org/alfresco/repo/search/impl/lucene/LuceneTest_model.xml"); - assertNotNull(modelStream); - M2Model model = M2Model.createModel(modelStream); - dictionaryDAO.putModel(model); - - StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis()); - rootNodeRef = nodeService.getRootNode(storeRef); - - n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}one"), - testSuperType, getOrderProperties()).getChildRef(); - nodeService.setProperty(n1, QName.createQName("{namespace}property-1"), "ValueOne"); - - n2 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}two"), - testSuperType, getOrderProperties()).getChildRef(); - nodeService.setProperty(n2, QName.createQName("{namespace}property-1"), "valueone"); - nodeService.setProperty(n2, QName.createQName("{namespace}property-2"), "valuetwo"); - - n3 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}three"), - testSuperType, getOrderProperties()).getChildRef(); - - ObjectOutputStream oos; - try - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - oos = new ObjectOutputStream(baos); - oos.writeObject(n3); - oos.close(); - - ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); - Object o = ois.readObject(); - ois.close(); - } - catch (IOException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - catch (ClassNotFoundException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - Map testProperties = new HashMap(); - testProperties.put(QName.createQName(TEST_NAMESPACE, "text-indexed-stored-tokenised-atomic"), - "TEXT THAT IS INDEXED STORED AND TOKENISED ATOMICALLY KEYONE"); - testProperties.put(QName.createQName(TEST_NAMESPACE, "text-indexed-unstored-tokenised-atomic"), - "TEXT THAT IS INDEXED STORED AND TOKENISED ATOMICALLY KEYUNSTORED"); - testProperties.put(QName.createQName(TEST_NAMESPACE, "text-indexed-stored-tokenised-nonatomic"), - "TEXT THAT IS INDEXED STORED AND TOKENISED BUT NOT ATOMICALLY KEYTWO"); - testProperties.put(QName.createQName(TEST_NAMESPACE, "int-ista"), Integer.valueOf(1)); - testProperties.put(QName.createQName(TEST_NAMESPACE, "long-ista"), Long.valueOf(2)); - testProperties.put(QName.createQName(TEST_NAMESPACE, "float-ista"), Float.valueOf(3.4f)); - testProperties.put(QName.createQName(TEST_NAMESPACE, "double-ista"), Double.valueOf(5.6)); - testProperties.put(QName.createQName(TEST_NAMESPACE, "date-ista"), new Date()); - testProperties.put(QName.createQName(TEST_NAMESPACE, "datetime-ista"), new Date()); - testProperties.put(QName.createQName(TEST_NAMESPACE, "boolean-ista"), Boolean.valueOf(true)); - testProperties.put(QName.createQName(TEST_NAMESPACE, "qname-ista"), QName.createQName("{wibble}wobble")); - testProperties.put(QName.createQName(TEST_NAMESPACE, "category-ista"), new NodeRef(storeRef, "CategoryId")); - testProperties.put(QName.createQName(TEST_NAMESPACE, "noderef-ista"), n1); - testProperties.put(QName.createQName(TEST_NAMESPACE, "path-ista"), nodeService.getPath(n3)); - testProperties.put(QName.createQName(TEST_NAMESPACE, "verbatim"), " "); - testProperties.put(QName.createQName(TEST_NAMESPACE, "null"), null); - testProperties.put(QName.createQName(TEST_NAMESPACE, "list"), new ArrayList()); - ArrayList testList = new ArrayList(); - testList.add(null); - testProperties.put(QName.createQName(TEST_NAMESPACE, "nullList"), testList); - ArrayList testList2 = new ArrayList(); - testList2.add("woof"); - testList2.add(null); - - n4 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}four"), - testType, testProperties).getChildRef(); - - nodeService.getProperties(n1); - nodeService.getProperties(n2); - nodeService.getProperties(n3); - nodeService.getProperties(n4); - - n5 = nodeService.createNode(n1, ASSOC_TYPE_QNAME, QName.createQName("{namespace}five"), testSuperType, - getOrderProperties()).getChildRef(); - n6 = nodeService.createNode(n1, ASSOC_TYPE_QNAME, QName.createQName("{namespace}six"), testSuperType, - getOrderProperties()).getChildRef(); - n7 = nodeService.createNode(n2, ASSOC_TYPE_QNAME, QName.createQName("{namespace}seven"), testSuperType, - getOrderProperties()).getChildRef(); - n8 = nodeService.createNode(n2, ASSOC_TYPE_QNAME, QName.createQName("{namespace}eight-2"), testSuperType, - getOrderProperties()).getChildRef(); - n9 = nodeService.createNode(n5, ASSOC_TYPE_QNAME, QName.createQName("{namespace}nine"), testSuperType, - getOrderProperties()).getChildRef(); - n10 = nodeService.createNode(n5, ASSOC_TYPE_QNAME, QName.createQName("{namespace}ten"), testSuperType, - getOrderProperties()).getChildRef(); - n11 = nodeService.createNode(n5, ASSOC_TYPE_QNAME, QName.createQName("{namespace}eleven"), testSuperType, - getOrderProperties()).getChildRef(); - n12 = nodeService.createNode(n5, ASSOC_TYPE_QNAME, QName.createQName("{namespace}twelve"), testSuperType, - getOrderProperties()).getChildRef(); - n13 = nodeService.createNode(n12, ASSOC_TYPE_QNAME, QName.createQName("{namespace}thirteen"), testSuperType, - getOrderProperties()).getChildRef(); - - Map properties = new HashMap(); - properties.put(ContentModel.PROP_CONTENT, new ContentData(null, "text/plain", 0L, "UTF-16")); - n14 = nodeService.createNode(n13, ASSOC_TYPE_QNAME, QName.createQName("{namespace}fourteen"), - ContentModel.TYPE_CONTENT, properties).getChildRef(); - // nodeService.addAspect(n14, DictionaryBootstrap.ASPECT_QNAME_CONTENT, - // properties); - - ContentWriter writer = contentService.getWriter(n14, ContentModel.PROP_CONTENT, true); - // InputStream is = - // this.getClass().getClassLoader().getResourceAsStream("test.doc"); - // writer.putContent(is); - writer.putContent("The quick brown fox jumped over the lazy dog"); - - nodeService.addChild(rootNodeRef, n8, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}eight-0")); - nodeService.addChild(n1, n8, ASSOC_TYPE_QNAME, QName.createQName("{namespace}eight-1")); - nodeService.addChild(n2, n13, ASSOC_TYPE_QNAME, QName.createQName("{namespace}link")); - - nodeService.addChild(n1, n14, ASSOC_TYPE_QNAME, QName.createQName("{namespace}common")); - nodeService.addChild(n2, n14, ASSOC_TYPE_QNAME, QName.createQName("{namespace}common")); - nodeService.addChild(n5, n14, ASSOC_TYPE_QNAME, QName.createQName("{namespace}common")); - nodeService.addChild(n6, n14, ASSOC_TYPE_QNAME, QName.createQName("{namespace}common")); - nodeService.addChild(n12, n14, ASSOC_TYPE_QNAME, QName.createQName("{namespace}common")); - nodeService.addChild(n13, n14, ASSOC_TYPE_QNAME, QName.createQName("{namespace}common")); - - documentOrder = new NodeRef[] { rootNodeRef, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14 }; - - } - - private double orderDoubleCount = -0.11d; - - private Date orderDate = new Date(); - - private float orderFloatCount = -3.5556f; - - private long orderLongCount = -1999999999999999l; - - private int orderIntCount = -45764576; - - public Map getOrderProperties() - { - Map testProperties = new HashMap(); - testProperties.put(createdDate, orderDate); - testProperties.put(orderDouble, orderDoubleCount); - testProperties.put(orderFloat, orderFloatCount); - testProperties.put(orderLong, orderLongCount); - testProperties.put(orderInt, orderIntCount); - orderDate = Duration.subtract(orderDate, new Duration("P1D")); - orderDoubleCount += 0.1d; - orderFloatCount += 0.82f; - orderLongCount += 299999999999999l; - orderIntCount += 8576457; - return testProperties; - } - - @Override - protected void tearDown() throws Exception - { - - if (testTX.getStatus() == Status.STATUS_ACTIVE) - { - testTX.rollback(); - } - AuthenticationUtil.clearCurrentSecurityContext(); - super.tearDown(); - } - - public LuceneTest(String arg0) - { - super(arg0); - } - - public void test0() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - luceneFTS.resume(); - } - - public void xtestDeleteIssue() throws Exception - { - - testTX.commit(); - - UserTransaction tx = transactionService.getUserTransaction(); - tx.begin(); - ChildAssociationRef testFind = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName - .createQName("{namespace}testFind"), testSuperType); - tx.commit(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - searcher.setQueryRegister(queryRegisterComponent); - - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "QNAME:\"namespace:testFind\""); - assertEquals(1, results.length()); - results.close(); - - UserTransaction tx1 = transactionService.getUserTransaction(); - tx1.begin(); - for (int i = 0; i < 100; i++) - { - HashSet refs = new HashSet(); - for (int j = 0; j < i; j++) - { - ChildAssociationRef test = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName - .createQName("{namespace}test"), testSuperType); - refs.add(test); - } - - for (ChildAssociationRef car : refs) - { - nodeService.deleteNode(car.getChildRef()); - } - - } - tx1.commit(); - - UserTransaction tx3 = transactionService.getUserTransaction(); - tx3.begin(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "QNAME:\"namespace:testFind\""); - assertEquals(1, results.length()); - results.close(); - tx3.commit(); - } - - public void xtestMTDeleteIssue() throws Exception - { - luceneFTS.pause(); - testTX.commit(); - - UserTransaction tx = transactionService.getUserTransaction(); - tx.begin(); - ChildAssociationRef testFind = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName - .createQName("{namespace}testFind"), testSuperType); - tx.commit(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - searcher.setQueryRegister(queryRegisterComponent); - - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "QNAME:\"namespace:testFind\""); - assertEquals(1, results.length()); - results.close(); - - Thread runner = null; - - for (int i = 0; i < 20; i++) - { - runner = new Nester("Concurrent-" + i, runner); - } - if (runner != null) - { - runner.start(); - - try - { - runner.join(); - } - catch (InterruptedException e) - { - e.printStackTrace(); - } - } - - UserTransaction tx3 = transactionService.getUserTransaction(); - tx3.begin(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "QNAME:\"namespace:testFind\""); - assertEquals(1, results.length()); - results.close(); - tx3.commit(); - } - - class Nester extends Thread - { - Thread waiter; - - Nester(String name, Thread waiter) - { - super(name); - this.setDaemon(true); - this.waiter = waiter; - } - - public void run() - { - authenticationComponent.setSystemUserAsCurrentUser(); - if (waiter != null) - { - waiter.start(); - } - try - { - System.out.println("Start " + this.getName()); - UserTransaction tx1 = transactionService.getUserTransaction(); - tx1.begin(); - for (int i = 0; i < 20; i++) - { - HashSet refs = new HashSet(); - for (int j = 0; j < i; j++) - { - ChildAssociationRef test = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, - QName.createQName("{namespace}test"), testSuperType); - refs.add(test); - } - - for (ChildAssociationRef car : refs) - { - nodeService.deleteNode(car.getChildRef()); - } - - } - tx1.commit(); - System.out.println("End " + this.getName()); - } - catch (Exception e) - { - e.printStackTrace(); - System.exit(12); - } - finally - { - authenticationComponent.clearCurrentSecurityContext(); - } - if (waiter != null) - { - try - { - waiter.join(); - } - catch (InterruptedException e) - { - } - } - } - - } - - public void testDeltaIssue() throws Exception - { - luceneFTS.pause(); - final NodeService pns = (NodeService) ctx.getBean("NodeService"); - - testTX.commit(); - UserTransaction tx = transactionService.getUserTransaction(); - tx.begin(); - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - tx.commit(); - - Thread thread = new Thread(new Runnable() - { - - public void run() - { - try - { - authenticationComponent.setSystemUserAsCurrentUser(); - UserTransaction tx = transactionService.getUserTransaction(); - tx = transactionService.getUserTransaction(); - tx.begin(); - - SearchParameters sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - ResultSet results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - Map props = new HashMap(); - props.put(ContentModel.PROP_TITLE, "woof"); - pns.addAspect(n1, ContentModel.ASPECT_TITLED, props); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - tx.rollback(); - } - catch (Throwable e) - { - throw new RuntimeException(e); - } - - } - - }); - - thread.start(); - thread.join(); - - tx = transactionService.getUserTransaction(); - tx.begin(); - - SearchParameters sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - ResultSet results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - runBaseTests(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - Map props = new HashMap(); - props.put(ContentModel.PROP_TITLE, "woof"); - pns.addAspect(n1, ContentModel.ASPECT_TITLED, props); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - pns.setProperty(n1, ContentModel.PROP_TITLE, "cube"); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - tx.rollback(); - - } - - public void testRepeatPerformance() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - - String query = "ID:\"" + rootNodeRef + "\""; - // check that we get the result - SearchParameters sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery(query); - ResultSet results = searcher.query(sp); - assertEquals("No results found from query", 1, results.length()); - - long start = System.nanoTime(); - int count = 1000; - // repeat - for (int i = 0; i < count; i++) - { - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery(query); - results = searcher.query(sp); - } - long end = System.nanoTime(); - // dump results - double duration = ((double) (end - start)) / 1E6; // duration in ms - double average = duration / (double) count; - System.out.println("Searched for identifier: \n" - + " count: " + count + "\n" + " average: " + average + " ms/search \n" - + " a million searches could take: " + (1E6 * average) / 1E3 / 60D + " minutes"); - // anything over 10ms is dire - if (average > 10.0) - { - logger.error("Search taking longer than 10ms: " + query); - } - } - - public void xtestSort() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - - SearchParameters sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.addSort("ID", true); - ResultSet results = searcher.query(sp); - - String current = null; - for (ResultSetRow row : results) - { - String id = row.getNodeRef().getId(); - - if (current != null) - { - if (current.compareTo(id) > 0) - { - fail(); - } - } - current = id; - } - results.close(); - - SearchParameters sp2 = new SearchParameters(); - sp2.addStore(rootNodeRef.getStoreRef()); - sp2.setLanguage(SearchService.LANGUAGE_LUCENE); - sp2.setQuery("PATH:\"//.\""); - sp2.addSort("ID", false); - results = searcher.query(sp2); - - current = null; - for (ResultSetRow row : results) - { - String id = row.getNodeRef().getId(); - if (current != null) - { - if (current.compareTo(id) < 0) - { - fail(); - } - } - current = id; - } - results.close(); - - luceneFTS.resume(); - - SearchParameters sp3 = new SearchParameters(); - sp3.addStore(rootNodeRef.getStoreRef()); - sp3.setLanguage(SearchService.LANGUAGE_LUCENE); - sp3.setQuery("PATH:\"//.\""); - sp3.addSort(SearchParameters.SORT_IN_DOCUMENT_ORDER_ASCENDING); - results = searcher.query(sp3); - - int count = 0; - for (ResultSetRow row : results) - { - assertEquals(documentOrder[count++], row.getNodeRef()); - } - results.close(); - - SearchParameters sp4 = new SearchParameters(); - sp4.addStore(rootNodeRef.getStoreRef()); - sp4.setLanguage(SearchService.LANGUAGE_LUCENE); - sp4.setQuery("PATH:\"//.\""); - sp4.addSort(SearchParameters.SORT_IN_DOCUMENT_ORDER_DESCENDING); - results = searcher.query(sp4); - - count = 1; - for (ResultSetRow row : results) - { - assertEquals(documentOrder[documentOrder.length - (count++)], row.getNodeRef()); - } - results.close(); - - SearchParameters sp5 = new SearchParameters(); - sp5.addStore(rootNodeRef.getStoreRef()); - sp5.setLanguage(SearchService.LANGUAGE_LUCENE); - sp5.setQuery("PATH:\"//.\""); - sp5.addSort(SearchParameters.SORT_IN_SCORE_ORDER_ASCENDING); - results = searcher.query(sp5); - - float score = 0; - for (ResultSetRow row : results) - { - assertTrue(score <= row.getScore()); - score = row.getScore(); - } - results.close(); - - SearchParameters sp6 = new SearchParameters(); - sp6.addStore(rootNodeRef.getStoreRef()); - sp6.setLanguage(SearchService.LANGUAGE_LUCENE); - sp6.setQuery("PATH:\"//.\""); - sp6.addSort(SearchParameters.SORT_IN_SCORE_ORDER_DESCENDING); - results = searcher.query(sp6); - - score = 1.0f; - for (ResultSetRow row : results) - { - assertTrue(score >= row.getScore()); - score = row.getScore(); - } - results.close(); - - // sort by created date - - SearchParameters sp7 = new SearchParameters(); - sp7.addStore(rootNodeRef.getStoreRef()); - sp7.setLanguage(SearchService.LANGUAGE_LUCENE); - sp7.setQuery("PATH:\"//.\""); - sp7.addSort("@" + createdDate, true); - results = searcher.query(sp7); - - Date date = null; - for (ResultSetRow row : results) - { - Date currentBun = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(row - .getNodeRef(), createdDate)); - //System.out.println(currentBun); - if (date != null) - { - assertTrue(date.compareTo(currentBun) <= 0); - } - date = currentBun; - } - results.close(); - - SearchParameters sp8 = new SearchParameters(); - sp8.addStore(rootNodeRef.getStoreRef()); - sp8.setLanguage(SearchService.LANGUAGE_LUCENE); - sp8.setQuery("PATH:\"//.\""); - sp8.addSort("@" + createdDate, false); - results = searcher.query(sp8); - - date = null; - for (ResultSetRow row : results) - { - Date currentBun = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(row - .getNodeRef(), createdDate)); - //System.out.println(currentBun); - if ((date != null) && (currentBun != null)) - { - assertTrue(date.compareTo(currentBun) >= 0); - } - date = currentBun; - } - results.close(); - - // sort by double - - SearchParameters sp9 = new SearchParameters(); - sp9.addStore(rootNodeRef.getStoreRef()); - sp9.setLanguage(SearchService.LANGUAGE_LUCENE); - sp9.setQuery("PATH:\"//.\""); - sp9.addSort("@" + orderDouble, true); - results = searcher.query(sp9); - - Double d = null; - for (ResultSetRow row : results) - { - Double currentBun = DefaultTypeConverter.INSTANCE.convert(Double.class, nodeService.getProperty(row - .getNodeRef(), orderDouble)); - //System.out.println( (currentBun == null ? "null" : NumericEncoder.encode(currentBun))+ " "+currentBun); - if (d != null) - { - assertTrue(d.compareTo(currentBun) <= 0); - } - d = currentBun; - } - results.close(); - - SearchParameters sp10 = new SearchParameters(); - sp10.addStore(rootNodeRef.getStoreRef()); - sp10.setLanguage(SearchService.LANGUAGE_LUCENE); - sp10.setQuery("PATH:\"//.\""); - sp10.addSort("@" + orderDouble, false); - results = searcher.query(sp10); - - d = null; - for (ResultSetRow row : results) - { - Double currentBun = DefaultTypeConverter.INSTANCE.convert(Double.class, nodeService.getProperty(row - .getNodeRef(), orderDouble)); - //System.out.println(currentBun); - if ((d != null) && (currentBun != null)) - { - assertTrue(d.compareTo(currentBun) >= 0); - } - d = currentBun; - } - results.close(); - - // sort by float - - SearchParameters sp11 = new SearchParameters(); - sp11.addStore(rootNodeRef.getStoreRef()); - sp11.setLanguage(SearchService.LANGUAGE_LUCENE); - sp11.setQuery("PATH:\"//.\""); - sp11.addSort("@" + orderFloat, true); - results = searcher.query(sp11); - - Float f = null; - for (ResultSetRow row : results) - { - Float currentBun = DefaultTypeConverter.INSTANCE.convert(Float.class, nodeService.getProperty(row - .getNodeRef(), orderFloat)); - //System.out.println( (currentBun == null ? "null" : NumericEncoder.encode(currentBun))+ " "+currentBun); - if (f != null) - { - assertTrue(f.compareTo(currentBun) <= 0); - } - f = currentBun; - } - results.close(); - - SearchParameters sp12 = new SearchParameters(); - sp12.addStore(rootNodeRef.getStoreRef()); - sp12.setLanguage(SearchService.LANGUAGE_LUCENE); - sp12.setQuery("PATH:\"//.\""); - sp12.addSort("@" + orderFloat, false); - results = searcher.query(sp12); - - f = null; - for (ResultSetRow row : results) - { - Float currentBun = DefaultTypeConverter.INSTANCE.convert(Float.class, nodeService.getProperty(row - .getNodeRef(), orderFloat)); - //System.out.println(currentBun); - if ((f != null) && (currentBun != null)) - { - assertTrue(f.compareTo(currentBun) >= 0); - } - f = currentBun; - } - results.close(); - - // sort by long - - SearchParameters sp13 = new SearchParameters(); - sp13.addStore(rootNodeRef.getStoreRef()); - sp13.setLanguage(SearchService.LANGUAGE_LUCENE); - sp13.setQuery("PATH:\"//.\""); - sp13.addSort("@" + orderLong, true); - results = searcher.query(sp13); - - Long l = null; - for (ResultSetRow row : results) - { - Long currentBun = DefaultTypeConverter.INSTANCE.convert(Long.class, nodeService.getProperty(row - .getNodeRef(), orderLong)); - //System.out.println( (currentBun == null ? "null" : NumericEncoder.encode(currentBun))+ " "+currentBun); - if (l != null) - { - assertTrue(l.compareTo(currentBun) <= 0); - } - l = currentBun; - } - results.close(); - - SearchParameters sp14 = new SearchParameters(); - sp14.addStore(rootNodeRef.getStoreRef()); - sp14.setLanguage(SearchService.LANGUAGE_LUCENE); - sp14.setQuery("PATH:\"//.\""); - sp14.addSort("@" + orderLong, false); - results = searcher.query(sp14); - - l = null; - for (ResultSetRow row : results) - { - Long currentBun = DefaultTypeConverter.INSTANCE.convert(Long.class, nodeService.getProperty(row - .getNodeRef(), orderLong)); - //System.out.println(currentBun); - if ((l != null) && (currentBun != null)) - { - assertTrue(l.compareTo(currentBun) >= 0); - } - l = currentBun; - } - results.close(); - - // sort by int - - SearchParameters sp15 = new SearchParameters(); - sp15.addStore(rootNodeRef.getStoreRef()); - sp15.setLanguage(SearchService.LANGUAGE_LUCENE); - sp15.setQuery("PATH:\"//.\""); - sp15.addSort("@" + orderInt, true); - results = searcher.query(sp15); - - Integer i = null; - for (ResultSetRow row : results) - { - Integer currentBun = DefaultTypeConverter.INSTANCE.convert(Integer.class, nodeService.getProperty(row - .getNodeRef(), orderInt)); - //System.out.println( (currentBun == null ? "null" : NumericEncoder.encode(currentBun))+ " "+currentBun); - if (i != null) - { - assertTrue(i.compareTo(currentBun) <= 0); - } - i = currentBun; - } - results.close(); - - SearchParameters sp16 = new SearchParameters(); - sp16.addStore(rootNodeRef.getStoreRef()); - sp16.setLanguage(SearchService.LANGUAGE_LUCENE); - sp16.setQuery("PATH:\"//.\""); - sp16.addSort("@" + orderInt, false); - results = searcher.query(sp16); - - i = null; - for (ResultSetRow row : results) - { - Integer currentBun = DefaultTypeConverter.INSTANCE.convert(Integer.class, nodeService.getProperty(row - .getNodeRef(), orderInt)); - //System.out.println(currentBun); - if ((i != null) && (currentBun != null)) - { - assertTrue(i.compareTo(currentBun) >= 0); - } - i = currentBun; - } - results.close(); - - luceneFTS.resume(); - } - - public void test1() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - luceneFTS.resume(); - } - - public void test2() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - luceneFTS.resume(); - } - - public void test3() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - luceneFTS.resume(); - } - - public void test4() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setDictionaryService(dictionaryService); - - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "\\@\\{namespace\\}property\\-2:\"valuetwo\"", null, null); - results.close(); - luceneFTS.resume(); - } - - public void test5() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - luceneFTS.resume(); - } - - public void test6() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - luceneFTS.resume(); - } - - public void testNoOp() throws Exception - { - luceneFTS.pause(); - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis() + "_1", indexerAndSearcher); - - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - - indexer.prepare(); - indexer.commit(); - luceneFTS.resume(); - } - - /** - * Test basic index and search - * - * @throws InterruptedException - * - */ - - public void testStandAloneIndexerCommit() throws Exception - { - luceneFTS.pause(); - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis() + "_1", indexerAndSearcher); - - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - - // //indexer.clearIndex(); - - indexer.createNode(new ChildAssociationRef(null, null, null, rootNodeRef)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName - .createQName("{namespace}one"), n1)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName - .createQName("{namespace}two"), n2)); - indexer.updateNode(n1); - // indexer.deleteNode(new ChildRelationshipRef(rootNode, "path", - // newNode)); - - indexer.prepare(); - indexer.commit(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "\\@\\{namespace\\}property\\-2:\"valuetwo\"", null, null); - simpleResultSetTest(results); - - ChildAssocRefResultSet r2 = new ChildAssocRefResultSet(nodeService, results.getNodeRefs(), null, false); - simpleResultSetTest(r2); - - ChildAssocRefResultSet r3 = new ChildAssocRefResultSet(nodeService, results.getNodeRefs(), null, true); - simpleResultSetTest(r3); - - ChildAssocRefResultSet r4 = new ChildAssocRefResultSet(nodeService, results.getChildAssocRefs(), null); - simpleResultSetTest(r4); - - DetachedResultSet r5 = new DetachedResultSet(results, null); - simpleResultSetTest(r5); - - DetachedResultSet r6 = new DetachedResultSet(r2, null); - simpleResultSetTest(r6); - - DetachedResultSet r7 = new DetachedResultSet(r3, null); - simpleResultSetTest(r7); - - DetachedResultSet r8 = new DetachedResultSet(r4, null); - simpleResultSetTest(r8); - - DetachedResultSet r9 = new DetachedResultSet(r5, null); - simpleResultSetTest(r9); - - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@\\{namespace\\}property\\-1:\"valueone\"", - null, null); - assertEquals(2, results.length()); - assertEquals(n2.getId(), results.getNodeRef(0).getId()); - assertEquals(n1.getId(), results.getNodeRef(1).getId()); - assertEquals(1.0f, results.getScore(0)); - assertEquals(1.0f, results.getScore(1)); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@namespace\\:property\\-1:\"valueone\"", null, - null); - assertEquals(2, results.length()); - assertEquals(n2.getId(), results.getNodeRef(0).getId()); - assertEquals(n1.getId(), results.getNodeRef(1).getId()); - assertEquals(1.0f, results.getScore(0)); - assertEquals(1.0f, results.getScore(1)); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@property\\-1:\"valueone\"", null, null); - assertEquals(2, results.length()); - assertEquals(n2.getId(), results.getNodeRef(0).getId()); - assertEquals(n1.getId(), results.getNodeRef(1).getId()); - assertEquals(1.0f, results.getScore(0)); - assertEquals(1.0f, results.getScore(1)); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@property\\-1:\"Valueone\"", null, null); - assertEquals(2, results.length()); - assertEquals(n2.getId(), results.getNodeRef(0).getId()); - assertEquals(n1.getId(), results.getNodeRef(1).getId()); - assertEquals(1.0f, results.getScore(0)); - assertEquals(1.0f, results.getScore(1)); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@property\\-1:ValueOne", null, null); - assertEquals(2, results.length()); - assertEquals(n2.getId(), results.getNodeRef(0).getId()); - assertEquals(n1.getId(), results.getNodeRef(1).getId()); - assertEquals(1.0f, results.getScore(0)); - assertEquals(1.0f, results.getScore(1)); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@property\\-1:valueone", null, null); - assertEquals(2, results.length()); - assertEquals(n2.getId(), results.getNodeRef(0).getId()); - assertEquals(n1.getId(), results.getNodeRef(1).getId()); - assertEquals(1.0f, results.getScore(0)); - assertEquals(1.0f, results.getScore(1)); - results.close(); - - QName qname = QName.createQName("", "property-1"); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "ID:\"" + n1.toString() + "\"", null, null); - - assertEquals(2, results.length()); - - results.close(); - luceneFTS.resume(); - } - - private void simpleResultSetTest(ResultSet results) - { - assertEquals(1, results.length()); - assertEquals(n2.getId(), results.getNodeRef(0).getId()); - assertEquals(n2, results.getNodeRef(0)); - assertEquals(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName - .createQName("{namespace}two"), n2), results.getChildAssocRef(0)); - assertEquals(1, results.getChildAssocRefs().size()); - assertNotNull(results.getChildAssocRefs()); - assertEquals(0, results.getRow(0).getIndex()); - assertEquals(1.0f, results.getRow(0).getScore()); - assertEquals(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName - .createQName("{namespace}two"), n2), results.getRow(0).getChildAssocRef()); - assertEquals(n2, results.getRow(0).getNodeRef()); - assertEquals(QName.createQName("{namespace}two"), results.getRow(0).getQName()); - assertEquals("valuetwo", results.getRow(0).getValue(QName.createQName("{namespace}property-2"))); - for (ResultSetRow row : results) - { - assertNotNull(row); - } - } - - public void testStandAlonePathIndexer() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@\\{namespace\\}property-1:valueone", - null, null); - try - { - assertEquals(2, results.length()); - assertEquals(n1.getId(), results.getNodeRef(0).getId()); - assertEquals(n2.getId(), results.getNodeRef(1).getId()); - // assertEquals(1.0f, results.getScore(0)); - // assertEquals(1.0f, results.getScore(1)); - - QName qname = QName.createQName("", "property-1"); - - } - finally - { - results.close(); - } - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "+ID:\"" + n1.toString() + "\"", null, null); - try - { - assertEquals(2, results.length()); - } - finally - { - results.close(); - } - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "ID:\"" + rootNodeRef.toString() + "\"", null, - null); - try - { - assertEquals(1, results.length()); - } - finally - { - results.close(); - } - luceneFTS.resume(); - } - - private void buildBaseIndex() - { - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis() + "_" + (new Random().nextInt()), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - // indexer.clearIndex(); - indexer.createNode(new ChildAssociationRef(null, null, null, rootNodeRef)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName - .createQName("{namespace}one"), n1)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName - .createQName("{namespace}two"), n2)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName - .createQName("{namespace}three"), n3)); - indexer.createNode(new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, rootNodeRef, QName - .createQName("{namespace}four"), n4)); - indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n1, QName.createQName("{namespace}five"), n5)); - indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n1, QName.createQName("{namespace}six"), n6)); - indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n2, QName.createQName("{namespace}seven"), n7)); - indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n2, QName.createQName("{namespace}eight"), n8)); - indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n5, QName.createQName("{namespace}nine"), n9)); - indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n5, QName.createQName("{namespace}ten"), n10)); - indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n5, QName.createQName("{namespace}eleven"), n11)); - indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n5, QName.createQName("{namespace}twelve"), n12)); - indexer - .createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n12, QName.createQName("{namespace}thirteen"), - n13)); - indexer - .createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n13, QName.createQName("{namespace}fourteen"), - n14)); - indexer.prepare(); - indexer.commit(); - } - - public void testAllPathSearch() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - - runBaseTests(); - luceneFTS.resume(); - } - - private void runBaseTests() - { - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - searcher.setQueryRegister(queryRegisterComponent); - ResultSet results; - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/.\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:three\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:four\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:eight-0\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:five\"", null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:one\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:two\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:one\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:two\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:five\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:six\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:seven\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-1\"", - null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-2\"", - null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-2\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-1\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-0\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-0\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:ten\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:eleven\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve/namespace:thirteen\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve/namespace:thirteen/namespace:fourteen\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/namespace:*/namespace:*\"", - null, null); - assertEquals(8, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:*\"", null, null); - assertEquals(6, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:five\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH_WITH_REPEATS:\"/namespace:*/namespace:*/namespace:*\"", null, null); - assertEquals(8, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:*/namespace:*\"", - null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:*/namespace:five/namespace:*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:*/namespace:nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/*/*\"", null, null); - assertEquals(8, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/*\"", null, null); - assertEquals(6, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/namespace:five\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/*/*/*\"", null, null); - assertEquals(8, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/*/*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/namespace:five/*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/*/namespace:nine\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//.\"", null, null); - assertEquals(26, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//.\"", null, null); - assertEquals(15, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*\"", null, null); - assertEquals(25, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*/.\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*/.\"", null, null); - assertEquals(25, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*/./.\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*/./.\"", null, null); - assertEquals(25, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//./*\"", null, null); - assertEquals(25, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//./*\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//././*/././.\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//././*/././.\"", null, null); - assertEquals(25, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//common\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//common\"", null, null); - assertEquals(7, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//common\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/one//common\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one/five//*\"", null, null); - assertEquals(6, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/one/five//*\"", null, null); - assertEquals(9, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one/five//.\"", null, null); - assertEquals(7, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/one/five//.\"", null, null); - assertEquals(10, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//five/nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//thirteen/fourteen\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//thirteen/fourteen//.\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//thirteen/fourteen//.//.\"", null, - null); - assertEquals(1, results.length()); - results.close(); - - // Type search tests - - QName qname = QName.createQName(TEST_NAMESPACE, "int-ista"); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":\"1\"", null, null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "int-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":1", null, null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "int-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":\"01\"", null, - null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "int-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":01", null, null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "int-ista"); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "@" + escapeQName(qname) + ":\"001\"", null, null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "int-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@test\\:int\\-ista:\"0001\"", null, null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "int-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":[0 TO 2]", null, - null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "int-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":{0 TO 1}", null, - null); - assertEquals(0, results.length()); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "int-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":{1 TO 2}", null, - null); - assertEquals(0, results.length()); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "long-ista"); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":\"2\"", null, null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "long-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":\"02\"", null, - null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "long-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":\"002\"", null, - null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "long-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":\"0002\"", null, - null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "long-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":[0 TO 2]", null, - null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "long-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":{0 TO 2}", null, - null); - assertEquals(0, results.length()); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "long-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":{2 TO 3}", null, - null); - assertEquals(0, results.length()); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "float-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":\"3.4\"", null, - null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "float-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":[3 TO 4]", null, - null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "float-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":[3.3 TO 3.4]", - null, null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "float-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":{3.3 TO 3.4}", - null, null); - assertEquals(0, results.length()); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "float-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":\"3.40\"", null, - null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "float-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":\"03.4\"", null, - null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "float-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":\"03.40\"", null, - null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "double-ista")) + ":\"5.6\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "double-ista")) + ":\"05.6\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "double-ista")) + ":\"5.60\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "double-ista")) + ":\"05.60\"", null, null); - assertEquals(1, results.length()); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "double-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":[5.5 TO 5.7]", - null, null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "double-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":{5.5 TO 5.6}", - null, null); - assertEquals(0, results.length()); - results.close(); - - qname = QName.createQName(TEST_NAMESPACE, "double-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(qname) + ":{5.6 TO 5.7}", - null, null); - assertEquals(0, results.length()); - results.close(); - - Date date = new Date(); - String sDate = CachingDateFormat.getDateFormat().format(date); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":\"" + sDate + "\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":\"" + sDate + "\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "boolean-ista")) + ":\"true\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "qname-ista")) + ":\"{wibble}wobble\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "category-ista")) - + ":\"" - + DefaultTypeConverter.INSTANCE.convert(String.class, new NodeRef(rootNodeRef.getStoreRef(), - "CategoryId")) + "\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "noderef-ista")) + ":\"" + n1 + "\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "path-ista")) + ":\"" + nodeService.getPath(n3) + "\"", - null, null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(QName.createQName(TEST_NAMESPACE, "path-ista"))); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "verbatim")) + ":\" \"", - null, null); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(QName.createQName(TEST_NAMESPACE, "verbatim"))); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "verbatim")) + ":\" \"", - null, null); - assertEquals(0, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "TYPE:\"" + testType.toString() + "\"", null, - null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "TYPE:\"" + testSuperType.toString() + "\"", - null, null); - assertEquals(13, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "ASPECT:\"" - + ISO9075.getXPathName(testAspect) + "\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "ASPECT:\"" - + ISO9075.getXPathName(testSuperAspect) + "\"", null, null); - assertEquals(1, results.length()); - results.close(); - - // FTS test - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "TEXT:\"fox\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" - + LuceneQueryParser.escape(ContentModel.PROP_CONTENT.toString()) + ":\"fox\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" - + LuceneQueryParser.escape(ContentModel.PROP_CONTENT.toString()) + ".mimetype:\"text/plain\"", null, - null); - assertEquals(1, results.length()); - results.close(); - - QName queryQName = QName.createQName("alf:test1", namespacePrefixResolver); - results = searcher.query(rootNodeRef.getStoreRef(), queryQName, null); - assertEquals(1, results.length()); - results.close(); - - // Parameters - - queryQName = QName.createQName("alf:test2", namespacePrefixResolver); - results = searcher.query(rootNodeRef.getStoreRef(), queryQName, null); - assertEquals(1, results.length()); - results.close(); - - queryQName = QName.createQName("alf:test2", namespacePrefixResolver); - QueryParameter qp = new QueryParameter(QName.createQName("alf:banana", namespacePrefixResolver), "woof"); - results = searcher.query(rootNodeRef.getStoreRef(), queryQName, new QueryParameter[] { qp }); - assertEquals(0, results.length()); - results.close(); - - queryQName = QName.createQName("alf:test3", namespacePrefixResolver); - qp = new QueryParameter(QName.createQName("alf:banana", namespacePrefixResolver), "/one/five//*"); - results = searcher.query(rootNodeRef.getStoreRef(), queryQName, new QueryParameter[] { qp }); - assertEquals(6, results.length()); - results.close(); - - // TODO: should not have a null property type definition - QueryParameterDefImpl paramDef = new QueryParameterDefImpl(QName.createQName("alf:lemur", - namespacePrefixResolver), (DataTypeDefinition) null, true, "fox"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "TEXT:\"${alf:lemur}\"", null, - new QueryParameterDefinition[] { paramDef }); - assertEquals(1, results.length()); - results.close(); - - paramDef = new QueryParameterDefImpl(QName.createQName("alf:intvalue", namespacePrefixResolver), - (DataTypeDefinition) null, true, "1"); - qname = QName.createQName(TEST_NAMESPACE, "int-ista"); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(qname) + ":\"${alf:intvalue}\"", null, new QueryParameterDefinition[] { paramDef }); - assertEquals(1, results.length()); - assertNotNull(results.getRow(0).getValue(qname)); - results.close(); - - } - - public void testPathSearch() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - - // //* - - ResultSet - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//common\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//common\"", null, null); - assertEquals(7, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//common\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/one//common\"", null, null); - assertEquals(5, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one/five//*\"", null, null); - assertEquals(6, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/one/five//*\"", null, null); - assertEquals(9, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one/five//.\"", null, null); - assertEquals(7, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/one/five//.\"", null, null); - assertEquals(10, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//five/nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//thirteen/fourteen\"", null, null); - assertEquals(1, results.length()); - results.close(); - luceneFTS.resume(); - } - - public void testXPathSearch() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - - // //* - - ResultSet - - results = searcher.query(rootNodeRef.getStoreRef(), "xpath", "//./*", null, null); - assertEquals(14, results.length()); - results.close(); - luceneFTS.resume(); - - QueryParameterDefinition paramDef = new QueryParameterDefImpl(QName.createQName("alf:query", - namespacePrefixResolver), (DataTypeDefinition) null, true, "//./*"); - results = searcher.query(rootNodeRef.getStoreRef(), "xpath", "${alf:query}", null, - new QueryParameterDefinition[] { paramDef }); - assertEquals(14, results.length()); - results.close(); - } - - public void testMissingIndex() throws Exception - { - luceneFTS.pause(); - StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "_missing_"); - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(storeRef, indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - - // //* - - ResultSet - - results = searcher.query(storeRef, "xpath", "//./*", null, null); - assertEquals(0, results.length()); - luceneFTS.resume(); - } - - public void testUpdateIndex() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - - runBaseTests(); - - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis(), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - - indexer.updateNode(rootNodeRef); - indexer.updateNode(n1); - indexer.updateNode(n2); - indexer.updateNode(n3); - indexer.updateNode(n4); - indexer.updateNode(n5); - indexer.updateNode(n6); - indexer.updateNode(n7); - indexer.updateNode(n8); - indexer.updateNode(n9); - indexer.updateNode(n10); - indexer.updateNode(n11); - indexer.updateNode(n12); - indexer.updateNode(n13); - indexer.updateNode(n14); - - indexer.commit(); - - runBaseTests(); - luceneFTS.resume(); - } - - public void testDeleteLeaf() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis(), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - - indexer - .deleteNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n13, QName.createQName("{namespace}fourteen"), - n14)); - - indexer.commit(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:three\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:four\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:eight-0\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:five\"", null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:one\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:two\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:one\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:two\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:five\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:six\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:seven\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-1\"", - null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-2\"", - null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-2\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-1\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-0\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-0\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:ten\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:eleven\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve/namespace:thirteen\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve/namespace:thirteen/namespace:fourteen\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/namespace:*/namespace:*\"", - null, null); - assertEquals(6, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:five\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:*/namespace:*\"", - null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:*\"", null, null); - assertEquals(3, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:*/namespace:five/namespace:*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:*/namespace:nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/*/*\"", null, null); - assertEquals(6, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/namespace:five\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/*/*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/*\"", null, null); - assertEquals(3, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/namespace:five/*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/*/namespace:nine\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//.\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//.\"", null, null); - assertEquals(17, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*\"", null, null); - assertEquals(13, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*\"", null, null); - assertEquals(16, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*/.\"", null, null); - assertEquals(13, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*/.\"", null, null); - assertEquals(16, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*/./.\"", null, null); - assertEquals(13, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*/./.\"", null, null); - assertEquals(16, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//./*\"", null, null); - assertEquals(13, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//./*\"", null, null); - assertEquals(16, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//././*/././.\"", null, null); - assertEquals(13, results.length()); - results.close(); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//././*/././.\"", null, null); - assertEquals(16, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//common\"", null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//common\"", null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one/five//*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/one/five//*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one/five//.\"", null, null); - assertEquals(6, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//five/nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//thirteen/fourteen\"", null, null); - assertEquals(0, results.length()); - results.close(); - luceneFTS.resume(); - } - - public void testAddEscapedChild() throws Exception - { - String COMPLEX_LOCAL_NAME = " `¬¦!\"£$%^&*()-_=+\t\n\\\u0000[]{};'#:@~,./<>?\\|\u0123\u4567\u8900\uabcd\uefff_xT65A_"; - - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis(), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - - ChildAssociationRef car = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName - .createQName("{namespace}" + COMPLEX_LOCAL_NAME), testSuperType); - indexer.createNode(car); - - indexer.commit(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:" - + ISO9075.encode(COMPLEX_LOCAL_NAME) + "\"", null, null); - assertEquals(1, results.length()); - results.close(); - } - - public void testNumericInPath() throws Exception - { - String COMPLEX_LOCAL_NAME = "Woof12"; - - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis(), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - - ChildAssociationRef car = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName - .createQName("{namespace}" + COMPLEX_LOCAL_NAME), testSuperType); - indexer.createNode(car); - - indexer.commit(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:" - + ISO9075.encode(COMPLEX_LOCAL_NAME) + "\"", null, null); - assertEquals(1, results.length()); - results.close(); - } - - public void testDeleteContainer() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis(), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - - indexer - .deleteNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, n12, QName.createQName("{namespace}thirteen"), - n13)); - - indexer.commit(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:three\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:four\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:eight-0\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:five\"", null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:one\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:two\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:one\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:two\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:five\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:six\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:seven\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-1\"", - null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-2\"", - null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-2\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-1\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-0\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-0\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:ten\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:eleven\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve/namespace:thirteen\"", null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve/namespace:thirteen/namespace:fourteen\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/namespace:*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/namespace:*/namespace:*\"", - null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:five\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:*/namespace:*\"", - null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:*\"", null, null); - assertEquals(3, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:*/namespace:five/namespace:*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:*/namespace:nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/*/*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/namespace:five\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/*/*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/*/*/*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/*\"", null, null); - assertEquals(3, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/namespace:five/*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/*/namespace:nine\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//.\"", null, null); - assertEquals(13, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//.\"", null, null); - assertEquals(15, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*\"", null, null); - assertEquals(12, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*/.\"", null, null); - assertEquals(12, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*/.\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*/./.\"", null, null); - assertEquals(12, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*/./.\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//./*\"", null, null); - assertEquals(12, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//./*\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//././*/././.\"", null, null); - assertEquals(12, results.length()); - results.close(); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//././*/././.\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//common\"", null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//common\"", null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one/five//*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one/five//.\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//five/nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//thirteen/fourteen\"", null, null); - assertEquals(0, results.length()); - results.close(); - luceneFTS.resume(); - } - - public void testDeleteAndAddReference() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis(), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - - nodeService.removeChild(n2, n13); - indexer.deleteChildRelationship(new ChildAssociationRef(ASSOC_TYPE_QNAME, n2, QName - .createQName("{namespace}link"), n13)); - - indexer.commit(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:three\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:four\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:eight-0\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:five\"", null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:one\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:two\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:one\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:two\"", null, - null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:five\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:six\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:seven\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-1\"", - null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-2\"", - null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-2\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-1\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:two/namespace:eight-0\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:eight-0\"", - null, null); - assertEquals(0, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:ten\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:eleven\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve/namespace:thirteen\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:five/namespace:twelve/namespace:thirteen/namespace:fourteen\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/namespace:*/namespace:*\"", - null, null); - assertEquals(7, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:five\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:*/namespace:*/namespace:*\"", - null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH_WITH_REPEATS:\"/namespace:*/namespace:*/namespace:*\"", null, null); - assertEquals(6, results.length()); - results.close(); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/namespace:*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:*/namespace:five/namespace:*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH:\"/namespace:one/namespace:*/namespace:nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/*/*\"", null, null); - assertEquals(7, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/namespace:five\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/*/*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/*/*/*\"", null, null); - assertEquals(6, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/*\"", null, null); - assertEquals(4, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/*/namespace:five/*\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/namespace:one/*/namespace:nine\"", null, - null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//.\"", null, null); - assertEquals(15, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//.\"", null, null); - assertEquals(23, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*\"", null, null); - assertEquals(22, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*/.\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*/.\"", null, null); - assertEquals(22, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//*/./.\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//*/./.\"", null, null); - assertEquals(22, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//./*\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//./*\"", null, null); - assertEquals(22, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//././*/././.\"", null, null); - assertEquals(14, results.length()); - results.close(); - results = searcher - .query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//././*/././.\"", null, null); - assertEquals(22, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//common\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//common\"", null, null); - assertEquals(6, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//common\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/one//common\"", null, null); - assertEquals(5, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one/five//*\"", null, null); - assertEquals(6, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/one/five//*\"", null, null); - assertEquals(9, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one/five//.\"", null, null); - assertEquals(7, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"/one/five//.\"", null, null); - assertEquals(10, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//five/nine\"", null, null); - assertEquals(1, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"/one//thirteen/fourteen\"", null, null); - assertEquals(1, results.length()); - results.close(); - - indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" + System.currentTimeMillis(), - indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - - nodeService.addChild(n2, n13, ASSOC_TYPE_QNAME, QName.createQName("{namespace}link")); - indexer.createChildRelationship(new ChildAssociationRef(ASSOC_TYPE_QNAME, n2, QName - .createQName("{namespace}link"), n13)); - - indexer.commit(); - - runBaseTests(); - luceneFTS.resume(); - } - - public void testRenameReference() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//namespace:link//.\"", null, - null); - assertEquals(2, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH_WITH_REPEATS:\"//namespace:link//.\"", - null, null); - assertEquals(3, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//namespace:renamed_link//.\"", null, - null); - assertEquals(0, results.length()); - results.close(); - - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis(), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - - nodeService.removeChild(n2, n13); - nodeService.addChild(n2, n13, ASSOC_TYPE_QNAME, QName.createQName("{namespace}renamed_link")); - - indexer.updateChildRelationship(new ChildAssociationRef(ASSOC_TYPE_QNAME, n2, QName.createQName("namespace", - "link"), n13), new ChildAssociationRef(ASSOC_TYPE_QNAME, n2, QName.createQName("namespace", - "renamed_link"), n13)); - - indexer.commit(); - - runBaseTests(); - - searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - searcher.setDictionaryService(dictionaryService); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//namespace:link//.\"", null, null); - assertEquals(0, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PATH:\"//namespace:renamed_link//.\"", null, - null); - assertEquals(2, results.length()); - results.close(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", - "PATH_WITH_REPEATS:\"//namespace:renamed_link//.\"", null, null); - assertEquals(3, results.length()); - results.close(); - luceneFTS.resume(); - } - - public void testDelayIndex() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-stored-tokenised-atomic")) - + ":\"KEYONE\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-unstored-tokenised-atomic")) - + ":\"KEYUNSTORED\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-stored-tokenised-nonatomic")) - + ":\"KEYTWO\"", null, null); - assertEquals(0, results.length()); - results.close(); - - // Do index - - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis() + "_" + (new Random().nextInt()), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - indexer.updateFullTextSearch(1000); - indexer.prepare(); - indexer.commit(); - - searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - searcher.setDictionaryService(dictionaryService); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-stored-tokenised-atomic")) - + ":\"keyone\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-stored-tokenised-nonatomic")) - + ":\"keytwo\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-unstored-tokenised-atomic")) - + ":\"keyunstored\"", null, null); - assertEquals(1, results.length()); - results.close(); - - runBaseTests(); - luceneFTS.resume(); - } - - public void testWaitForIndex() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-stored-tokenised-atomic")) - + ":\"KEYONE\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-unstored-tokenised-atomic")) - + ":\"KEYUNSTORED\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-stored-tokenised-nonatomic")) - + ":\"KEYTWO\"", null, null); - assertEquals(0, results.length()); - results.close(); - - // Do index - - searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-stored-tokenised-atomic")) - + ":\"keyone\"", null, null); - assertEquals(1, results.length()); - results.close(); - - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis() + "_" + (new Random().nextInt()), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - indexer.updateFullTextSearch(1000); - indexer.prepare(); - indexer.commit(); - - luceneFTS.resume(); - // luceneFTS.requiresIndex(rootNodeRef.getStoreRef()); - // luceneFTS.index(); - // luceneFTS.index(); - // luceneFTS.index(); - - Thread.sleep(35000); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-stored-tokenised-nonatomic")) - + ":\"keytwo\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" - + escapeQName(QName.createQName(TEST_NAMESPACE, "text-indexed-unstored-tokenised-atomic")) - + ":\"KEYUNSTORED\"", null, null); - assertEquals(1, results.length()); - results.close(); - - runBaseTests(); - } - - private String escapeQName(QName qname) - { - return LuceneQueryParser.escape(qname.toString()); - } - - public void testForKev() throws Exception - { - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "PARENT:\"" - + rootNodeRef.toString() + "\"", null, null); - assertEquals(5, results.length()); - results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "+PARENT:\"" - + rootNodeRef.toString() + "\" +QNAME:\"one\"", null, null); - assertEquals(1, results.length()); - results.close(); - - results = searcher - .query( - rootNodeRef.getStoreRef(), - "lucene", - "( +TYPE:\"{http://www.alfresco.org/model/content/1.0}content\" +@\\{http\\://www.alfresco.org/model/content/1.0\\}name:\"content woof\") OR TEXT:\"content\"", - null, null); - - luceneFTS.resume(); - } - - public void xtestIssueAR47() throws Exception - { - // This bug arose from repeated deletes and adds creating empty index - // segments. - // Two segements each containing one deletyed entry were merged together - // producing a single empty entry. - // This seemed to be bad for lucene - I am not sure why - - // So we add something, add and delete someting repeatedly and then - // check we can still do the search. - - // Running in autocommit against the index - testTX.commit(); - UserTransaction tx = transactionService.getUserTransaction(); - tx.begin(); - ChildAssociationRef testFind = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName - .createQName("{namespace}testFind"), testSuperType); - tx.commit(); - - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); - searcher.setNodeService(nodeService); - searcher.setDictionaryService(dictionaryService); - searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace")); - searcher.setQueryRegister(queryRegisterComponent); - - ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "QNAME:\"namespace:testFind\""); - assertEquals(1, results.length()); - results.close(); - - for (int i = 0; i < 100; i++) - { - UserTransaction tx1 = transactionService.getUserTransaction(); - tx1.begin(); - ChildAssociationRef test = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName - .createQName("{namespace}test"), testSuperType); - tx1.commit(); - - UserTransaction tx2 = transactionService.getUserTransaction(); - tx2.begin(); - nodeService.deleteNode(test.getChildRef()); - tx2.commit(); - } - - UserTransaction tx3 = transactionService.getUserTransaction(); - tx3.begin(); - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "QNAME:\"namespace:testFind\""); - assertEquals(1, results.length()); - results.close(); - tx3.commit(); - } - - // Ignore the following test until implementation is completed - - public void testReadAgainstDelta() throws Exception - { - testTX.commit(); - UserTransaction tx = transactionService.getUserTransaction(); - tx.begin(); - luceneFTS.pause(); - buildBaseIndex(); - runBaseTests(); - tx.commit(); - - // Delete - - tx = transactionService.getUserTransaction(); - tx.begin(); - - runBaseTests(); - - serviceRegistry.getNodeService().deleteNode(n1); - - SearchParameters sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - ResultSet results = serviceRegistry.getSearchService().query(sp); - assertEquals(5, results.length()); - results.close(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(true); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - tx.rollback(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.addSort("ID", true); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - // Create - - tx = transactionService.getUserTransaction(); - tx.begin(); - - runBaseTests(); - - assertEquals(5, serviceRegistry.getNodeService().getChildAssocs(rootNodeRef).size()); - serviceRegistry.getNodeService().createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, - QName.createQName("{namespace}texas"), testSuperType).getChildRef(); - assertEquals(6, serviceRegistry.getNodeService().getChildAssocs(rootNodeRef).size()); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(16, results.length()); - results.close(); - - tx.rollback(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.addSort("ID", true); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - // update property - - tx = transactionService.getUserTransaction(); - tx.begin(); - - runBaseTests(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("\\@\\{namespace\\}property\\-1:\"valueone\""); - sp.addSort("ID", true); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - - assertEquals(2, results.length()); - results.close(); - - nodeService.setProperty(n1, QName.createQName("{namespace}property-1"), "Different"); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("\\@\\{namespace\\}property\\-1:\"valueone\""); - sp.addSort("ID", true); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - - assertEquals(1, results.length()); - results.close(); - - tx.rollback(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("\\@\\{namespace\\}property\\-1:\"valueone\""); - sp.excludeDataInTheCurrentTransaction(false); - sp.addSort("ID", true); - results = serviceRegistry.getSearchService().query(sp); - - assertEquals(2, results.length()); - results.close(); - - // Add and delete - - tx = transactionService.getUserTransaction(); - tx.begin(); - - runBaseTests(); - - serviceRegistry.getNodeService().deleteNode(n1); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(5, results.length()); - results.close(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(true); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - NodeRef created = serviceRegistry.getNodeService().createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, - QName.createQName("{namespace}texas"), testSuperType).getChildRef(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(6, results.length()); - results.close(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(true); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - serviceRegistry.getNodeService().deleteNode(created); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(5, results.length()); - results.close(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.excludeDataInTheCurrentTransaction(true); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - tx.rollback(); - - sp = new SearchParameters(); - sp.addStore(rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"//.\""); - sp.addSort("ID", true); - sp.excludeDataInTheCurrentTransaction(false); - results = serviceRegistry.getSearchService().query(sp); - assertEquals(15, results.length()); - results.close(); - - } - - private void runPerformanceTest(double time, boolean clear) - { - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" - + System.currentTimeMillis() + "_" + (new Random().nextInt()), indexerAndSearcher); - indexer.setNodeService(nodeService); - indexer.setLuceneIndexLock(luceneIndexLock); - indexer.setDictionaryService(dictionaryService); - indexer.setLuceneFullTextSearchIndexer(luceneFTS); - indexer.setContentService(contentService); - if (clear) - { - // indexer.clearIndex(); - } - indexer.createNode(new ChildAssociationRef(null, null, null, rootNodeRef)); - - long startTime = System.currentTimeMillis(); - int count = 0; - for (int i = 0; i < 10000000; i++) - { - if (i % 10 == 0) - { - if (System.currentTimeMillis() - startTime > time) - { - count = i; - break; - } - } - - QName qname = QName.createQName("{namespace}a_" + i); - NodeRef ref = nodeService.createNode(rootNodeRef, ASSOC_TYPE_QNAME, qname, ContentModel.TYPE_CONTAINER) - .getChildRef(); - indexer.createNode(new ChildAssociationRef(ASSOC_TYPE_QNAME, rootNodeRef, qname, ref)); - - } - indexer.commit(); - float delta = ((System.currentTimeMillis() - startTime) / 1000.0f); - // System.out.println("\tCreated " + count + " in " + delta + " = " + - // (count / delta)); - } - - private NamespacePrefixResolver getNamespacePrefixReolsver(String defaultURI) - { - DynamicNamespacePrefixResolver nspr = new DynamicNamespacePrefixResolver(null); - nspr.registerNamespace(NamespaceService.ALFRESCO_PREFIX, NamespaceService.ALFRESCO_URI); - nspr.registerNamespace(NamespaceService.CONTENT_MODEL_PREFIX, NamespaceService.CONTENT_MODEL_1_0_URI); - nspr.registerNamespace("namespace", "namespace"); - nspr.registerNamespace("test", TEST_NAMESPACE); - nspr.registerNamespace(NamespaceService.DEFAULT_PREFIX, defaultURI); - return nspr; - } - - public static void main(String[] args) throws Exception - { - LuceneTest test = new LuceneTest(); - test.setUp(); - // test.testForKev(); - // test.testDeleteContainer(); - - // test.testReadAgainstDelta(); - - NodeRef targetNode = test.rootNodeRef; - Path path = test.serviceRegistry.getNodeService().getPath(targetNode); - - SearchParameters sp = new SearchParameters(); - sp.addStore(test.rootNodeRef.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("PATH:\"" + path + "//." + "\""); - ResultSet results = test.serviceRegistry.getSearchService().query(sp); - - results.close(); - - // test.dictionaryService.getType(test.nodeService.getType(test.rootNodeRef)).getDefaultAspects(); - } -} diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneTest2.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneTest2.java index 52dfd3a918..148c7f5f30 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneTest2.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneTest2.java @@ -443,7 +443,7 @@ public class LuceneTest2 extends TestCase tx3.commit(); } - public void testMTDeleteIssue() throws Exception + public void xtestMTDeleteIssue() throws Exception { luceneFTS.pause(); testTX.commit(); @@ -1109,7 +1109,7 @@ public class LuceneTest2 extends TestCase luceneFTS.pause(); buildBaseIndex(); - LuceneSearcherImpl searcher = LuceneSearcherImpl.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); + LuceneSearcherImpl2 searcher = LuceneSearcherImpl2.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher); searcher.setDictionaryService(dictionaryService); ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", @@ -1137,7 +1137,7 @@ public class LuceneTest2 extends TestCase public void testNoOp() throws Exception { luceneFTS.pause(); - LuceneIndexerImpl indexer = LuceneIndexerImpl.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" + LuceneIndexerImpl2 indexer = LuceneIndexerImpl2.getUpdateIndexer(rootNodeRef.getStoreRef(), "delta" + System.currentTimeMillis() + "_1", indexerAndSearcher); indexer.setNodeService(nodeService); diff --git a/source/java/org/alfresco/repo/search/impl/lucene/QueryParser.java b/source/java/org/alfresco/repo/search/impl/lucene/QueryParser.java index d5510eeb94..e57882c030 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/QueryParser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/QueryParser.java @@ -21,6 +21,7 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.RangeQuery; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.WildcardQuery; +import org.apache.lucene.search.BooleanClause.Occur; /** * This class is generated by JavaCC. The only method that clients should need @@ -219,8 +220,8 @@ public class QueryParser implements QueryParserConstants { // unless it's already prohibited if (clauses.size() > 0 && conj == CONJ_AND) { BooleanClause c = (BooleanClause) clauses.elementAt(clauses.size()-1); - if (!c.prohibited) - c.required = true; + if (!c.isProhibited()) + c.setOccur(Occur.MUST); } if (clauses.size() > 0 && operator == DEFAULT_OPERATOR_AND && conj == CONJ_OR) { @@ -229,8 +230,8 @@ public class QueryParser implements QueryParserConstants { // notice if the input is a OR b, first term is parsed as required; without // this modification a OR b would parsed as +a OR b BooleanClause c = (BooleanClause) clauses.elementAt(clauses.size()-1); - if (!c.prohibited) - c.required = false; + if (!c.isProhibited()) + c.setOccur(Occur.SHOULD); } // We might have been passed a null query; the term might have been @@ -252,7 +253,16 @@ public class QueryParser implements QueryParserConstants { prohibited = (mods == MOD_NOT); required = (!prohibited && conj != CONJ_OR); } - clauses.addElement(new BooleanClause(q, required, prohibited)); + Occur occur = Occur.SHOULD; + if(prohibited) + { + occur = Occur.MUST_NOT; + } + if(required) + { + occur = Occur.MUST; + } + clauses.addElement(new BooleanClause(q, occur)); } /** diff --git a/source/java/org/alfresco/repo/search/impl/lucene/fts/FullTextSearchIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/fts/FullTextSearchIndexerImpl.java index edce57ef06..d90e64501b 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/fts/FullTextSearchIndexerImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/fts/FullTextSearchIndexerImpl.java @@ -20,11 +20,8 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; -import org.alfresco.repo.search.Indexer; import org.alfresco.repo.search.IndexerSPI; -import org.alfresco.repo.search.impl.lucene.LuceneIndexer; import org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcher; -import org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcherFactory; import org.alfresco.service.cmr.repository.StoreRef; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; diff --git a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java index ddde7715ce..042b2235ac 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java @@ -48,11 +48,11 @@ import java.util.zip.CRC32; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.repo.search.IndexerException; import org.alfresco.repo.search.impl.lucene.FilterIndexReaderByNodeRefs2; +import org.alfresco.repo.search.impl.lucene.analysis.AlfrescoStandardAnalyser; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.util.GUID; import org.apache.log4j.Logger; import org.apache.lucene.analysis.Analyzer; -import org.alfresco.repo.search.impl.lucene.analysis.AlfrescoStandardAnalyser; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; @@ -64,8 +64,8 @@ import org.apache.lucene.search.Searcher; import org.apache.lucene.search.TermQuery; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; -import org.apache.lucene.store.InputStream; -import org.apache.lucene.store.OutputStream; +import org.apache.lucene.store.IndexInput; +import org.apache.lucene.store.IndexOutput; import org.apache.lucene.store.RAMDirectory; /** @@ -223,6 +223,14 @@ public class IndexInfo private boolean mergerUseCompoundFile = true; private int mergerTargetOverlays = 5; + + private long writeLockTimeout = IndexWriter.WRITE_LOCK_TIMEOUT; + + private long commitLockTimeout = IndexWriter.COMMIT_LOCK_TIMEOUT; + + private int maxFieldLength = IndexWriter.DEFAULT_MAX_FIELD_LENGTH; + + private int termIndexInterval = IndexWriter.DEFAULT_TERM_INDEX_INTERVAL; // TODO: Something to control the maximum number of overlays @@ -308,9 +316,13 @@ public class IndexInfo { writer = new IndexWriter(oldIndex, new AlfrescoStandardAnalyser(), false); writer.setUseCompoundFile(writerUseCompoundFile); - writer.minMergeDocs = writerMinMergeDocs; - writer.mergeFactor = writerMergeFactor; - writer.maxMergeDocs = writerMaxMergeDocs; + writer.setMaxBufferedDocs(writerMinMergeDocs); + writer.setMergeFactor(writerMergeFactor); + writer.setMaxMergeDocs(writerMaxMergeDocs); + writer.setCommitLockTimeout(commitLockTimeout); + writer.setWriteLockTimeout(writeLockTimeout); + writer.setMaxFieldLength(maxFieldLength); + writer.setTermIndexInterval(termIndexInterval); writer.optimize(); long docs = writer.docCount(); writer.close(); @@ -444,9 +456,13 @@ public class IndexInfo { writer = new IndexWriter(emptyIndex, new AlfrescoStandardAnalyser(), true); writer.setUseCompoundFile(writerUseCompoundFile); - writer.minMergeDocs = writerMinMergeDocs; - writer.mergeFactor = writerMergeFactor; - writer.maxMergeDocs = writerMaxMergeDocs; + writer.setMaxBufferedDocs(writerMinMergeDocs); + writer.setMergeFactor(writerMergeFactor); + writer.setMaxMergeDocs(writerMaxMergeDocs); + writer.setCommitLockTimeout(commitLockTimeout); + writer.setWriteLockTimeout(writeLockTimeout); + writer.setMaxFieldLength(maxFieldLength); + writer.setTermIndexInterval(termIndexInterval); } catch (IOException e) { @@ -555,9 +571,13 @@ public class IndexInfo { IndexWriter creator = new IndexWriter(location, analyzer, true); creator.setUseCompoundFile(writerUseCompoundFile); - creator.minMergeDocs = writerMinMergeDocs; - creator.mergeFactor = writerMergeFactor; - creator.maxMergeDocs = writerMaxMergeDocs; + creator.setMaxBufferedDocs(writerMinMergeDocs); + creator.setMergeFactor(writerMergeFactor); + creator.setMaxMergeDocs(writerMaxMergeDocs); + creator.setCommitLockTimeout(commitLockTimeout); + creator.setWriteLockTimeout(writeLockTimeout); + creator.setMaxFieldLength(maxFieldLength); + creator.setTermIndexInterval(termIndexInterval); return creator; } return null; @@ -582,9 +602,13 @@ public class IndexInfo { writer = new IndexWriter(location, analyzer, false); writer.setUseCompoundFile(writerUseCompoundFile); - writer.minMergeDocs = writerMinMergeDocs; - writer.mergeFactor = writerMergeFactor; - writer.maxMergeDocs = writerMaxMergeDocs; + writer.setMaxBufferedDocs(writerMinMergeDocs); + writer.setMergeFactor(writerMergeFactor); + writer.setMaxMergeDocs(writerMaxMergeDocs); + writer.setCommitLockTimeout(commitLockTimeout); + writer.setWriteLockTimeout(writeLockTimeout); + writer.setMaxFieldLength(maxFieldLength); + writer.setTermIndexInterval(termIndexInterval); } indexWriters.put(id, writer); } @@ -2173,7 +2197,7 @@ public class IndexInfo Document doc = hits.doc(i); if (doc.getField("ISCONTAINER") == null) { - reader.delete(hits.id(i)); + reader.deleteDocument(hits.id(i)); invalidIndexes.add(key); // There should only be one thing to delete // break; @@ -2185,7 +2209,7 @@ public class IndexInfo } else { - if (reader.delete(new Term("ID", nodeRef.toString())) > 0) + if (reader.deleteDocuments(new Term("ID", nodeRef.toString())) > 0) { invalidIndexes.add(key); } @@ -2440,9 +2464,11 @@ public class IndexInfo } writer.setUseCompoundFile(mergerUseCompoundFile); - writer.minMergeDocs = mergerMinMergeDocs; - writer.mergeFactor = mergerMergeFactor; - writer.maxMergeDocs = mergerMaxMergeDocs; + writer.setMaxBufferedDocs(mergerMinMergeDocs); + writer.setMergeFactor(mergerMergeFactor); + writer.setMaxMergeDocs(mergerMaxMergeDocs); + writer.setCommitLockTimeout(commitLockTimeout); + writer.setWriteLockTimeout(writeLockTimeout); } } writer.addIndexes(readers); @@ -2455,9 +2481,9 @@ public class IndexInfo for (int i = 0; i < files.length; i++) { // make place on ram disk - OutputStream os = directory.createFile(files[i]); + IndexOutput os = directory.createOutput(files[i]); // read current file - InputStream is = ramDirectory.openFile(files[i]); + IndexInput is = ramDirectory.openInput(files[i]); // and copy to ram disk int len = (int) is.length(); byte[] buf = new byte[len]; diff --git a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfoTest.java b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfoTest.java index 7f48f2748a..77fd33aa52 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfoTest.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfoTest.java @@ -100,9 +100,9 @@ public static final String[] UPDATE_LIST_2 = { "alpha2", "bravo2", "charlie2", " Document doc = new Document(); for (int k = 0; k < 15; k++) { - doc.add(new Field("ID" + k, guid, false, true, false)); + doc.add(new Field("ID" + k, guid, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } - doc.add(new Field("TEXT", WORD_LIST[i], false, true, false)); + doc.add(new Field("TEXT", WORD_LIST[i], Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); writer.addDocument(doc); ii.closeDeltaIndexWriter(guid); @@ -198,12 +198,12 @@ public static final String[] UPDATE_LIST_2 = { "alpha2", "bravo2", "charlie2", " Document doc = new Document(); for (int k = 0; k < 15; k++) { - doc.add(new Field("ID" + k, guid, false, true, false)); + doc.add(new Field("ID" + k, guid, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } - doc.add(new Field("TEXT", CREATE_LIST[i], false, true, false)); + doc.add(new Field("TEXT", CREATE_LIST[i], Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); NodeRef nodeRef = new NodeRef(storeRef, GUID.generate()); nodeRefs.add(nodeRef); - doc.add(new Field("ID", nodeRef.toString(), false, true, false)); + doc.add(new Field("ID", nodeRef.toString(), Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); writer.addDocument(doc); ii.closeDeltaIndexWriter(guid); @@ -388,12 +388,12 @@ public static final String[] UPDATE_LIST_2 = { "alpha2", "bravo2", "charlie2", " Document doc = new Document(); for (int k = 0; k < 15; k++) { - doc.add(new Field("ID" + k, guid, false, true, false)); + doc.add(new Field("ID" + k, guid, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } - doc.add(new Field("TEXT", CREATE_LIST[i], false, true, false)); + doc.add(new Field("TEXT", CREATE_LIST[i], Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); NodeRef nodeRef = new NodeRef(storeRef, GUID.generate()); nodeRefs.add(nodeRef); - doc.add(new Field("ID", nodeRef.toString(), false, true, false)); + doc.add(new Field("ID", nodeRef.toString(), Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); writer.addDocument(doc); ii.closeDeltaIndexWriter(guid); @@ -474,9 +474,9 @@ public static final String[] UPDATE_LIST_2 = { "alpha2", "bravo2", "charlie2", " Document doc = new Document(); for (int k = 0; k < 15; k++) { - doc.add(new Field("ID" + k, guid, false, true, false)); + doc.add(new Field("ID" + k, guid, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } - doc.add(new Field("TEXT", UPDATE_LIST[i], false, true, false)); + doc.add(new Field("TEXT", UPDATE_LIST[i], Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); writer.addDocument(doc); ii.closeDeltaIndexWriter(guid); @@ -654,12 +654,12 @@ public static final String[] UPDATE_LIST_2 = { "alpha2", "bravo2", "charlie2", " Document doc = new Document(); for (int k = 0; k < 15; k++) { - doc.add(new Field("ID" + k, guid, false, true, false)); + doc.add(new Field("ID" + k, guid, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } - doc.add(new Field("TEXT", create[i], false, true, false)); + doc.add(new Field("TEXT", create[i], Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); NodeRef nodeRef = new NodeRef(storeRef, GUID.generate()); nodeRefs.add(nodeRef); - doc.add(new Field("ID", nodeRef.toString(), false, true, false)); + doc.add(new Field("ID", nodeRef.toString(), Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); writer.addDocument(doc); ii.closeDeltaIndexWriter(guid); @@ -745,9 +745,9 @@ public static final String[] UPDATE_LIST_2 = { "alpha2", "bravo2", "charlie2", " Document doc = new Document(); for (int k = 0; k < 15; k++) { - doc.add(new Field("ID" + k, guid, false, true, false)); + doc.add(new Field("ID" + k, guid, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); } - doc.add(new Field("TEXT", update[i], false, true, false)); + doc.add(new Field("TEXT", update[i], Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); writer.addDocument(doc); ii.closeDeltaIndexWriter(guid);