JavaProviderpublic abstract class JavaProvider extends org.apache.axis.providers.BasicProvider Base class for Java dispatching. Fetches various fields out of envelope,
looks up service object (possibly using session state), and delegates
envelope body processing to subclass via abstract processMessage method. |
Fields Summary |
---|
protected static Log | log | protected static Log | entLog | public static final String | OPTION_CLASSNAME | public static final String | OPTION_ALLOWEDMETHODS | public static final String | OPTION_SCOPE |
Methods Summary |
---|
private java.lang.String | getAllowedMethods(org.apache.axis.Handler service)
String val = (String)service.getOption(OPTION_ALLOWEDMETHODS);
if (val == null || val.length() == 0) {
// Try the old option for backwards-compatibility
val = (String)service.getOption("methodName");
}
return val;
| private java.lang.Object | getApplicationScopedObject(org.apache.axis.MessageContext msgContext, java.lang.String serviceName, java.lang.String clsName, javax.xml.rpc.holders.IntHolder scopeHolder)
AxisEngine engine = msgContext.getAxisEngine();
Session appSession = engine.getApplicationSession();
if (appSession != null) {
return getSessionServiceObject(appSession, serviceName,
msgContext, clsName);
} else {
// was no application session - log an error and
// treat as request scope
log.error(Messages.getMessage("noAppSession"));
scopeHolder.value = Scope.DEFAULT.getValue();
return getNewServiceObject(msgContext, clsName);
}
| private java.lang.Object | getNewServiceObject(org.apache.axis.MessageContext msgContext, java.lang.String clsName)Return a new service object which, if it implements the ServiceLifecycle
interface, has been init()ed.
Object serviceObject = makeNewServiceObject(msgContext, clsName);
if (serviceObject != null &&
serviceObject instanceof ServiceLifecycle) {
((ServiceLifecycle)serviceObject).init(
msgContext.getProperty(Constants.MC_SERVLET_ENDPOINT_CONTEXT));
}
return serviceObject;
| protected java.lang.Class | getServiceClass(java.lang.String clsName, org.apache.axis.handlers.soap.SOAPService service, org.apache.axis.MessageContext msgContext)Returns the Class info about the service class.
ClassLoader cl = null;
Class serviceClass = null;
AxisEngine engine = service.getEngine();
// If we have a message context, use that to get classloader
// otherwise get the current threads classloader
if (msgContext != null) {
cl = msgContext.getClassLoader();
} else {
cl = Thread.currentThread().getContextClassLoader();
}
// If we have an engine, use its class cache
if (engine != null) {
ClassCache cache = engine.getClassCache();
try {
JavaClass jc = cache.lookup(clsName, cl);
serviceClass = jc.getJavaClass();
} catch (ClassNotFoundException e) {
log.error(Messages.getMessage("exception00"), e);
throw new AxisFault(Messages.getMessage("noClassForService00", clsName), e);
}
} else {
// if no engine, we don't have a cache, use Class.forName instead.
try {
serviceClass = ClassUtils.forName(clsName, true, cl);
} catch (ClassNotFoundException e) {
log.error(Messages.getMessage("exception00"), e);
throw new AxisFault(Messages.getMessage("noClassForService00", clsName), e);
}
}
return serviceClass;
| protected java.lang.String | getServiceClassName(org.apache.axis.Handler service)Return the class name of the service
return (String) service.getOption( getServiceClassNameOptionName() );
| protected java.lang.String | getServiceClassNameOptionName()Return the option in the configuration that contains the service class
name
return OPTION_CLASSNAME;
| public java.lang.Object | getServiceObject(org.apache.axis.MessageContext msgContext, org.apache.axis.Handler service, java.lang.String clsName, javax.xml.rpc.holders.IntHolder scopeHolder)Get the service object whose method actually provides the service.
May look up in session table.
String serviceName = msgContext.getService().getName();
// scope can be "Request", "Session", "Application", "Factory"
Scope scope = Scope.getScope((String)service.getOption(OPTION_SCOPE), Scope.DEFAULT);
scopeHolder.value = scope.getValue();
if (scope == Scope.REQUEST) {
// make a one-off
return getNewServiceObject(msgContext, clsName);
} else if (scope == Scope.SESSION) {
// What do we do if serviceName is null at this point???
if (serviceName == null)
serviceName = msgContext.getService().toString();
// look in incoming session
Session session = msgContext.getSession();
if (session != null) {
return getSessionServiceObject(session, serviceName,
msgContext, clsName);
} else {
// was no incoming session, sigh, treat as request scope
scopeHolder.value = Scope.DEFAULT.getValue();
return getNewServiceObject(msgContext, clsName);
}
} else if (scope == Scope.APPLICATION) {
// MUST be AxisEngine here!
return getApplicationScopedObject(msgContext, serviceName, clsName, scopeHolder);
} else if (scope == Scope.FACTORY) {
String objectID = msgContext.getStrProp("objectID");
if (objectID == null) {
return getApplicationScopedObject(msgContext, serviceName, clsName, scopeHolder);
}
SOAPService svc = (SOAPService)service;
Object ret = svc.serviceObjects.get(objectID);
if (ret == null) {
throw new AxisFault("NoSuchObject", null, null, null);
}
return ret;
}
// NOTREACHED
return null;
| private java.lang.Object | getSessionServiceObject(org.apache.axis.session.Session session, java.lang.String serviceName, org.apache.axis.MessageContext msgContext, java.lang.String clsName)Get a service object from a session. Handles threading / locking
issues when multiple threads might be accessing the same session
object, and ensures only one thread gets to create the service
object if there isn't one already.
Object obj = null;
boolean makeNewObject = false;
// This is a little tricky.
synchronized (session.getLockObject()) {
// store service objects in session, indexed by class name
obj = session.get(serviceName);
// If nothing there, put in a placeholder object so
// other threads wait for us to create the real
// service object.
if (obj == null) {
obj = new LockObject();
makeNewObject = true;
session.set(serviceName, obj);
msgContext.getService().addSession(session);
}
}
// OK, we DEFINITELY have something in obj at this point. Either
// it's the service object or it's a LockObject (ours or someone
// else's).
if (LockObject.class == obj.getClass()) {
LockObject lock = (LockObject)obj;
// If we were the lucky thread who got to install the
// placeholder, create a new service object and install it
// instead, then notify anyone waiting on the LockObject.
if (makeNewObject) {
try {
obj = getNewServiceObject(msgContext, clsName);
session.set(serviceName, obj);
msgContext.getService().addSession(session);
} catch(final Exception e) {
session.remove(serviceName);
throw e;
} finally {
lock.complete();
}
} else {
// It's someone else's LockObject, so wait around until
// it's completed.
lock.waitUntilComplete();
// Now we are guaranteed there is a service object in the
// session, so this next part doesn't need syncing
obj = session.get(serviceName);
}
}
return obj;
| public void | initServiceDesc(org.apache.axis.handlers.soap.SOAPService service, org.apache.axis.MessageContext msgContext)Fill in a service description with the correct impl class
and typemapping set. This uses methods that can be overridden by
other providers (like the EJBProvider) to get the class from the
right place.
// Set up the Implementation class for the service
String clsName = getServiceClassName(service);
if (clsName == null) {
throw new AxisFault(Messages.getMessage("noServiceClass"));
}
Class cls = getServiceClass(clsName, service, msgContext);
JavaServiceDesc serviceDescription = (JavaServiceDesc)service.getServiceDescription();
// And the allowed methods, if necessary
if (serviceDescription.getAllowedMethods() == null && service != null) {
String allowedMethods = getAllowedMethods(service);
if (allowedMethods != null && !"*".equals(allowedMethods)) {
ArrayList methodList = new ArrayList();
StringTokenizer tokenizer = new StringTokenizer(allowedMethods, " ,");
while (tokenizer.hasMoreTokens()) {
methodList.add(tokenizer.nextToken());
}
serviceDescription.setAllowedMethods(methodList);
}
}
serviceDescription.loadServiceDescByIntrospection(cls);
| public void | invoke(org.apache.axis.MessageContext msgContext)Invoke the message by obtaining various common fields, looking up
the service object (via getServiceObject), and actually processing
the message (via processMessage).
if (log.isDebugEnabled())
log.debug("Enter: JavaProvider::invoke (" + this + ")");
/* Find the service we're invoking so we can grab it's options */
/***************************************************************/
String serviceName = msgContext.getTargetService();
Handler service = msgContext.getService();
/* Now get the service (RPC) specific info */
/********************************************/
String clsName = getServiceClassName(service);
if ((clsName == null) || clsName.equals("")) {
throw new AxisFault("Server.NoClassForService",
Messages.getMessage("noOption00", getServiceClassNameOptionName(), serviceName),
null, null);
}
IntHolder scope = new IntHolder();
Object serviceObject = null;
try {
serviceObject = getServiceObject(msgContext, service, clsName, scope);
SOAPEnvelope resEnv = null;
// If there IS a response message AND this is a one-way operation,
// we delete the response message here. Note that this might
// cause confusing results in some cases - i.e. nothing fails,
// but your response headers don't go anywhere either. It might
// be nice if in the future there was a way to detect an error
// when trying to install a response message in a MessageContext
// associated with a one-way operation....
OperationDesc operation = msgContext.getOperation();
if (operation != null &&
OperationType.ONE_WAY.equals(operation.getMep())) {
msgContext.setResponseMessage(null);
} else {
Message resMsg = msgContext.getResponseMessage();
// If we didn't have a response message, make sure we set one up
// with the appropriate versions of SOAP and Schema
if (resMsg == null) {
resEnv = new SOAPEnvelope(msgContext.getSOAPConstants(),
msgContext.getSchemaVersion());
resMsg = new Message(resEnv);
String encoding = XMLUtils.getEncoding(msgContext);
resMsg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, encoding);
msgContext.setResponseMessage( resMsg );
} else {
resEnv = resMsg.getSOAPEnvelope();
}
}
Message reqMsg = msgContext.getRequestMessage();
SOAPEnvelope reqEnv = reqMsg.getSOAPEnvelope();
processMessage(msgContext, reqEnv, resEnv, serviceObject);
} catch( SAXException exp ) {
entLog.debug( Messages.getMessage("toAxisFault00"), exp);
Exception real = exp.getException();
if (real == null) {
real = exp;
}
throw AxisFault.makeFault(real);
} catch( Exception exp ) {
entLog.debug( Messages.getMessage("toAxisFault00"), exp);
AxisFault fault = AxisFault.makeFault(exp);
//make a note if this was a runtime fault, for better logging
if (exp instanceof RuntimeException) {
fault.addFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION,
"true");
}
throw fault;
} finally {
// If this is a request scoped service object which implements
// ServiceLifecycle, let it know that it's being destroyed now.
if (serviceObject != null &&
scope.value == Scope.REQUEST.getValue() &&
serviceObject instanceof ServiceLifecycle)
{
((ServiceLifecycle)serviceObject).destroy();
}
}
if (log.isDebugEnabled())
log.debug("Exit: JavaProvider::invoke (" + this + ")");
| protected java.lang.Object | makeNewServiceObject(org.apache.axis.MessageContext msgContext, java.lang.String clsName)Default java service object comes from simply instantiating the
class wrapped in jc
ClassLoader cl = msgContext.getClassLoader();
ClassCache cache = msgContext.getAxisEngine().getClassCache();
JavaClass jc = cache.lookup(clsName, cl);
return jc.getJavaClass().newInstance();
| public abstract void | processMessage(org.apache.axis.MessageContext msgContext, org.apache.axis.message.SOAPEnvelope reqEnv, org.apache.axis.message.SOAPEnvelope resEnv, java.lang.Object obj)Process the current message. Side-effect resEnv to create return value.
|
|