1 17 package org.apache.geronimo.webservices.builder; 18 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.lang.reflect.Method ; 22 import java.math.BigDecimal ; 23 import java.math.BigInteger ; 24 import java.net.URI ; 25 import java.net.URISyntaxException ; 26 import java.net.URL ; 27 import java.util.ArrayList ; 28 import java.util.Calendar ; 29 import java.util.HashMap ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.jar.JarFile ; 33 import java.util.zip.ZipEntry ; 34 35 import javax.wsdl.Definition; 36 import javax.wsdl.Operation; 37 import javax.wsdl.Port; 38 import javax.xml.namespace.QName ; 39 import javax.xml.rpc.handler.HandlerInfo ; 40 import javax.xml.rpc.holders.BigDecimalHolder ; 41 import javax.xml.rpc.holders.BigIntegerHolder ; 42 import javax.xml.rpc.holders.BooleanHolder ; 43 import javax.xml.rpc.holders.BooleanWrapperHolder ; 44 import javax.xml.rpc.holders.ByteArrayHolder ; 45 import javax.xml.rpc.holders.ByteHolder ; 46 import javax.xml.rpc.holders.ByteWrapperHolder ; 47 import javax.xml.rpc.holders.CalendarHolder ; 48 import javax.xml.rpc.holders.DoubleHolder ; 49 import javax.xml.rpc.holders.DoubleWrapperHolder ; 50 import javax.xml.rpc.holders.FloatHolder ; 51 import javax.xml.rpc.holders.FloatWrapperHolder ; 52 import javax.xml.rpc.holders.IntHolder ; 53 import javax.xml.rpc.holders.IntegerWrapperHolder ; 54 import javax.xml.rpc.holders.LongHolder ; 55 import javax.xml.rpc.holders.LongWrapperHolder ; 56 import javax.xml.rpc.holders.ObjectHolder ; 57 import javax.xml.rpc.holders.QNameHolder ; 58 import javax.xml.rpc.holders.ShortHolder ; 59 import javax.xml.rpc.holders.ShortWrapperHolder ; 60 import javax.xml.rpc.holders.StringHolder ; 61 62 import org.apache.geronimo.common.DeploymentException; 63 import org.apache.geronimo.kernel.ClassLoading; 64 import org.apache.geronimo.xbeans.j2ee.ExceptionMappingType; 65 import org.apache.geronimo.xbeans.j2ee.JavaWsdlMappingDocument; 66 import org.apache.geronimo.xbeans.j2ee.JavaWsdlMappingType; 67 import org.apache.geronimo.xbeans.j2ee.PackageMappingType; 68 import org.apache.geronimo.xbeans.j2ee.ParamValueType; 69 import org.apache.geronimo.xbeans.j2ee.PortComponentHandlerType; 70 import org.apache.geronimo.xbeans.j2ee.PortComponentType; 71 import org.apache.geronimo.xbeans.j2ee.ServiceEndpointInterfaceMappingType; 72 import org.apache.geronimo.xbeans.j2ee.ServiceEndpointMethodMappingType; 73 import org.apache.geronimo.xbeans.j2ee.ServiceImplBeanType; 74 import org.apache.geronimo.xbeans.j2ee.WebserviceDescriptionType; 75 import org.apache.geronimo.xbeans.j2ee.WebservicesDocument; 76 import org.apache.geronimo.xbeans.j2ee.WebservicesType; 77 import org.apache.geronimo.xbeans.j2ee.XsdQNameType; 78 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil; 79 import org.apache.geronimo.webservices.builder.PortInfo; 80 import org.apache.geronimo.webservices.builder.SchemaInfoBuilder; 81 import org.apache.xmlbeans.XmlException; 82 83 86 public class WSDescriptorParser { 87 88 89 public static JavaWsdlMappingType readJaxrpcMapping(JarFile moduleFile, URI jaxrpcMappingURI) throws DeploymentException { 90 String jaxrpcMappingPath = jaxrpcMappingURI.toString(); 91 return readJaxrpcMapping(moduleFile, jaxrpcMappingPath); 92 } 93 94 public static JavaWsdlMappingType readJaxrpcMapping(JarFile moduleFile, String jaxrpcMappingPath) throws DeploymentException { 95 JavaWsdlMappingType mapping; 96 InputStream jaxrpcInputStream = null; 97 try { 98 ZipEntry zipEntry = moduleFile.getEntry(jaxrpcMappingPath); 99 if(zipEntry == null){ 100 throw new DeploymentException("The JAX-RPC mapping file "+jaxrpcMappingPath+" specified in webservices.xml for the ejb module could not be found."); 101 } 102 jaxrpcInputStream = moduleFile.getInputStream(zipEntry); 103 } catch (IOException e) { 104 throw new DeploymentException("Could not open stream to jaxrpc mapping document", e); 105 } 106 JavaWsdlMappingDocument mappingDocument = null; 107 try { 108 mappingDocument = JavaWsdlMappingDocument.Factory.parse(jaxrpcInputStream); 109 } catch (XmlException e) { 110 throw new DeploymentException("Could not parse jaxrpc mapping document", e); 111 } catch (IOException e) { 112 throw new DeploymentException("Could not read jaxrpc mapping document", e); 113 } 114 mapping = mappingDocument.getJavaWsdlMapping(); 115 return mapping; 116 } 117 118 119 public static Map getExceptionMap(JavaWsdlMappingType mapping) { 120 Map exceptionMap = new HashMap (); 121 if (mapping != null) { 122 ExceptionMappingType[] exceptionMappings = mapping.getExceptionMappingArray(); 123 for (int i = 0; i < exceptionMappings.length; i++) { 124 ExceptionMappingType exceptionMapping = exceptionMappings[i]; 125 QName exceptionMessageQName = exceptionMapping.getWsdlMessage().getQNameValue(); 126 exceptionMap.put(exceptionMessageQName, exceptionMapping); 127 } 128 } 129 return exceptionMap; 130 } 131 132 public static String getPackageFromNamespace(String namespace, JavaWsdlMappingType mapping) throws DeploymentException { 133 PackageMappingType[] packageMappings = mapping.getPackageMappingArray(); 134 for (int i = 0; i < packageMappings.length; i++) { 135 PackageMappingType packageMapping = packageMappings[i]; 136 if (namespace.equals(packageMapping.getNamespaceURI().getStringValue().trim())) { 137 return packageMapping.getPackageType().getStringValue().trim(); 138 } 139 } 140 throw new DeploymentException("Namespace " + namespace + " was not mapped in jaxrpc mapping file"); 141 } 142 143 private static final Map rpcHolderClasses = new HashMap (); 144 145 static { 146 rpcHolderClasses.put(BigDecimal .class, BigDecimalHolder .class); 147 rpcHolderClasses.put(BigInteger .class, BigIntegerHolder .class); 148 rpcHolderClasses.put(boolean.class, BooleanHolder .class); 149 rpcHolderClasses.put(Boolean .class, BooleanWrapperHolder .class); 150 rpcHolderClasses.put(byte[].class, ByteArrayHolder .class); 151 rpcHolderClasses.put(byte.class, ByteHolder .class); 152 rpcHolderClasses.put(Byte .class, ByteWrapperHolder .class); 153 rpcHolderClasses.put(Calendar .class, CalendarHolder .class); 154 rpcHolderClasses.put(double.class, DoubleHolder .class); 155 rpcHolderClasses.put(Double .class, DoubleWrapperHolder .class); 156 rpcHolderClasses.put(float.class, FloatHolder .class); 157 rpcHolderClasses.put(Float .class, FloatWrapperHolder .class); 158 rpcHolderClasses.put(int.class, IntHolder .class); 159 rpcHolderClasses.put(Integer .class, IntegerWrapperHolder .class); 160 rpcHolderClasses.put(long.class, LongHolder .class); 161 rpcHolderClasses.put(Long .class, LongWrapperHolder .class); 162 rpcHolderClasses.put(Object .class, ObjectHolder .class); 163 rpcHolderClasses.put(QName .class, QNameHolder .class); 164 rpcHolderClasses.put(short.class, ShortHolder .class); 165 rpcHolderClasses.put(Short .class, ShortWrapperHolder .class); 166 rpcHolderClasses.put(String .class, StringHolder .class); 167 } 168 169 public static Class getHolderType(String paramJavaTypeName, boolean isInOnly, QName typeQName, boolean isComplexType, JavaWsdlMappingType mapping, ClassLoader classLoader) throws DeploymentException { 170 Class paramJavaType = null; 171 if (isInOnly) { 172 try { 174 paramJavaType = ClassLoading.loadClass(paramJavaTypeName, classLoader); 175 } catch (ClassNotFoundException e) { 176 throw new DeploymentException("could not load parameter type", e); 177 } 178 return paramJavaType; 179 } else { 180 String holderName; 182 if (isComplexType) { 183 String namespace = typeQName.getNamespaceURI(); 187 String packageName = WSDescriptorParser.getPackageFromNamespace(namespace, mapping); 188 StringBuffer buf = new StringBuffer (packageName.length() + typeQName.getLocalPart().length() + 14); 189 buf.append(packageName).append(".holders.").append(typeQName.getLocalPart()).append("Holder"); 190 buf.setCharAt(packageName.length() + 9, Character.toUpperCase(typeQName.getLocalPart().charAt(0))); 191 holderName = buf.toString(); 192 } else { 193 try { 195 paramJavaType = ClassLoading.loadClass(paramJavaTypeName, classLoader); 196 } catch (ClassNotFoundException e) { 197 throw new DeploymentException("could not load parameter type", e); 198 } 199 Class holder = (Class ) rpcHolderClasses.get(paramJavaType); 200 if (holder != null) { 201 try { 202 holder = ClassLoading.loadClass(holder.getName(), classLoader); 204 } catch (ClassNotFoundException e) { 205 throw new DeploymentException("could not load holder type in correct classloader", e); 206 } 207 return holder; 208 } 209 String paramTypeName = paramJavaType.getName(); 213 StringBuffer buf = new StringBuffer (paramTypeName.length() + 14); 214 int dot = paramTypeName.lastIndexOf("."); 215 buf.append(paramTypeName.substring(0, dot)).append(".holders").append(paramTypeName.substring(dot)).append("Holder"); 217 holderName = buf.toString(); 218 } 219 try { 220 Class holder = ClassLoading.loadClass(holderName, classLoader); 221 return holder; 222 } catch (ClassNotFoundException e) { 223 throw new DeploymentException("Could not load holder class", e); 224 } 225 } 226 } 227 228 public static ServiceEndpointMethodMappingType getMethodMappingForOperation(String operationName, ServiceEndpointMethodMappingType[] methodMappings) throws DeploymentException { 229 for (int i = 0; i < methodMappings.length; i++) { 230 ServiceEndpointMethodMappingType methodMapping = methodMappings[i]; 231 if (operationName.equals(methodMapping.getWsdlOperation().getStringValue())) { 232 return methodMapping; 233 } 234 } 235 StringBuffer availOps = new StringBuffer (128); 237 for (int i = 0; i < methodMappings.length; i++) { 238 if (i != 0) availOps.append(","); 239 availOps.append(methodMappings[i].getWsdlOperation().getStringValue()); 240 } 241 throw new DeploymentException("No method found for operation named '" + operationName + "'. Available operations: " + availOps); 242 } 243 244 public static ServiceEndpointInterfaceMappingType getServiceEndpointInterfaceMapping(ServiceEndpointInterfaceMappingType[] endpointMappings, QName portTypeQName) throws DeploymentException { 245 for (int i = 0; i < endpointMappings.length; i++) { 246 ServiceEndpointInterfaceMappingType endpointMapping = endpointMappings[i]; 247 QName testPortQName = endpointMapping.getWsdlPortType().getQNameValue(); 248 if (portTypeQName.equals(testPortQName)) { 249 return endpointMapping; 250 } 251 } 252 throw new DeploymentException("Could not find service endpoint interface for port named " + portTypeQName); 253 } 254 255 public static javax.wsdl.Service getService(QName serviceQName, Definition definition) throws DeploymentException { 256 javax.wsdl.Service service; 257 if (serviceQName != null) { 258 service = definition.getService(serviceQName); 259 } else { 260 Map services = definition.getServices(); 261 if (services.size() != 1) { 262 throw new DeploymentException("no serviceQName supplied, and there are " + services.size() + " services"); 263 } 264 service = (javax.wsdl.Service) services.values().iterator().next(); 265 } 266 if (service == null) { 267 throw new DeploymentException("No service wsdl for supplied service qname " + serviceQName); 268 } 269 return service; 270 } 271 272 public static Method getMethodForOperation(Class serviceEndpointInterface, Operation operation) throws DeploymentException { 273 Method [] methods = serviceEndpointInterface.getMethods(); 274 String opName = operation.getName(); 275 Method found = null; 276 for (int i = 0; i < methods.length; i++) { 277 Method method = methods[i]; 278 if (method.getName().equals(opName)) { 279 if (found != null) { 280 throw new DeploymentException("Overloaded methods are not allowed in lightweight mappings"); 281 } 282 found = method; 283 } 284 } 285 if (found == null) { 286 throw new DeploymentException("No method found for operation named " + opName); 287 } 288 return found; 289 } 290 291 302 public static Map parseWebServiceDescriptor(WebservicesType webservicesType, JarFile moduleFile, boolean isEJB, Map servletLocations) throws DeploymentException { 303 Map portMap = new HashMap (); 304 WebserviceDescriptionType[] webserviceDescriptions = webservicesType.getWebserviceDescriptionArray(); 305 for (int i = 0; i < webserviceDescriptions.length; i++) { 306 WebserviceDescriptionType webserviceDescription = webserviceDescriptions[i]; 307 URI wsdlURI = null; 308 try { 309 wsdlURI = new URI (webserviceDescription.getWsdlFile().getStringValue().trim()); 310 } catch (URISyntaxException e) { 311 throw new DeploymentException("could not construct wsdl uri from " + webserviceDescription.getWsdlFile().getStringValue(), e); 312 } 313 URI jaxrpcMappingURI = null; 314 try { 315 jaxrpcMappingURI = new URI (webserviceDescription.getJaxrpcMappingFile().getStringValue().trim()); 316 } catch (URISyntaxException e) { 317 throw new DeploymentException("Could not construct jaxrpc mapping uri from " + webserviceDescription.getJaxrpcMappingFile(), e); 318 } 319 SchemaInfoBuilder schemaInfoBuilder = new SchemaInfoBuilder(moduleFile, wsdlURI); 320 Map wsdlPortMap = schemaInfoBuilder.getPortMap(); 321 322 JavaWsdlMappingType javaWsdlMapping = readJaxrpcMapping(moduleFile, jaxrpcMappingURI); 323 HashMap seiMappings = new HashMap (); 324 ServiceEndpointInterfaceMappingType[] mappings = javaWsdlMapping.getServiceEndpointInterfaceMappingArray(); 325 for (int j = 0; j < mappings.length; j++) { 326 ServiceEndpointInterfaceMappingType seiMapping = mappings[j]; 327 seiMappings.put(seiMapping.getServiceEndpointInterface().getStringValue(), seiMapping); 328 } 329 330 PortComponentType[] portComponents = webserviceDescription.getPortComponentArray(); 331 for (int j = 0; j < portComponents.length; j++) { 332 PortComponentType portComponent = portComponents[j]; 333 String portComponentName = portComponent.getPortComponentName().getStringValue().trim(); 334 QName portQName = portComponent.getWsdlPort().getQNameValue(); 335 String seiInterfaceName = portComponent.getServiceEndpointInterface().getStringValue().trim(); 336 ServiceImplBeanType serviceImplBeanType = portComponent.getServiceImplBean(); 337 if (isEJB == serviceImplBeanType.isSetServletLink()) { 338 throw new DeploymentException("Wrong kind of web service described in web service descriptor: expected " + (isEJB ? "EJB" : "POJO(Servlet)")); 339 } 340 String linkName; 341 String servletLocation; 342 if (serviceImplBeanType.isSetServletLink()) { 343 linkName = serviceImplBeanType.getServletLink().getStringValue().trim(); 344 servletLocation = (String ) servletLocations.get(linkName); 345 if (servletLocation == null) { 346 throw new DeploymentException("No servlet mapping for port " + portQName); 347 } 348 schemaInfoBuilder.movePortLocation(portQName.getLocalPart(), servletLocation); 349 } else { 350 linkName = serviceImplBeanType.getEjbLink().getStringValue().trim(); 351 servletLocation = (String ) servletLocations.get(linkName); 352 servletLocation = schemaInfoBuilder.movePortLocation(portQName.getLocalPart(), servletLocation); 353 } 354 PortComponentHandlerType[] handlers = portComponent.getHandlerArray(); 355 356 Port port = (Port) wsdlPortMap.get(portQName.getLocalPart()); 357 if (port == null) { 358 throw new DeploymentException("No WSDL Port definition for port-component " + portComponentName); 359 } 360 361 ServiceEndpointInterfaceMappingType seiMapping = (ServiceEndpointInterfaceMappingType) seiMappings.get(seiInterfaceName); 362 363 String wsdlLocation = webserviceDescription.getWsdlFile().getStringValue().trim(); 364 URI contextURI = null; 365 try { 366 contextURI = new URI (servletLocation); 367 } catch (URISyntaxException e) { 368 throw new DeploymentException("Could not construct URI for web service location", e); 369 } 370 371 PortInfo portInfo = new PortInfo(portComponentName, portQName, schemaInfoBuilder, javaWsdlMapping, seiInterfaceName, handlers, port, seiMapping, wsdlLocation, contextURI); 372 373 if (portMap.put(linkName, portInfo) != null) { 374 throw new DeploymentException("Ambiguous description of port associated with j2ee component " + linkName); 375 } 376 } 377 } 378 return portMap; 379 } 380 381 public static Map parseWebServiceDescriptor(URL wsDDUrl, JarFile moduleFile, boolean isEJB, Map servletLocations) throws DeploymentException { 382 try { 383 WebservicesDocument webservicesDocument = WebservicesDocument.Factory.parse(wsDDUrl); 384 XmlBeansUtil.validateDD(webservicesDocument); 385 WebservicesType webservicesType = webservicesDocument.getWebservices(); 386 return parseWebServiceDescriptor(webservicesType, moduleFile, isEJB, servletLocations); 387 } catch (XmlException e) { 388 throw new DeploymentException("Could not read descriptor document", e); 389 } catch (IOException e) { 390 return null; 391 } 392 393 } 394 395 public static List createHandlerInfoList(PortComponentHandlerType[] handlers, ClassLoader classLoader) throws DeploymentException { 396 List list = new ArrayList (); 397 for (int i = 0; i < handlers.length; i++) { 398 PortComponentHandlerType handler = handlers[i]; 399 400 Class handlerClass = null; 402 String className = handler.getHandlerClass().getStringValue().trim(); 403 try { 404 handlerClass = classLoader.loadClass(className); 405 } catch (ClassNotFoundException e) { 406 throw new DeploymentException("Unable to load handler class: " + className, e); 407 } 408 409 Map config = new HashMap (); 411 ParamValueType[] paramValues = handler.getInitParamArray(); 412 for (int j = 0; j < paramValues.length; j++) { 413 ParamValueType paramValue = paramValues[j]; 414 String paramName = paramValue.getParamName().getStringValue().trim(); 415 String paramStringValue = paramValue.getParamValue().getStringValue().trim(); 416 config.put(paramName, paramStringValue); 417 } 418 419 XsdQNameType[] soapHeaderQNames = handler.getSoapHeaderArray(); 421 QName [] headers = new QName [soapHeaderQNames.length]; 422 for (int j = 0; j < soapHeaderQNames.length; j++) { 423 XsdQNameType soapHeaderQName = soapHeaderQNames[j]; 424 headers[j] = soapHeaderQName.getQNameValue(); 425 } 426 427 list.add(new HandlerInfo (handlerClass, config, headers)); 428 } 429 return list; 430 } 431 } 432 | Popular Tags |