You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by al...@apache.org on 2006/11/23 00:00:06 UTC

svn commit: r478362 - in /incubator/uima/uimaj/trunk/uimaj-examples/src/main: descriptors/cas_multiplier/ java/org/apache/uima/examples/ java/org/apache/uima/examples/casMultiplier/ resources/org/apache/uima/examples/

Author: alally
Date: Wed Nov 22 15:00:05 2006
New Revision: 478362

URL: http://svn.apache.org/viewvc?view=rev&rev=478362
Log:
UIMA-66: created example SimpleTextMerger

Added:
    incubator/uima/uimaj/trunk/uimaj-examples/src/main/descriptors/cas_multiplier/Segment_Annotate_Merge_AE.xml
    incubator/uima/uimaj/trunk/uimaj-examples/src/main/descriptors/cas_multiplier/SimpleTextMerger.xml
    incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/casMultiplier/SimpleTextMerger.java
Modified:
    incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/SourceDocumentInformation.java
    incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/SourceDocumentInformation_Type.java
    incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/casMultiplier/SimpleTextSegmenter.java
    incubator/uima/uimaj/trunk/uimaj-examples/src/main/resources/org/apache/uima/examples/SourceDocumentInformation.xml

Added: incubator/uima/uimaj/trunk/uimaj-examples/src/main/descriptors/cas_multiplier/Segment_Annotate_Merge_AE.xml
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-examples/src/main/descriptors/cas_multiplier/Segment_Annotate_Merge_AE.xml?view=auto&rev=478362
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-examples/src/main/descriptors/cas_multiplier/Segment_Annotate_Merge_AE.xml (added)
+++ incubator/uima/uimaj/trunk/uimaj-examples/src/main/descriptors/cas_multiplier/Segment_Annotate_Merge_AE.xml Wed Nov 22 15:00:05 2006
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+***************************************************************
+* 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.
+***************************************************************
+-->
+<analysisEngineDescription xmlns="http://uima.watson.ibm.com/resourceSpecifier">
+	<frameworkImplementation>org.apache.uima.java</frameworkImplementation>
+	<primitive>false</primitive>
+	
+	<delegateAnalysisEngineSpecifiers>
+		<delegateAnalysisEngine key="Segmenter">
+			<import location="SimpleTextSegmenter.xml"/>
+		</delegateAnalysisEngine>
+		
+		<delegateAnalysisEngine key="Tokenizer">
+			<import
+				location="../analysis_engine/SimpleTokenAndSentenceAnnotator.xml"/>
+		</delegateAnalysisEngine>
+		
+		<delegateAnalysisEngine key="NameRecognizer">
+			<import
+				location="../analysis_engine/SimpleNameRecognizer_RegEx_TAE.xml"/>
+		</delegateAnalysisEngine>
+		
+		<delegateAnalysisEngine key="Merger">
+			<import location="SimpleTextMerger.xml"/>
+		</delegateAnalysisEngine>
+	</delegateAnalysisEngineSpecifiers>
+	
+	<analysisEngineMetaData>
+		<name>Segment, Annotate, and Merge Example AE</name>
+		<description>Splits a document into pieces and runs the tokenizer and name
+			recognizer on each piece independently. Then runs the merger to reassemble the
+			document, keeping the name annotations in the merged document but discarding
+			the tokens. 
+		
+		    TODO: we should use a custom flow controller to drop the segments that are merged,
+			so that they are not output from the aggregate.  Then the aggregate would take one
+			CAS in and produce one CAS as output.
+		</description>
+		<version>1.0</version>
+		<vendor>The Apache Software Foundation</vendor>
+		<flowConstraints>
+			<fixedFlow>
+				<node>Segmenter</node>
+				<node>Tokenizer</node>
+				<node>NameRecognizer</node>
+				<node>Merger</node>
+			</fixedFlow>
+		</flowConstraints>
+		
+		<configurationParameters>
+			<configurationParameter>
+				<name>AnnotationTypesToPreserve</name>
+				<description>Names of annotation types to be preserved in the merged CAS.</description>
+				<type>String</type>
+				<multiValued>true</multiValued>
+				<mandatory>true</mandatory>
+				<overrides>
+					<parameter>Merger/AnnotationTypesToCopy</parameter>
+				</overrides>
+			</configurationParameter>
+		</configurationParameters>
+		<configurationParameterSettings>
+			<nameValuePair>
+				<name>AnnotationTypesToPreserve</name>
+				<value>
+					<array>
+						<string>example.Name</string>
+					</array>
+				</value>
+			</nameValuePair>
+		</configurationParameterSettings>
+		
+		<capabilities>
+			<capability>
+				<inputs/>
+				<outputs>
+					<type allAnnotatorFeatures="true">
+						org.apache.uima.examples.tokenizer.Sentence</type>
+					<type allAnnotatorFeatures="true">
+						org.apache.uima.examples.tokenizer.Token</type>
+					<type allAnnotatorFeatures="true">example.Name</type>
+				</outputs>
+				<languagesSupported>
+					<language>en</language>
+				</languagesSupported>
+			</capability>
+		</capabilities>
+		<operationalProperties>
+			<modifiesCas>true</modifiesCas>
+			<multipleDeploymentAllowed>true</multipleDeploymentAllowed>
+			<outputsNewCASes>true</outputsNewCASes>
+		</operationalProperties>
+	</analysisEngineMetaData>
+</analysisEngineDescription>
\ No newline at end of file

