Term termUuid = new Term(fldUuid);
if (bCheckIndex) {
termDocs = this.reader.termDocs();
}
StringSet delUuids = new StringSet();
// build the database query
StringBuffer sb = new StringBuffer("SELECT");
sb.append(" ").append(this.resourceTable).append(".DOCUUID");
sb.append(",").append(this.resourceTable).append(".APPROVALSTATUS");
sb.append(",").append(this.resourceTable).append(".PROTOCOL_TYPE");
sb.append(",").append(this.resourceTable).append(".FINDABLE");
sb.append(",").append(this.resourceTable).append(".UPDATEDATE");
sb.append(",").append(this.resourceTable).append(".ACL");
sb.append(" FROM ").append(this.resourceTable);
String sql = sb.toString();
LOGGER.finest(sql);
// execute the query, walk through the database records
Connection con = this.context.getConnectionBroker().returnConnection("").getJdbcConnection();
st = con.prepareStatement(sql);
ResultSet rs = st.executeQuery();
if (this.checkInterrupted()) return;
if (useCollections && hasCollections) {
stCol = con.prepareStatement(sqlCol);
}
while (rs.next()) {
info.numProcessed++;
info.loopCount++;
long nDbTimeModified = 0;
Timestamp tsDbModified = null;
String sDbAcl = null;
boolean bIndexable = false;
// read the database uuid and approval status
String uuid = rs.getString(1);
String status = rs.getString(2);
String protocolType = Val.chkStr(rs.getString(3));
boolean findable = Val.chkBool(rs.getString(4),false);
bIndexable = (status != null) &&
(status.equalsIgnoreCase("approved") || status.equalsIgnoreCase("reviewed"));
if (bIndexable && protocolType.length()>0 && !findable) {
bIndexable = false;
}
// read the database modification date
if (bIndexable) {
tsDbModified = rs.getTimestamp(5);
if (tsDbModified != null) {
nDbTimeModified = tsDbModified.getTime();
}
bIndexable = (nDbTimeModified > 0);
}
// for non-indexable documents, delete
if (!bIndexable) {
info.numNonIndexable++;
if (bCheckIndex) {
termDocs.seek(termUuid.createTerm(uuid));
if (termDocs.next()) {
info.numNonIndexableFound++;
info.numRequiringDelete++;
delUuids.add(uuid);
if (delUuids.size() >= this.maxDeleteTokens) {
if (this.checkInterrupted()) return;
this.deleteDocuments(delUuids);
info.numDocsDeleted += delUuids.size();
delUuids.clear();
if (this.checkInterrupted()) return;
}
}
}
}
// for indexable documents, check to ensure that they are in sync
if (bIndexable) {
info.numIndexable++;
boolean bRequiresUpdate = true;
// find the document within the index
if (bCheckIndex) {
termDocs.seek(termUuid.createTerm(uuid));
if (termDocs.next()) {
info.numIndexableFound++;
Document doc = this.reader.document(termDocs.doc(),selector);
if (doc != null) {
bRequiresUpdate = false;
// check the modification date
long nIdxTimeModified = 0;
String sModified = doc.get(fldModified);
if (sModified != null) {
try {
nIdxTimeModified = Long.valueOf(sModified);
} catch (NumberFormatException e) {
nIdxTimeModified = 0;
}
}
bRequiresUpdate = (nIdxTimeModified == 0) || (nDbTimeModified > nIdxTimeModified);
if (bRequiresUpdate) info.numWithInconsistentDates++;
// check the acl
if (!bRequiresUpdate && bCheckAcl) {
long tAclStartMillis = System.currentTimeMillis();
bRequiresUpdate = true;
String[] aclsDb = null;
sDbAcl = rs.getString(6);
try {
// use an internal method for quick parsing
//aclsDb = acl.makeDocumentAcl(sDbAcl);
aclsDb = this.parseAcl(sDbAcl);
} catch (Exception eacl) {
String sMsg = "Error parsing acl";
sMsg += ", uuid="+uuid+"\n"+Val.chkStr(eacl.getMessage());
LOGGER.log(Level.WARNING,sMsg,eacl);
}
if (aclsDb == null) aclsDb = new String[0];
ArrayList<String> aclsIdx = new ArrayList<String>();
Field[] aclFields = doc.getFields(fldAcl);
if ((aclFields != null) && (aclFields.length > 0)) {
for (Field aclField: aclFields) {
aclsIdx.add(aclField.stringValue());
}
}
if (aclsDb.length == aclsIdx.size()) {
int nMatched = 0;
if (aclsDb.length > 0) {
for (String s1: aclsDb) {
for (String s2: aclsIdx) {
if (s1.equalsIgnoreCase(s2)) {
nMatched++;
break;
}
}
}
}
bRequiresUpdate = (nMatched != aclsDb.length);
}
if (bRequiresUpdate) info.numWithInconsistentAcls++;
info.aclMillis += (System.currentTimeMillis() - tAclStartMillis);
}
// check collection membership
if (!bRequiresUpdate && useCollections) {
long tColStartMillis = System.currentTimeMillis();
bRequiresUpdate = true;
ArrayList<String> colDb = new ArrayList<String>();
if (useCollections && hasCollections) {
stCol.clearParameters();
stCol.setString(1,uuid);
ResultSet rsCol = stCol.executeQuery();
while (rsCol.next()) {
String sCUuid = rsCol.getString(1);
for (String[] col: collections) {
if (sCUuid.equals(col[0])) {
colDb.add(col[1]);
break;
}
}
}
rsCol.close();
}
ArrayList<String> colIdx = new ArrayList<String>();
Field[] colFields = doc.getFields("isPartOf");
if ((colFields != null) && (colFields.length > 0)) {
for (Field colField: colFields) {
colIdx.add(colField.stringValue());
}
}
if (colDb.size() == colIdx.size()) {
int nMatched = 0;
if (colDb.size() > 0) {
for (String s1: colDb) {
for (String s2: colIdx) {
if (s1.equalsIgnoreCase(s2)) {
nMatched++;
break;
}
}
}
}
bRequiresUpdate = (nMatched != colDb.size());
}
if (bRequiresUpdate) info.numWithInconsistentColMembership++;
info.colMillis += (System.currentTimeMillis() - tColStartMillis);
}
}
}
}
// execute the update if required
if (bRequiresUpdate) {
if (this.checkInterrupted()) return;
try {
if (bCheckAcl) {
if (sDbAcl == null) sDbAcl = rs.getString(6);
}
String sXml = Val.chkStr(this.readXml(uuid));
if (sXml.length() > 0) {
info.numRequiringUpdate++;
MetadataDocument mdDoc = new MetadataDocument();
Schema schema = mdDoc.prepareForView(this.context,sXml);
this.adapter.publishDocument(uuid,tsDbModified,schema,sDbAcl);
info.numDocsUpdated++;
}
} catch (SchemaException se) {
// dont' allow the entire process to fail over one bad xml
String sMsg = "Error indexing document during synchronization";
sMsg += ", uuid="+uuid+"\n"+Val.chkStr(se.getMessage());
LOGGER.log(Level.WARNING,sMsg,se);
}
if (this.checkInterrupted()) return;
}
}
// cache the synchronized uuids
if (this.synchedUuidCache != null) {
this.synchedUuidCache.put(uuid,"");
if (this.synchedUuidCache.size() > this.maxUuidCache) {
this.synchedUuidCache = null;
}
}
// log a status message if the feedback threshold was reached
if (this.checkInterrupted()) return;
if ((System.currentTimeMillis() - info.loopStartMillis) >= this.feedbackMillis) {
LOGGER.info(info.getLoopMessage());
}
}
// delete any documents left over in the buffer
if (delUuids.size() >= 0) {
if (this.checkInterrupted()) return;
this.deleteDocuments(delUuids);
info.numDocsDeleted += delUuids.size();
}
LOGGER.info(info.getStepMessage());
} finally {
try {if (st != null) st.close();} catch (Exception ef) {}