EJBProviderpublic class EJBProvider extends RPCProvider
Fields Summary |
---|
protected static Log | log | protected static Log | entLog | public static final String | OPTION_BEANNAME | public static final String | OPTION_HOMEINTERFACENAME | public static final String | OPTION_REMOTEINTERFACENAME | public static final String | OPTION_LOCALHOMEINTERFACENAME | public static final String | OPTION_LOCALINTERFACENAME | public static final String | jndiContextClass | public static final String | jndiURL | public static final String | jndiUsername | public static final String | jndiPassword | protected static final Class[] | empty_class_array | protected static final Object[] | empty_object_array | private static InitialContext | cached_context |
Methods Summary |
---|
private java.lang.Object | createLocalEJB(org.apache.axis.MessageContext msgContext, java.lang.String beanJndiName, java.lang.Class homeClass)Create an EJB using a local home object
// Get the EJB Home object from JNDI
Object ejbHome = getEJBHome(msgContext.getService(),
msgContext, beanJndiName);
// the home object is a local home object
Object ehome;
if (homeClass.isInstance(ejbHome))
ehome = ejbHome;
else
throw new ClassCastException(
Messages.getMessage("badEjbHomeType"));
// Invoke the create method of the ejbHome class without actually
// touching any EJB classes (i.e. no cast to EJBLocalHome)
Method createMethod = homeClass.getMethod("create", empty_class_array);
Object result = createMethod.invoke(ehome, empty_object_array);
return result;
| private java.lang.Object | createRemoteEJB(org.apache.axis.MessageContext msgContext, java.lang.String beanJndiName, java.lang.Class homeClass)Create an EJB using a remote home object
// Get the EJB Home object from JNDI
Object ejbHome = getEJBHome(msgContext.getService(),
msgContext, beanJndiName);
Object ehome = javax.rmi.PortableRemoteObject.narrow(ejbHome, homeClass);
// Invoke the create method of the ejbHome class without actually
// touching any EJB classes (i.e. no cast to EJBHome)
Method createMethod = homeClass.getMethod("create", empty_class_array);
Object result = createMethod.invoke(ehome, empty_object_array);
return result;
| protected javax.naming.InitialContext | getCachedContext()
if (cached_context == null)
cached_context = new InitialContext();
return cached_context;
| private java.lang.Throwable | getCause(java.lang.Throwable original)Get the cause of an exception, using reflection so that
it still works under JDK 1.3
try {
Method method = original.getClass().getMethod("getCause", null);
Throwable cause = (Throwable) method.invoke(original, null);
if (cause != null) {
return cause;
}
} catch (NoSuchMethodException nsme) {
// ignore, this occurs under JDK 1.3
} catch (Throwable t) {
}
return original;
| protected javax.naming.InitialContext | getContext(java.util.Properties properties)
// if we got any stuff from the configuration file
// create a new context using these properties
// otherwise, we get a default context and cache it for next time
return ((properties == null)
? getCachedContext()
: new InitialContext(properties));
| private java.lang.Object | getEJBHome(org.apache.axis.handlers.soap.SOAPService serviceHandler, org.apache.axis.MessageContext msgContext, java.lang.String beanJndiName)Common routine to do the JNDI lookup on the Home interface object
username and password for jndi lookup are got from the configuration or from
the messageContext if not found in the configuration
Object ejbHome = null;
// Set up an InitialContext and use it get the beanJndiName from JNDI
try {
Properties properties = null;
// collect all the properties we need to access JNDI:
// username, password, factoryclass, contextUrl
// username
String username = getStrOption(jndiUsername, serviceHandler);
if ((username == null) && (msgContext != null))
username = msgContext.getUsername();
if (username != null) {
if (properties == null)
properties = new Properties();
properties.setProperty(Context.SECURITY_PRINCIPAL, username);
}
// password
String password = getStrOption(jndiPassword, serviceHandler);
if ((password == null) && (msgContext != null))
password = msgContext.getPassword();
if (password != null) {
if (properties == null)
properties = new Properties();
properties.setProperty(Context.SECURITY_CREDENTIALS, password);
}
// factory class
String factoryClass = getStrOption(jndiContextClass, serviceHandler);
if (factoryClass != null) {
if (properties == null)
properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, factoryClass);
}
// contextUrl
String contextUrl = getStrOption(jndiURL, serviceHandler);
if (contextUrl != null) {
if (properties == null)
properties = new Properties();
properties.setProperty(Context.PROVIDER_URL, contextUrl);
}
// get context using these properties
InitialContext context = getContext(properties);
// if we didn't get a context, fail
if (context == null)
throw new AxisFault( Messages.getMessage("cannotCreateInitialContext00"));
ejbHome = getEJBHome(context, beanJndiName);
if (ejbHome == null)
throw new AxisFault( Messages.getMessage("cannotFindJNDIHome00",beanJndiName));
}
// Should probably catch javax.naming.NameNotFoundException here
catch (Exception exception) {
entLog.info(Messages.getMessage("toAxisFault00"), exception);
throw AxisFault.makeFault(exception);
}
return ejbHome;
| protected java.lang.Object | getEJBHome(javax.naming.InitialContext context, java.lang.String beanJndiName)
// Do the JNDI lookup
return context.lookup(beanJndiName);
| private java.lang.Class | getRemoteInterfaceClassFromHome(java.lang.String beanJndiName, org.apache.axis.handlers.soap.SOAPService service, org.apache.axis.MessageContext msgContext)Get the remote interface of an ejb from its home class.
This function can only be used for remote ejbs
// Get the EJB Home object from JNDI
Object ejbHome = getEJBHome(service, msgContext, beanJndiName);
String homeName = getStrOption(OPTION_HOMEINTERFACENAME,
service);
if (homeName == null)
throw new AxisFault(
Messages.getMessage("noOption00",
OPTION_HOMEINTERFACENAME,
service.getName()));
// Load the Home class name given in the config file
ClassLoader cl = (msgContext != null) ?
msgContext.getClassLoader() :
Thread.currentThread().getContextClassLoader();
Class homeClass = ClassUtils.forName(homeName, true, cl);
// Make sure the object we got back from JNDI is the same type
// as the what is specified in the config file
Object ehome = javax.rmi.PortableRemoteObject.narrow(ejbHome, homeClass);
// This code requires the use of ejb.jar, so we do the stuff below
// EJBHome ejbHome = (EJBHome) ehome;
// EJBMetaData meta = ejbHome.getEJBMetaData();
// Class interfaceClass = meta.getRemoteInterfaceClass();
// Invoke the getEJBMetaData method of the ejbHome class without
// actually touching any EJB classes (i.e. no cast to EJBHome)
Method getEJBMetaData =
homeClass.getMethod("getEJBMetaData", empty_class_array);
Object metaData = getEJBMetaData.invoke(ehome, empty_object_array);
Method getRemoteInterfaceClass =
metaData.getClass().getMethod("getRemoteInterfaceClass",
empty_class_array);
return (Class) getRemoteInterfaceClass.invoke(metaData,
empty_object_array);
| protected java.lang.Class | getServiceClass(java.lang.String beanJndiName, org.apache.axis.handlers.soap.SOAPService service, org.apache.axis.MessageContext msgContext)Get the class description for the EJB Remote or Local Interface,
which is what we are interested in exposing to the world (i.e. in WSDL).
Class interfaceClass = null;
try {
// First try to get the interface class from the configuation
// Note that we don't verify that remote remoteInterfaceName is used for
// remote ejb and localInterfaceName for local ejb. Should we ?
String remoteInterfaceName =
getStrOption(OPTION_REMOTEINTERFACENAME, service);
String localInterfaceName =
getStrOption(OPTION_LOCALINTERFACENAME, service);
String interfaceName = (remoteInterfaceName != null ? remoteInterfaceName : localInterfaceName);
if(interfaceName != null){
ClassLoader cl = (msgContext != null) ?
msgContext.getClassLoader() :
Thread.currentThread().getContextClassLoader();
interfaceClass = ClassUtils.forName(interfaceName,
true,
cl);
}
else
{
// cannot get the interface name from the configuration, we get
// it from the EJB Home (if remote)
if (isRemoteEjb(service)) {
interfaceClass = getRemoteInterfaceClassFromHome(beanJndiName,
service,
msgContext);
}
else
if (isLocalEjb(service)) {
// we cannot get the local interface from the local ejb home
// localInterfaceName is mandatory for local ejbs
throw new AxisFault(
Messages.getMessage("noOption00",
OPTION_LOCALINTERFACENAME,
service.getName()));
}
else
{
// neither a local ejb or a remote one ...
throw new AxisFault(Messages.getMessage("noOption00",
OPTION_HOMEINTERFACENAME,
service.getName()));
}
}
} catch (Exception e) {
throw AxisFault.makeFault(e);
}
// got it, return it
return interfaceClass;
| protected java.lang.String | getServiceClassNameOptionName()Return the option in the configuration that contains the service class
name. In the EJB case, it is the JNDI name of the bean.
return OPTION_BEANNAME;
| protected java.lang.String | getStrOption(java.lang.String optionName, org.apache.axis.Handler service)Get a String option by looking first in the service options,
and then at the Handler's options. This allows defaults to be
specified at the provider level, and then overriden for particular
services.
String value = null;
if (service != null)
value = (String)service.getOption(optionName);
if (value == null)
value = (String)getOption(optionName);
return value;
| protected java.lang.Object | invokeMethod(org.apache.axis.MessageContext msgContext, java.lang.reflect.Method method, java.lang.Object obj, java.lang.Object[] argValues)Override the default implementation such that we can include
special handling for {@link java.rmi.ServerException}.
Converts {@link java.rmi.ServerException} exceptions to
{@link InvocationTargetException} exceptions with the same cause.
This allows the axis framework to create a SOAP fault.
try {
return super.invokeMethod(msgContext, method, obj, argValues);
} catch (InvocationTargetException ite) {
Throwable cause = getCause(ite);
if (cause instanceof java.rmi.ServerException) {
throw new InvocationTargetException(getCause(cause));
}
throw ite;
}
| private boolean | isLocalEjb(org.apache.axis.handlers.soap.SOAPService service)Tells if the ejb that will be used to handle this service is a local
one
return (!isRemoteEjb(service)) &&
(getStrOption(OPTION_LOCALHOMEINTERFACENAME,service) != null);
| private boolean | isRemoteEjb(org.apache.axis.handlers.soap.SOAPService service)Tells if the ejb that will be used to handle this service is a remote
one
return getStrOption(OPTION_HOMEINTERFACENAME,service) != null;
| protected java.lang.Object | makeNewServiceObject(org.apache.axis.MessageContext msgContext, java.lang.String clsName)Return a object which implements the service.
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
/////// Default methods from JavaProvider ancestor, overridden
/////// for ejbeans
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
String remoteHomeName = getStrOption(OPTION_HOMEINTERFACENAME,
msgContext.getService());
String localHomeName = getStrOption(OPTION_LOCALHOMEINTERFACENAME,
msgContext.getService());
String homeName = (remoteHomeName != null ? remoteHomeName:localHomeName);
if (homeName == null) {
// cannot find both remote home and local home
throw new AxisFault(
Messages.getMessage("noOption00",
OPTION_HOMEINTERFACENAME,
msgContext.getTargetService()));
}
// Load the Home class name given in the config file
Class homeClass = ClassUtils.forName(homeName, true, msgContext.getClassLoader());
// we create either the ejb using either the RemoteHome or LocalHome object
if (remoteHomeName != null)
return createRemoteEJB(msgContext, clsName, homeClass);
else
return createLocalEJB(msgContext, clsName, homeClass);
|
|