ServiceInvocationHandlerpublic class ServiceInvocationHandler extends Object implements InvocationHandlerInvocationHandler used to intercept calls to concrete JAXRPC
Service implementation.
NOTE : This class makes no distinction between "partial" WSDL and
"full" WSDL. If a service-ref's packaged WSDL is "partial", the
deployer is required to specify a wsdl-override in the runtime info
that points to a final WSDL. In such a case, the behavior for each
method listed in the table in section 4.2.2.7 of the spec is the
same as Full WSDL. |
Fields Summary |
---|
private com.sun.enterprise.deployment.ServiceReferenceDescriptor | serviceRef | private javax.xml.rpc.Service | serviceDelegate | private javax.xml.rpc.Service | configuredServiceDelegate | private ClassLoader | classLoader | private Method | getClientManagedPortMethod | private URL | wsdlLocation | private boolean | fullWsdl | private boolean | noWsdl | private WsUtil | wsUtil | private static final int | CREATE_CALL_NO_ARGS | private static final int | CREATE_CALL_PORT | private static final int | CREATE_CALL_OPERATION_QNAME | private static final int | CREATE_CALL_OPERATION_STRING | private static final int | GET_CALLS | private static final int | GET_HANDLER_REGISTRY | private static final int | GET_PORT_CONTAINER_MANAGED | private static final int | GET_PORT_CLIENT_MANAGED | private static final int | GET_PORTS | private static final int | GET_SERVICE_NAME | private static final int | GET_TYPE_MAPPING_REGISTRY | private static final int | GET_WSDL_LOCATION | private static final int | GENERATED_SERVICE_METHOD | private static Map | serviceMethodTypes | private static Set | fullWsdlIllegalMethods | private static Set | noWsdlIllegalMethods |
Constructors Summary |
---|
public ServiceInvocationHandler(com.sun.enterprise.deployment.ServiceReferenceDescriptor descriptor, javax.xml.rpc.Service delegate, ClassLoader loader)
Init();
serviceRef = descriptor;
serviceDelegate = delegate;
classLoader = loader;
if( serviceRef.hasWsdlFile() ) {
wsdlLocation = wsUtil.privilegedGetServiceRefWsdl(serviceRef);
fullWsdl = true;
} else {
noWsdl = true;
}
getClientManagedPortMethod = javax.xml.rpc.Service.class.getMethod
("getPort", new Class[] { QName.class, Class.class } );
addMessageSecurityHandler(delegate);
|
Methods Summary |
---|
private static void | Init()Convert invocation method to a constant for easier processing.
serviceMethodTypes = new HashMap();
fullWsdlIllegalMethods = new HashSet();
noWsdlIllegalMethods = new HashSet();
try {
Class noParams[] = new Class[0];
String createCall = "createCall";
Class serviceClass = javax.xml.rpc.Service.class;
//
// Map Service method to method type.
//
Method createCallNoArgs =
serviceClass.getDeclaredMethod(createCall, noParams);
serviceMethodTypes.put(createCallNoArgs,
new Integer(CREATE_CALL_NO_ARGS));
Method createCallPort =
serviceClass.getDeclaredMethod(createCall,
new Class[] { QName.class });
serviceMethodTypes.put(createCallPort,
new Integer(CREATE_CALL_PORT));
Method createCallOperationQName =
serviceClass.getDeclaredMethod
(createCall, new Class[] { QName.class, QName.class });
serviceMethodTypes.put(createCallOperationQName,
new Integer(CREATE_CALL_OPERATION_QNAME));
Method createCallOperationString =
serviceClass.getDeclaredMethod
(createCall, new Class[] { QName.class, String.class });
serviceMethodTypes.put(createCallOperationString,
new Integer(CREATE_CALL_OPERATION_STRING));
Method getCalls = serviceClass.getDeclaredMethod
("getCalls", new Class[] { QName.class });
serviceMethodTypes.put(getCalls, new Integer(GET_CALLS));
Method getHandlerRegistry = serviceClass.getDeclaredMethod
("getHandlerRegistry", noParams);
serviceMethodTypes.put(getHandlerRegistry,
new Integer(GET_HANDLER_REGISTRY));
Method getPortContainerManaged = serviceClass.getDeclaredMethod
("getPort", new Class[] { Class.class });
serviceMethodTypes.put(getPortContainerManaged,
new Integer(GET_PORT_CONTAINER_MANAGED));
Method getPortClientManaged = serviceClass.getDeclaredMethod
("getPort", new Class[] { QName.class, Class.class });
serviceMethodTypes.put(getPortClientManaged,
new Integer(GET_PORT_CLIENT_MANAGED));
Method getPorts = serviceClass.getDeclaredMethod
("getPorts", noParams);
serviceMethodTypes.put(getPorts, new Integer(GET_PORTS));
Method getServiceName = serviceClass.getDeclaredMethod
("getServiceName", noParams);
serviceMethodTypes.put(getServiceName,
new Integer(GET_SERVICE_NAME));
Method getTypeMappingRegistry = serviceClass.getDeclaredMethod
("getTypeMappingRegistry", noParams);
serviceMethodTypes.put(getTypeMappingRegistry,
new Integer(GET_TYPE_MAPPING_REGISTRY));
Method getWsdlLocation = serviceClass.getDeclaredMethod
("getWSDLDocumentLocation", noParams);
serviceMethodTypes.put(getWsdlLocation,
new Integer(GET_WSDL_LOCATION));
} catch(NoSuchMethodException nsme) {}
// Implementation of table 4.2.2.7. All "No WSDL" column cells
// with value Unspecified throw UnsupportedOperationException
fullWsdlIllegalMethods.add(new Integer(GET_HANDLER_REGISTRY));
fullWsdlIllegalMethods.add(new Integer(GET_TYPE_MAPPING_REGISTRY));
noWsdlIllegalMethods.add(new Integer(CREATE_CALL_PORT));
noWsdlIllegalMethods.add(new Integer(CREATE_CALL_OPERATION_QNAME));
noWsdlIllegalMethods.add(new Integer(CREATE_CALL_OPERATION_STRING));
noWsdlIllegalMethods.add(new Integer(GET_CALLS));
noWsdlIllegalMethods.add(new Integer(GET_HANDLER_REGISTRY));
noWsdlIllegalMethods.add(new Integer(GET_PORT_CONTAINER_MANAGED));
noWsdlIllegalMethods.add(new Integer(GET_PORT_CLIENT_MANAGED));
noWsdlIllegalMethods.add(new Integer(GET_PORTS));
noWsdlIllegalMethods.add(new Integer(GET_SERVICE_NAME));
noWsdlIllegalMethods.add(new Integer(GET_TYPE_MAPPING_REGISTRY));
noWsdlIllegalMethods.add(new Integer(GET_WSDL_LOCATION));
// This case shouldn't happen since if service-ref has generated
// service and no WSDL it won't get past deployment, but it's here
// for completeness.
noWsdlIllegalMethods.add(new Integer(GENERATED_SERVICE_METHOD));
| private boolean | addMessageSecurityHandler(javax.xml.rpc.Service service)
HandlerRegistry registry = service.getHandlerRegistry();
Iterator ports = null;
try {
ports = service.getPorts();
} catch (Exception e) {
// FIXME: should make sure that the exception was thrown because
// the service is not fully defined; but for now just return.
ports = null;
}
while(ports != null && ports.hasNext()) {
QName nextPort = (QName) ports.next();
List handlerChain = registry.getHandlerChain(nextPort);
// append security handler to the end of every handler chain
// ASSUMPTION 1: that registry.getHandlerChain() never returns null.
// ASSUMPTION 2: that handlers from ServiceRef have already been added
HandlerInfo handlerInfo = getMessageSecurityHandlerInfo(nextPort);
if (handlerInfo != null) {
handlerChain.add(handlerInfo);
}
}
return ports == null ? false : true;
| private void | checkUnsupportedMethods(int methodType)
Set illegalMethods = fullWsdl ?
fullWsdlIllegalMethods : noWsdlIllegalMethods;
if( illegalMethods.contains(new Integer(methodType)) ) {
throw new UnsupportedOperationException();
}
return;
| private javax.xml.rpc.Service | getConfiguredServiceDelegate()
synchronized(this) {
if( configuredServiceDelegate == null ) {
// We need a ConfiguredService to handle these
// invocations, since the JAXRPC RI Generated Service impl
// does not. Configured service is potentially
// a heavy-weight object so we lazily instantiate it to
// take advantage of the likelihood that
// GeneratedService service-refs won't be used for DII.
Service configuredService =
wsUtil.createConfiguredService(serviceRef);
wsUtil.configureHandlerChain(serviceRef, configuredService,
configuredService.getPorts(), classLoader);
configuredServiceDelegate = configuredService;
addMessageSecurityHandler(configuredService);
}
}
return configuredServiceDelegate;
| public javax.xml.rpc.handler.HandlerInfo | getMessageSecurityHandlerInfo(javax.xml.namespace.QName port)
HandlerInfo rvalue = null;
MessageSecurityBindingDescriptor binding = null;
ServiceRefPortInfo portInfo = serviceRef.getPortInfoByPort(port);
if (portInfo != null) {
binding = portInfo.getMessageSecurityBinding();
}
ClientAuthConfig config = ClientAuthConfig.getConfig
(com.sun.enterprise.security.jauth.AuthConfig.SOAP,
binding, null);
if (config != null) {
// get understood headers from auth module.
QName[] headers = config.getMechanisms();
Map properties = new HashMap();
properties.put(MessageLayerClientHandler.CLIENT_AUTH_CONFIG, config);
properties.put(javax.xml.ws.handler.MessageContext.WSDL_SERVICE,
serviceRef.getServiceName());
rvalue = new HandlerInfo(MessageLayerClientHandler.class,
properties, headers);
}
return rvalue;
| private int | getMethodType(java.lang.reflect.Method method)
Integer methodType = (Integer) serviceMethodTypes.get(method);
return (methodType != null) ?
methodType.intValue() : GENERATED_SERVICE_METHOD;
| private java.util.Set | getPropertiesForCall(int methodType, java.lang.Object[] args)
Set callProperties = null;
switch(methodType) {
case CREATE_CALL_PORT :
case CREATE_CALL_OPERATION_QNAME :
case CREATE_CALL_OPERATION_STRING :
case GET_CALLS :
// Each of these methods has port as first argument.
QName port = (QName) args[0];
// Check if call properties are set at the port level.
ServiceRefPortInfo portInfo =
serviceRef.getPortInfoByPort(port);
if( portInfo != null ) {
callProperties = portInfo.getCallProperties();
}
break;
case CREATE_CALL_NO_ARGS :
callProperties = serviceRef.getCallProperties();
break;
}
return callProperties;
| public java.lang.Object | invoke(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args)
// NOTE : be careful with "args" parameter. It is null
// if method signature has 0 arguments.
if( method.getDeclaringClass() == java.lang.Object.class ) {
return invokeJavaObjectMethod(this, method, args);
}
int methodType = getMethodType(method);
checkUnsupportedMethods(methodType);
Object returnValue = null;
try {
// Initialize method info for invocation based on arguments.
// Some/All of this might be overridden below.
Object serviceToInvoke = serviceDelegate;
Method methodToInvoke = method;
int methodTypeToInvoke = methodType;
Object[] argsForInvoke = args;
switch(methodType) {
case GET_PORT_CONTAINER_MANAGED :
Class serviceEndpointInterfaceClass = (Class) args[0];
String serviceEndpointInterface =
serviceEndpointInterfaceClass.getName();
ServiceRefPortInfo portInfo =
serviceRef.getPortInfo(serviceEndpointInterface);
// If we have a port, use it to call getPort(QName, SEI) instead
if( (portInfo != null) && portInfo.hasWsdlPort() ) {
methodToInvoke = getClientManagedPortMethod;
methodTypeToInvoke = GET_PORT_CLIENT_MANAGED;
argsForInvoke = new Object[] { portInfo.getWsdlPort(),
args[0] };
} else {
// This means the deployer did not resolve the port to
// which this SEI is mapped. Just call getPort(SEI)
// method on delegate. This is not guaranteed to work.
}
break;
case GET_WSDL_LOCATION :
return wsdlLocation;
case CREATE_CALL_PORT :
case CREATE_CALL_OPERATION_QNAME :
case CREATE_CALL_OPERATION_STRING :
case GET_CALLS :
case GET_PORTS :
serviceToInvoke = getConfiguredServiceDelegate();
break;
} // End switch (methodType)
returnValue = methodToInvoke.invoke(serviceToInvoke, argsForInvoke);
if( returnValue instanceof Stub ) {
Stub stub = (Stub) returnValue;
setStubProperties(stub, methodTypeToInvoke, methodToInvoke,
argsForInvoke);
} else if( returnValue instanceof Call ) {
Call[] calls = new Call[1];
calls[0] = (Call) returnValue;
setCallProperties(calls, methodTypeToInvoke, argsForInvoke);
} else if( methodType == GET_CALLS ) {
Call[] calls = (Call[]) returnValue;
setCallProperties(calls, methodTypeToInvoke, argsForInvoke);
}
} catch(InvocationTargetException ite) {
throw ite.getCause();
}
return returnValue;
| private java.lang.Object | invokeJavaObjectMethod(java.lang.reflect.InvocationHandler handler, java.lang.reflect.Method method, java.lang.Object[] args)
Object returnValue = null;
// Can only be one of :
// boolean java.lang.Object.equals(Object)
// int java.lang.Object.hashCode()
// String java.lang.Object.toString()
//
// Optimize by comparing as few characters as possible.
switch( method.getName().charAt(0) ) {
case 'e" :
Object other = Proxy.isProxyClass(args[0].getClass()) ?
Proxy.getInvocationHandler(args[0]) : args[0];
returnValue = new Boolean(handler.equals(other));
break;
case 'h" :
returnValue = new Integer(handler.hashCode());
break;
case 't" :
returnValue = handler.toString();
break;
default :
throw new Throwable("Object method " + method.getName() +
"not found");
}
return returnValue;
| private void | setCallProperties(javax.xml.rpc.Call[] calls, int methodType, java.lang.Object[] args)
Set callProperties = getPropertiesForCall(methodType, args);
if( callProperties != null ) {
for(int callIndex = 0; callIndex < calls.length; callIndex++) {
setCallProperties(calls[callIndex], callProperties);
}
}
| private void | setCallProperties(javax.xml.rpc.Call call, java.util.Set callProperties)
for(Iterator iter = callProperties.iterator(); iter.hasNext();) {
NameValuePairDescriptor next = (NameValuePairDescriptor)
iter.next();
call.setProperty(next.getName(), next.getValue());
}
| private void | setJBIProperties(java.lang.Object stubOrCall, com.sun.enterprise.deployment.ServiceRefPortInfo portInfo)
// Check if the target service is a JBI service, and get its QName
QName svcQName = serviceRef.getServiceName();
if ( svcQName == null )
return;
if ( stubOrCall instanceof Stub ) {
com.sun.xml.rpc.spi.runtime.StubBase stub =
(com.sun.xml.rpc.spi.runtime.StubBase)stubOrCall;
try {
// This statement is getting executed only
//because jbi-enabled property on the stub is set to true
ServiceEngineUtil.setJBITransportFactory(portInfo, stub, true);
} catch(Throwable e) {
// Do nothing
//logger.severe("Exception raised while setting transport " +
// "factory to NMR : " + e.getMessage());
}
return;
}
| private void | setStubProperties(javax.xml.rpc.Stub stub, int methodType, java.lang.reflect.Method method, java.lang.Object[] args)
// Port info lookup will be based on SEI or port.
QName port = null;
String serviceEndpointInterface = null;
switch(methodType) {
case GET_PORT_CONTAINER_MANAGED :
serviceEndpointInterface = ((Class) args[0]).getName();
break;
case GET_PORT_CLIENT_MANAGED :
port = (QName) args[0];
serviceEndpointInterface = ((Class) args[1]).getName();
break;
case GENERATED_SERVICE_METHOD :
// java.rmi.Remote get<Name_of_wsdl:port>()
String portLocalPart = method.getName().startsWith("get") ?
method.getName().substring(3) : null;
if( portLocalPart != null ) {
QName serviceName = serviceRef.getServiceName();
port = new QName(serviceName.getNamespaceURI(), portLocalPart);
}
serviceEndpointInterface = method.getReturnType().getName();
break;
default :
return;
}
ServiceRefPortInfo portInfo = null;
// If port is known, it takes precedence in lookup.
if( port != null ) {
portInfo = serviceRef.getPortInfoByPort(port);
}
if( portInfo == null ) {
portInfo = serviceRef.getPortInfoBySEI(serviceEndpointInterface);
}
if( portInfo != null ) {
Set properties = portInfo.getStubProperties();
for(Iterator iter = properties.iterator(); iter.hasNext();) {
NameValuePairDescriptor next = (NameValuePairDescriptor)
iter.next();
if( next.getName().equals
(WsUtil.CLIENT_TRANSPORT_LOG_PROPERTY) ) {
// value is a URL
wsUtil.setClientTransportLog(serviceRef, stub,
next.getValue());
} else if(next.getName().equals(ServiceEngineUtil.JBI_ENABLED)){
setJBIProperties(stub, portInfo);
} else {
stub._setProperty(next.getName(), next.getValue());
}
}
// If this port has a resolved target endpoint address due to a
// port-component-link, set it on stub. However, if the runtime
// info has an entry for target endpoint address, that takes
// precedence.
if( portInfo.hasTargetEndpointAddress() ) {
if(!portInfo.hasStubProperty(Stub.ENDPOINT_ADDRESS_PROPERTY)) {
stub._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY,
portInfo.getTargetEndpointAddress());
}
}
}
|
|