mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Index rebuld and vlidation support for AVM.
Added AVM indexes to the configuration checker git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5818 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -271,6 +271,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="avmIndexRecoveryBootstrap" class="org.alfresco.repo.node.index.IndexRecoveryBootstrapBean" >
|
||||||
|
<property name="indexRecoveryComponent">
|
||||||
|
<ref bean="avmIndexRecoveryComponent"/>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
<!-- This component checks the interconnection between the metadata, indexes and content -->
|
<!-- This component checks the interconnection between the metadata, indexes and content -->
|
||||||
<bean id="configurationChecker" class="org.alfresco.repo.admin.ConfigurationChecker">
|
<bean id="configurationChecker" class="org.alfresco.repo.admin.ConfigurationChecker">
|
||||||
<property name="strict">
|
<property name="strict">
|
||||||
|
@@ -44,6 +44,22 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean
|
||||||
|
id="avmIndexRecoveryComponent"
|
||||||
|
class="org.alfresco.repo.node.index.AVMFullIndexRecoveryComponent"
|
||||||
|
parent="indexRecoveryComponentBase">
|
||||||
|
<property name="recoveryMode">
|
||||||
|
<value>${index.recovery.mode}</value>
|
||||||
|
</property>
|
||||||
|
<property name="avmService">
|
||||||
|
<ref bean="avmService" />
|
||||||
|
</property>
|
||||||
|
<property name="avmSnapShotTriggeredIndexingMethodInterceptor">
|
||||||
|
<ref bean="avmSnapShotTriggeredIndexingMethodInterceptor" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
<!-- Bean that attempts to index content that was previously missing -->
|
<!-- Bean that attempts to index content that was previously missing -->
|
||||||
<bean
|
<bean
|
||||||
id="missingContentReindexComponent"
|
id="missingContentReindexComponent"
|
||||||
|
@@ -211,10 +211,10 @@ public class ConfigurationChecker extends AbstractLifecycleBean
|
|||||||
for (StoreRef storeRef : storeRefs)
|
for (StoreRef storeRef : storeRefs)
|
||||||
{
|
{
|
||||||
// TODO: For now, do not check existence of index for AVM stores
|
// TODO: For now, do not check existence of index for AVM stores
|
||||||
if (storeRef.getProtocol().equals(StoreRef.PROTOCOL_AVM))
|
//if (storeRef.getProtocol().equals(StoreRef.PROTOCOL_AVM))
|
||||||
{
|
//{
|
||||||
continue;
|
// continue;
|
||||||
}
|
//}
|
||||||
|
|
||||||
NodeRef rootNodeRef = null;
|
NodeRef rootNodeRef = null;
|
||||||
try
|
try
|
||||||
@@ -237,7 +237,7 @@ public class ConfigurationChecker extends AbstractLifecycleBean
|
|||||||
SearchParameters sp = new SearchParameters();
|
SearchParameters sp = new SearchParameters();
|
||||||
sp.addStore(storeRef);
|
sp.addStore(storeRef);
|
||||||
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||||
sp.setQuery("ID:" + LuceneQueryParser.escape(rootNodeRef.toString()));
|
sp.setQuery("ISROOT:T");
|
||||||
|
|
||||||
ResultSet results = null;
|
ResultSet results = null;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
@@ -0,0 +1,218 @@
|
|||||||
|
package org.alfresco.repo.node.index;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode;
|
||||||
|
import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
|
||||||
|
import org.alfresco.repo.transaction.TransactionUtil;
|
||||||
|
import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
|
||||||
|
import org.alfresco.service.cmr.avm.AVMService;
|
||||||
|
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check and recover the indexes for AVM stores
|
||||||
|
*
|
||||||
|
* @author andyh
|
||||||
|
*/
|
||||||
|
public class AVMFullIndexRecoveryComponent extends AbstractReindexComponent
|
||||||
|
{
|
||||||
|
private static Log logger = LogFactory.getLog(AVMFullIndexRecoveryComponent.class);
|
||||||
|
|
||||||
|
private RecoveryMode recoveryMode;
|
||||||
|
|
||||||
|
private boolean lockServer;
|
||||||
|
|
||||||
|
private AVMService avmService;
|
||||||
|
|
||||||
|
private AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the type of recovery to perform. Default is {@link RecoveryMode#VALIDATE to validate} the indexes only.
|
||||||
|
*
|
||||||
|
* @param recoveryMode
|
||||||
|
* one of the {@link RecoveryMode } values
|
||||||
|
*/
|
||||||
|
public void setRecoveryMode(String recoveryMode)
|
||||||
|
{
|
||||||
|
this.recoveryMode = RecoveryMode.valueOf(recoveryMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this on to put the server into READ-ONLY mode for the duration of the index recovery. The default is
|
||||||
|
* <tt>true</tt>, i.e. the server will be locked against further updates.
|
||||||
|
*
|
||||||
|
* @param lockServer
|
||||||
|
* true to force the server to be read-only
|
||||||
|
*/
|
||||||
|
public void setLockServer(boolean lockServer)
|
||||||
|
{
|
||||||
|
this.lockServer = lockServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setAvmService(AVMService avmService)
|
||||||
|
{
|
||||||
|
this.avmService = avmService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvmSnapShotTriggeredIndexingMethodInterceptor(
|
||||||
|
AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor)
|
||||||
|
{
|
||||||
|
this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void reindexImpl()
|
||||||
|
{
|
||||||
|
processStores();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processStores()
|
||||||
|
{
|
||||||
|
List<AVMStoreDescriptor> stores = avmService.getStores();
|
||||||
|
if(stores.size() == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
int tracker = -1;
|
||||||
|
logger.info("Checking indexes for AVM Stores");
|
||||||
|
for (AVMStoreDescriptor store : stores)
|
||||||
|
{
|
||||||
|
if (isShuttingDown())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
processStore(store.getName());
|
||||||
|
count++;
|
||||||
|
if (count*10l/stores.size() > tracker)
|
||||||
|
{
|
||||||
|
tracker = (int)(count*10l/stores.size());
|
||||||
|
logger.info(" Stores "+(tracker*10)+"% complete");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("Finished checking indexes for AVM Stores");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processStore(String store)
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Performing AVM index recovery for type: " + recoveryMode + " on store " + store);
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we just ignore
|
||||||
|
if (recoveryMode == RecoveryMode.NONE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// check the level of cover required
|
||||||
|
boolean fullRecoveryRequired = false;
|
||||||
|
if (recoveryMode == RecoveryMode.FULL) // no validate required
|
||||||
|
{
|
||||||
|
fullRecoveryRequired = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// validate first
|
||||||
|
{
|
||||||
|
int lastActualSnapshotId = avmService.getLatestSnapshotID(store);
|
||||||
|
if (lastActualSnapshotId <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int lastIndexedSnapshotId = avmSnapShotTriggeredIndexingMethodInterceptor.getLastIndexedSnapshot(store);
|
||||||
|
if (lastActualSnapshotId != lastIndexedSnapshotId)
|
||||||
|
{
|
||||||
|
logger.warn("Index for avm store " + store + " is out of date");
|
||||||
|
// this store isn't up to date
|
||||||
|
if (recoveryMode == RecoveryMode.VALIDATE)
|
||||||
|
{
|
||||||
|
// the store is out of date - validation failed
|
||||||
|
}
|
||||||
|
else if (recoveryMode == RecoveryMode.AUTO)
|
||||||
|
{
|
||||||
|
fullRecoveryRequired = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// put the server into read-only mode for the duration
|
||||||
|
boolean allowWrite = !transactionService.isReadOnly();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (lockServer)
|
||||||
|
{
|
||||||
|
// set the server into read-only mode
|
||||||
|
transactionService.setAllowWrite(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we need to perform a full recovery
|
||||||
|
if (fullRecoveryRequired)
|
||||||
|
{
|
||||||
|
recoverStore(store);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// restore read-only state
|
||||||
|
transactionService.setAllowWrite(allowWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recoverStore(String store)
|
||||||
|
{
|
||||||
|
int tracker = -1;
|
||||||
|
int latest = avmService.getLatestSnapshotID(store);
|
||||||
|
if(latest <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.info("Recovery for "+store);
|
||||||
|
|
||||||
|
if(!avmSnapShotTriggeredIndexingMethodInterceptor.hasIndexBeenCreated(store))
|
||||||
|
{
|
||||||
|
avmSnapShotTriggeredIndexingMethodInterceptor.createIndex(store);
|
||||||
|
}
|
||||||
|
for (int i = 0; i <= latest; i++)
|
||||||
|
{
|
||||||
|
if (isShuttingDown())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
recoverSnapShot(store, i);
|
||||||
|
if (i*10l/latest > tracker)
|
||||||
|
{
|
||||||
|
tracker = (int)(i*10l/latest);
|
||||||
|
logger.info(" Store "+store +" "+(tracker*10)+"% complete");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("Recovery for "+store+" done");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recoverSnapShot(final String store, final int id)
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Reindexing avm store: " + store + " snapshot id " + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionWork<Object> reindexWork = new TransactionWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
if (!avmSnapShotTriggeredIndexingMethodInterceptor.isSnapshotIndexed(store, id))
|
||||||
|
{
|
||||||
|
avmSnapShotTriggeredIndexingMethodInterceptor.indexSnapshot(store, id - 1, id);
|
||||||
|
}
|
||||||
|
// done
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
TransactionUtil.executeInNonPropagatingUserTransaction(transactionService, reindexWork, true);
|
||||||
|
// done
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -115,14 +115,7 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
|
|||||||
int before = initialStates.get(store).intValue();
|
int before = initialStates.get(store).intValue();
|
||||||
if (after > before)
|
if (after > before)
|
||||||
{
|
{
|
||||||
|
indexSnapshot(store, before, after);
|
||||||
StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
|
|
||||||
Indexer indexer = indexerAndSearcher.getIndexer(storeRef);
|
|
||||||
if (indexer instanceof AVMLuceneIndexer)
|
|
||||||
{
|
|
||||||
AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer) indexer;
|
|
||||||
avmIndexer.index(store, before, after, getIndexMode(store));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return returnValue;
|
return returnValue;
|
||||||
@@ -144,13 +137,7 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
|
|||||||
{
|
{
|
||||||
String store = (String) mi.getArguments()[0];
|
String store = (String) mi.getArguments()[0];
|
||||||
Object returnValue = mi.proceed();
|
Object returnValue = mi.proceed();
|
||||||
StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
|
createIndex(store);
|
||||||
Indexer indexer = indexerAndSearcher.getIndexer(storeRef);
|
|
||||||
if (indexer instanceof AVMLuceneIndexer)
|
|
||||||
{
|
|
||||||
AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer) indexer;
|
|
||||||
avmIndexer.createIndex(store, IndexMode.SYNCHRONOUS);
|
|
||||||
}
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
else if (mi.getMethod().getName().equals("renameStore"))
|
else if (mi.getMethod().getName().equals("renameStore"))
|
||||||
@@ -246,6 +233,63 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
|
|||||||
this.defaultMode = defaultMode;
|
this.defaultMode = defaultMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param store
|
||||||
|
* @param before
|
||||||
|
* @param after
|
||||||
|
*/
|
||||||
|
public void indexSnapshot(String store, int before, int after)
|
||||||
|
{
|
||||||
|
StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
|
||||||
|
Indexer indexer = indexerAndSearcher.getIndexer(storeRef);
|
||||||
|
if (indexer instanceof AVMLuceneIndexer)
|
||||||
|
{
|
||||||
|
AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer) indexer;
|
||||||
|
avmIndexer.index(store, before, after, getIndexMode(store));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param store
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getLastIndexedSnapshot(String store)
|
||||||
|
{
|
||||||
|
StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
|
||||||
|
Indexer indexer = indexerAndSearcher.getIndexer(storeRef);
|
||||||
|
if (indexer instanceof AVMLuceneIndexer)
|
||||||
|
{
|
||||||
|
AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer) indexer;
|
||||||
|
return avmIndexer.getLastIndexedSnapshot(store);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the snapshot applied to the index?
|
||||||
|
*
|
||||||
|
* Is there an entry for any node that was added OR have all the nodes in the transaction been deleted as expected?
|
||||||
|
*
|
||||||
|
* @param store
|
||||||
|
* @param id
|
||||||
|
* @return - true if applied, false if not
|
||||||
|
*/
|
||||||
|
public boolean isSnapshotIndexed(String store, int id)
|
||||||
|
{
|
||||||
|
StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
|
||||||
|
Indexer indexer = indexerAndSearcher.getIndexer(storeRef);
|
||||||
|
if (indexer instanceof AVMLuceneIndexer)
|
||||||
|
{
|
||||||
|
AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer) indexer;
|
||||||
|
return avmIndexer.isSnapshotIndexed(store, id);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized IndexMode getIndexMode(String store)
|
private synchronized IndexMode getIndexMode(String store)
|
||||||
{
|
{
|
||||||
IndexMode mode = modeCache.get(store);
|
IndexMode mode = modeCache.get(store);
|
||||||
@@ -363,4 +407,27 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
|
|||||||
{
|
{
|
||||||
STAGING, STAGING_PREVIEW, AUTHOR, AUTHOR_PREVIEW, WORKFLOW, WORKFLOW_PREVIEW, AUTHOR_WORKFLOW, AUTHOR_WORKFLOW_PREVIEW, UNKNOWN;
|
STAGING, STAGING_PREVIEW, AUTHOR, AUTHOR_PREVIEW, WORKFLOW, WORKFLOW_PREVIEW, AUTHOR_WORKFLOW, AUTHOR_WORKFLOW_PREVIEW, UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasIndexBeenCreated(String store)
|
||||||
|
{
|
||||||
|
StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
|
||||||
|
Indexer indexer = indexerAndSearcher.getIndexer(storeRef);
|
||||||
|
if (indexer instanceof AVMLuceneIndexer)
|
||||||
|
{
|
||||||
|
AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer) indexer;
|
||||||
|
return avmIndexer.hasIndexBeenCreated(store);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createIndex(String store)
|
||||||
|
{
|
||||||
|
StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);
|
||||||
|
Indexer indexer = indexerAndSearcher.getIndexer(storeRef);
|
||||||
|
if (indexer instanceof AVMLuceneIndexer)
|
||||||
|
{
|
||||||
|
AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer) indexer;
|
||||||
|
avmIndexer.createIndex(store, IndexMode.SYNCHRONOUS);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -61,4 +61,42 @@ public interface AVMLuceneIndexer extends LuceneIndexer, BackgroundIndexerAware
|
|||||||
* @param mode
|
* @param mode
|
||||||
*/
|
*/
|
||||||
public void createIndex(String store, IndexMode mode);
|
public void createIndex(String store, IndexMode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the id of the last snapshot added to the index
|
||||||
|
* @param store
|
||||||
|
*
|
||||||
|
* @param mode
|
||||||
|
* - IndexMode.SYNCHRONOUS - the last searchable snapshop
|
||||||
|
* - IndexMode.ASYNCHRONOUS - the last pending snapshot to be indexed. It may or may not be searchable.
|
||||||
|
* @return - the snapshot id
|
||||||
|
*/
|
||||||
|
public int getLastIndexedSnapshot(String store);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the snapshot applied to the index?
|
||||||
|
*
|
||||||
|
* Is there an entry for any node that was added OR have all the nodes in the transaction been deleted as expected?
|
||||||
|
*
|
||||||
|
* @param store
|
||||||
|
* @param id
|
||||||
|
* @return - true if applied, false if not
|
||||||
|
*/
|
||||||
|
public boolean isSnapshotIndexed(String store, int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is snapshot searchable
|
||||||
|
* @param store
|
||||||
|
* @param id
|
||||||
|
* @return - true if snapshot has been fully indexed, false if pending or unindexed.
|
||||||
|
*/
|
||||||
|
public boolean isSnapshotSearchable(String store, int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has the index been ceated
|
||||||
|
*
|
||||||
|
* @param store
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean hasIndexBeenCreated(String store);
|
||||||
}
|
}
|
||||||
|
@@ -40,6 +40,7 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.i18n.I18NUtil;
|
import org.alfresco.i18n.I18NUtil;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.model.WCMModel;
|
import org.alfresco.model.WCMModel;
|
||||||
@@ -52,7 +53,6 @@ import org.alfresco.repo.content.MimetypeMap;
|
|||||||
import org.alfresco.repo.content.transform.ContentTransformer;
|
import org.alfresco.repo.content.transform.ContentTransformer;
|
||||||
import org.alfresco.repo.domain.PropertyValue;
|
import org.alfresco.repo.domain.PropertyValue;
|
||||||
import org.alfresco.repo.search.IndexMode;
|
import org.alfresco.repo.search.IndexMode;
|
||||||
import org.alfresco.repo.search.impl.lucene.analysis.NumericEncoder;
|
|
||||||
import org.alfresco.repo.search.impl.lucene.fts.FTSIndexerAware;
|
import org.alfresco.repo.search.impl.lucene.fts.FTSIndexerAware;
|
||||||
import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer;
|
import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer;
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||||
@@ -74,6 +74,9 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||||
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
|
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
|
||||||
|
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.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.EqualsHelper;
|
import org.alfresco.util.EqualsHelper;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
@@ -82,7 +85,10 @@ import org.alfresco.util.Pair;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
|
import org.apache.lucene.index.TermDocs;
|
||||||
|
import org.apache.lucene.index.TermEnum;
|
||||||
import org.apache.lucene.search.Hits;
|
import org.apache.lucene.search.Hits;
|
||||||
import org.apache.lucene.search.PrefixQuery;
|
import org.apache.lucene.search.PrefixQuery;
|
||||||
import org.apache.lucene.search.Searcher;
|
import org.apache.lucene.search.Searcher;
|
||||||
@@ -94,9 +100,7 @@ import org.apache.lucene.search.Searcher;
|
|||||||
*/
|
*/
|
||||||
public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> implements AVMLuceneIndexer
|
public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> implements AVMLuceneIndexer
|
||||||
{
|
{
|
||||||
private static String SNAP_SHOT_ID = "SnapShotId_";
|
private static String SNAP_SHOT_ID = "SnapShot";
|
||||||
|
|
||||||
private static String SNAP_SHOT_STORE = "SnapShotStore";
|
|
||||||
|
|
||||||
static Logger s_logger = Logger.getLogger(AVMLuceneIndexerImpl.class);
|
static Logger s_logger = Logger.getLogger(AVMLuceneIndexerImpl.class);
|
||||||
|
|
||||||
@@ -213,29 +217,28 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void asynchronousIndex(String store, int srcVersion, int dstVersion)
|
private void asynchronousIndex(String store, int srcVersion, int dstVersion)
|
||||||
{
|
{
|
||||||
if(s_logger.isDebugEnabled())
|
if (s_logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
s_logger.debug("Async index for "+store + " from " + srcVersion + " to " + dstVersion);
|
s_logger.debug("Async index for " + store + " from " + srcVersion + " to " + dstVersion);
|
||||||
}
|
}
|
||||||
index("\u0000BG:STORE:" + store + ":" + srcVersion + ":" + dstVersion + ":" + GUID.generate());
|
index("\u0000BG:STORE:" + store + ":" + srcVersion + ":" + dstVersion + ":" + GUID.generate());
|
||||||
fullTextSearchIndexer.requiresIndex(AVMNodeConverter.ToStoreRef(store));
|
fullTextSearchIndexer.requiresIndex(AVMNodeConverter.ToStoreRef(store));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void synchronousIndex(String store, int srcVersion, int dstVersion)
|
private void synchronousIndex(String store, int srcVersion, int dstVersion)
|
||||||
{
|
{
|
||||||
if(startVersion == -1)
|
if (startVersion == -1)
|
||||||
{
|
{
|
||||||
startVersion = srcVersion;
|
startVersion = srcVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
endVersion = dstVersion;
|
endVersion = dstVersion;
|
||||||
|
|
||||||
|
if (s_logger.isDebugEnabled())
|
||||||
if(s_logger.isDebugEnabled())
|
|
||||||
{
|
{
|
||||||
s_logger.debug("Sync index for "+store + " from " + srcVersion + " to "+dstVersion);
|
s_logger.debug("Sync index for " + store + " from " + srcVersion + " to " + dstVersion);
|
||||||
}
|
}
|
||||||
String path = store + ":/";
|
String path = store + ":/";
|
||||||
List<AVMDifference> changeList = avmSyncService.compare(srcVersion, path, dstVersion, path, null);
|
List<AVMDifference> changeList = avmSyncService.compare(srcVersion, path, dstVersion, path, null);
|
||||||
@@ -275,13 +278,21 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
// Anything else then we reindex
|
// Anything else then we reindex
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: Check hen to rebuild aux paths
|
if (!difference.getSourcePath().equals(difference.getDestinationPath()))
|
||||||
// Should only reindex if the path has changed - not anything on a directory
|
{
|
||||||
reindex(difference.getSourcePath(), srcDesc.isDirectory());
|
reindex(difference.getSourcePath(), srcDesc.isDirectory());
|
||||||
reindex(difference.getDestinationPath(), dstDesc.isDirectory());
|
reindex(difference.getDestinationPath(), dstDesc.isDirectory());
|
||||||
|
reindexAllAncestors(difference.getSourcePath());
|
||||||
reindexAllAncestors(difference.getDestinationPath());
|
reindexAllAncestors(difference.getDestinationPath());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If it is a directory, it is at the same path,
|
||||||
|
// so no cascade update is required for the bridge table data.
|
||||||
|
reindex(difference.getDestinationPath(), false);
|
||||||
reindexAllAncestors(difference.getDestinationPath());
|
reindexAllAncestors(difference.getDestinationPath());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case AVMDifference.DIRECTORY:
|
case AVMDifference.DIRECTORY:
|
||||||
// Never seen
|
// Never seen
|
||||||
@@ -293,7 +304,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// record the snap shotid
|
// record the snap shotid
|
||||||
reindex(SNAP_SHOT_ID + store, false);
|
reindex(SNAP_SHOT_ID + ":" + store + ":" + srcVersion + ":" + dstVersion, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -355,11 +366,6 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
{
|
{
|
||||||
Document sdoc = new Document();
|
Document sdoc = new Document();
|
||||||
sdoc.add(new Field("ID", stringNodeRef, Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO));
|
sdoc.add(new Field("ID", stringNodeRef, Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO));
|
||||||
String storeName = stringNodeRef.substring(SNAP_SHOT_ID.length());
|
|
||||||
sdoc.add(new Field(SNAP_SHOT_ID, NumericEncoder.encode(avmService.getLatestSnapshotID(storeName)),
|
|
||||||
Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO));
|
|
||||||
sdoc.add(new Field(SNAP_SHOT_STORE, NumericEncoder.encode(avmService.getLatestSnapshotID(storeName)),
|
|
||||||
Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO));
|
|
||||||
docs.add(sdoc);
|
docs.add(sdoc);
|
||||||
return docs;
|
return docs;
|
||||||
}
|
}
|
||||||
@@ -375,19 +381,19 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Pair<Integer, String>> allPaths = avmService.getPaths(desc);
|
List<Pair<Integer, String>> allPaths = avmService.getPaths(desc);
|
||||||
List<Pair<Integer, String>> paths = new ArrayList<Pair<Integer, String>> ();
|
List<Pair<Integer, String>> paths = new ArrayList<Pair<Integer, String>>();
|
||||||
for(Pair<Integer, String> pair: allPaths)
|
for (Pair<Integer, String> pair : allPaths)
|
||||||
{
|
{
|
||||||
if(pair.getFirst().intValue() == endVersion)
|
if (pair.getFirst().intValue() == endVersion)
|
||||||
{
|
{
|
||||||
paths.add(pair);
|
paths.add(pair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(paths.size() == 0)
|
if (paths.size() == 0)
|
||||||
{
|
{
|
||||||
for(Pair<Integer, String> pair: allPaths)
|
for (Pair<Integer, String> pair : allPaths)
|
||||||
{
|
{
|
||||||
if(pair.getFirst().intValue() == -1)
|
if (pair.getFirst().intValue() == -1)
|
||||||
{
|
{
|
||||||
paths.add(pair);
|
paths.add(pair);
|
||||||
}
|
}
|
||||||
@@ -437,17 +443,17 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
|
|
||||||
boolean isAtomic = true;
|
boolean isAtomic = true;
|
||||||
|
|
||||||
Map<QName, Serializable> properties = getIndexableProperties(desc, node, nodeRef, endVersion, stringNodeRef);
|
Map<QName, Serializable> properties = getIndexableProperties(desc, nodeRef, endVersion, stringNodeRef);
|
||||||
for (QName propertyName : properties.keySet())
|
for (QName propertyName : properties.keySet())
|
||||||
{
|
{
|
||||||
Serializable value = properties.get(propertyName);
|
Serializable value = properties.get(propertyName);
|
||||||
if (indexAllProperties)
|
if (indexAllProperties)
|
||||||
{
|
{
|
||||||
indexProperty(node, nodeRef, propertyName, value, xdoc, false);
|
indexProperty(nodeRef, propertyName, value, xdoc, false, endVersion, stringNodeRef);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
isAtomic &= indexProperty(node, nodeRef, propertyName, value, xdoc, true);
|
isAtomic &= indexProperty(nodeRef, propertyName, value, xdoc, true, endVersion, stringNodeRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,10 +623,10 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<QName, Serializable> getIndexableProperties(AVMNodeDescriptor desc, AVMNode node, NodeRef nodeRef,
|
private Map<QName, Serializable> getIndexableProperties(AVMNodeDescriptor desc, NodeRef nodeRef, Integer version,
|
||||||
Integer version, String path)
|
String path)
|
||||||
{
|
{
|
||||||
Map<QName, PropertyValue> properties = node.getProperties();
|
Map<QName, PropertyValue> properties = avmService.getNodeProperties(version, path);
|
||||||
|
|
||||||
Map<QName, Serializable> result = new HashMap<QName, Serializable>();
|
Map<QName, Serializable> result = new HashMap<QName, Serializable>();
|
||||||
for (QName qName : properties.keySet())
|
for (QName qName : properties.keySet())
|
||||||
@@ -642,11 +648,14 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
result.put(ContentModel.PROP_STORE_IDENTIFIER, nodeRef.getStoreRef().getIdentifier());
|
result.put(ContentModel.PROP_STORE_IDENTIFIER, nodeRef.getStoreRef().getIdentifier());
|
||||||
if (desc.isLayeredDirectory())
|
if (desc.isLayeredDirectory())
|
||||||
{
|
{
|
||||||
result.put(WCMModel.PROP_AVM_DIR_INDIRECTION, AVMNodeConverter.ToNodeRef(endVersion, desc.getIndirection()));
|
result
|
||||||
|
.put(WCMModel.PROP_AVM_DIR_INDIRECTION, AVMNodeConverter.ToNodeRef(endVersion, desc
|
||||||
|
.getIndirection()));
|
||||||
}
|
}
|
||||||
if (desc.isLayeredFile())
|
if (desc.isLayeredFile())
|
||||||
{
|
{
|
||||||
result.put(WCMModel.PROP_AVM_FILE_INDIRECTION, AVMNodeConverter.ToNodeRef(endVersion, desc.getIndirection()));
|
result.put(WCMModel.PROP_AVM_FILE_INDIRECTION, AVMNodeConverter
|
||||||
|
.ToNodeRef(endVersion, desc.getIndirection()));
|
||||||
}
|
}
|
||||||
if (desc.isFile())
|
if (desc.isFile())
|
||||||
{
|
{
|
||||||
@@ -696,8 +705,8 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean indexProperty(AVMNode node, NodeRef banana, QName propertyName, Serializable value, Document doc,
|
protected boolean indexProperty(NodeRef banana, QName propertyName, Serializable value, Document doc,
|
||||||
boolean indexAtomicPropertiesOnly)
|
boolean indexAtomicPropertiesOnly, int version, String path)
|
||||||
{
|
{
|
||||||
String attributeName = "@"
|
String attributeName = "@"
|
||||||
+ QName.createQName(propertyName.getNamespaceURI(), ISO9075.encode(propertyName.getLocalName()));
|
+ QName.createQName(propertyName.getNamespaceURI(), ISO9075.encode(propertyName.getLocalName()));
|
||||||
@@ -937,7 +946,8 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
// TODO: Use the node locale in preferanced to the system locale
|
// TODO: Use the node locale in preferanced to the system locale
|
||||||
Locale locale = null;
|
Locale locale = null;
|
||||||
|
|
||||||
Serializable localeProperty = node.getProperty(ContentModel.PROP_LOCALE);
|
Serializable localeProperty = avmService.getNodeProperties(version, path).get(
|
||||||
|
ContentModel.PROP_LOCALE);
|
||||||
if (localeProperty != null)
|
if (localeProperty != null)
|
||||||
{
|
{
|
||||||
locale = DefaultTypeConverter.INSTANCE.convert(Locale.class, localeProperty);
|
locale = DefaultTypeConverter.INSTANCE.convert(Locale.class, localeProperty);
|
||||||
@@ -1169,20 +1179,20 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
public void syncronousDeleteIndex(String store)
|
public void syncronousDeleteIndex(String store)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(s_logger.isDebugEnabled())
|
if (s_logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
s_logger.debug("Sync delete for "+store);
|
s_logger.debug("Sync delete for " + store);
|
||||||
}
|
}
|
||||||
deleteAll();
|
deleteAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void asyncronousDeleteIndex(String store)
|
public void asyncronousDeleteIndex(String store)
|
||||||
{
|
{
|
||||||
if(s_logger.isDebugEnabled())
|
if (s_logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
s_logger.debug("Async delete for "+store);
|
s_logger.debug("Async delete for " + store);
|
||||||
}
|
}
|
||||||
index("\u0000BG:DELETE:" + store+":"+GUID.generate());
|
index("\u0000BG:DELETE:" + store + ":" + GUID.generate());
|
||||||
fullTextSearchIndexer.requiresIndex(AVMNodeConverter.ToStoreRef(store));
|
fullTextSearchIndexer.requiresIndex(AVMNodeConverter.ToStoreRef(store));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1214,9 +1224,9 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
public void syncronousCreateIndex(String store)
|
public void syncronousCreateIndex(String store)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(s_logger.isDebugEnabled())
|
if (s_logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
s_logger.debug("Sync create for "+store);
|
s_logger.debug("Sync create for " + store);
|
||||||
}
|
}
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
AVMNodeDescriptor rootDesc = avmService.getStoreRoot(-1, store);
|
AVMNodeDescriptor rootDesc = avmService.getStoreRoot(-1, store);
|
||||||
@@ -1226,11 +1236,11 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
|
|
||||||
public void asyncronousCreateIndex(String store)
|
public void asyncronousCreateIndex(String store)
|
||||||
{
|
{
|
||||||
if(s_logger.isDebugEnabled())
|
if (s_logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
s_logger.debug("Async create for "+store);
|
s_logger.debug("Async create for " + store);
|
||||||
}
|
}
|
||||||
index("\u0000BG:CREATE:" + store+":"+GUID.generate());
|
index("\u0000BG:CREATE:" + store + ":" + GUID.generate());
|
||||||
fullTextSearchIndexer.requiresIndex(AVMNodeConverter.ToStoreRef(store));
|
fullTextSearchIndexer.requiresIndex(AVMNodeConverter.ToStoreRef(store));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1275,15 +1285,15 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
Document doc = hits.doc(0);
|
Document doc = hits.doc(0);
|
||||||
action = doc.getField("ID").stringValue();
|
action = doc.getField("ID").stringValue();
|
||||||
String[] split = action.split(":");
|
String[] split = action.split(":");
|
||||||
if(split[1].equals("DELETE"))
|
if (split[1].equals("DELETE"))
|
||||||
{
|
{
|
||||||
deleteAll("\u0000BG:");
|
deleteAll("\u0000BG:");
|
||||||
}
|
}
|
||||||
else if(split[1].equals("CREATE"))
|
else if (split[1].equals("CREATE"))
|
||||||
{
|
{
|
||||||
syncronousCreateIndex(split[2]);
|
syncronousCreateIndex(split[2]);
|
||||||
}
|
}
|
||||||
else if(split[1].equals("STORE"))
|
else if (split[1].equals("STORE"))
|
||||||
{
|
{
|
||||||
synchronousIndex(split[2], Integer.parseInt(split[3]), Integer.parseInt(split[4]));
|
synchronousIndex(split[2], Integer.parseInt(split[3]), Integer.parseInt(split[4]));
|
||||||
}
|
}
|
||||||
@@ -1329,4 +1339,177 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
|
|||||||
{
|
{
|
||||||
this.fullTextSearchIndexer = fullTextSearchIndexer;
|
this.fullTextSearchIndexer = fullTextSearchIndexer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getLastIndexedSnapshot(String store)
|
||||||
|
{
|
||||||
|
int last = getLastAsynchronousSnapshot(store);
|
||||||
|
if (last >= 0)
|
||||||
|
{
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
return getLastSynchronousSnapshot(store);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSnapshotIndexed(String store, int id)
|
||||||
|
{
|
||||||
|
return (id <= getLastAsynchronousSnapshot(store)) || (id <= getLastSynchronousSnapshot(store));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSnapshotSearchable(String store, int id)
|
||||||
|
{
|
||||||
|
return (id <= getLastSynchronousSnapshot(store));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getLastSynchronousSnapshot(String store)
|
||||||
|
{
|
||||||
|
String prefix = SNAP_SHOT_ID + ":" + store;
|
||||||
|
IndexReader mainReader = null;
|
||||||
|
int end = -1;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mainReader = getReader();
|
||||||
|
TermEnum terms = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
terms = mainReader.terms(new Term("ID", prefix));
|
||||||
|
|
||||||
|
while (terms.next())
|
||||||
|
{
|
||||||
|
Term term = terms.term();
|
||||||
|
if (term.text().startsWith(prefix))
|
||||||
|
{
|
||||||
|
String[] split = term.text().split(":");
|
||||||
|
end = Integer.parseInt(split[3]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (terms != null)
|
||||||
|
{
|
||||||
|
terms.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("IO error", e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (mainReader != null)
|
||||||
|
{
|
||||||
|
mainReader.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
s_logger.warn("Failed to close main reader", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getLastAsynchronousSnapshot(String store)
|
||||||
|
{
|
||||||
|
String prefix = "\u0000BG:STORE:" + store + ":";
|
||||||
|
IndexReader mainReader = null;
|
||||||
|
int end = -1;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mainReader = getReader();
|
||||||
|
TermEnum terms = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
terms = mainReader.terms(new Term("ID", prefix));
|
||||||
|
|
||||||
|
while (terms.next())
|
||||||
|
{
|
||||||
|
Term term = terms.term();
|
||||||
|
if (term.text().startsWith(prefix))
|
||||||
|
{
|
||||||
|
String[] split = term.text().split(":");
|
||||||
|
end = Integer.parseInt(split[4]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (terms != null)
|
||||||
|
{
|
||||||
|
terms.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("IO error", e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (mainReader != null)
|
||||||
|
{
|
||||||
|
mainReader.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
s_logger.warn("Failed to close main reader", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasIndexBeenCreated(String store)
|
||||||
|
{
|
||||||
|
IndexReader mainReader = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mainReader = getReader();
|
||||||
|
TermDocs termDocs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
termDocs = mainReader.termDocs(new Term("ISROOT", "T"));
|
||||||
|
return termDocs.next();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (termDocs != null)
|
||||||
|
{
|
||||||
|
termDocs.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("IO error", e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (mainReader != null)
|
||||||
|
{
|
||||||
|
mainReader.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
s_logger.warn("Failed to close main reader", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -215,6 +215,21 @@ public class LuceneQueryParser extends QueryParser
|
|||||||
TermQuery termQuery = new TermQuery(new Term(field, queryText));
|
TermQuery termQuery = new TermQuery(new Term(field, queryText));
|
||||||
return termQuery;
|
return termQuery;
|
||||||
}
|
}
|
||||||
|
else if (field.equals("ISROOT"))
|
||||||
|
{
|
||||||
|
TermQuery termQuery = new TermQuery(new Term(field, queryText));
|
||||||
|
return termQuery;
|
||||||
|
}
|
||||||
|
else if (field.equals("ISCONTAINER"))
|
||||||
|
{
|
||||||
|
TermQuery termQuery = new TermQuery(new Term(field, queryText));
|
||||||
|
return termQuery;
|
||||||
|
}
|
||||||
|
else if (field.equals("ISNODE"))
|
||||||
|
{
|
||||||
|
TermQuery termQuery = new TermQuery(new Term(field, queryText));
|
||||||
|
return termQuery;
|
||||||
|
}
|
||||||
else if (field.equals("TX"))
|
else if (field.equals("TX"))
|
||||||
{
|
{
|
||||||
TermQuery termQuery = new TermQuery(new Term(field, queryText));
|
TermQuery termQuery = new TermQuery(new Term(field, queryText));
|
||||||
|
Reference in New Issue
Block a user