Added: incubator/uima/uimaj/trunk/uimaj-examples/src/main/descriptors/cas_multiplier/SimpleTextMerger.xml
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-examples/src/main/descriptors/cas_multiplier/SimpleTextMerger.xml?view=auto&rev=478362
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-examples/src/main/descriptors/cas_multiplier/SimpleTextMerger.xml (added)
+++ incubator/uima/uimaj/trunk/uimaj-examples/src/main/descriptors/cas_multiplier/SimpleTextMerger.xml Wed Nov 22 15:00:05 2006
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" ?> 
+<!--
+***************************************************************
+* 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.
+***************************************************************
+-->
+
+<analysisEngineDescription xmlns="http://uima.watson.ibm.com/resourceSpecifier">
+<frameworkImplementation>org.apache.uima.java</frameworkImplementation>
+<primitive>true</primitive>
+<annotatorImplementationName>org.apache.uima.examples.casMultiplier.SimpleTextMerger</annotatorImplementationName>
+ 
+<analysisEngineMetaData>
+	<name>Simple Text Merger</name>
+	<description>Merges text documents into larger ones.</description>
+	<version>1.0</version>
+	<vendor>The Apache Software Foundation</vendor>
+
+	<configurationParameters>
+		<configurationParameter>
+			<name>AnnotationTypesToCopy</name>
+			<description>Names of annotation types to be copied from source CASes into the merged CAS.</description>
+			<type>String</type>
+			<multiValued>true</multiValued>
+			<mandatory>true</mandatory>
+		</configurationParameter>
+	</configurationParameters>
+	<configurationParameterSettings>
+		<nameValuePair>
+			<name>AnnotationTypesToCopy</name>
+			<value>
+				<array/>
+			</value>
+		</nameValuePair>
+	</configurationParameterSettings>
+
+	<typeSystemDescription>
+	  <imports>
+		<import name="org.apache.uima.examples.SourceDocumentInformation"/>
+	  </imports>
+	</typeSystemDescription>
+		
+	<capabilities>
+		<capability>
+			<outputs/>
+		</capability>
+	</capabilities>
+	
+	<operationalProperties>
+		<modifiesCas>false</modifiesCas>
+		<multipleDeploymentAllowed>true</multipleDeploymentAllowed>
+		<outputsNewCASes>true</outputsNewCASes>
+	</operationalProperties>
+	
+</analysisEngineMetaData>
+</analysisEngineDescription>
\ No newline at end of file

