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 2007/03/01 20:33:37 UTC
svn commit: r513458 - in /incubator/uima/uimaj/trunk/uimaj-core/src:
main/java/org/apache/uima/analysis_engine/ main/java/org/apache/uima/flow/
main/java/org/apache/uima/flow/impl/ main/resources/org/apache/uima/
test/java/org/apache/uima/flow/ test/ja...
Author: alally
Date: Thu Mar 1 11:33:36 2007
New Revision: 513458
URL: http://svn.apache.org/viewvc?view=rev&rev=513458
Log:
Added FlowController APIs addAnalysisEngines and removeAnalysisEngines.
UIMA-327: https://issues.apache.org/jira/browse/UIMA-327
Added:
incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/flow/
incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/flow/impl/
incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/flow/impl/FixedFlowControllerTest.java
Modified:
incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/AnalysisEngineProcessException.java
incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/FlowController.java
incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/FlowController_ImplBase.java
incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/impl/FixedFlowController.java
incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/impl/FlowControllerContext_impl.java
incubator/uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties
Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/AnalysisEngineProcessException.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/AnalysisEngineProcessException.java?view=diff&rev=513458&r1=513457&r2=513458
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/AnalysisEngineProcessException.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/AnalysisEngineProcessException.java Thu Mar 1 11:33:36 2007
@@ -75,6 +75,20 @@
public static final String INCORRECT_CAS_INTERFACE = "incorrect_cas_interface";
/**
+ * Message key for a standard UIMA exception message: "The FlowController class {0} does not
+ * support the removeAnalysisEngines method. Analysis Engines cannot be dynamically removed
+ * from the flow."
+ */
+ public static final String REMOVE_AE_FROM_FLOW_NOT_SUPPORTED = "remove_ae_from_flow_not_supported";
+
+ /**
+ * Message key for a standard UIMA exception message: "The Analysis Engine(s) {0} have
+ * been removed from the flow, and the FlowController has determined the Aggregate
+ * Analysis Engine's processing can no longer continue."
+ */
+ public static final String FLOW_CANNOT_CONTINUE_AFTER_REMOVE = "flow_cannot_continue_after_remove";
+
+ /**
* Creates a new exception with a null message.
*/
public AnalysisEngineProcessException() {
Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/FlowController.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/FlowController.java?view=diff&rev=513458&r1=513457&r2=513458
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/FlowController.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/FlowController.java Thu Mar 1 11:33:36 2007
@@ -19,6 +19,8 @@
package org.apache.uima.flow;
+import java.util.Collection;
+
import org.apache.uima.UimaContext;
import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
import org.apache.uima.cas.AbstractCas;
@@ -152,4 +154,50 @@
* @return the required CAS interface. This must specify a subtype of {@link AbstractCas}.
*/
Class getRequiredCasInterface();
+
+ /**
+ * Notifies this FlowController that new Analysis Engines are now available to route CASes to.
+ * Prior to calling this method the framework will update
+ * {@link FlowControllerContext#getAnalysisEngineMetaDataMap()}
+ * with the metadata for these new Analysis Engines.
+ * <p>
+ * This FlowController is not obligated to do anything in response to this method if it does
+ * not want to consider routing CASes to the new AnalysisEngines.
+ * <p>
+ * The contract for this method is that the framework will not concurrently call any
+ * {@link Flow#next()} methods on any Flow objects produced by this FlowController, during the
+ * time between when the Analysis Engine MetaData map is updated and the time when this method
+ * completes.
+ *
+ * @param aKeys a Collection of Strings, each of which is the key of an Analysis Engine to which
+ * CASes can be routed. These are the same keys as used in
+ * {@link FlowControllerContext#getAnalysisEngineMetaDataMap()}.
+ */
+ void addAnalysisEngines(Collection aKeys);
+
+ /**
+ * Notifies this FlowController that some Analysis Engines are no longer available to route CASes to.
+ * Prior to calling this method the framework will update
+ * {@link FlowControllerContext#getAnalysisEngineMetaDataMap()}
+ * and will remove the metadata for these new Analysis Engines.
+ * <p>
+ * It is not required for a FlowController implementation to support this method. It may throw
+ * an exception if this operation is not supported
+ * (see {@link AnalysisEngineProcessException#REMOVE_AE_FROM_FLOW_NOT_SUPPORTED}.
+ * Also the FlowController may throw an Exception if it determines that it does not make sense for
+ * the flow to continue in the absence of the removed Analysis Engines
+ * (see {@link AnalysisEngineProcessException#FLOW_CANNOT_CONTINUE_AFTER_REMOVE}.
+ * <p>
+ * The contract for this method is that the framework will not concurrently call any
+ * {@link Flow#next()} methods on any Flow objects produced by this FlowController, during the
+ * time between when the Analysis Engine MetaData map is updated and the time when this method
+ * completes.
+ *
+ * @param aKeys a Collection of Strings, each of which is the key of an Analysis Engine to which CASes
+ * may no longer be routed.
+ *
+ * @throws AnalysisEngineProcessException if the FlowController cannot continue with these
+ * Analysis Engines removed, or doesn't support removing Analysis Engines at all.
+ */
+ void removeAnalysisEngines(Collection aKeys) throws AnalysisEngineProcessException;
}
Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/FlowController_ImplBase.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/FlowController_ImplBase.java?view=diff&rev=513458&r1=513457&r2=513458
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/FlowController_ImplBase.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/FlowController_ImplBase.java Thu Mar 1 11:33:36 2007
@@ -19,6 +19,8 @@
package org.apache.uima.flow;
+import java.util.Collection;
+
import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
import org.apache.uima.resource.ResourceConfigurationException;
import org.apache.uima.resource.ResourceInitializationException;
@@ -81,6 +83,28 @@
* @see org.apache.uima.flow.FlowController#destroy()
*/
public void destroy() {
+ }
+
+
+
+ /**
+ * Does nothing by default. Subclasses may override this to support adding new
+ * AnalysisEngines to the flow.
+ * @see org.apache.uima.flow.FlowController#addAnalysisEngines(java.util.Collection)
+ */
+ public void addAnalysisEngines(Collection aKeys) {
+ //does nothing by default
+ }
+
+ /**
+ * Throws an AnalysisEngineProcessException by default. Subclasses may override
+ * this to support removing AnalysisEngines from the flow.
+ * @see org.apache.uima.flow.FlowController#removeAnalysisEngines(java.util.Collection)
+ */
+ public void removeAnalysisEngines(Collection aKeys) throws AnalysisEngineProcessException {
+ throw new AnalysisEngineProcessException(
+ AnalysisEngineProcessException.REMOVE_AE_FROM_FLOW_NOT_SUPPORTED,
+ new Object[] { getClass().getName() });
}
/**
Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/impl/FixedFlowController.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/impl/FixedFlowController.java?view=diff&rev=513458&r1=513457&r2=513458
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/impl/FixedFlowController.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/impl/FixedFlowController.java Thu Mar 1 11:33:36 2007
@@ -21,6 +21,9 @@
import java.io.IOException;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import org.apache.uima.UIMAFramework;
import org.apache.uima.UIMARuntimeException;
@@ -59,14 +62,15 @@
private static final int ACTION_DROP_IF_NEW_CAS_PRODUCED = 3;
- private String[] mSequence;
+ private ArrayList mSequence;
private int mActionAfterCasMultiplier;
public void initialize(FlowControllerContext aContext) throws ResourceInitializationException {
super.initialize(aContext);
FlowConstraints flowConstraints = aContext.getAggregateMetadata().getFlowConstraints();
- mSequence = ((FixedFlow) flowConstraints).getFixedFlow();
+ mSequence = new ArrayList();
+ mSequence.addAll(Arrays.asList(((FixedFlow) flowConstraints).getFixedFlow()));
String actionAfterCasMultiplier = (String) aContext
.getConfigParameterValue(PARAM_ACTION_AFTER_CAS_MULTIPLIER);
@@ -93,6 +97,22 @@
public Flow computeFlow(CAS aCAS) throws AnalysisEngineProcessException {
return new FixedFlowObject(0);
}
+
+ /* (non-Javadoc)
+ * @see org.apache.uima.flow.FlowController_ImplBase#addAnalysisEngines(java.util.Collection)
+ */
+ public void addAnalysisEngines(Collection aKeys) {
+ // Append new keys to end of Sequence
+ mSequence.addAll(aKeys);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.uima.flow.FlowController_ImplBase#removeAnalysisEngines(java.util.Collection)
+ */
+ public void removeAnalysisEngines(Collection aKeys) throws AnalysisEngineProcessException {
+ //Remove keys from Sequence
+ mSequence.removeAll(aKeys);
+ }
public static FlowControllerDescription getDescription() {
URL descUrl = FixedFlowController.class
@@ -170,19 +190,19 @@
casMultiplierProducedNewCas = false;
}
- if (currentStep >= mSequence.length) {
+ if (currentStep >= mSequence.size()) {
return new FinalStep(); // this CAS has finished the sequence
}
// if next step is a CasMultiplier, set wasPassedToCasMultiplier to true for next time
// TODO: optimize
AnalysisEngineMetaData md = (AnalysisEngineMetaData) getContext()
- .getAnalysisEngineMetaDataMap().get(mSequence[currentStep]);
+ .getAnalysisEngineMetaDataMap().get(mSequence.get(currentStep));
if (md.getOperationalProperties().getOutputsNewCASes())
wasPassedToCasMultiplier = true;
// now send the CAS to the next AE in sequence.
- return new SimpleStep(mSequence[currentStep++]);
+ return new SimpleStep((String)mSequence.get(currentStep++));
}
/*
@@ -195,7 +215,7 @@
casMultiplierProducedNewCas = true;
// start the new output CAS from the next node after the CasMultiplier that produced it
int i = 0;
- while (!mSequence[i].equals(producedBy))
+ while (!mSequence.get(i).equals(producedBy))
i++;
return new FixedFlowObject(i + 1, true);
}
Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/impl/FlowControllerContext_impl.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/impl/FlowControllerContext_impl.java?view=diff&rev=513458&r1=513457&r2=513458
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/impl/FlowControllerContext_impl.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/flow/impl/FlowControllerContext_impl.java Thu Mar 1 11:33:36 2007
@@ -19,6 +19,7 @@
package org.apache.uima.flow.impl;
+import java.util.Collections;
import java.util.Map;
import org.apache.uima.UimaContextAdmin;
@@ -46,7 +47,7 @@
Map aSofaMappings, Map aAnalysisEngineMetaDataMap,
AnalysisEngineMetaData aAggregateMetadata) {
super(aParentContext, aContextName, aSofaMappings);
- mAnalysisEngineMetaDataMap = aAnalysisEngineMetaDataMap;
+ mAnalysisEngineMetaDataMap = Collections.unmodifiableMap(aAnalysisEngineMetaDataMap);
mAggregateMetadata = aAggregateMetadata;
// add our MBean to the tree
Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties?view=diff&rev=513458&r1=513457&r2=513458
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties Thu Mar 1 11:33:36 2007
@@ -181,6 +181,13 @@
incorrect_cas_interface = Expected CAS interface {0}, but received interface {1}.
+remove_ae_from_flow_not_supported = The FlowController class {0} does not support the removeAnalysisEngines method. \
+ Analysis Engines cannot be dynamically removed from the flow.
+
+flow_cannot_continue_after_remove = The Analysis Engine(s) {0} have been removed from the flow, and the FlowController \
+ has determined that the Aggregate Analysis Engine's processing can no longer continue.
+
+
#-------------------------------
#ResourceInitializationException
#-------------------------------
Added: incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/flow/impl/FixedFlowControllerTest.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/flow/impl/FixedFlowControllerTest.java?view=auto&rev=513458
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/flow/impl/FixedFlowControllerTest.java (added)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/flow/impl/FixedFlowControllerTest.java Thu Mar 1 11:33:36 2007
@@ -0,0 +1,212 @@
+/*
+ * 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.flow.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.UimaContextAdmin;
+import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData;
+import org.apache.uima.analysis_engine.metadata.FixedFlow;
+import org.apache.uima.analysis_engine.metadata.impl.AnalysisEngineMetaData_impl;
+import org.apache.uima.analysis_engine.metadata.impl.FixedFlow_impl;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.flow.FinalStep;
+import org.apache.uima.flow.Flow;
+import org.apache.uima.flow.FlowControllerContext;
+import org.apache.uima.flow.SimpleStep;
+import org.apache.uima.flow.Step;
+import org.apache.uima.resource.metadata.OperationalProperties;
+import org.apache.uima.resource.metadata.impl.OperationalProperties_impl;
+import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl;
+import org.apache.uima.util.CasCreationUtils;
+
+/**
+ *
+ */
+public class FixedFlowControllerTest extends TestCase {
+
+ private Map analysisEngineMetaDataMap;
+ private FixedFlowController fixedFlowController;
+
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ analysisEngineMetaDataMap = new HashMap();
+ AnalysisEngineMetaData delegateMd = new AnalysisEngineMetaData_impl();
+ delegateMd.setOperationalProperties(new OperationalProperties_impl());
+ analysisEngineMetaDataMap.put("key1", delegateMd);
+ analysisEngineMetaDataMap.put("key2", delegateMd);
+ analysisEngineMetaDataMap.put("key3", delegateMd);
+
+ AnalysisEngineMetaData aggregateMd = new AnalysisEngineMetaData_impl();
+ FixedFlow fixedFlow = new FixedFlow_impl();
+ fixedFlow.setFixedFlow(new String[]{"key1", "key2", "key3"});
+ aggregateMd.setFlowConstraints(fixedFlow);
+ OperationalProperties opProps = new OperationalProperties_impl();
+ aggregateMd.setOperationalProperties(opProps);
+
+ UimaContextAdmin rootContext = UIMAFramework.newUimaContext(
+ UIMAFramework.getLogger(), UIMAFramework.newDefaultResourceManager(),
+ UIMAFramework.newConfigurationManager());
+ FlowControllerContext fcContext = new FlowControllerContext_impl(
+ rootContext, "_FlowController", Collections.EMPTY_MAP,
+ analysisEngineMetaDataMap, aggregateMd);
+ fixedFlowController = new FixedFlowController();
+ fixedFlowController.initialize(fcContext);
+ }
+
+ public void testComputeFlow() throws Exception {
+ CAS cas1 = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null);
+ CAS cas2 = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null);
+ Flow flow1 = fixedFlowController.computeFlow(cas1);
+ Flow flow2 = fixedFlowController.computeFlow(cas2);
+ //two steps in flow 1
+ Step step = flow1.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow1.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key2", ((SimpleStep)step).getAnalysisEngineKey());
+
+ //one step in flow 2
+ step = flow2.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey());
+
+ //third step in flow 1
+ step = flow1.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey());
+
+ //one step in flow 2
+ step = flow2.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key2", ((SimpleStep)step).getAnalysisEngineKey());
+
+ //finish flow 1
+ step = flow1.next();
+ assertTrue(step instanceof FinalStep);
+
+ //finish flow 2
+ step = flow2.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow2.next();
+ assertTrue(step instanceof FinalStep);
+ }
+
+ public void testAddAnalysisEngines() throws Exception {
+ CAS cas = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null);
+ Flow flow = fixedFlowController.computeFlow(cas);
+ //two steps in flow
+ Step step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key2", ((SimpleStep)step).getAnalysisEngineKey());
+
+ //now add two new AEs
+ //first update AE metadata map
+ AnalysisEngineMetaData delegateMd = new AnalysisEngineMetaData_impl();
+ delegateMd.setOperationalProperties(new OperationalProperties_impl());
+ analysisEngineMetaDataMap.put("key4", delegateMd);
+ analysisEngineMetaDataMap.put("key5", delegateMd);
+ //then notify FC
+ List newAeKeys = new ArrayList();
+ newAeKeys.add("key4");
+ newAeKeys.add("key5");
+ fixedFlowController.addAnalysisEngines(newAeKeys);
+
+ //finish flow
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key4", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key5", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof FinalStep);
+
+ //test new flow
+ flow = fixedFlowController.computeFlow(cas);
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key2", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key4", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key5", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof FinalStep);
+ }
+
+ public void testRemoveAnalysisEngines() throws Exception {
+ CAS cas = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null);
+ Flow flow = fixedFlowController.computeFlow(cas);
+ //one step in flow
+ Step step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey());
+
+ //remove "key2"
+ analysisEngineMetaDataMap.remove("key2");
+ List removedKeys = new ArrayList();
+ removedKeys.add("key2");
+ fixedFlowController.removeAnalysisEngines(removedKeys);
+
+ //finish flow
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof FinalStep);
+
+ //test new flow
+ flow = fixedFlowController.computeFlow(cas);
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof SimpleStep);
+ assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey());
+ step = flow.next();
+ assertTrue(step instanceof FinalStep);
+ }
+}