You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by ea...@apache.org on 2008/03/20 20:19:49 UTC
svn commit: r639416 - in /incubator/uima/uimaj/trunk/uimaj-core/src:
main/java/org/apache/uima/analysis_engine/impl/PrimitiveAnalysisEngine_impl.java
test/java/org/apache/uima/analysis_engine/impl/NewlineSegmenter.java
Author: eae
Date: Thu Mar 20 12:19:49 2008
New Revision: 639416
URL: http://svn.apache.org/viewvc?rev=639416&view=rev
Log:
UIMA-911 Apply Burn's patches to test and fix
Modified:
incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/PrimitiveAnalysisEngine_impl.java
incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/NewlineSegmenter.java
Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/PrimitiveAnalysisEngine_impl.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/PrimitiveAnalysisEngine_impl.java?rev=639416&r1=639415&r2=639416&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/PrimitiveAnalysisEngine_impl.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/PrimitiveAnalysisEngine_impl.java Thu Mar 20 12:19:49 2008
@@ -1,612 +1,617 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.uima.analysis_engine.impl;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.uima.Constants;
-import org.apache.uima.UIMAFramework;
-import org.apache.uima.UIMA_IllegalStateException;
-import org.apache.uima.UimaContextAdmin;
-import org.apache.uima.analysis_component.AnalysisComponent;
-import org.apache.uima.analysis_engine.AnalysisEngine;
-import org.apache.uima.analysis_engine.AnalysisEngineDescription;
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
-import org.apache.uima.analysis_engine.CasIterator;
-import org.apache.uima.analysis_engine.ResultNotSupportedException;
-import org.apache.uima.analysis_engine.ResultSpecification;
-import org.apache.uima.analysis_engine.TypeOrFeature;
-import org.apache.uima.analysis_engine.impl.compatibility.AnalysisComponentAdapterFactory;
-import org.apache.uima.cas.AbstractCas;
-import org.apache.uima.cas.CAS;
-import org.apache.uima.cas.TypeSystem;
-import org.apache.uima.cas.impl.CASImpl;
-import org.apache.uima.impl.UimaContext_ImplBase;
-import org.apache.uima.internal.util.UUIDGenerator;
-import org.apache.uima.jcas.JCas;
-import org.apache.uima.resource.ResourceConfigurationException;
-import org.apache.uima.resource.ResourceCreationSpecifier;
-import org.apache.uima.resource.ResourceInitializationException;
-import org.apache.uima.resource.ResourceSpecifier;
-import org.apache.uima.resource.metadata.Capability;
-import org.apache.uima.resource.metadata.ProcessingResourceMetaData;
-import org.apache.uima.resource.metadata.ResourceMetaData;
-import org.apache.uima.util.Level;
-import org.apache.uima.util.Logger;
-
-/**
- * Reference implementation of {@link AnalysisEngine}.
- *
- *
- */
-public class PrimitiveAnalysisEngine_impl extends AnalysisEngineImplBase implements AnalysisEngine {
- /**
- * current class
- */
- private static final Class CLASS_NAME = PrimitiveAnalysisEngine_impl.class;
-
- private static final String [] X_UNSPECIFIED = new String [] {"x-unspecified"};
-
- private static final String [] EMPTY_STRING_ARRAY = new String [0];
-
- private ResultSpecification mCurrentResultSpecification;
-
- private boolean mResultSpecChanged;
-
- private TypeSystem mLastTypeSystem;
-
- /**
- * The ResourceCreationSpecifier parsed from this component's descriptor.
- */
- private ResourceCreationSpecifier mDescription;
-
- /**
- * The AnalysisComponent that holds the user-developed analysis logic.
- */
- private AnalysisComponent mAnalysisComponent;
-
- /**
- * If this is set it indicates that the AnalysisEngine is being constructed only to verify the
- * validity of the descriptor. The Annotator classes should not be instantiated in this case.
- */
- private boolean mVerificationMode = false;
-
- private boolean mSofaAware;
-
- /**
- * @see org.apache.uima.resource.Resource#initialize(ResourceSpecifier, Map)
- */
- public boolean initialize(ResourceSpecifier aSpecifier, Map aAdditionalParams)
- throws ResourceInitializationException {
- try {
- // Primitive AnalysisEngine can be build from any ResourceCreationSpecifier-
- // this includes CollectionReader, and CasConsumer descriptors
- // as well as AnalysisEngine descriptors.
-
- if (!(aSpecifier instanceof ResourceCreationSpecifier)) {
- return false;
- }
-
- // BUT, for AnalysisEngineDescriptions, must not be an aggregate
- if (aSpecifier instanceof AnalysisEngineDescription
- && !((AnalysisEngineDescription) aSpecifier).isPrimitive()) {
- return false;
- }
-
- mDescription = (ResourceCreationSpecifier) aSpecifier;
-
- // also framework implementation must start with org.apache.uima.java
- final String fwImpl = mDescription.getFrameworkImplementation();
- if (!fwImpl.startsWith(Constants.JAVA_FRAMEWORK_NAME)) {
- return false;
- }
-
- super.initialize(aSpecifier, aAdditionalParams);
- ProcessingResourceMetaData md = (ProcessingResourceMetaData) mDescription.getMetaData();
-
- getLogger().logrb(Level.CONFIG, CLASS_NAME.getName(), "initialize", LOG_RESOURCE_BUNDLE,
- "UIMA_analysis_engine_init_begin__CONFIG", md.getName());
-
- // Normalize language codes. Need to do this since a wide variety of
- // spellings are acceptable according to ISO.
- normalizeIsoLangCodes(md);
-
- // clone this metadata and assign a UUID if not already present
- ResourceMetaData mdCopy = (ResourceMetaData) md.clone();
-
- if (mdCopy.getUUID() == null) {
- mdCopy.setUUID(UUIDGenerator.generate());
- }
- setMetaData(mdCopy);
-
- // validate the AnalysisEngineDescription and throw a
- // ResourceInitializationException if there is a problem
- mDescription.validate(getResourceManager());
-
- // Read parameters from the aAdditionalParams map.
- if (aAdditionalParams == null) {
- aAdditionalParams = Collections.EMPTY_MAP;
- }
- // determine if verification mode is on
- mVerificationMode = aAdditionalParams.containsKey(PARAM_VERIFICATION_MODE);
-
- // determine if this component is Sofa-aware (based on whether it
- // declares any input or output sofas in its capabilities)
- mSofaAware = getAnalysisEngineMetaData().isSofaAware();
-
- initializeAnalysisComponent(aAdditionalParams);
-
- // Initialize ResultSpec based on output capabilities
- // TODO: should only do this for outermost AE
- resetResultSpecificationToDefault();
-
- getLogger().logrb(Level.CONFIG, CLASS_NAME.getName(), "initialize", LOG_RESOURCE_BUNDLE,
- "UIMA_analysis_engine_init_successful__CONFIG", md.getName());
- return true;
- } catch (ResourceConfigurationException e) {
- throw new ResourceInitializationException(
- ResourceInitializationException.ERROR_INITIALIZING_FROM_DESCRIPTOR, new Object[] {
- getMetaData().getName(), aSpecifier.getSourceUrlString() });
- }
- }
-
- /**
- * Loads, instantiates, and initializes the AnalysisComponent contained in this AE.
- *
- * @param aAdditionalParams
- * parameters passed to this AE's initialize method
- *
- * @throws ResourceInitializationException
- * if an initialization failure occurs
- */
- protected void initializeAnalysisComponent(Map aAdditionalParams)
- throws ResourceInitializationException {
- // instantiate Annotator class
- String annotatorClassName;
- annotatorClassName = mDescription.getImplementationName();
-
- if (annotatorClassName == null || annotatorClassName.length() == 0) {
- throw new ResourceInitializationException(
- ResourceInitializationException.MISSING_ANNOTATOR_CLASS_NAME,
- new Object[] { mDescription.getSourceUrlString() });
- }
-
- // load annotator class
- Class annotatorClass = null;
- try {
- // get UIMA extension ClassLoader if available
- ClassLoader cl = getUimaContextAdmin().getResourceManager().getExtensionClassLoader();
-
- if (cl != null) {
- // use UIMA extension ClassLoader to load the class
- annotatorClass = cl.loadClass(annotatorClassName);
- } else {
- // use application ClassLoader to load the class
- annotatorClass = Class.forName(annotatorClassName);
- }
- } catch (ClassNotFoundException e) {
- throw new ResourceInitializationException(
- ResourceInitializationException.ANNOTATOR_CLASS_NOT_FOUND, new Object[] {
- annotatorClassName, mDescription.getSourceUrlString() }, e);
- }
-
- // Make sure the specified class can be adapter to an AnalysisComponent.
- if (!(AnalysisComponent.class.isAssignableFrom(annotatorClass))
- && !AnalysisComponentAdapterFactory.isAdaptable(annotatorClass)) {
- throw new ResourceInitializationException(
- ResourceInitializationException.NOT_AN_ANALYSIS_COMPONENT, new Object[] {
- annotatorClass.getName(), mDescription.getSourceUrlString() });
- }
-
- // if we're in verification mode, stop here and do not try to instantiate the
- // analysis component
- if (mVerificationMode) {
- return;
- }
-
- try {
- Object userObject = annotatorClass.newInstance();
- if (userObject instanceof AnalysisComponent) {
- mAnalysisComponent = (AnalysisComponent) userObject;
- } else {
- mAnalysisComponent = AnalysisComponentAdapterFactory.createAdapter(userObject,
- getAnalysisEngineMetaData(), aAdditionalParams);
- }
- } catch (ResourceInitializationException e) {
- throw e;
- } catch (Exception e) {
- throw new ResourceInitializationException(
- ResourceInitializationException.COULD_NOT_INSTANTIATE_ANNOTATOR, new Object[] {
- annotatorClassName, mDescription.getSourceUrlString() }, e);
- }
-
- // Set Logger, to enable annotator-specific logging
- UimaContextAdmin uimaContext = getUimaContextAdmin();
- Logger logger = UIMAFramework.getLogger(annotatorClass);
- logger.setResourceManager(this.getResourceManager());
- uimaContext.setLogger(logger);
-
- // initialize AnalysisComponent
- try {
- mAnalysisComponent.initialize(getUimaContext());
- } catch (Exception e) {
- throw new ResourceInitializationException(
- ResourceInitializationException.ANNOTATOR_INITIALIZATION_FAILED, new Object[] {
- annotatorClassName, mDescription.getSourceUrlString() }, e);
- }
-
- // set up the CAS pool for this AE (this won't do anything if
- // mAnalysisComponent.getCasInstancesRequired() == 0)
- getUimaContextAdmin().defineCasPool(mAnalysisComponent.getCasInstancesRequired(),
- getPerformanceTuningSettings(), mSofaAware);
- }
-
- /**
- * @see org.apache.uima.resource.Resource#destroy()
- */
- public void destroy() {
- if (mAnalysisComponent != null) {
- mAnalysisComponent.destroy();
- getLogger().logrb(Level.CONFIG, CLASS_NAME.getName(), "initialize", LOG_RESOURCE_BUNDLE,
- "UIMA_analysis_engine_destroyed__CONFIG", getMetaData().getName());
- }
- super.destroy();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.analysis_engine.AnalysisEngine#setResultSpecification(org.apache.uima.analysis_engine.ResultSpecification)
- */
- public void setResultSpecification(ResultSpecification aResultSpec) {
- if (aResultSpec == null) {
- resetResultSpecificationToDefault();
- } else {
- mCurrentResultSpecification = aResultSpec;
- mResultSpecChanged = true;
- }
- }
-
- /**
- * @see AnalysisEngine#processAndOutputNewCASes(CAS)
- */
- public CasIterator processAndOutputNewCASes(CAS aCAS) throws AnalysisEngineProcessException {
- enterProcess();
- try {
- // make initial call to the AnalysisComponent
- callAnalysisComponentProcess(aCAS);
-
- // return a CasIterator that allows caller to step through the outputs
- // of this AnalysisComponent (if any)
- return new AnalysisComponentCasIterator(mAnalysisComponent, aCAS);
- } finally {
- exitProcess();
- }
- }
-
- public void batchProcessComplete() throws AnalysisEngineProcessException {
- enterBatchProcessComplete();
- try {
- getAnalysisComponent().batchProcessComplete();
- } finally {
- exitBatchProcessComplete();
- }
- }
-
- public void collectionProcessComplete() throws AnalysisEngineProcessException {
- enterCollectionProcessComplete();
- try {
- getAnalysisComponent().collectionProcessComplete();
- } finally {
- exitCollectionProcessComplete();
- }
- }
-
- /**
- * Calls the Analysis Component's process method.
- *
- * @param aCAS
- * CAS to be processed by annotator
- * @param aResultSpec
- * result specification to be passed to annotator
- * @param aProcessTrace
- * keeps track of time spent in each component
- */
- protected void callAnalysisComponentProcess(CAS aCAS) throws AnalysisEngineProcessException {
- // logging and instrumentation
- String resourceName = getMetaData().getName();
- getLogger().logrb(Level.FINE, CLASS_NAME.getName(), "process", LOG_RESOURCE_BUNDLE,
- "UIMA_analysis_engine_process_begin__FINE", resourceName);
- try {
- // call Annotator's process method
- try {
- // set the current component info of the CAS, so that it knows the sofa
- // mappings for the component that's about to process it
- aCAS.setCurrentComponentInfo(getUimaContextAdmin().getComponentInfo());
-
- // Get the right view of the CAS. Sofa-aware components get the base CAS.
- // Sofa-unaware components get whatever is mapped to the _InitialView.
- CAS view = ((CASImpl) aCAS).getBaseCAS();
- if (!mSofaAware) {
- view = aCAS.getView(CAS.NAME_DEFAULT_SOFA);
- }
- // now get the right interface(e.g. CAS or JCAS)
- Class requiredInterface = mAnalysisComponent.getRequiredCasInterface();
- AbstractCas casToPass = getCasManager().getCasInterface(view, requiredInterface);
-
- // check if there was a change in the ResultSpecification or in
- // the TypeSystem. If so, set the changed type system into the ResultSpecification and
- // inform the component
- if (mResultSpecChanged || mLastTypeSystem != view.getTypeSystem()) {
- mLastTypeSystem = view.getTypeSystem();
- mCurrentResultSpecification.setTypeSystem(mLastTypeSystem);
- // the actual ResultSpec we send to the component is formed by
- // looking at this primitive AE's declared output types and eliminiating
- // any that are not in mCurrentResultSpecification.
- ResultSpecification analysisComponentResultSpec = computeAnalysisComponentResultSpec(
- mCurrentResultSpecification, getAnalysisEngineMetaData().getCapabilities());
- mAnalysisComponent.setResultSpecification(analysisComponentResultSpec);
- mResultSpecChanged = false;
- }
-
- ((CASImpl)aCAS).switchClassLoaderLockCasCL(this.getResourceManager().getExtensionClassLoader());
-
- // call the process method
- mAnalysisComponent.process(casToPass);
- getMBean().incrementCASesProcessed();
-
- //note we do not clear the CAS's currentComponentInfo at this time
- // nor do we unlock the cas and switch it back (class loader-wise). The AnalysisComponents still
- //can access the CAS until such time as its hasNext method returns false. Thus is is the
- //AnalysisComponentCasIterator that knows when it is time to clear the currentComponentInfo.
- } catch (Exception e) {
- // catching Throwable to catch out-of-memory errors too, which are not Exceptions
- aCAS.setCurrentComponentInfo(null);
- ((CASImpl)aCAS).restoreClassLoaderUnlockCas();
- if (e instanceof AnalysisEngineProcessException) {
- throw (AnalysisEngineProcessException) e;
- } else {
- throw new AnalysisEngineProcessException(
- AnalysisEngineProcessException.ANNOTATOR_EXCEPTION, null, e);
- }
- } catch (Error e) { // out of memory error, for instance
- aCAS.setCurrentComponentInfo(null);
- ((CASImpl)aCAS).restoreClassLoaderUnlockCas();
- throw e;
- }
-
- // log end of event
- getLogger().logrb(Level.FINE, CLASS_NAME.getName(), "process", LOG_RESOURCE_BUNDLE,
- "UIMA_analysis_engine_process_end__FINE", resourceName);
- } catch (Exception e) {
- // log and rethrow exception
- getLogger().log(Level.SEVERE, "", e);
- if (e instanceof AnalysisEngineProcessException)
- throw (AnalysisEngineProcessException) e;
- else
- throw new AnalysisEngineProcessException(e);
- }
- }
-
- /**
- * Creates the ResultSpecification to be passed to the AnalysisComponent. This is derived from the
- * ResultSpec that is input to this AE (via its setResultSpecification method) by intersecting
- * with the declared outputs of this AE, so that we never ask an AnalysisComponent to produce a
- * result type that it does not declare in its outputs.
- *
- * @param currentResultSpecification
- * the result spec passed to this AE's setResultSpecification method
- * @param capabilities
- * the capabilities of this AE
- *
- * @return a ResultSpecifciation to pass to the AnalysisComponent
- */
- protected ResultSpecification computeAnalysisComponentResultSpec(
- ResultSpecification inputResultSpec, Capability[] capabilities) {
- ResultSpecification newResultSpec = new ResultSpecification_impl(inputResultSpec.getTypeSystem());
- List<String> languagesToAdd = new ArrayList<String>();
-
- for (Capability capability : capabilities) {
- TypeOrFeature[] outputs = capability.getOutputs();
- String[] languages = capability.getLanguagesSupported();
- if (null == languages || languages.length == 0) {
- languages = X_UNSPECIFIED;
- }
-
- for (TypeOrFeature tof : outputs) {
- String tofName = tof.getName();
- languagesToAdd.clear();
- for (String language : languages) {
- if ((tof.isType() && inputResultSpec.containsType(tofName, language)) ||
- (!tof.isType() && inputResultSpec.containsFeature(tofName, language))) {
- languagesToAdd.add(language);
- }
- }
- if (0 < languagesToAdd.size()) {
- if (tof.isType()) {
- newResultSpec.addResultType(tofName, tof.isAllAnnotatorFeatures(),
- languagesToAdd.toArray(EMPTY_STRING_ARRAY));
- } else {
- newResultSpec.addResultFeature(tofName, languagesToAdd.toArray(EMPTY_STRING_ARRAY));
- }
- }
- }
- }
- return newResultSpec;
- }
-
-// for (int i = 0; i < capabilities.length; i++) {
-// Capability cap = capabilities[i];
-// TypeOrFeature[] outputs = cap.getOutputs();
-// String[] languages = cap.getLanguagesSupported();
-// if (languages.length == 0) {
-// languages = X_UNSPECIFIED;
-// }
-// for (int j = 0; j < outputs.length; j++) {
-// for (int k = 0; k < languages.length; k++) {
-// if (outputs[j].isType()
-// && inputResultSpec.containsType(outputs[j].getName(), languages[k])) {
-// newResultSpec.addResultType(outputs[j].getName(), outputs[j].isAllAnnotatorFeatures(),
-// new String[] { languages[k] });
-// } else if (!outputs[j].isType()
-// && inputResultSpec.containsFeature(outputs[j].getName(), languages[k])) {
-// newResultSpec.addResultFeature(outputs[j].getName(), new String[] { languages[k] });
-// }
-// }
-// }
-// }
-// return newResultSpec;
-// }
-
- /**
- * Calls the Analysis Component's next() method.
- *
- * @return CAS returned by the analysis component
- */
- protected CAS callAnalysisComponentNext() throws AnalysisEngineProcessException,
- ResultNotSupportedException {
- try {
- AbstractCas absCas = mAnalysisComponent.next();
- getMBean().incrementCASesProcessed();
- // notify UimaContext that a CAS was returned -- it uses
- // this information to track how many CASes the AnalysisComponent
- // is using at any one time.
- ((UimaContext_ImplBase) getUimaContext()).returnedCAS(absCas);
-
- // convert back to CASImpl and then get the initial View
- CAS casToReturn;
- if (absCas instanceof JCas) {
- casToReturn = ((JCas) absCas).getCas();
- } else {
- casToReturn = (CAS) absCas;
- }
- casToReturn = casToReturn.getView(CAS.NAME_DEFAULT_SOFA);
-
- // clear the CAS's component info, since it is no longer
- // being processed by this AnalysisComponent
- casToReturn.setCurrentComponentInfo(null);
- ((CASImpl)casToReturn).restoreClassLoaderUnlockCas();
- return casToReturn;
- } catch (Exception e) {
- // log and rethrow exception
- getLogger().log(Level.SEVERE, "", e);
- if (e instanceof AnalysisEngineProcessException)
- throw (AnalysisEngineProcessException) e;
- else
- throw new AnalysisEngineProcessException(e);
- }
- }
-
- /**
- * @see org.apache.uima.resource.AnalysisEngine#reconfigure()
- */
- public void reconfigure() throws ResourceConfigurationException {
- // do base resource reconfiguration
- super.reconfigure();
-
- // inform the annotator
- try {
- mAnalysisComponent.reconfigure();
- } catch (ResourceInitializationException e) {
- throw new ResourceConfigurationException(e);
- }
- }
-
- protected AnalysisComponent getAnalysisComponent() {
- return mAnalysisComponent;
- }
-
- /**
- * Implements the iterator that steps through all outputs from an AnalysisComponent.
- */
- class AnalysisComponentCasIterator implements CasIterator {
- private AnalysisComponent mMyAnalysisComponent;
- private CAS mInputCas;
-
- AnalysisComponentCasIterator(AnalysisComponent aAnalysisComponent, CAS aInputCas) {
- mMyAnalysisComponent = aAnalysisComponent;
- mInputCas = aInputCas;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.core.CasIterator#hasNext()
- */
- public boolean hasNext() throws AnalysisEngineProcessException {
- enterProcess();
- try {
- boolean result = mMyAnalysisComponent.hasNext();
- if (!result) {
- //when hasNext returns false, by contract the AnalysisComponent is done processing its
- //input CAS. Now is the time to clear the currentComponentInfo to indicate that the
- //CAS is no longer being processed.
- mInputCas.setCurrentComponentInfo(null);
- ((CASImpl)mInputCas).restoreClassLoaderUnlockCas();
- }
- return result;
- } finally {
- exitProcess();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.core.CasIterator#next(java.lang.Class)
- */
- public CAS next() throws AnalysisEngineProcessException {
- enterProcess();
- try {
- // Make sure that the AnalysisComponent has a next CAS to return
- boolean analysisComponentHasNext = mMyAnalysisComponent.hasNext();
- if (!analysisComponentHasNext) {
- throw new UIMA_IllegalStateException(UIMA_IllegalStateException.NO_NEXT_CAS,
- new Object[0]);
- }
- // call AnalysisComponent.next method to populate CAS
- try {
- CAS cas = callAnalysisComponentNext();
- // cas.setParentID(mOriginalCas.getID());
- return cas;
- } catch (Exception e) {
- if (e instanceof AnalysisEngineProcessException) {
- throw (AnalysisEngineProcessException) e;
- }
- throw new AnalysisEngineProcessException(e);
- }
- } finally {
- exitProcess();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.analysis_engine.CasIterator#release()
- */
- public void release() {
- // nothing to do
- }
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.uima.analysis_engine.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.uima.Constants;
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.UIMA_IllegalStateException;
+import org.apache.uima.UimaContextAdmin;
+import org.apache.uima.analysis_component.AnalysisComponent;
+import org.apache.uima.analysis_engine.AnalysisEngine;
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.analysis_engine.CasIterator;
+import org.apache.uima.analysis_engine.ResultNotSupportedException;
+import org.apache.uima.analysis_engine.ResultSpecification;
+import org.apache.uima.analysis_engine.TypeOrFeature;
+import org.apache.uima.analysis_engine.impl.compatibility.AnalysisComponentAdapterFactory;
+import org.apache.uima.cas.AbstractCas;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.cas.impl.CASImpl;
+import org.apache.uima.impl.UimaContext_ImplBase;
+import org.apache.uima.internal.util.UUIDGenerator;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.resource.ResourceConfigurationException;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.metadata.Capability;
+import org.apache.uima.resource.metadata.ProcessingResourceMetaData;
+import org.apache.uima.resource.metadata.ResourceMetaData;
+import org.apache.uima.util.Level;
+import org.apache.uima.util.Logger;
+
+/**
+ * Reference implementation of {@link AnalysisEngine}.
+ *
+ *
+ */
+public class PrimitiveAnalysisEngine_impl extends AnalysisEngineImplBase implements AnalysisEngine {
+ /**
+ * current class
+ */
+ private static final Class CLASS_NAME = PrimitiveAnalysisEngine_impl.class;
+
+ private static final String [] X_UNSPECIFIED = new String [] {"x-unspecified"};
+
+ private static final String [] EMPTY_STRING_ARRAY = new String [0];
+
+ private ResultSpecification mCurrentResultSpecification;
+
+ private boolean mResultSpecChanged;
+
+ private TypeSystem mLastTypeSystem;
+
+ /**
+ * The ResourceCreationSpecifier parsed from this component's descriptor.
+ */
+ private ResourceCreationSpecifier mDescription;
+
+ /**
+ * The AnalysisComponent that holds the user-developed analysis logic.
+ */
+ private AnalysisComponent mAnalysisComponent;
+
+ /**
+ * If this is set it indicates that the AnalysisEngine is being constructed only to verify the
+ * validity of the descriptor. The Annotator classes should not be instantiated in this case.
+ */
+ private boolean mVerificationMode = false;
+
+ private boolean mSofaAware;
+
+ /**
+ * @see org.apache.uima.resource.Resource#initialize(ResourceSpecifier, Map)
+ */
+ public boolean initialize(ResourceSpecifier aSpecifier, Map aAdditionalParams)
+ throws ResourceInitializationException {
+ try {
+ // Primitive AnalysisEngine can be build from any ResourceCreationSpecifier-
+ // this includes CollectionReader, and CasConsumer descriptors
+ // as well as AnalysisEngine descriptors.
+
+ if (!(aSpecifier instanceof ResourceCreationSpecifier)) {
+ return false;
+ }
+
+ // BUT, for AnalysisEngineDescriptions, must not be an aggregate
+ if (aSpecifier instanceof AnalysisEngineDescription
+ && !((AnalysisEngineDescription) aSpecifier).isPrimitive()) {
+ return false;
+ }
+
+ mDescription = (ResourceCreationSpecifier) aSpecifier;
+
+ // also framework implementation must start with org.apache.uima.java
+ final String fwImpl = mDescription.getFrameworkImplementation();
+ if (!fwImpl.startsWith(Constants.JAVA_FRAMEWORK_NAME)) {
+ return false;
+ }
+
+ super.initialize(aSpecifier, aAdditionalParams);
+ ProcessingResourceMetaData md = (ProcessingResourceMetaData) mDescription.getMetaData();
+
+ getLogger().logrb(Level.CONFIG, CLASS_NAME.getName(), "initialize", LOG_RESOURCE_BUNDLE,
+ "UIMA_analysis_engine_init_begin__CONFIG", md.getName());
+
+ // Normalize language codes. Need to do this since a wide variety of
+ // spellings are acceptable according to ISO.
+ normalizeIsoLangCodes(md);
+
+ // clone this metadata and assign a UUID if not already present
+ ResourceMetaData mdCopy = (ResourceMetaData) md.clone();
+
+ if (mdCopy.getUUID() == null) {
+ mdCopy.setUUID(UUIDGenerator.generate());
+ }
+ setMetaData(mdCopy);
+
+ // validate the AnalysisEngineDescription and throw a
+ // ResourceInitializationException if there is a problem
+ mDescription.validate(getResourceManager());
+
+ // Read parameters from the aAdditionalParams map.
+ if (aAdditionalParams == null) {
+ aAdditionalParams = Collections.EMPTY_MAP;
+ }
+ // determine if verification mode is on
+ mVerificationMode = aAdditionalParams.containsKey(PARAM_VERIFICATION_MODE);
+
+ // determine if this component is Sofa-aware (based on whether it
+ // declares any input or output sofas in its capabilities)
+ mSofaAware = getAnalysisEngineMetaData().isSofaAware();
+
+ initializeAnalysisComponent(aAdditionalParams);
+
+ // Initialize ResultSpec based on output capabilities
+ // TODO: should only do this for outermost AE
+ resetResultSpecificationToDefault();
+
+ getLogger().logrb(Level.CONFIG, CLASS_NAME.getName(), "initialize", LOG_RESOURCE_BUNDLE,
+ "UIMA_analysis_engine_init_successful__CONFIG", md.getName());
+ return true;
+ } catch (ResourceConfigurationException e) {
+ throw new ResourceInitializationException(
+ ResourceInitializationException.ERROR_INITIALIZING_FROM_DESCRIPTOR, new Object[] {
+ getMetaData().getName(), aSpecifier.getSourceUrlString() });
+ }
+ }
+
+ /**
+ * Loads, instantiates, and initializes the AnalysisComponent contained in this AE.
+ *
+ * @param aAdditionalParams
+ * parameters passed to this AE's initialize method
+ *
+ * @throws ResourceInitializationException
+ * if an initialization failure occurs
+ */
+ protected void initializeAnalysisComponent(Map aAdditionalParams)
+ throws ResourceInitializationException {
+ // instantiate Annotator class
+ String annotatorClassName;
+ annotatorClassName = mDescription.getImplementationName();
+
+ if (annotatorClassName == null || annotatorClassName.length() == 0) {
+ throw new ResourceInitializationException(
+ ResourceInitializationException.MISSING_ANNOTATOR_CLASS_NAME,
+ new Object[] { mDescription.getSourceUrlString() });
+ }
+
+ // load annotator class
+ Class annotatorClass = null;
+ try {
+ // get UIMA extension ClassLoader if available
+ ClassLoader cl = getUimaContextAdmin().getResourceManager().getExtensionClassLoader();
+
+ if (cl != null) {
+ // use UIMA extension ClassLoader to load the class
+ annotatorClass = cl.loadClass(annotatorClassName);
+ } else {
+ // use application ClassLoader to load the class
+ annotatorClass = Class.forName(annotatorClassName);
+ }
+ } catch (ClassNotFoundException e) {
+ throw new ResourceInitializationException(
+ ResourceInitializationException.ANNOTATOR_CLASS_NOT_FOUND, new Object[] {
+ annotatorClassName, mDescription.getSourceUrlString() }, e);
+ }
+
+ // Make sure the specified class can be adapter to an AnalysisComponent.
+ if (!(AnalysisComponent.class.isAssignableFrom(annotatorClass))
+ && !AnalysisComponentAdapterFactory.isAdaptable(annotatorClass)) {
+ throw new ResourceInitializationException(
+ ResourceInitializationException.NOT_AN_ANALYSIS_COMPONENT, new Object[] {
+ annotatorClass.getName(), mDescription.getSourceUrlString() });
+ }
+
+ // if we're in verification mode, stop here and do not try to instantiate the
+ // analysis component
+ if (mVerificationMode) {
+ return;
+ }
+
+ try {
+ Object userObject = annotatorClass.newInstance();
+ if (userObject instanceof AnalysisComponent) {
+ mAnalysisComponent = (AnalysisComponent) userObject;
+ } else {
+ mAnalysisComponent = AnalysisComponentAdapterFactory.createAdapter(userObject,
+ getAnalysisEngineMetaData(), aAdditionalParams);
+ }
+ } catch (ResourceInitializationException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ResourceInitializationException(
+ ResourceInitializationException.COULD_NOT_INSTANTIATE_ANNOTATOR, new Object[] {
+ annotatorClassName, mDescription.getSourceUrlString() }, e);
+ }
+
+ // Set Logger, to enable annotator-specific logging
+ UimaContextAdmin uimaContext = getUimaContextAdmin();
+ Logger logger = UIMAFramework.getLogger(annotatorClass);
+ logger.setResourceManager(this.getResourceManager());
+ uimaContext.setLogger(logger);
+
+ // initialize AnalysisComponent
+ try {
+ mAnalysisComponent.initialize(getUimaContext());
+ } catch (Exception e) {
+ throw new ResourceInitializationException(
+ ResourceInitializationException.ANNOTATOR_INITIALIZATION_FAILED, new Object[] {
+ annotatorClassName, mDescription.getSourceUrlString() }, e);
+ }
+
+ // set up the CAS pool for this AE (this won't do anything if
+ // mAnalysisComponent.getCasInstancesRequired() == 0)
+ getUimaContextAdmin().defineCasPool(mAnalysisComponent.getCasInstancesRequired(),
+ getPerformanceTuningSettings(), mSofaAware);
+ }
+
+ /**
+ * @see org.apache.uima.resource.Resource#destroy()
+ */
+ public void destroy() {
+ if (mAnalysisComponent != null) {
+ mAnalysisComponent.destroy();
+ getLogger().logrb(Level.CONFIG, CLASS_NAME.getName(), "initialize", LOG_RESOURCE_BUNDLE,
+ "UIMA_analysis_engine_destroyed__CONFIG", getMetaData().getName());
+ }
+ super.destroy();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.uima.analysis_engine.AnalysisEngine#setResultSpecification(org.apache.uima.analysis_engine.ResultSpecification)
+ */
+ public void setResultSpecification(ResultSpecification aResultSpec) {
+ if (aResultSpec == null) {
+ resetResultSpecificationToDefault();
+ } else {
+ mCurrentResultSpecification = aResultSpec;
+ mResultSpecChanged = true;
+ }
+ }
+
+ /**
+ * @see AnalysisEngine#processAndOutputNewCASes(CAS)
+ */
+ public CasIterator processAndOutputNewCASes(CAS aCAS) throws AnalysisEngineProcessException {
+ enterProcess();
+ try {
+ // make initial call to the AnalysisComponent
+ callAnalysisComponentProcess(aCAS);
+
+ // return a CasIterator that allows caller to step through the outputs
+ // of this AnalysisComponent (if any)
+ return new AnalysisComponentCasIterator(mAnalysisComponent, aCAS);
+ } finally {
+ exitProcess();
+ }
+ }
+
+ public void batchProcessComplete() throws AnalysisEngineProcessException {
+ enterBatchProcessComplete();
+ try {
+ getAnalysisComponent().batchProcessComplete();
+ } finally {
+ exitBatchProcessComplete();
+ }
+ }
+
+ public void collectionProcessComplete() throws AnalysisEngineProcessException {
+ enterCollectionProcessComplete();
+ try {
+ getAnalysisComponent().collectionProcessComplete();
+ } finally {
+ exitCollectionProcessComplete();
+ }
+ }
+
+ /**
+ * Calls the Analysis Component's process method.
+ *
+ * @param aCAS
+ * CAS to be processed by annotator
+ * @param aResultSpec
+ * result specification to be passed to annotator
+ * @param aProcessTrace
+ * keeps track of time spent in each component
+ */
+ protected void callAnalysisComponentProcess(CAS aCAS) throws AnalysisEngineProcessException {
+ // logging and instrumentation
+ String resourceName = getMetaData().getName();
+ getLogger().logrb(Level.FINE, CLASS_NAME.getName(), "process", LOG_RESOURCE_BUNDLE,
+ "UIMA_analysis_engine_process_begin__FINE", resourceName);
+ try {
+ // call Annotator's process method
+ try {
+ // set the current component info of the CAS, so that it knows the sofa
+ // mappings for the component that's about to process it
+ aCAS.setCurrentComponentInfo(getUimaContextAdmin().getComponentInfo());
+
+ // Get the right view of the CAS. Sofa-aware components get the base CAS.
+ // Sofa-unaware components get whatever is mapped to the _InitialView.
+ CAS view = ((CASImpl) aCAS).getBaseCAS();
+ if (!mSofaAware) {
+ view = aCAS.getView(CAS.NAME_DEFAULT_SOFA);
+ }
+ // now get the right interface(e.g. CAS or JCAS)
+ Class requiredInterface = mAnalysisComponent.getRequiredCasInterface();
+ AbstractCas casToPass = getCasManager().getCasInterface(view, requiredInterface);
+
+ // check if there was a change in the ResultSpecification or in
+ // the TypeSystem. If so, set the changed type system into the ResultSpecification and
+ // inform the component
+ if (mResultSpecChanged || mLastTypeSystem != view.getTypeSystem()) {
+ mLastTypeSystem = view.getTypeSystem();
+ mCurrentResultSpecification.setTypeSystem(mLastTypeSystem);
+ // the actual ResultSpec we send to the component is formed by
+ // looking at this primitive AE's declared output types and eliminiating
+ // any that are not in mCurrentResultSpecification.
+ ResultSpecification analysisComponentResultSpec = computeAnalysisComponentResultSpec(
+ mCurrentResultSpecification, getAnalysisEngineMetaData().getCapabilities());
+ mAnalysisComponent.setResultSpecification(analysisComponentResultSpec);
+ mResultSpecChanged = false;
+ }
+
+ ((CASImpl)aCAS).switchClassLoaderLockCasCL(this.getResourceManager().getExtensionClassLoader());
+
+ // call the process method
+ mAnalysisComponent.process(casToPass);
+ getMBean().incrementCASesProcessed();
+
+ //note we do not clear the CAS's currentComponentInfo at this time
+ // nor do we unlock the cas and switch it back (class loader-wise). The AnalysisComponents still
+ //can access the CAS until such time as its hasNext method returns false. Thus is is the
+ //AnalysisComponentCasIterator that knows when it is time to clear the currentComponentInfo.
+ } catch (Exception e) {
+ // catching Throwable to catch out-of-memory errors too, which are not Exceptions
+ aCAS.setCurrentComponentInfo(null);
+ ((CASImpl)aCAS).restoreClassLoaderUnlockCas();
+ if (e instanceof AnalysisEngineProcessException) {
+ throw (AnalysisEngineProcessException) e;
+ } else {
+ throw new AnalysisEngineProcessException(
+ AnalysisEngineProcessException.ANNOTATOR_EXCEPTION, null, e);
+ }
+ } catch (Error e) { // out of memory error, for instance
+ aCAS.setCurrentComponentInfo(null);
+ ((CASImpl)aCAS).restoreClassLoaderUnlockCas();
+ throw e;
+ }
+
+ // log end of event
+ getLogger().logrb(Level.FINE, CLASS_NAME.getName(), "process", LOG_RESOURCE_BUNDLE,
+ "UIMA_analysis_engine_process_end__FINE", resourceName);
+ } catch (Exception e) {
+ // log and rethrow exception
+ getLogger().log(Level.SEVERE, "", e);
+ if (e instanceof AnalysisEngineProcessException)
+ throw (AnalysisEngineProcessException) e;
+ else
+ throw new AnalysisEngineProcessException(e);
+ }
+ }
+
+ /**
+ * Creates the ResultSpecification to be passed to the AnalysisComponent. This is derived from the
+ * ResultSpec that is input to this AE (via its setResultSpecification method) by intersecting
+ * with the declared outputs of this AE, so that we never ask an AnalysisComponent to produce a
+ * result type that it does not declare in its outputs.
+ *
+ * @param currentResultSpecification
+ * the result spec passed to this AE's setResultSpecification method
+ * @param capabilities
+ * the capabilities of this AE
+ *
+ * @return a ResultSpecifciation to pass to the AnalysisComponent
+ */
+ protected ResultSpecification computeAnalysisComponentResultSpec(
+ ResultSpecification inputResultSpec, Capability[] capabilities) {
+ ResultSpecification newResultSpec = new ResultSpecification_impl(inputResultSpec.getTypeSystem());
+ List<String> languagesToAdd = new ArrayList<String>();
+
+ for (Capability capability : capabilities) {
+ TypeOrFeature[] outputs = capability.getOutputs();
+ String[] languages = capability.getLanguagesSupported();
+ if (null == languages || languages.length == 0) {
+ languages = X_UNSPECIFIED;
+ }
+
+ for (TypeOrFeature tof : outputs) {
+ String tofName = tof.getName();
+ languagesToAdd.clear();
+ for (String language : languages) {
+ if ((tof.isType() && inputResultSpec.containsType(tofName, language)) ||
+ (!tof.isType() && inputResultSpec.containsFeature(tofName, language))) {
+ languagesToAdd.add(language);
+ }
+ }
+ if (0 < languagesToAdd.size()) {
+ if (tof.isType()) {
+ newResultSpec.addResultType(tofName, tof.isAllAnnotatorFeatures(),
+ languagesToAdd.toArray(EMPTY_STRING_ARRAY));
+ } else {
+ newResultSpec.addResultFeature(tofName, languagesToAdd.toArray(EMPTY_STRING_ARRAY));
+ }
+ }
+ }
+ }
+ return newResultSpec;
+ }
+
+// for (int i = 0; i < capabilities.length; i++) {
+// Capability cap = capabilities[i];
+// TypeOrFeature[] outputs = cap.getOutputs();
+// String[] languages = cap.getLanguagesSupported();
+// if (languages.length == 0) {
+// languages = X_UNSPECIFIED;
+// }
+// for (int j = 0; j < outputs.length; j++) {
+// for (int k = 0; k < languages.length; k++) {
+// if (outputs[j].isType()
+// && inputResultSpec.containsType(outputs[j].getName(), languages[k])) {
+// newResultSpec.addResultType(outputs[j].getName(), outputs[j].isAllAnnotatorFeatures(),
+// new String[] { languages[k] });
+// } else if (!outputs[j].isType()
+// && inputResultSpec.containsFeature(outputs[j].getName(), languages[k])) {
+// newResultSpec.addResultFeature(outputs[j].getName(), new String[] { languages[k] });
+// }
+// }
+// }
+// }
+// return newResultSpec;
+// }
+
+ /**
+ * Calls the Analysis Component's next() method.
+ *
+ * @return CAS returned by the analysis component
+ */
+ protected CAS callAnalysisComponentNext() throws AnalysisEngineProcessException,
+ ResultNotSupportedException {
+ try {
+ AbstractCas absCas = mAnalysisComponent.next();
+ getMBean().incrementCASesProcessed();
+ // notify UimaContext that a CAS was returned -- it uses
+ // this information to track how many CASes the AnalysisComponent
+ // is using at any one time.
+ ((UimaContext_ImplBase) getUimaContext()).returnedCAS(absCas);
+
+ // convert back to CASImpl and then get the initial View
+ CAS casToReturn;
+ if (absCas instanceof JCas) {
+ casToReturn = ((JCas) absCas).getCas();
+ } else {
+ casToReturn = (CAS) absCas;
+ }
+ casToReturn = casToReturn.getView(CAS.NAME_DEFAULT_SOFA);
+
+ // clear the CAS's component info, since it is no longer
+ // being processed by this AnalysisComponent
+ casToReturn.setCurrentComponentInfo(null);
+ ((CASImpl)casToReturn).restoreClassLoaderUnlockCas();
+ return casToReturn;
+ } catch (Exception e) {
+ // log and rethrow exception
+ getLogger().log(Level.SEVERE, "", e);
+ if (e instanceof AnalysisEngineProcessException)
+ throw (AnalysisEngineProcessException) e;
+ else
+ throw new AnalysisEngineProcessException(e);
+ }
+ }
+
+ /**
+ * @see org.apache.uima.resource.AnalysisEngine#reconfigure()
+ */
+ public void reconfigure() throws ResourceConfigurationException {
+ // do base resource reconfiguration
+ super.reconfigure();
+
+ // inform the annotator
+ try {
+ mAnalysisComponent.reconfigure();
+ } catch (ResourceInitializationException e) {
+ throw new ResourceConfigurationException(e);
+ }
+ }
+
+ protected AnalysisComponent getAnalysisComponent() {
+ return mAnalysisComponent;
+ }
+
+ /**
+ * Implements the iterator that steps through all outputs from an AnalysisComponent.
+ */
+ class AnalysisComponentCasIterator implements CasIterator {
+ private AnalysisComponent mMyAnalysisComponent;
+ private CAS mInputCas;
+ private boolean casAvailable;
+
+ AnalysisComponentCasIterator(AnalysisComponent aAnalysisComponent, CAS aInputCas) {
+ mMyAnalysisComponent = aAnalysisComponent;
+ mInputCas = aInputCas;
+ casAvailable = false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.uima.core.CasIterator#hasNext()
+ */
+ public boolean hasNext() throws AnalysisEngineProcessException {
+ enterProcess();
+ if (casAvailable)
+ return true;
+ try {
+ casAvailable = mMyAnalysisComponent.hasNext();
+ if (!casAvailable) {
+ //when hasNext returns false, by contract the AnalysisComponent is done processing its
+ //input CAS. Now is the time to clear the currentComponentInfo to indicate that the
+ //CAS is no longer being processed.
+ mInputCas.setCurrentComponentInfo(null);
+ ((CASImpl)mInputCas).restoreClassLoaderUnlockCas();
+ }
+ return casAvailable;
+ } finally {
+ exitProcess();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.uima.core.CasIterator#next(java.lang.Class)
+ */
+ public CAS next() throws AnalysisEngineProcessException {
+ enterProcess();
+ try {
+ // Make sure that the AnalysisComponent has a next CAS to return
+ // Use the saved value so hasNext not called twice before next
+ if (!casAvailable) {
+ throw new UIMA_IllegalStateException(UIMA_IllegalStateException.NO_NEXT_CAS,
+ new Object[0]);
+ }
+ casAvailable = false;
+ // call AnalysisComponent.next method to populate CAS
+ try {
+ CAS cas = callAnalysisComponentNext();
+ // cas.setParentID(mOriginalCas.getID());
+ return cas;
+ } catch (Exception e) {
+ if (e instanceof AnalysisEngineProcessException) {
+ throw (AnalysisEngineProcessException) e;
+ }
+ throw new AnalysisEngineProcessException(e);
+ }
+ } finally {
+ exitProcess();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.uima.analysis_engine.CasIterator#release()
+ */
+ public void release() {
+ // nothing to do
+ }
+ }
+}
Modified: incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/NewlineSegmenter.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/NewlineSegmenter.java?rev=639416&r1=639415&r2=639416&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/NewlineSegmenter.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/NewlineSegmenter.java Thu Mar 20 12:19:49 2008
@@ -1,66 +1,73 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.apache.uima.analysis_engine.impl;
-
-import java.util.StringTokenizer;
-
-import org.apache.uima.analysis_component.CasMultiplier_ImplBase;
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
-import org.apache.uima.cas.AbstractCas;
-import org.apache.uima.cas.CAS;
-
-/**
- *
- */
-public class NewlineSegmenter extends CasMultiplier_ImplBase {
- StringTokenizer mStringTok;
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.analysis_component.CasSegmenter_ImplBase#process(org.apache.uima.cas.CAS)
- */
- public void process(CAS aCAS) throws AnalysisEngineProcessException {
- String doc = aCAS.getCurrentView().getDocumentText();
- mStringTok = new StringTokenizer(doc, "\n");
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.analysis_component.AnalysisComponent#hasNext()
- */
- public boolean hasNext() throws AnalysisEngineProcessException {
- return mStringTok.hasMoreTokens();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.analysis_component.AnalysisComponent#next()
- */
- public AbstractCas next() throws AnalysisEngineProcessException {
- String nextSeg = mStringTok.nextToken();
- CAS cas = (CAS) getContext().getEmptyCas(CAS.class);
- cas.getCurrentView().setDocumentText(nextSeg);
- return cas;
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.uima.analysis_engine.impl;
+
+import java.util.StringTokenizer;
+
+import org.apache.uima.analysis_component.CasMultiplier_ImplBase;
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.cas.AbstractCas;
+import org.apache.uima.cas.CAS;
+
+/**
+ *
+ */
+public class NewlineSegmenter extends CasMultiplier_ImplBase {
+ StringTokenizer mStringTok;
+ private boolean casAvailable;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.uima.analysis_component.CasSegmenter_ImplBase#process(org.apache.uima.cas.CAS)
+ */
+ public void process(CAS aCAS) throws AnalysisEngineProcessException {
+ String doc = aCAS.getCurrentView().getDocumentText();
+ mStringTok = new StringTokenizer(doc, "\n");
+ casAvailable = false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.uima.analysis_component.AnalysisComponent#hasNext()
+ */
+ public boolean hasNext() throws AnalysisEngineProcessException {
+ // Check if have already returned true without an intervening next()
+ if (casAvailable) {
+ throw new RuntimeException("CasMultiplier's hasNext() called twice");
+ }
+ return (casAvailable = mStringTok.hasMoreTokens());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.uima.analysis_component.AnalysisComponent#next()
+ */
+ public AbstractCas next() throws AnalysisEngineProcessException {
+ String nextSeg = mStringTok.nextToken();
+ CAS cas = (CAS) getContext().getEmptyCas(CAS.class);
+ cas.getCurrentView().setDocumentText(nextSeg);
+ casAvailable = false;
+ return cas;
+ }
+
+}