blob: 62b3a70324538e0d0f5780996e13e4fcb2491d03 [file] [log] [blame]
/*
* 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.asb.impl;
import java.util.Collection;
import java.util.Map;
import org.apache.uima.Constants;
import org.apache.uima.UIMAFramework;
import org.apache.uima.UimaContextAdmin;
import org.apache.uima.analysis_engine.AnalysisEngine;
import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
import org.apache.uima.analysis_engine.impl.AnalysisEngineManagementImpl;
import org.apache.uima.cas.AbstractCas;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.impl.CASImpl;
import org.apache.uima.flow.Flow;
import org.apache.uima.flow.FlowController;
import org.apache.uima.flow.FlowControllerContext;
import org.apache.uima.flow.FlowControllerDescription;
import org.apache.uima.internal.util.JmxMBeanAgent;
import org.apache.uima.resource.ConfigurableResource_ImplBase;
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.ProcessingResourceMetaData;
import org.apache.uima.util.Logger;
import org.apache.uima.util.UimaTimer;
/**
* Container for a FlowController. Manages configuration parameters, resources, CAS interface
* conversions, and performance timing.
*/
public class FlowControllerContainer extends ConfigurableResource_ImplBase {
private FlowController mFlowController;
private UimaTimer mTimer = UIMAFramework.newTimer();
private boolean mSofaAware;
private Object mMBeanServer;
/*
* (non-Javadoc)
*
* @see org.apache.uima.resource.Resource_ImplBase#initialize(org.apache.uima.resource.ResourceSpecifier,
* java.util.Map)
*/
public boolean initialize(ResourceSpecifier aSpecifier, Map aAdditionalParams)
throws ResourceInitializationException {
try {
// specifier must be a FlowControllerDescription. (Eventually, we
// might support remote specifiers, but not yet)
if (!(aSpecifier instanceof FlowControllerDescription)) {
throw new ResourceInitializationException(
ResourceInitializationException.NOT_A_FLOW_CONTROLLER_DESCRIPTOR, new Object[] {
aSpecifier.getSourceUrlString(), aSpecifier.getClass().getName() });
}
ResourceCreationSpecifier desc = (ResourceCreationSpecifier) aSpecifier;
// also framework implementation must start with org.apache.uima.java
final String fwImpl = desc.getFrameworkImplementation();
if (fwImpl == null
|| !fwImpl.equalsIgnoreCase(Constants.JAVA_FRAMEWORK_NAME)) {
throw new ResourceInitializationException(
ResourceInitializationException.UNSUPPORTED_FRAMEWORK_IMPLEMENTATION, new Object[] {
fwImpl, aSpecifier.getSourceUrlString() });
}
super.initialize(aSpecifier, aAdditionalParams);
// validate the descriptor
desc.validate(getResourceManager());
// instantiate FlowController
mFlowController = instantiateFlowController(desc);
// record metadata
setMetaData(desc.getMetaData());
// add our metadata to the CasManager, so that it will pick up our
// type system, priorities, and indexes
getCasManager().addMetaData(getProcessingResourceMetaData());
// determine if this component is Sofa-aware (based on whether it
// declares any input or output sofas in its capabilities)
mSofaAware = getProcessingResourceMetaData().isSofaAware();
// Set Logger, to enable component-specific logging configuration
UimaContextAdmin uimaContext = getUimaContextAdmin();
Logger logger = UIMAFramework.getLogger(mFlowController.getClass());
logger.setResourceManager(this.getResourceManager());
uimaContext.setLogger(logger);
// initialize FlowController
mFlowController.initialize(getFlowControllerContext());
mMBeanServer = null;
String mbeanNamePrefix = null;
if (aAdditionalParams != null) {
mMBeanServer = aAdditionalParams.get(AnalysisEngine.PARAM_MBEAN_SERVER);
mbeanNamePrefix = (String)aAdditionalParams.get(AnalysisEngine.PARAM_MBEAN_NAME_PREFIX);
}
// update MBean with the name taken from metadata
getMBean().setName(getMetaData().getName(), getUimaContextAdmin(), mbeanNamePrefix);
// register MBean with MBeanServer. If no MBeanServer specified in the
// additionalParams map, this will use the platform MBean Server
// (Java 1.5 only)
JmxMBeanAgent.registerMBean(getMBean(), mMBeanServer);
return true;
} catch (ResourceConfigurationException e) {
throw new ResourceInitializationException(e);
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#finalize()
*/
protected void finalize() throws Throwable {
// unregister MBean from MBeanServer when GC occurs
// NOTE: we don't want to do this in destroy() because all AEs in a CPE are
// destroyed when the CPE processing completes. If we unregistered the MBean then,
// the user could not see the stats of a completed CPE.
JmxMBeanAgent.unregisterMBean(getMBean(), mMBeanServer);
super.finalize();
}
/**
* @return
*/
private FlowControllerContext getFlowControllerContext() {
return (FlowControllerContext) getUimaContext();
}
/*
* (non-Javadoc)
*
* @see org.apache.uima.resource.ConfigurableResource_ImplBase#reconfigure()
*/
public void reconfigure() throws ResourceConfigurationException {
try {
mFlowController.reconfigure();
} catch (ResourceInitializationException e) {
throw new ResourceConfigurationException(e);
}
}
/*
* (non-Javadoc)
*
* @see org.apache.uima.resource.Resource_ImplBase#destroy()
*/
public void destroy() {
mFlowController.destroy();
super.destroy();
}
/**
* Invokes the FlowController's computeFlow method, returning a Flow object that routes the given
* CAS through this aggregate. This method makes sure to provide the FlowController with its
* required CAS interface (e.g. JCas).
*
* @param aCAS
* the CAS to pass to the FlowController
* @return a Flow object that routes this CAS
*
* @throws AnalysisEngineProcessException
* if the FlowController failed
*/
public FlowContainer computeFlow(CAS aCAS) throws AnalysisEngineProcessException {
mTimer.startIt();
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 (the FlowController)
aCAS.setCurrentComponentInfo(getUimaContextAdmin().getComponentInfo());
// must get the appropriate CAS interface for the FlowController
// Get the right view of the CAS. Sofa-aware components get the base CAS.
// Sofa-unaware components get whatever is mapped to the default text sofa.
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 = mFlowController.getRequiredCasInterface();
AbstractCas casToPass = getCasManager().getCasInterface(view, requiredInterface);
((CASImpl)aCAS).switchClassLoaderLockCasCL(this.getResourceManager().getExtensionClassLoader());
Flow flow = mFlowController.computeFlow(casToPass);
return new FlowContainer(flow, this, aCAS);
} finally {
((CASImpl)aCAS).restoreClassLoaderUnlockCas();
aCAS.setCurrentComponentInfo(null);
mTimer.stopIt();
getMBean().reportAnalysisTime(mTimer.getDuration());
getMBean().incrementCASesProcessed();
}
}
/** Get the required CAS interface of the FlowController. */
public Class getRequiredCasInterface() {
return mFlowController.getRequiredCasInterface();
}
public ProcessingResourceMetaData getProcessingResourceMetaData() {
return (ProcessingResourceMetaData) getMetaData();
}
/**
* Gets the MBean to use to report performance statistics.
*/
public AnalysisEngineManagementImpl getMBean() {
return (AnalysisEngineManagementImpl) getUimaContextAdmin().getManagementInterface();
}
/**
* Notifies this FlowController that new Analysis Engines
* @see FlowController#addAnalysisEngines(Collection)
*/
public void addAnalysisEngines(Collection aKeys) {
mFlowController.addAnalysisEngines(aKeys);
}
/**
* Notifies this FlowController that some Analysis Engines are no longer available to route CASes to.
* @see FlowController#removeAnalysisEngines(Collection)
*/
public void removeAnalysisEngines(Collection aKeys) throws AnalysisEngineProcessException {
mFlowController.removeAnalysisEngines(aKeys);
}
/**
* Instantiates the FlowController class specified in the descriptor.
*/
private FlowController instantiateFlowController(ResourceCreationSpecifier aDescriptor)
throws ResourceInitializationException {
String flowControllerClassName;
flowControllerClassName = aDescriptor.getImplementationName();
if (flowControllerClassName == null || flowControllerClassName.length() == 0) {
throw new ResourceInitializationException(
ResourceInitializationException.MISSING_IMPLEMENTATION_CLASS_NAME,
new Object[] { aDescriptor.getSourceUrlString() });
}
// load FlowController class
Class flowControllerClass = null;
try {
// get UIMA extension ClassLoader if available
ClassLoader cl = getUimaContextAdmin().getResourceManager().getExtensionClassLoader();
if (cl != null) {
// use UIMA extension ClassLoader to load the class
flowControllerClass = cl.loadClass(flowControllerClassName);
} else {
// use application ClassLoader to load the class
flowControllerClass = Class.forName(flowControllerClassName);
}
} catch (ClassNotFoundException e) {
throw new ResourceInitializationException(ResourceInitializationException.CLASS_NOT_FOUND,
new Object[] { flowControllerClassName, aDescriptor.getSourceUrlString() }, e);
}
Object userObject;
try {
userObject = flowControllerClass.newInstance();
} catch (Exception e) {
throw new ResourceInitializationException(
ResourceInitializationException.COULD_NOT_INSTANTIATE, new Object[] {
flowControllerClassName, aDescriptor.getSourceUrlString() }, e);
}
if (!(userObject instanceof FlowController)) {
throw new ResourceInitializationException(
ResourceInitializationException.RESOURCE_DOES_NOT_IMPLEMENT_INTERFACE, new Object[] {
flowControllerClassName, FlowController.class, aDescriptor.getSourceUrlString() });
}
return (FlowController) userObject;
}
}