blob: 64e611de7cc71a7e7a3adba499386c7d285fb6c3 [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.adapter.soap;
import java.util.HashMap;
import java.util.Map;
import org.apache.axis.AxisFault;
import org.apache.axis.Handler;
import org.apache.axis.MessageContext;
import org.apache.uima.UIMAFramework;
import org.apache.uima.analysis_engine.AnalysisEngine;
import org.apache.uima.analysis_engine.service.impl.AnalysisEngineService_impl;
import org.apache.uima.resource.ResourceSpecifier;
import org.apache.uima.resource.service.impl.ResourceService_impl;
import org.apache.uima.util.Level;
import org.apache.uima.util.Logger;
import org.apache.uima.util.XMLInputSource;
/**
* Utility class for deploying Resources as Axis (SOAP) services. This class mantains a map between
* Axis service names and the {@link ResourceService_impl} classes that provide the implementation
* for those service names. This map is maintained as static data on this class so that it persists
* between invocations of the Axis services.
* <P>
* SOAP service implementation classes call the static {@link #getServiceImpl(Class)} method from
* their constructors. The service's name and configuration parameters will be read from the Axis
* MessageContext. If a {@link ResourceService_impl} instance has already been registered under this
* service's name, that instance will be returned. Otherwise, a new
* <code>ResourceService_impl</code> will be created.
*/
public class AxisResourceServiceManager {
/**
* The name of the deployment parameter whose value is the path to an XML resource specifier. This
* resource specifier is used to constuct Resource instances that process the requests received by
* this service. A value for this option must be speciifed in the deployment descriptor for this
* service.
*/
public static final String PARAM_RESOURCE_SPECIFIER_PATH = "resourceSpecifierPath";
/**
* The name of the deployment parameter whose value is the number of instances of the Resource
* (specified by {@link #PARAM_RESOURCE_SPECIFIER_PATH}) to be created. The Resources are kept in
* a pool and used to service requests. A value for this option must be speciifed in the
* deployment descriptor for this service.
*/
public static final String PARAM_NUM_INSTANCES = "numInstances";
/**
* The name of the deployment parameter whose value is a boolean indicating whether to write log
* messages during each service invocation. This currently applies only to Analysis Engine
* services.
*/
public static final String PARAM_ENABLE_LOGGING = "enableLogging";
/**
* Map from service names to ResourceService_impl objects.
*/
private static Map mResourceServiceImplMap = new HashMap();
/**
* Gets a {@link ResourceService_impl} class to be used to process an request.This method
* retrieves the service name and configuration parameters from the Axis MessageContext. If a
* {@link ResourceService_impl} object already exists for that service name, that object will be
* returned. Otherwise, a new <code>ResourceService_impl</code> object will be created from the
* information in the MessageContext.
*
* @param aResourceImplClass
* the class that will be instantiated when a new <code>ResourceService_impl</code> is
* to be created. This must be a subclass of ResourceService_impl.
* @throws AxisFault
* if the configuration information could not be read
*/
public static ResourceService_impl getServiceImpl(Class aServiceImplClass) throws AxisFault {
try {
MessageContext ctx = MessageContext.getCurrentContext();
if (ctx == null) {
throw new Exception("MessageContext = NULL");
}
Handler self = ctx.getService();
if (self == null) {
throw new Exception("Handler = NULL");
}
// Get service name
String serviceName = self.getName();
// see if we have a ResourceService_impl registered for that name
ResourceService_impl serviceImpl = (ResourceService_impl) mResourceServiceImplMap
.get(serviceName);
if (serviceImpl != null) {
return serviceImpl;
}
// No service impl registered for this service name, attempt to
// create a new one
// Get the Resource Specifier Path
String resourceSpecifierPath = (String) self.getOption(PARAM_RESOURCE_SPECIFIER_PATH);
if (resourceSpecifierPath == null || resourceSpecifierPath.trim().length() == 0) {
throw new Exception("Invalid Configuration - " + PARAM_RESOURCE_SPECIFIER_PATH
+ " not Defined. Check your deployment descriptor file (WSDD)");
}
// parse ResourceSpecifier
ResourceSpecifier resourceSpecifier = UIMAFramework.getXMLParser().parseResourceSpecifier(
new XMLInputSource(resourceSpecifierPath));
// Get the number of instances to create
String numInstancesStr = (String) self.getOption(PARAM_NUM_INSTANCES);
int numInstances;
try {
numInstances = Integer.parseInt(numInstancesStr);
} catch (NumberFormatException e) {
throw new Exception("Invalid Configuration - " + PARAM_NUM_INSTANCES
+ " not valid. Check your deployment descriptor file (WSDD)");
}
// Get whether to enable logging
String enableLogStr = (String) self.getOption(PARAM_ENABLE_LOGGING);
boolean enableLog = "true".equalsIgnoreCase(enableLogStr);
// create and initialize the service implementation
serviceImpl = (ResourceService_impl) aServiceImplClass.newInstance();
HashMap initParams = new HashMap();
initParams.put(AnalysisEngine.PARAM_NUM_SIMULTANEOUS_REQUESTS, new Integer(numInstances));
serviceImpl.initialize(resourceSpecifier, initParams);
// disable logging for Analysis Engines if deployer so indicated
if (!enableLog && serviceImpl instanceof AnalysisEngineService_impl) {
Logger nullLogger = UIMAFramework.newLogger();
nullLogger.setOutputStream(null);
((AnalysisEngineService_impl) serviceImpl).getAnalysisEngine().setLogger(nullLogger);
}
mResourceServiceImplMap.put(serviceName, serviceImpl);
return serviceImpl;
} catch (Exception e) {
UIMAFramework.getLogger().log(Level.SEVERE, e.getMessage(), e);
throw AxisFault.makeFault(e);
}
}
}