1 23 package com.sun.enterprise.webservice; 24 25 import java.lang.UnsupportedOperationException ; 26 27 import java.net.URL ; 28 29 import java.util.HashSet ; 30 import java.util.Set ; 31 import java.util.Map ; 32 import java.util.HashMap ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.lang.reflect.Method ; 36 import java.lang.reflect.Proxy ; 37 import java.lang.reflect.InvocationHandler ; 38 import java.lang.reflect.InvocationTargetException ; 39 40 import javax.xml.namespace.QName ; 41 import javax.xml.rpc.Service ; 42 import javax.xml.rpc.handler.HandlerInfo ; 43 import javax.xml.rpc.handler.HandlerRegistry ; 44 import javax.xml.rpc.Stub ; 45 import javax.xml.rpc.Call ; 46 47 import com.sun.enterprise.deployment.ServiceReferenceDescriptor; 48 import com.sun.enterprise.deployment.ServiceRefPortInfo; 49 import com.sun.enterprise.deployment.NameValuePairDescriptor; 50 import com.sun.enterprise.deployment.runtime.common.MessageSecurityBindingDescriptor; 51 52 import com.sun.enterprise.security.jauth.ClientAuthConfig; 53 import com.sun.enterprise.webservice.WSSCallbackHandler; 54 import com.sun.enterprise.webservice.MessageLayerClientHandler; 55 56 69 public class ServiceInvocationHandler implements InvocationHandler { 70 71 private ServiceReferenceDescriptor serviceRef; 72 73 private Service serviceDelegate; 75 76 private Service configuredServiceDelegate; 78 79 private ClassLoader classLoader; 80 81 private Method getClientManagedPortMethod; 82 83 private URL wsdlLocation; 85 86 private boolean fullWsdl = false; 87 private boolean noWsdl = false; 88 89 private WsUtil wsUtil = new WsUtil(); 90 91 private static final int CREATE_CALL_NO_ARGS = 1; 93 private static final int CREATE_CALL_PORT = 2; 94 private static final int CREATE_CALL_OPERATION_QNAME = 3; 95 private static final int CREATE_CALL_OPERATION_STRING = 4; 96 private static final int GET_CALLS = 5; 97 private static final int GET_HANDLER_REGISTRY = 6; 98 private static final int GET_PORT_CONTAINER_MANAGED = 7; 99 private static final int GET_PORT_CLIENT_MANAGED = 8; 100 private static final int GET_PORTS = 9; 101 private static final int GET_SERVICE_NAME = 10; 102 private static final int GET_TYPE_MAPPING_REGISTRY = 11; 103 private static final int GET_WSDL_LOCATION = 12; 104 private static final int GENERATED_SERVICE_METHOD = 13; 105 106 private static Map serviceMethodTypes; 107 private static Set fullWsdlIllegalMethods; 108 private static Set noWsdlIllegalMethods; 109 110 static { 111 Init(); 112 } 113 114 public ServiceInvocationHandler(ServiceReferenceDescriptor descriptor, 115 Service delegate, ClassLoader loader) 116 throws Exception { 117 118 serviceRef = descriptor; 119 serviceDelegate = delegate; 120 classLoader = loader; 121 122 if( serviceRef.hasWsdlFile() ) { 123 wsdlLocation = wsUtil.privilegedGetServiceRefWsdl(serviceRef); 124 fullWsdl = true; 125 } else { 126 noWsdl = true; 127 } 128 129 getClientManagedPortMethod = javax.xml.rpc.Service .class.getMethod 130 ("getPort", new Class [] { QName .class, Class .class } ); 131 132 addMessageSecurityHandler(delegate); 133 } 134 135 public Object invoke(Object proxy, Method method, Object [] args) 136 throws Throwable { 137 138 141 if( method.getDeclaringClass() == java.lang.Object .class ) { 142 return invokeJavaObjectMethod(this, method, args); 143 } 144 145 int methodType = getMethodType(method); 146 147 checkUnsupportedMethods(methodType); 148 149 Object returnValue = null; 150 151 try { 152 153 Object serviceToInvoke = serviceDelegate; 156 Method methodToInvoke = method; 157 int methodTypeToInvoke = methodType; 158 Object [] argsForInvoke = args; 159 160 switch(methodType) { 161 162 case GET_PORT_CONTAINER_MANAGED : 163 Class serviceEndpointInterfaceClass = (Class ) args[0]; 164 String serviceEndpointInterface = 165 serviceEndpointInterfaceClass.getName(); 166 ServiceRefPortInfo portInfo = 167 serviceRef.getPortInfo(serviceEndpointInterface); 168 169 if( (portInfo != null) && portInfo.hasWsdlPort() ) { 171 methodToInvoke = getClientManagedPortMethod; 172 methodTypeToInvoke = GET_PORT_CLIENT_MANAGED; 173 argsForInvoke = new Object [] { portInfo.getWsdlPort(), 174 args[0] }; 175 } else { 176 } 180 break; 181 182 case GET_WSDL_LOCATION : 183 return wsdlLocation; 184 185 case CREATE_CALL_PORT : 186 case CREATE_CALL_OPERATION_QNAME : 187 case CREATE_CALL_OPERATION_STRING : 188 case GET_CALLS : 189 case GET_PORTS : 190 191 serviceToInvoke = getConfiguredServiceDelegate(); 192 break; 193 194 } 196 returnValue = methodToInvoke.invoke(serviceToInvoke, argsForInvoke); 197 198 if( returnValue instanceof Stub ) { 199 Stub stub = (Stub ) returnValue; 200 setStubProperties(stub, methodTypeToInvoke, methodToInvoke, 201 argsForInvoke); 202 } else if( returnValue instanceof Call ) { 203 Call [] calls = new Call [1]; 204 calls[0] = (Call ) returnValue; 205 setCallProperties(calls, methodTypeToInvoke, argsForInvoke); 206 } else if( methodType == GET_CALLS ) { 207 Call [] calls = (Call []) returnValue; 208 setCallProperties(calls, methodTypeToInvoke, argsForInvoke); 209 } 210 211 } catch(InvocationTargetException ite) { 212 throw ite.getCause(); 213 } 214 215 return returnValue; 216 } 217 218 public HandlerInfo getMessageSecurityHandlerInfo(QName port) throws Exception 219 { 220 HandlerInfo rvalue = null; 221 222 MessageSecurityBindingDescriptor binding = null; 223 ServiceRefPortInfo portInfo = serviceRef.getPortInfoByPort(port); 224 if (portInfo != null) { 225 binding = portInfo.getMessageSecurityBinding(); 226 } 227 228 ClientAuthConfig config = ClientAuthConfig.getConfig 229 (com.sun.enterprise.security.jauth.AuthConfig.SOAP, 230 binding,WSSCallbackHandler.getInstance()); 231 232 if (config != null) { 233 234 QName [] headers = config.getMechanisms(); 236 237 Map properties = new HashMap (); 238 properties.put(MessageLayerClientHandler.CLIENT_AUTH_CONFIG, config); 239 properties.put(javax.xml.ws.handler.MessageContext.WSDL_SERVICE, 240 serviceRef.getServiceName()); 241 242 rvalue = new HandlerInfo (MessageLayerClientHandler.class, 243 properties, headers); 244 } 245 246 return rvalue; 247 } 248 249 private boolean addMessageSecurityHandler(Service service) throws Exception 250 { 251 HandlerRegistry registry = service.getHandlerRegistry(); 252 Iterator ports = null; 253 try { 254 ports = service.getPorts(); 255 } catch (Exception e) { 256 ports = null; 259 } 260 261 while(ports != null && ports.hasNext()) { 262 263 QName nextPort = (QName ) ports.next(); 264 265 List handlerChain = registry.getHandlerChain(nextPort); 266 267 271 HandlerInfo handlerInfo = getMessageSecurityHandlerInfo(nextPort); 272 273 if (handlerInfo != null) { 274 handlerChain.add(handlerInfo); 275 } 276 } 277 278 return ports == null ? false : true; 279 } 280 281 private Service getConfiguredServiceDelegate() throws Exception { 282 synchronized(this) { 283 if( configuredServiceDelegate == null ) { 284 Service configuredService = 291 wsUtil.createConfiguredService(serviceRef); 292 wsUtil.configureHandlerChain(serviceRef, configuredService, 293 configuredService.getPorts(), classLoader); 294 configuredServiceDelegate = configuredService; 295 296 addMessageSecurityHandler(configuredService); 297 } 298 } 299 return configuredServiceDelegate; 300 } 301 302 private int getMethodType(Method method) { 303 Integer methodType = (Integer ) serviceMethodTypes.get(method); 304 return (methodType != null) ? 305 methodType.intValue() : GENERATED_SERVICE_METHOD; 306 } 307 308 311 private static void Init() { 312 313 serviceMethodTypes = new HashMap (); 314 fullWsdlIllegalMethods = new HashSet (); 315 noWsdlIllegalMethods = new HashSet (); 316 317 try { 318 319 Class noParams[] = new Class [0]; 320 String createCall = "createCall"; 321 Class serviceClass = javax.xml.rpc.Service .class; 322 323 327 Method createCallNoArgs = 328 serviceClass.getDeclaredMethod(createCall, noParams); 329 serviceMethodTypes.put(createCallNoArgs, 330 new Integer (CREATE_CALL_NO_ARGS)); 331 332 Method createCallPort = 333 serviceClass.getDeclaredMethod(createCall, 334 new Class [] { QName .class }); 335 serviceMethodTypes.put(createCallPort, 336 new Integer (CREATE_CALL_PORT)); 337 338 Method createCallOperationQName = 339 serviceClass.getDeclaredMethod 340 (createCall, new Class [] { QName .class, QName .class }); 341 serviceMethodTypes.put(createCallOperationQName, 342 new Integer (CREATE_CALL_OPERATION_QNAME)); 343 344 Method createCallOperationString = 345 serviceClass.getDeclaredMethod 346 (createCall, new Class [] { QName .class, String .class }); 347 serviceMethodTypes.put(createCallOperationString, 348 new Integer (CREATE_CALL_OPERATION_STRING)); 349 350 Method getCalls = serviceClass.getDeclaredMethod 351 ("getCalls", new Class [] { QName .class }); 352 serviceMethodTypes.put(getCalls, new Integer (GET_CALLS)); 353 354 Method getHandlerRegistry = serviceClass.getDeclaredMethod 355 ("getHandlerRegistry", noParams); 356 serviceMethodTypes.put(getHandlerRegistry, 357 new Integer (GET_HANDLER_REGISTRY)); 358 359 Method getPortContainerManaged = serviceClass.getDeclaredMethod 360 ("getPort", new Class [] { Class .class }); 361 serviceMethodTypes.put(getPortContainerManaged, 362 new Integer (GET_PORT_CONTAINER_MANAGED)); 363 364 Method getPortClientManaged = serviceClass.getDeclaredMethod 365 ("getPort", new Class [] { QName .class, Class .class }); 366 serviceMethodTypes.put(getPortClientManaged, 367 new Integer (GET_PORT_CLIENT_MANAGED)); 368 369 Method getPorts = serviceClass.getDeclaredMethod 370 ("getPorts", noParams); 371 serviceMethodTypes.put(getPorts, new Integer (GET_PORTS)); 372 373 Method getServiceName = serviceClass.getDeclaredMethod 374 ("getServiceName", noParams); 375 serviceMethodTypes.put(getServiceName, 376 new Integer (GET_SERVICE_NAME)); 377 378 Method getTypeMappingRegistry = serviceClass.getDeclaredMethod 379 ("getTypeMappingRegistry", noParams); 380 serviceMethodTypes.put(getTypeMappingRegistry, 381 new Integer (GET_TYPE_MAPPING_REGISTRY)); 382 383 Method getWsdlLocation = serviceClass.getDeclaredMethod 384 ("getWSDLDocumentLocation", noParams); 385 serviceMethodTypes.put(getWsdlLocation, 386 new Integer (GET_WSDL_LOCATION)); 387 } catch(NoSuchMethodException nsme) {} 388 389 392 fullWsdlIllegalMethods.add(new Integer (GET_HANDLER_REGISTRY)); 393 fullWsdlIllegalMethods.add(new Integer (GET_TYPE_MAPPING_REGISTRY)); 394 395 noWsdlIllegalMethods.add(new Integer (CREATE_CALL_PORT)); 396 noWsdlIllegalMethods.add(new Integer (CREATE_CALL_OPERATION_QNAME)); 397 noWsdlIllegalMethods.add(new Integer (CREATE_CALL_OPERATION_STRING)); 398 noWsdlIllegalMethods.add(new Integer (GET_CALLS)); 399 noWsdlIllegalMethods.add(new Integer (GET_HANDLER_REGISTRY)); 400 noWsdlIllegalMethods.add(new Integer (GET_PORT_CONTAINER_MANAGED)); 401 noWsdlIllegalMethods.add(new Integer (GET_PORT_CLIENT_MANAGED)); 402 noWsdlIllegalMethods.add(new Integer (GET_PORTS)); 403 noWsdlIllegalMethods.add(new Integer (GET_SERVICE_NAME)); 404 noWsdlIllegalMethods.add(new Integer (GET_TYPE_MAPPING_REGISTRY)); 405 noWsdlIllegalMethods.add(new Integer (GET_WSDL_LOCATION)); 406 407 noWsdlIllegalMethods.add(new Integer (GENERATED_SERVICE_METHOD)); 411 } 412 413 private void checkUnsupportedMethods(int methodType) 414 throws UnsupportedOperationException { 415 416 Set illegalMethods = fullWsdl ? 417 fullWsdlIllegalMethods : noWsdlIllegalMethods; 418 419 if( illegalMethods.contains(new Integer (methodType)) ) { 420 throw new UnsupportedOperationException (); 421 } 422 423 return; 424 } 425 426 private void setStubProperties(Stub stub, int methodType, Method method, 427 Object [] args) { 428 429 QName port = null; 431 String serviceEndpointInterface = null; 432 433 switch(methodType) { 434 case GET_PORT_CONTAINER_MANAGED : 435 436 serviceEndpointInterface = ((Class ) args[0]).getName(); 437 break; 438 439 case GET_PORT_CLIENT_MANAGED : 440 441 port = (QName ) args[0]; 442 serviceEndpointInterface = ((Class ) args[1]).getName(); 443 break; 444 445 case GENERATED_SERVICE_METHOD : 446 447 String portLocalPart = method.getName().startsWith("get") ? 449 method.getName().substring(3) : null; 450 if( portLocalPart != null ) { 451 QName serviceName = serviceRef.getServiceName(); 452 port = new QName (serviceName.getNamespaceURI(), portLocalPart); 453 } 454 serviceEndpointInterface = method.getReturnType().getName(); 455 456 break; 457 458 default : 459 return; 460 } 461 462 ServiceRefPortInfo portInfo = null; 463 464 if( port != null ) { 466 portInfo = serviceRef.getPortInfoByPort(port); 467 } 468 if( portInfo == null ) { 469 portInfo = serviceRef.getPortInfoBySEI(serviceEndpointInterface); 470 } 471 472 if( portInfo != null ) { 473 Set properties = portInfo.getStubProperties(); 474 475 for(Iterator iter = properties.iterator(); iter.hasNext();) { 476 NameValuePairDescriptor next = (NameValuePairDescriptor) 477 iter.next(); 478 if( next.getName().equals 479 (WsUtil.CLIENT_TRANSPORT_LOG_PROPERTY) ) { 480 wsUtil.setClientTransportLog(serviceRef, stub, 482 next.getValue()); 483 } else if(next.getName().equals(ServiceEngineUtil.JBI_ENABLED)){ 484 setJBIProperties(stub, portInfo); 485 } else { 486 stub._setProperty(next.getName(), next.getValue()); 487 } 488 } 489 490 if( portInfo.hasTargetEndpointAddress() ) { 495 if(!portInfo.hasStubProperty(Stub.ENDPOINT_ADDRESS_PROPERTY)) { 496 stub._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, 497 portInfo.getTargetEndpointAddress()); 498 } 499 } 500 } 501 } 502 503 private void setCallProperties(Call [] calls, int methodType, Object [] args){ 504 505 Set callProperties = getPropertiesForCall(methodType, args); 506 507 if( callProperties != null ) { 508 for(int callIndex = 0; callIndex < calls.length; callIndex++) { 509 setCallProperties(calls[callIndex], callProperties); 510 } 511 } 512 } 513 514 private Set getPropertiesForCall(int methodType, Object args[]) { 515 516 Set callProperties = null; 517 switch(methodType) { 518 519 case CREATE_CALL_PORT : 520 case CREATE_CALL_OPERATION_QNAME : 521 case CREATE_CALL_OPERATION_STRING : 522 case GET_CALLS : 523 524 QName port = (QName ) args[0]; 526 527 ServiceRefPortInfo portInfo = 529 serviceRef.getPortInfoByPort(port); 530 if( portInfo != null ) { 531 callProperties = portInfo.getCallProperties(); 532 } 533 534 break; 535 536 case CREATE_CALL_NO_ARGS : 537 538 callProperties = serviceRef.getCallProperties(); 539 break; 540 541 } 542 543 return callProperties; 544 } 545 546 private void setCallProperties(Call call, Set callProperties) { 547 for(Iterator iter = callProperties.iterator(); iter.hasNext();) { 548 NameValuePairDescriptor next = (NameValuePairDescriptor) 549 iter.next(); 550 call.setProperty(next.getName(), next.getValue()); 551 } 552 } 553 554 private Object invokeJavaObjectMethod(InvocationHandler handler, 555 Method method, Object [] args) 556 throws Throwable { 557 558 Object returnValue = null; 559 560 567 switch( method.getName().charAt(0) ) { 568 case 'e' : 569 Object other = Proxy.isProxyClass(args[0].getClass()) ? 570 Proxy.getInvocationHandler(args[0]) : args[0]; 571 returnValue = new Boolean (handler.equals(other)); 572 break; 573 case 'h' : 574 returnValue = new Integer (handler.hashCode()); 575 break; 576 case 't' : 577 returnValue = handler.toString(); 578 break; 579 default : 580 throw new Throwable ("Object method " + method.getName() + 581 "not found"); 582 } 583 584 return returnValue; 585 } 586 587 private void setJBIProperties(Object stubOrCall, ServiceRefPortInfo portInfo) { 588 QName svcQName = serviceRef.getServiceName(); 590 if ( svcQName == null ) 591 return; 592 593 if ( stubOrCall instanceof Stub ) { 594 com.sun.xml.rpc.spi.runtime.StubBase stub = 595 (com.sun.xml.rpc.spi.runtime.StubBase)stubOrCall; 596 597 try { 598 ServiceEngineUtil.setJBITransportFactory(portInfo, stub, true); 601 } catch(Throwable e) { 602 } 606 return; 607 } 608 } 609 } 610 | Popular Tags |