protected boolean processNext(Object[] aCasObjectList, ProcessTrace pTrTemp)
throws ResourceProcessException, IOException, CollectionException, AbortCPMException,
KillPipelineException {
maybeLogFinest("UIMA_CPM_start_analysis__FINEST");
// String lastDocId = "";
CasProcessor processor = null;
// This is used to hold an index of the current CasObject
// int currentIndex = -1;
boolean doneAlready = false;
// If there are no CASes in the list, return false since there is nothing else to do
if (aCasObjectList == null || aCasObjectList[0] == null) {
maybeLogFinest("UIMA_CPM_invalid_cas_reference__SEVERE");
return false;
}
Object[] casObjects = null;
// Determine if the Cas'es contained in the CasList are of type CAS. Samples the first CAS in
// the list.
// The list contains CASes of the same type ( either CasData or CAS ). Mixed model not
// supported.
boolean isCasObject = aCasObjectList[0] instanceof CAS;
// String docid = "";
maybeLogFinest("UIMA_CPM_entering_pipeline__FINEST");
ProcessingContainer container = null;
// *******************************************
// ** P R O C E S S I N G P I P E L I N E **
// *******************************************
// Send Cas Object through the processing pipeline.
for (int i = 0; processContainers != null && i < processContainers.size(); i++) {
if (UIMAFramework.getLogger().isLoggable(Level.FINEST)) {
logFinest("UIMA_CPM_retrieve_container__FINEST", String.valueOf(i));
}
container = (ProcessingContainer) processContainers.get(i);
synchronized (container) {
// Check to see if the CasProcessor is available for processing
if (!isProcessorReady(container.getStatus())) {
maybeLogFinest("UIMA_CPM_container_not_ready__FINEST", container);
boolean breakTheLoop = (i == (processContainers.size() - 1));
if (breakTheLoop && isCasObject) {
releaseCases(aCasObjectList, true, container.getName());
break;
}
// Skip any CasProcessor that is not ready to process
continue;
}
}
// Check if any of the Cas'es in the set has a required feature structure.
if (!isCasObject && !container.processCas(aCasObjectList)) {
maybeLogFinest("UIMA_CPM_skip_CAS__FINEST", container);
container.incrementFilteredCount(aCasObjectList.length);
container.logAbortedCases(aCasObjectList);
continue;
}
long byteCount;
// Flag controlling do-while loop that facilitates retries. Retries are defined in the
// CasProcessor configuration.
boolean retry = false;
// Retry Loop.
do {
if (System.getProperty("SHOW_MEMORY") != null) {
maybeLogMemoryFinest();
}
maybeLogFinest("UIMA_CPM_checkout_cp_from_container__FINEST", container);
threadState = 2004; // Entering dequeue()
processor = container.getCasProcessor();
if (processor == null) {
maybeLogSevere("UIMA_CPM_checkout_null_cp_from_container__SEVERE", container.getName());
throw new ResourceProcessException(CpmLocalizedMessage.getLocalizedMessage(
CPMUtils.CPM_LOG_RESOURCE_BUNDLE,
"UIMA_CPM_EXP_invalid_component_reference__WARNING", new Object[] {
Thread.currentThread().getName(), "CasProcessor", "NULL" }), null);
}
// Check to see if the CasProcessor is available for processing
// Container may have been disabled by another thread, so first check
if (!isProcessorReady(container.getStatus())) {
maybeLogFinest("UIMA_CPM_container_not_ready__FINEST", container);
if (container.getStatus() == Constants.CAS_PROCESSOR_KILLED) {
container.releaseCasProcessor(processor);
// Another thread has initiated CPM Abort. That Thread has already notified
// the application of the Abort. Here we just return as the CPM has been
// killed most likely due to excessive errors.
return false;
}
// Skip any CasProcessor that is not ready to process
break;
}
maybeLogFinest("UIMA_CPM_checkedout_cp_from_container__FINEST", container, processor);
try {
if (processor instanceof CasDataProcessor) {
maybeLogFinest("UIMA_CPM_cas_data_processor__FINEST", container, processor);
pTrTemp.startEvent(container.getName(), "Process", "");
if (isCasObject == true) {
CasData[] casDataObjects = new CasData[aCasObjectList.length];
for (int casIndex = 0; casIndex < aCasObjectList.length; casIndex++) {
casDataObjects[casIndex] = mConverter
.casContainerToCasData((CAS) aCasObjectList[casIndex]);
if ((CAS) aCasObjectList[casIndex] != null) {
((CAS) aCasObjectList[casIndex]).reset();
}
}
casCache = (CAS[]) aCasObjectList;
aCasObjectList = casDataObjects;
}
isCasObject = false;
byteCount = 0;
if (!retry) {
for (int casIndex = 0; casIndex < aCasObjectList.length; casIndex++) {
byteCount = getBytes(aCasObjectList[casIndex]);
container.addBytesIn(byteCount);
}
}
casObjects = aCasObjectList;
long pStart = System.currentTimeMillis();
if (UIMAFramework.getLogger().isLoggable(Level.FINEST)) {
logFinest("UIMA_CPM_call_process__FINEST", container, processor);
logFinest("UIMA_CPM_casObjects_class__FINEST", casObjects.getClass().getName());
}
if (!(casObjects instanceof CasData[])) {
maybeLogFinest("UIMA_CPM_expected_casdata__FINEST", casObjects.getClass().getName());
}
maybeLogFinest("UIMA_CPM_call_process__FINEST", container, processor);
casObjects = ((CasDataProcessor) processor).process((CasData[]) casObjects);
maybeLogFinest("UIMA_CPM_call_process_completed__FINEST", container, processor);
long pEnd = System.currentTimeMillis();
container.incrementTotalTime((pEnd - pStart));
if (casObjects != null) {
if (processor instanceof CasDataConsumer) {
container.addBytesOut(byteCount);
} else {
aCasObjectList = casObjects;
if (!retry) {
for (int casIndex = 0; casIndex < aCasObjectList.length; casIndex++) {
byteCount = getBytes(aCasObjectList[casIndex]);
container.addBytesOut(byteCount);
}
}
}
}
pTrTemp.endEvent(container.getName(), "Process", "success");
} else if (processor instanceof CasObjectProcessor) {
maybeLogFinest("UIMA_CPM_casobject_processor__FINEST", container, processor);
maybeLogMemoryFinest();
casList = new CAS[aCasObjectList.length];
for (int casIndex = 0; casIndex < aCasObjectList.length; casIndex++) {
maybeLogFinest("UIMA_CPM_initialize_cas__FINEST", container);
if (aCasObjectList[casIndex] == null) {
if (UIMAFramework.getLogger().isLoggable(Level.SEVERE)) {
logSevere("UIMA_CPM_casobjectlist_is_null__SEVERE",
container.getName(), String.valueOf(casIndex));
}
break;
}
if (isCasObject == false) {
// The following may be true if the CollectionReader is CasData based and this is
// the first CasObject based annotator in the chain.
if (casCache == null || casCache[casIndex] == null) {
casList[casIndex] = null;
while (casList[casIndex] == null) {
maybeLogFinest("UIMA_CPM_get_cas_from_pool__FINEST", container);
// Retrieve a Cas from Cas Pool. Wait max 10 millis for an instance
casList[casIndex] = casPool.getCas(0);
maybeLogFinest("UIMA_CPM_got_cas_from_pool__FINEST", container);
}
if (casList[casIndex] != null) {
maybeLogFinest("UIMA_CPM_call_cas_reset__FINEST", container);
casList[casIndex].reset();
}
} else {
casList[casIndex] = casCache[casIndex];
casList[casIndex].reset();
maybeLogFinest("UIMA_CPM_nullify_cas__FINEST", container);
// Cas is used up
casCache[casIndex] = null;
}
// Convert CasData to CAS
mConverter.casDataToCasContainer((CasData) aCasObjectList[casIndex],
casList[casIndex], true);
} else {
casList[casIndex] = (CAS) aCasObjectList[casIndex];
}
// Set the type from CasData to CasObject. When an error occurs in the proces()
// we need to know what type of object we deal with.
isCasObject = true;
aCasObjectList = casList;
if (processor instanceof AnalysisEngine) {
maybeLogFinest("UIMA_CPM_call_process__FINEST", container, processor);
threadState = 2005;
pTrTemp.aggregate(((AnalysisEngine) processor).process(casList[casIndex]));
maybeLogFinest("UIMA_CPM_call_process_completed__FINEST", container, processor);
} else {
pTrTemp.startEvent(container.getName(), "Process", "");
threadState = 2006;
maybeLogFinest("UIMA_CPM_call_process__FINEST", container, processor);
((CasObjectProcessor) processor).processCas(casList[casIndex]);
maybeLogFinest("UIMA_CPM_call_process_completed__FINEST", container, processor);
pTrTemp.endEvent(container.getName(), "Process", "success");
}
}
}
// Release the CAS and notify listeners if the end of the
// pipeline is reached.
if ((releaseCAS) && (i == (processContainers.size() - 1))) {
// This flag is used to prevent multiple notifications
doneAlready = true;
EntityProcessStatus aEntityProcStatus = new EntityProcessStatusImpl(pTrTemp);
maybeLogFinest("UIMA_CPM_notify_listeners__FINEST");
threadState = 2007;
notifyListeners(aCasObjectList, isCasObject, aEntityProcStatus);
if (UIMAFramework.getLogger().isLoggable(Level.FINEST)) {
logFinest("UIMA_CPM_done_notify_listeners__FINEST");
logFinest("UIMA_CPM_releasing_cases__FINEST",
container.getName(), String.valueOf(releaseCAS), "true");
}
if (casCache != null) {
clearCasCache();
}
// Release CAS's.
if (aCasObjectList instanceof CAS[]) {
cpm.releaseCASes((CAS[]) aCasObjectList);
}
maybeLogFinest("UIMA_CPM_done_releasing_cases__FINEST", container);
}
maybeLogFinest("UIMA_CPM_pipeline_completed__FINEST");
retry = false;
// On successfull processing reset the restart counter. Restart counter determines how
// many times to restart Cas Processor on the same CAS
// Do this conditionally. If the CAS is to be dropped on Exception this restart counter
// scope extends to the entire collection not just one CAS
if (!cpm.dropCasOnException()) {
container.resetRestartCount();
}
} catch (Exception e) {
e.printStackTrace();
if (UIMAFramework.getLogger().isLoggable(Level.SEVERE)) {
logSevere("UIMA_CPM_pipeline_exception__SEVERE", container.getName(), e.getMessage());
maybeLogSevereException(e);
logFinest("UIMA_CPM_pipeline_exception__FINEST",
container.getName(), String.valueOf(container.isPaused()));
}
EntityProcessStatusImpl enProcSt = new EntityProcessStatusImpl(pTrTemp);
enProcSt.addEventStatus("Process", "Failed", e);
threadState = 2008;
notifyListeners(aCasObjectList, isCasObject, enProcSt);
doneAlready = true;
threadState = 2009;
// Check the policy to determine what to do with the CAS on exception. Return the CAS back
// to the pool
// and stop the processing chain if required. The policy for what to do with the CAS on
// exception is
// defined in the CPE descriptor
if (cpm.dropCasOnException()) {
if (casCache != null) {
clearCasCache();
}
if (aCasObjectList instanceof CAS[]) {
cpm.invalidateCASes((CAS[]) aCasObjectList);
}
retry = false; // Dont retry. The CAS has been released
maybeLogWarning("UIMA_CPM_drop_cas__WARNING",
container.getName(), processor.getClass().getName());
} else {
retry = true; // default on Exception
}
// If the container is in pause state dont increment errors since one thread has already
// done this. While the container is in pause state the CPM is attempting to re-connect