Modified: incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/SourceDocumentInformation.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/SourceDocumentInformation.java?view=diff&rev=478362&r1=478361&r2=478362
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/SourceDocumentInformation.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/SourceDocumentInformation.java Wed Nov 22 15:00:05 2006
@@ -26,7 +26,8 @@
 
 
 /** Stores detailed information about the original source document from which the current CAS was initialized. All information (like size) refers to the source document and not to the document in the CAS which may be converted and filtered by a CAS Initializer. For example this information will be written to the Semantic Search index so that the original document contents can be retrieved by queries.
- * Updated by JCasGen Thu Dec 02 11:37:07 EST 2004
+ * Updated by JCasGen Wed Nov 22 16:51:13 EST 2006
+ * XML source: C:/alally/dev/workspace_apache/uimaj-examples/src/main/resources/org/apache/uima/examples/SourceDocumentInformation.xml
  * @generated */
 public class SourceDocumentInformation extends Annotation {
   /** @generated
@@ -57,6 +58,7 @@
     readObject();   
   } 
   
+  /** @generated */
   public SourceDocumentInformation(JCas jcas, int begin, int end) {
     super(jcas);
     setBegin(begin);
@@ -82,7 +84,7 @@
       JCas.throwFeatMissing("uri", "org.apache.uima.examples.SourceDocumentInformation");
     return jcasType.ll_cas.ll_getStringValue(addr, ((SourceDocumentInformation_Type)jcasType).casFeatCode_uri);}
     
-  /** setter for uri - sets URI of document. (For example, file:///MyDirectory/myFile.txt for a simple file or http://incubator.apache.org/uima/index.html for content from a web source) 
+  /** setter for uri - sets URI of document. (For example, file:///MyDirectory/myFile.txt for a simple file or http://incubator.apache.org/uima/index.html for content from a web source.) 
    * @generated */
   public void setUri(String v) {
     if (SourceDocumentInformation_Type.featOkTst && ((SourceDocumentInformation_Type)jcasType).casFeat_uri == null)
@@ -124,6 +126,24 @@
     if (SourceDocumentInformation_Type.featOkTst && ((SourceDocumentInformation_Type)jcasType).casFeat_documentSize == null)
       JCas.throwFeatMissing("documentSize", "org.apache.uima.examples.SourceDocumentInformation");
     jcasType.ll_cas.ll_setIntValue(addr, ((SourceDocumentInformation_Type)jcasType).casFeatCode_documentSize, v);}    
+   
+    
+  //*--------------*
+  //* Feature: lastSegment
+
+  /** getter for lastSegment - gets For a CAS that represents a segment of a larger source document, this flag indicates whether this CAS is the final segment of the source document.  This is useful for downstream components that want to take some action after having seen all of the segments of a particular source document.
+   * @generated */
+  public boolean getLastSegment() {
+    if (SourceDocumentInformation_Type.featOkTst && ((SourceDocumentInformation_Type)jcasType).casFeat_lastSegment == null)
+      JCas.throwFeatMissing("lastSegment", "org.apache.uima.examples.SourceDocumentInformation");
+    return jcasType.ll_cas.ll_getBooleanValue(addr, ((SourceDocumentInformation_Type)jcasType).casFeatCode_lastSegment);}
+    
+  /** setter for lastSegment - sets For a CAS that represents a segment of a larger source document, this flag indicates whether this CAS is the final segment of the source document.  This is useful for downstream components that want to take some action after having seen all of the segments of a particular source document. 
+   * @generated */
+  public void setLastSegment(boolean v) {
+    if (SourceDocumentInformation_Type.featOkTst && ((SourceDocumentInformation_Type)jcasType).casFeat_lastSegment == null)
+      JCas.throwFeatMissing("lastSegment", "org.apache.uima.examples.SourceDocumentInformation");
+    jcasType.ll_cas.ll_setBooleanValue(addr, ((SourceDocumentInformation_Type)jcasType).casFeatCode_lastSegment, v);}    
   }
 
