if (RUNNING) {
LOGGER.log(Level.INFO,"Synchronization run aborted, reason: already running.");
return;
}
RUNNING = true;
Lock backgroundLock = null;
try {
// initialize
int numDeleted = 0;
int numUpdated = 0;
this.context = RequestContext.extract(null);
this.startMillis = System.currentTimeMillis();
StringAttributeMap catParams = this.context.getCatalogConfiguration().getParameters();
// initialize index
this.context.getObjectMap().put("lucene.useRemoteWriter",false);
this.adapter = new LuceneIndexAdapter(context);
if (this.adapter == null) {
LOGGER.severe("A valid CatalogIndexAdapter cound not be initialized.");
}
this.adapter.touch(); // ensures that a proper directory structure exists
if (this.checkInterrupted()) return;
if (!this.adapter.getUsingSingleWriter()) {
backgroundLock = this.adapter.obtainBackgroundLock();
}
this.searcher = this.adapter.newSearcher();
this.reader = this.searcher.getIndexReader();
if (this.checkInterrupted()) return;
if (this.adapter.getUsingSingleWriter()) {
this.writer = this.adapter.newWriter();
this.adapter.setAutoCommitSingleWriter(false);
}
// initialize database
ManagedConnection mc = this.context.getConnectionBroker().returnConnection("");
this.con = mc.getJdbcConnection();
this.mutator = mc.getClobMutator();
this.resourceTable = this.context.getCatalogConfiguration().getResourceTableName();
this.resourceDataTable = this.context.getCatalogConfiguration().getResourceDataTableName();
// count current documents within the index and database
CountInfo countInfo = new CountInfo();
countInfo.numIndexedDocs = this.reader.numDocs();
this.countDatabaseDocs(countInfo);
if (this.checkInterrupted()) return;
this.countIndexableDocs(countInfo);
if (this.checkInterrupted()) return;
// purge the index if required
if (countInfo.numIndexableDocs == 0) {
if (countInfo.numIndexedDocs > 0) {
String p = Val.chkStr(catParams.getValue(
"lucene.synchronizer.allowFullIndexPurge"));
boolean bAllowFullIndexPurge = p.equalsIgnoreCase("true");
if (bAllowFullIndexPurge) {
numDeleted = countInfo.numIndexedDocs;
this.closeAll();
this.adapter.purgeIndex();
} else {
this.closeAll();
LOGGER.severe("The database contains no indexable documents," +
" the Lucene index contains "+countInfo.numIndexedDocs+
" indexed documents. A manual purge of the index is recommended.");
}
}
} else {
// walk the database
WalkDatabaseInfo walkDbInfo = new WalkDatabaseInfo(countInfo);
this.walkDatabase(walkDbInfo);
numDeleted = walkDbInfo.numDocsDeleted;
numUpdated = walkDbInfo.numDocsUpdated;
if (this.checkInterrupted()) return;
// determine if the index should be walked for deletions
boolean bWalkIndex = true;
if (walkDbInfo.numOriginallyIndexed == 0) {
bWalkIndex = false;
} else {
boolean bConsistent = (walkDbInfo.numIndexable == walkDbInfo.numIndexableFound) &&
(walkDbInfo.numIndexable == walkDbInfo.numOriginallyIndexed);
if (bConsistent) {
bWalkIndex = false;
} else {
int nFound = (walkDbInfo.numIndexableFound + walkDbInfo.numNonIndexableFound);
boolean bFoundAll = (nFound == walkDbInfo.numOriginallyIndexed);
if (bFoundAll) {
bWalkIndex = false;
}
}
}
// walk the index if required
if (bWalkIndex) {
WalkIndexInfo walkIndexInfo = new WalkIndexInfo(countInfo);
this.walkIndex(walkIndexInfo);
numDeleted += walkIndexInfo.numDocsDeleted;
}
}
// close connections
this.closeAll();
// log the summary message
double dSec = (System.currentTimeMillis() - this.startMillis) / 1000.0;
StringBuffer msg = new StringBuffer();
msg.append("Synchronization run completed.");
msg.append("\n processed=").append(countInfo.numDatabaseDocs);
msg.append(" docsUpdated=").append(numUpdated);
msg.append(" docsDeleted=").append(numDeleted);
msg.append(", runtime: ");
msg.append(Math.round(dSec / 60.0 * 100.0) / 100.0).append(" minutes");
if (dSec <= 600) {
msg.append(", ").append(Math.round(dSec * 100.0) / 100.0).append(" seconds");
}
LOGGER.info(msg.toString());
} catch (LockObtainFailedException e) {
LOGGER.log(Level.INFO,"Synchronization run aborted, reason: "+e.getMessage());
} catch (Throwable t) {
LOGGER.log(Level.SEVERE,"Error synchronizing index.",t);
} finally {
this.closeAll();
if (backgroundLock != null) {
try {
backgroundLock.release();
} catch (Throwable t) {
LOGGER.log(Level.WARNING,"Error releasing lock.",t);
}
}
if (this.wasInterrupted) {