1 7 8 package org.jboss.webservice.client; 10 11 13 import org.jboss.logging.Logger; 14 import org.jboss.mx.util.MBeanServerLocator; 15 import org.jboss.system.server.ServerConfig; 16 import org.jboss.webservice.AxisServiceMBean; 17 import org.jboss.webservice.PortComponentInfo; 18 import org.jboss.webservice.deployment.ServiceDescription; 19 import org.jboss.webservice.metadata.jaxrpcmapping.JavaWsdlMapping; 20 import org.jboss.webservice.metadata.serviceref.HandlerMetaData; 21 import org.jboss.webservice.metadata.serviceref.InitParamMetaData; 22 import org.jboss.webservice.metadata.serviceref.PortComponentRefMetaData; 23 import org.jboss.webservice.metadata.serviceref.ServiceRefMetaData; 24 import org.jboss.webservice.util.WSDLUtilities; 25 26 import javax.management.MBeanServer ; 27 import javax.naming.Context ; 28 import javax.naming.Name ; 29 import javax.naming.NamingException ; 30 import javax.naming.RefAddr ; 31 import javax.naming.Reference ; 32 import javax.naming.spi.NamingManager ; 33 import javax.naming.spi.ObjectFactory ; 34 import javax.wsdl.Definition; 35 import javax.wsdl.Port; 36 import javax.wsdl.Service; 37 import javax.xml.namespace.QName ; 38 import javax.xml.rpc.JAXRPCException ; 39 import javax.xml.rpc.handler.HandlerInfo ; 40 import java.io.BufferedReader ; 41 import java.io.ByteArrayInputStream ; 42 import java.io.File ; 43 import java.io.IOException ; 44 import java.io.InputStream ; 45 import java.io.InputStreamReader ; 46 import java.io.ObjectInputStream ; 47 import java.lang.reflect.InvocationHandler ; 48 import java.lang.reflect.Proxy ; 49 import java.net.MalformedURLException ; 50 import java.net.URL ; 51 import java.net.URLClassLoader ; 52 import java.net.URLEncoder ; 53 import java.util.ArrayList ; 54 import java.util.Arrays ; 55 import java.util.HashMap ; 56 import java.util.HashSet ; 57 import java.util.Hashtable ; 58 import java.util.Iterator ; 59 import java.util.List ; 60 import java.util.Properties ; 61 62 71 public class ServiceObjectFactory implements ObjectFactory 72 { 73 private static final Logger log = Logger.getLogger(ServiceObjectFactory.class); 75 76 96 public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) 97 throws Exception 98 { 99 Reference ref = (Reference )obj; 100 101 ServiceRefMetaData serviceRef = null; 102 103 RefAddr metaRefAddr = ref.get(ServiceReferenceable.SERVICE_REF_META_DATA); 105 ByteArrayInputStream bais = new ByteArrayInputStream ((byte[])metaRefAddr.getContent()); 106 try 107 { 108 ObjectInputStream ois = new ObjectInputStream (bais); 109 serviceRef = (ServiceRefMetaData)ois.readObject(); 110 ois.close(); 111 } 112 catch (IOException e) 113 { 114 throw new NamingException ("Cannot unmarshall service ref meta data, cause: " + e.toString()); 115 } 116 117 URL url = new URL ((String )ref.get(ServiceReferenceable.DEPLOYMENT_URL).getContent()); 119 ClassLoader contextCL = Thread.currentThread().getContextClassLoader(); 120 URLClassLoader resourceCl = new URLClassLoader (new URL []{url}, contextCL); 121 serviceRef.setResourceCl(resourceCl); 122 123 URL wsdlURL = serviceRef.getWsdlOverride(); 125 if (wsdlURL == null && serviceRef.getWsdlFile() != null) 126 { 127 String wsdlFile = serviceRef.getWsdlFile(); 128 wsdlURL = resourceCl.findResource(wsdlFile); 129 if (wsdlURL == null) 130 throw new NamingException ("Cannot load wsdl file '" + wsdlFile + "' from: " + url); 131 } 132 133 JavaWsdlMapping javaWsdlMapping = serviceRef.getJavaWsdlMapping(); 134 135 URL ws4eeMetaData = findTypeMappingMetaData(resourceCl); 137 138 ServiceImpl jaxrpcService = null; 139 Definition wsdlDefinition = null; 140 Service wsdlService = null; 141 142 if (wsdlURL != null) 143 { 144 log.debug("Create jaxrpc service for wsdl: " + wsdlURL); 145 wsdlDefinition = serviceRef.getWsdlDefinition(); 146 147 QName serviceName = serviceRef.getServiceQName(); 150 151 if (serviceName == null && wsdlDefinition.getServices().values().size() == 1) 152 serviceName = (QName )wsdlDefinition.getServices().keySet().iterator().next(); 153 154 if (serviceName == null) 155 throw new IllegalStateException ("Cannot obtain service name, use <service-qname> in your <service-ref>"); 156 157 jaxrpcService = new ServiceImpl(wsdlURL, serviceName); 159 jaxrpcService.setWsdlDefinition(wsdlDefinition); 160 jaxrpcService.setJavaWsdlMapping(javaWsdlMapping); 161 162 wsdlService = getServiceForName(wsdlDefinition, serviceName); 163 } 164 else 165 { 166 log.debug("Create jaxrpc service with no wsdl"); 167 jaxrpcService = new ServiceImpl(); 168 jaxrpcService.setJavaWsdlMapping(javaWsdlMapping); 169 } 170 171 if (wsdlService != null) 173 { 174 PortComponentRefMetaData[] pcRefs = serviceRef.getPortComponentRefs(); 176 if (pcRefs.length > 0) 177 { 178 for (int i = 0; i < pcRefs.length; i++) 179 { 180 PortComponentRefMetaData pcRef = pcRefs[i]; 181 String seiName = pcRef.getServiceEndpointInterface(); 182 183 QName portTypeQName = null; 184 if (javaWsdlMapping != null) 185 portTypeQName = javaWsdlMapping.getPortTypeQNameForServiceEndpointInterface(seiName); 186 187 List portNames = getPortNameForType(wsdlService, portTypeQName); 188 for (Iterator j = portNames.iterator(); j.hasNext();) 189 { 190 String portName = (String )j.next(); 191 ServiceDescription serviceDesc = new ServiceDescription(wsdlDefinition, javaWsdlMapping, ws4eeMetaData, portName); 192 serviceDesc.setCallProperties(pcRef.getCallProperties()); 193 jaxrpcService.initService(serviceDesc, portName); 194 } 195 } 196 } 197 else 198 { 199 ServiceDescription serviceDesc = new ServiceDescription(wsdlDefinition, javaWsdlMapping, ws4eeMetaData, null); 201 jaxrpcService.initService(serviceDesc, null); 202 } 203 204 setupHandlerChain(jaxrpcService, serviceRef, wsdlService); 206 } 207 208 Properties callProps = serviceRef.getCallProperties(); 210 jaxrpcService.setCallProperties(callProps); 211 212 RefAddr pclinkRef = ref.get(ServiceReferenceable.PORT_COMPONENT_LINK); 215 if (pclinkRef != null) 216 { 217 String serviceID = (String )pclinkRef.getContent(); 218 log.debug("Resolving port-component-link: " + serviceID); 219 220 String targetEndpointAddress = null; 222 try 223 { 224 MBeanServer server = MBeanServerLocator.locateJBoss(); 225 PortComponentInfo pcInfo = (PortComponentInfo)server.invoke(AxisServiceMBean.OBJECT_NAME, "getPortComponentInfo", 226 new Object []{serviceID}, new String []{String .class.getName()}); 227 228 targetEndpointAddress = pcInfo.getServiceEndpointURL(); 229 } 230 catch (Exception ignore) 231 { 232 } 233 234 if (targetEndpointAddress == null) 236 { 237 String servletPath = (String )ref.get(ServiceReferenceable.PORT_COMPONENT_LINK_SERVLET).getContent(); 238 servletPath += "?serviceID=" + URLEncoder.encode(serviceID, "UTF-8"); 239 InputStream is = new URL (servletPath).openStream(); 240 BufferedReader br = new BufferedReader (new InputStreamReader (is)); 241 targetEndpointAddress = br.readLine(); 242 is.close(); 243 } 244 245 log.debug("Resolved to: " + targetEndpointAddress); 246 jaxrpcService.setTargetEndpointAddress(targetEndpointAddress); 247 } 248 249 252 253 Class siClass = serviceRef.getServiceInterfaceClass(); 255 if (javax.xml.rpc.Service .class.isAssignableFrom(siClass) == false) 256 throw new JAXRPCException ("The service interface does not implement javax.xml.rpc.Service: " + siClass.getName()); 257 258 PortComponentRefMetaData[] pcrArray = serviceRef.getPortComponentRefs(); 260 for (int i = 0; i < pcrArray.length; i++) 261 { 262 PortComponentRefMetaData pcr = pcrArray[i]; 263 Class seiClass = pcr.getServiceEndpointInterfaceClass(); 264 if (java.rmi.Remote .class.isAssignableFrom(seiClass) == false) 265 throw new IllegalArgumentException ("The SEI does not implement java.rmi.Remote: " + seiClass.getName()); 266 267 if (wsdlDefinition != null) 268 WSDLUtilities.endorseServiceEndpointInterface(wsdlDefinition, seiClass, javaWsdlMapping); 269 } 270 271 InvocationHandler handler = new ServiceProxy(jaxrpcService, siClass); 272 return (javax.xml.rpc.Service )Proxy.newProxyInstance(contextCL, new Class []{siClass}, handler); 273 } 274 275 281 private List getPortNameForType(javax.wsdl.Service wsdlService, QName portType) 282 { 283 List portNames = new ArrayList (); 284 285 if (portType != null) 286 { 287 for (Iterator i = wsdlService.getPorts().values().iterator(); i.hasNext();) 288 { 289 Port wsdlPort = (Port)i.next(); 290 if (wsdlPort.getBinding().getPortType().getQName().equals(portType)) 291 portNames.add(wsdlPort.getName()); 292 } 293 } 294 295 else if (wsdlService.getPorts().values().size() == 1) 297 { 298 for (Iterator i = wsdlService.getPorts().values().iterator(); i.hasNext();) 299 { 300 Port wsdlPort = (Port)i.next(); 301 portNames.add(wsdlPort.getName()); 302 } 303 } 304 305 if (portNames.isEmpty()) 306 throw new IllegalArgumentException ("Cannot obtatin portName for binding: " + portType); 307 308 return portNames; 309 } 310 311 private javax.wsdl.Service getServiceForName(Definition wsdlDefinition, QName serviceName) 312 { 313 javax.wsdl.Service wsdlService = null; 314 315 if (serviceName != null) 316 { 317 wsdlService = wsdlDefinition.getService(serviceName); 318 } 319 else if (wsdlDefinition.getServices().values().size() == 1) 320 { 321 wsdlService = (javax.wsdl.Service)wsdlDefinition.getServices().values().iterator().next(); 322 } 323 324 if (wsdlService == null) 325 throw new IllegalArgumentException ("Cannot obtain WSDL service for name: " + serviceName); 326 327 return wsdlService; 328 } 329 330 337 private URL findTypeMappingMetaData(URLClassLoader resourceCL) 338 { 339 URL resourceURL = null; 340 341 String dataDir = System.getProperty(ServerConfig.SERVER_DATA_DIR); 343 File resourceFile = new File (dataDir + "/wsdl/ws4ee-deployment.xml"); 344 if (resourceFile.exists()) 345 { 346 try 347 { 348 resourceURL = resourceFile.toURL(); 349 } 350 catch (MalformedURLException e) 351 { 352 log.warn("Could not get url to ws4ee-deployment.xml.", e); 353 } 354 } 355 356 if (resourceURL == null) 357 { 358 String [] infDirs = new String []{"META-INF", "WEB-INF"}; 359 for (int i = 0; resourceURL == null && i < infDirs.length; i++) 360 { 361 String resName = infDirs[i] + "/ws4ee-deployment.xml"; 362 resourceURL = resourceCL.findResource(resName); 363 } 364 } 365 366 return resourceURL; 367 } 368 369 375 private void setupHandlerChain(ServiceImpl jaxrpcService, ServiceRefMetaData serviceRef, javax.wsdl.Service wsdlService) throws Exception 376 { 377 HandlerMetaData[] handlers = serviceRef.getHandlers(); 378 379 ClientEngine engine = (ClientEngine)jaxrpcService.getAxisClient(); 380 381 Iterator itPorts = wsdlService.getPorts().values().iterator(); 383 while (itPorts.hasNext()) 384 { 385 Port wsdlPort = (Port)itPorts.next(); 386 String portName = wsdlPort.getName(); 387 388 ServiceDescription serviceDesc = jaxrpcService.getServiceDescription(portName); 389 390 if (serviceDesc != null) 392 { 393 HashSet handlerRoles = new HashSet (); 394 ArrayList handlerInfos = new ArrayList (); 395 for (int i = 0; i < handlers.length; i++) 396 { 397 HandlerMetaData hMetaData = handlers[i]; 398 handlerRoles.addAll(Arrays.asList(hMetaData.getSoapRoles())); 399 400 List hPortNames = Arrays.asList(hMetaData.getPortNames()); 401 if (hPortNames.size() == 0 || hPortNames.contains(portName)) 402 { 403 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 404 Class hClass = cl.loadClass(hMetaData.getHandlerClass()); 405 406 HashMap hConfig = new HashMap (); 407 InitParamMetaData[] params = hMetaData.getInitParams(); 408 for (int j = 0; j < params.length; j++) 409 { 410 InitParamMetaData param = params[j]; 411 hConfig.put(param.getParamName(), param.getParamValue()); 412 } 413 414 QName [] hHeaders = hMetaData.getSoapHeaders(); 415 HandlerInfo info = new HandlerInfo (hClass, hConfig, hHeaders); 416 417 log.debug("Adding client side handler to port '" + portName + "': " + info); 418 handlerInfos.add(info); 419 } 420 } 421 422 if (handlerInfos.size() > 0) 424 engine.registerHandlerChain(portName, handlerInfos, handlerRoles); 425 } 426 } 427 } 428 } 429 | Popular Tags |