-    
+    
\ No newline at end of file

Modified: incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/SourceDocumentInformation_Type.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/SourceDocumentInformation_Type.java?view=diff&rev=478362&r1=478361&r2=478362
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/SourceDocumentInformation_Type.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/SourceDocumentInformation_Type.java Wed Nov 22 15:00:05 2006
@@ -30,7 +30,7 @@
 import org.apache.uima.jcas.tcas.Annotation_Type;
 
 /** Stores detailed information about the original source document from which the current CAS was initialized. All information (like size) refers to the source document and not to the document in the CAS which may be converted and filtered by a CAS Initializer. For example this information will be written to the Semantic Search index so that the original document contents can be retrieved by queries.
- * Updated by JCasGen Thu Dec 02 11:37:08 EST 2004
+ * Updated by JCasGen Wed Nov 22 16:51:13 EST 2006
  * @generated */
 public class SourceDocumentInformation_Type extends Annotation_Type {
   /** @generated */
@@ -39,20 +39,20 @@
   private final FSGenerator fsGenerator = 
     new FSGenerator() {
       public FeatureStructure createFS(int addr, CASImpl cas) {
-  			 if (instanceOf_Type.useExistingInstance) {
+  			 if (SourceDocumentInformation_Type.this.useExistingInstance) {
   			   // Return eq fs instance if already created
-  		     FeatureStructure fs = instanceOf_Type.jcas.getJfsFromCaddr(addr);
+  		     FeatureStructure fs = SourceDocumentInformation_Type.this.jcas.getJfsFromCaddr(addr);
   		     if (null == fs) {
-  		       fs = new SourceDocumentInformation(addr, instanceOf_Type);
-  			   instanceOf_Type.jcas.putJfsFromCaddr(addr, fs);
+  		       fs = new SourceDocumentInformation(addr, SourceDocumentInformation_Type.this);
+  			   SourceDocumentInformation_Type.this.jcas.putJfsFromCaddr(addr, fs);
   			   return fs;
   		     }
   		     return fs;
-        } else return new SourceDocumentInformation(addr, instanceOf_Type);
+        } else return new SourceDocumentInformation(addr, SourceDocumentInformation_Type.this);
   	  }
     };
   /** @generated */
-  public final static int typeIndexID = SourceDocumentInformation.type;
+  public final static int typeIndexID = SourceDocumentInformation.typeIndexID;
   /** @generated 
      @modifiable */
   public final static boolean featOkTst = JCas.getFeatOkTst("org.apache.uima.examples.SourceDocumentInformation");
@@ -110,6 +110,24 @@
     ll_cas.ll_setIntValue(addr, casFeatCode_documentSize, v);}
     
   
+ 
+  /** @generated */
+  final Feature casFeat_lastSegment;
+  /** @generated */
+  final int     casFeatCode_lastSegment;
+  /** @generated */ 
+  public boolean getLastSegment(int addr) {
+        if (featOkTst && casFeat_lastSegment == null)
+      JCas.throwFeatMissing("lastSegment", "org.apache.uima.examples.SourceDocumentInformation");
+    return ll_cas.ll_getBooleanValue(addr, casFeatCode_lastSegment);
+  }
+  /** @generated */    
+  public void setLastSegment(int addr, boolean v) {
+        if (featOkTst && casFeat_lastSegment == null)
+      JCas.throwFeatMissing("lastSegment", "org.apache.uima.examples.SourceDocumentInformation");
+    ll_cas.ll_setBooleanValue(addr, casFeatCode_lastSegment, v);}
+    
+  
 
 
   /** initialize variables to correspond with Cas Type and Features
@@ -130,9 +148,13 @@
     casFeat_documentSize = jcas.getRequiredFeatureDE(casType, "documentSize", "uima.cas.Integer", featOkTst);
     casFeatCode_documentSize  = (null == casFeat_documentSize) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl)casFeat_documentSize).getCode();
 
+ 
+    casFeat_lastSegment = jcas.getRequiredFeatureDE(casType, "lastSegment", "uima.cas.Boolean", featOkTst);
+    casFeatCode_lastSegment  = (null == casFeat_lastSegment) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl)casFeat_lastSegment).getCode();
+
   }
 }
 
 
 
-    
+    
\ No newline at end of file

Added: incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/casMultiplier/SimpleTextMerger.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/casMultiplier/SimpleTextMerger.java?view=auto&rev=478362
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/casMultiplier/SimpleTextMerger.java (added)
+++ incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/casMultiplier/SimpleTextMerger.java Wed Nov 22 15:00:05 2006
@@ -0,0 +1,158 @@
+/*
+ * 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.examples.casMultiplier;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.uima.UimaContext;
+import org.apache.uima.analysis_component.JCasMultiplier_ImplBase;
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.cas.AbstractCas;
+import org.apache.uima.cas.FSIndex;
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.FeatureStructure;
+import org.apache.uima.cas.Type;
+import org.apache.uima.examples.SourceDocumentInformation;
+import org.apache.uima.jcas.impl.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.util.CasCopier;
+
+/**
+ * An example CasMultiplier, which merges text documents into larger ones.
+ * It attempts to merge all of the segments that came from one original artifact.
+ * This is done by checking the "lastSegment" feature of the SourceDocumentInformation
+ * FeatureStructure, which is expected to be populated by the CollectionReader
+ * or CasMultiplier that produced the input CASes.
+ * <p>
+ * Limitations:  if the lastSegment feature is never set to true by the component producing
+ * the input CASes, the merger will never produce any output.  Also, this implementation
+ * relies on the CASes arriving in order, which could be a problem in a 
+ * mulithreaded framework implementation.  The order requirement could be relieved by recording
+ * a segment number in the SourceDocumentInformation, but that would also make this example
+ * more complicated. 
+ */
+public class SimpleTextMerger extends JCasMultiplier_ImplBase {
+  private StringBuffer mDocBuf = new StringBuffer();
+
+  private JCas mMergedCas;
+
+  private boolean mReadyToOutput = false;
+
+  private String[] mAnnotationTypesToCopy;
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.analysis_component.AnalysisComponent_ImplBase#initialize(org.apache.uima.UimaContext)
+   */
+  public void initialize(UimaContext aContext) throws ResourceInitializationException {
+    super.initialize(aContext);
+    mAnnotationTypesToCopy = (String[]) aContext.getConfigParameterValue("AnnotationTypesToCopy");
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see JCasMultiplier_ImplBase#process(JCas)
+   */
+  public void process(JCas aJCas) throws AnalysisEngineProcessException {
+    // procure a new CAS if we don't have one already
+    if (mMergedCas == null) {
+      mMergedCas = getEmptyJCas();
+    }
+
+    // append document text
+    String docText = aJCas.getDocumentText();
+    int prevDocLen = mDocBuf.length();
+    mDocBuf.append(docText);
+
+    // copy specified annotation types
+    CasCopier copier = new CasCopier(mMergedCas.getCas());
+    Set copiedIndexedFs = new HashSet(); // needed in case one annotation is in two indexes (could
+                                          // happen if specified annotation types overlap)
+    for (int i = 0; i < mAnnotationTypesToCopy.length; i++) {
+      Type type = mMergedCas.getTypeSystem().getType(mAnnotationTypesToCopy[i]);
+      FSIndex index = aJCas.getCas().getAnnotationIndex(type);
+      Iterator iter = index.iterator();
+      while (iter.hasNext()) {
+        FeatureStructure fs = (FeatureStructure) iter.next();
+        if (!copiedIndexedFs.contains(fs)) {
+          Annotation copyOfFs = (Annotation) copier.copyFs(fs);
+          // update begin and end
+          copyOfFs.setBegin(copyOfFs.getBegin() + prevDocLen);
+          copyOfFs.setEnd(copyOfFs.getEnd() + prevDocLen);
+          mMergedCas.addFsToIndexes(copyOfFs);
+          copiedIndexedFs.add(fs);
+        }
+      }
+    }
+
+    // get the SourceDocumentInformation FS, which indicates the sourceURI of the document
+    // and whether the incoming CAS is the last segment
+    FSIterator it = aJCas.getJFSIndexRepository()
+                    .getAnnotationIndex(SourceDocumentInformation.type).iterator();
+    if (!it.hasNext()) {
+      throw new RuntimeException("Missing SourceDocumentInformation"); 
+    }
+    SourceDocumentInformation sourceDocInfo = (SourceDocumentInformation) it.next();
+    if (sourceDocInfo.getLastSegment()) {
+      // time to produce an output CAS
+      // set the document text
+      mMergedCas.setDocumentText(mDocBuf.toString());
+
+      // add source document info to destination CAS
+      SourceDocumentInformation destSDI = new SourceDocumentInformation(mMergedCas);
+      destSDI.setUri(sourceDocInfo.getUri());
+      destSDI.setOffsetInSource(0);
+      destSDI.setLastSegment(true);
+      destSDI.addToIndexes();
+
+      mDocBuf = new StringBuffer();
+      mReadyToOutput = true;
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.analysis_component.AnalysisComponent#hasNext()
+   */
+  public boolean hasNext() throws AnalysisEngineProcessException {
+    return mReadyToOutput;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.analysis_component.AnalysisComponent#next()
+   */
+  public AbstractCas next() throws AnalysisEngineProcessException {
+    if (!mReadyToOutput) {
+      throw new RuntimeException("No next CAS"); 
+    }
+    JCas casToReturn = mMergedCas;
+    mMergedCas = null;
+    mReadyToOutput = false;
+    return casToReturn;
+  }
+
+}

Modified: incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/casMultiplier/SimpleTextSegmenter.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/casMultiplier/SimpleTextSegmenter.java?view=diff&rev=478362&r1=478361&r2=478362
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/casMultiplier/SimpleTextSegmenter.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/casMultiplier/SimpleTextSegmenter.java Wed Nov 22 15:00:05 2006
@@ -110,6 +110,10 @@
         sdi.setOffsetInSource(mPos);
         sdi.setDocumentSize(breakAt - mPos);
         sdi.addToIndexes();
+
+        if (breakAt == mDoc.length()) {
+          sdi.setLastSegment(true);
+        }
       }
 
       mPos = breakAt;

Modified: incubator/uima/uimaj/trunk/uimaj-examples/src/main/resources/org/apache/uima/examples/SourceDocumentInformation.xml
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-examples/src/main/resources/org/apache/uima/examples/SourceDocumentInformation.xml?view=diff&rev=478362&r1=478361&r2=478362
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-examples/src/main/resources/org/apache/uima/examples/SourceDocumentInformation.xml (original)
+++ incubator/uima/uimaj/trunk/uimaj-examples/src/main/resources/org/apache/uima/examples/SourceDocumentInformation.xml Wed Nov 22 15:00:05 2006
@@ -47,6 +47,11 @@
 					<description>Size of original document in bytes before processing by CAS Initializer. Either absolute file size of size within file or other source.</description>
 					<rangeTypeName>uima.cas.Integer</rangeTypeName>
 				</featureDescription>
+				<featureDescription>
+				  <name>lastSegment</name>
+				  <description>For a CAS that represents a segment of a larger source document, this flag indicates whether this CAS is the final segment of the source document.  This is useful for downstream components that want to take some action after having seen all of the segments of a particular source document. </description>
+			      <rangeTypeName>uima.cas.Boolean</rangeTypeName>
+			    </featureDescription>				
 			</features>
 		</typeDescription>
 	</types>