1 19 package org.apache.beehive.wsm.model.wsdl; 20 21 import java.io.File ; 22 import java.io.InputStream ; 23 import java.io.IOException ; 24 import java.lang.reflect.Array ; 25 import java.lang.reflect.Method ; 26 import java.net.MalformedURLException ; 27 import java.net.URL ; 28 import java.util.ArrayList ; 29 import java.util.Collection ; 30 import java.util.HashMap ; 31 import java.util.List ; 32 import java.util.Map ; 33 34 import javax.jws.WebParam; 35 import javax.jws.soap.SOAPBinding; 36 import javax.xml.namespace.QName ; 37 38 import org.apache.beehive.wsm.databinding.BindingLookupService; 39 import org.apache.beehive.wsm.util.TypeMappingUtil; 40 import org.apache.beehive.wsm.util.XmlBeanTypeMappingUtil; 41 import org.apache.beehive.wsm.wsdl.WSDLProcessor; 42 43 import org.apache.beehive.wsm.model.BeehiveWsSOAPBindingInfo; 44 import org.apache.beehive.wsm.model.BeehiveWsMethodMetadata; 45 import org.apache.beehive.wsm.model.BeehiveWsParameterMetadata; 46 import org.apache.beehive.wsm.model.BeehiveWsTypeMetadata; 47 import org.apache.beehive.wsm.model.jsr181.Jsr181MethodMetadataImpl; 48 import org.apache.beehive.wsm.model.jsr181.Jsr181ParameterMetadataImpl; 49 import org.apache.beehive.wsm.model.jsr181.Jsr181TypeMetadataImpl; 50 import org.apache.beehive.wsm.model.jsr181.SOAPBindingInfo; 51 import org.apache.xmlbeans.SchemaType; 52 import org.apache.xmlbeans.SchemaTypeLoader; 53 import org.apache.xmlbeans.XmlBeans; 54 import org.apache.xmlbeans.XmlCursor; 55 import org.apache.xmlbeans.XmlException; 56 import org.apache.xmlbeans.XmlObject; 57 import org.xmlsoap.schemas.wsdl.DefinitionsDocument; 58 import org.xmlsoap.schemas.wsdl.TBinding; 59 import org.xmlsoap.schemas.wsdl.TBindingOperation; 60 import org.xmlsoap.schemas.wsdl.TBindingOperationMessage; 61 import org.xmlsoap.schemas.wsdl.TDefinitions; 62 import org.xmlsoap.schemas.wsdl.TMessage; 63 import org.xmlsoap.schemas.wsdl.TOperation; 64 import org.xmlsoap.schemas.wsdl.TParam; 65 import org.xmlsoap.schemas.wsdl.TPart; 66 import org.xmlsoap.schemas.wsdl.TPort; 67 import org.xmlsoap.schemas.wsdl.TPortType; 68 import org.xmlsoap.schemas.wsdl.TService; 69 import org.xmlsoap.schemas.wsdl.TTypes; 70 import org.xmlsoap.schemas.wsdl.soap.HeaderDocument; 71 import org.xmlsoap.schemas.wsdl.soap.TStyleChoice; 72 import org.xmlsoap.schemas.wsdl.soap.UseChoice; 73 74 import org.apache.xmlbeans.impl.xb.xsdschema.Element; 75 import org.apache.xmlbeans.impl.xb.xsdschema.Group; 76 import org.apache.xmlbeans.impl.xb.xsdschema.ComplexType; 77 import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; 78 import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema; 79 80 86 public class XmlBeanWSDLProcessor { 87 88 private BindingLookupService lookupService; 89 DefinitionsDocument defDoc; 90 91 92 93 public QName getServiceName() { 94 TService[] services = defDoc.getDefinitions().getServiceArray(); 95 return new QName (services[0].getName()); 96 } 97 98 public static final String TRANSPORT = "http://schemas.xmlsoap.org/soap/http"; 99 100 public static final String SOAPENCODING = "http://schemas.xmlsoap.org/soap/encoding/"; 101 102 public static final String WSDLNS = "http://schemas.xmlsoap.org/wsdl/soap/"; 103 104 public static final String WSDLSOAPNS = "http://schemas.xmlsoap.org/wsdl/soap/"; 105 106 public BeehiveWsTypeMetadata getObjectModel(BindingLookupService lookupService) 107 throws Exception { 108 this.lookupService = lookupService; 109 110 BeehiveWsTypeMetadata wsm = new Jsr181TypeMetadataImpl(); 111 Map <String , BeehiveWsMethodMetadata> methodMap = new HashMap <String , BeehiveWsMethodMetadata>(); 112 TDefinitions defs = defDoc.getDefinitions(); 113 wsm.setWsTargetNamespace(defs.getTargetNamespace()); 114 Map <String , TPart[]> messageMap = new HashMap <String , TPart[]>(); 115 116 if (defs.sizeOfServiceArray() > 0) { 117 wsm.setWsServiceName(defs.getServiceArray(0).getName()); 118 } 119 120 if (defs.sizeOfMessageArray() > 0) { 121 TMessage[] messages = defs.getMessageArray(); 122 for (TMessage msg : messages) { 123 messageMap.put(msg.getName(), msg.getPartArray()); 124 } 125 } 126 127 TBinding tBind = null; 128 if (defs.sizeOfBindingArray() > 0) { 129 tBind = defs.getBindingArray(0); 130 processTBinding(tBind, wsm); 131 } 132 133 if (defs.sizeOfPortTypeArray() > 0) { 134 TPortType tP = defs.getPortTypeArray(0); 135 wsm.setWsName(tP.getName()); 136 TOperation[] operations = tP.getOperationArray(); 137 TTypes types = null; 138 if (defs.sizeOfTypesArray() > 0) { 139 types = defs.getTypesArray(0); 140 } 141 142 for (TOperation op : operations) { 143 144 processTOperation(op, wsm, methodMap, messageMap, tBind, types); 145 } 146 } 147 148 if (tBind != null) { 149 processTBindingOperation(tBind, wsm, methodMap); 150 } 151 return wsm; 152 } 153 154 155 private void processTOperation(TOperation op, BeehiveWsTypeMetadata wsm, 156 Map <String , BeehiveWsMethodMetadata> methodMap, 157 Map <String , TPart[]> messageMap, TBinding tBind, TTypes types) throws Exception { 158 String opName = op.getName(); 159 TParam outputParam = op.getOutput(); 160 161 Map <String , BeehiveWsParameterMetadata> outParamMap = null; 162 163 BeehiveWsParameterMetadata[] paraMeta = new BeehiveWsParameterMetadata[0]; if( null != outputParam ) { 165 166 TPart[] messageParts = messageMap.get(outputParam.getMessage() 167 .getLocalPart()); 168 paraMeta = processParameters(opName, messageParts, tBind, types, 169 messageMap, wsm, true); } 171 Class returnType; 172 QName returnXMLType; 173 174 if (paraMeta == null) { 175 throw new Exception ("Can't resolve the return type"); 178 } else if (paraMeta.length == 1) { 179 returnType = paraMeta[0].getJavaType(); 180 returnXMLType = paraMeta[0].getXmlType(); 181 } else { 182 returnType = Void.TYPE; 186 returnXMLType = null; 187 if (paraMeta.length > 1) { 188 outParamMap = new HashMap <String , BeehiveWsParameterMetadata>( 189 paraMeta.length); 190 boolean returnIsSet = false; 191 for (BeehiveWsParameterMetadata cpm : paraMeta) { 192 outParamMap.put(cpm.getWpName(), cpm); 193 } 194 } 195 } 196 BeehiveWsMethodMetadata wmm = new Jsr181MethodMetadataImpl(opName, returnType, 197 returnXMLType); 198 199 wmm.setWmOperationName(opName); 200 wmm.setWmAction(opName); 203 if (Void.TYPE.equals(returnType)) { 204 205 if (paraMeta.length == 0) { 206 wmm.setOneWay(true); 209 } 210 } else { 211 wmm.setWrName(paraMeta[0].getWpName()); 212 wmm.setWrTargetNamespace(paraMeta[0].getWpTargetNamespace()); 213 } 214 215 methodMap.put(opName, wmm); 216 217 List paramOrder = op.getParameterOrder(); TParam inputParam = op.getInput(); 220 if (inputParam != null) { 221 222 TPart[] messageParts = messageMap.get(inputParam.getMessage() 223 .getLocalPart()); 224 225 226 BeehiveWsParameterMetadata[] params = processParameters(opName, messageParts, tBind, types, 227 messageMap, wsm, false); 228 229 if (paramOrder != null) { 230 for (Object ord : paramOrder) { 234 for (BeehiveWsParameterMetadata wpm : params) { 235 if (ord.equals(wpm.getWpName())) { 236 if (outParamMap != null && outParamMap.containsKey(wpm.getWpName())) { 237 outParamMap.remove(wpm.getWpName()); wpm.setWpMode(WebParam.Mode.INOUT); 241 } else { 242 wpm.setWpMode(WebParam.Mode.IN); 243 } 244 wmm.addParam(wpm); 245 break; 246 } 247 } 248 } 249 } else if (params.length > 0) { 250 for (BeehiveWsParameterMetadata wpm : params) { 251 if (outParamMap != null && outParamMap.containsKey(wpm.getWpName())) { 254 outParamMap.remove(wpm.getWpName()); wpm.setWpMode(WebParam.Mode.INOUT); 262 } else { 263 wpm.setWpMode(WebParam.Mode.IN); 264 } 265 wmm.addParam(wpm); 266 } 267 } 268 } 269 270 if (outParamMap != null && outParamMap.size() > 0) { 272 if (outParamMap.size() == 1) { 273 BeehiveWsParameterMetadata wpm = outParamMap.values().iterator().next(); 274 wmm.setXmlReturnType(wpm.getXmlType()); 275 wmm.setReturnType(wpm.getJavaType()); 276 wmm.setOneWay(false); 277 } else { 278 for (BeehiveWsParameterMetadata wpm : outParamMap.values()) { 279 wpm.setWpMode(WebParam.Mode.OUT); 280 wmm.addParam(wpm); 281 } 282 } 283 } 284 285 286 295 wsm.addMethod(wmm); 296 297 } 298 299 private BeehiveWsParameterMetadata[] processParameters(String operationName, TPart[] messageParts, TBinding tBind, 300 TTypes types, Map <String , TPart[]> messageMap, BeehiveWsTypeMetadata wsm, boolean isOutputParameters) { 301 302 boolean paramStyleIsSet = false; 310 311 boolean shouldUnwrap; 312 313 if(isOutputParameters ) { 314 paramStyleIsSet = true; } 316 shouldUnwrap = isWrapped(operationName, messageParts, tBind, isOutputParameters); 317 318 List <BeehiveWsParameterMetadata> paramList = new ArrayList <BeehiveWsParameterMetadata>( 319 messageParts.length); 320 int j = 0; 321 for (TPart messagePart : messageParts) { 322 QName paramXmlType; 323 if (messagePart.isSetElement()) { 329 QName element = messagePart.getElement(); 332 Class javaType = findClassForQname(element); 333 String name = messagePart.getName(); 337 if (shouldUnwrap && 340 unwrapMessagePart(operationName, isOutputParameters, messagePart) ) { 343 if( !isOutputParameters) { wsm.getSoapBinding().setParameterStyle( 345 SOAPBinding.ParameterStyle.WRAPPED); 346 paramStyleIsSet = true; 347 } 348 if (types != null) { try { 350 Schema[] schemas = selectChildren(types, Schema.class); 351 356 for (Schema s : schemas) { 357 if (!s.getTargetNamespace().equals(element.getNamespaceURI())) 358 continue; 359 Element[] elements = s.getElementArray(); 360 for (Element e : elements) { 361 if (!e.getName().equals(element.getLocalPart())) 362 continue; 363 364 if (e.isSetType()) { 365 370 paramList.add(elementToParamMetaData(s 371 .getTargetNamespace(), e)); 372 } else { 373 378 ComplexType ct = e.getComplexType(); 379 if (ct != null && ct.isSetSequence()) { 380 386 Group g = ct.getSequence(); 387 for (Element el : g.getElementArray()) { 388 paramList.add(elementToParamMetaData(s 389 .getTargetNamespace(), el)); 390 } 391 } 392 } 393 break; 394 } 395 break; 396 } 397 } catch (Exception e) { 398 e.printStackTrace(); 399 } 400 } 401 } else { 402 if(!paramStyleIsSet) wsm.getSoapBinding().setParameterStyle( 408 SOAPBinding.ParameterStyle.BARE); 409 410 BeehiveWsParameterMetadata wpm = new Jsr181ParameterMetadataImpl(); 411 412 wpm.setWpTargetNamespace(element.getNamespaceURI()); 413 wpm.setWpName(name); wpm.setXmlType(element); 415 wpm.setJavaType(javaType); 416 paramList.add(wpm); 417 } 418 } else { BeehiveWsParameterMetadata wpm = new Jsr181ParameterMetadataImpl(); 420 wpm.setWpTargetNamespace(wsm.getWsTargetNamespace()); 423 wpm.setWpName(messagePart.getName()); 424 QName type = messagePart.getType(); 425 wpm.setXmlType(type); 426 wpm.setJavaType(findClassForQname(type)); 427 431 paramList.add(wpm); 432 } 433 } 434 return paramList.toArray(new BeehiveWsParameterMetadata[paramList.size()]); 435 436 } 437 438 439 private Class findClassForQname(QName element) { 440 return lookupService.qname2class(element); 442 } 443 444 private boolean isWrapped( String operationName, TPart[] messagePart, TBinding tBind,boolean isOutputParameters) { 451 for( TPart message : messagePart) { 452 if( !message.isSetElement()) return false; if( true == unwrapMessagePart(operationName, isOutputParameters, message)) return true; 454 } 455 return false; 456 } 457 458 private boolean unwrapMessagePart(String operationName, boolean isOutputParameters, TPart message) { 459 String name = message.getName(); 460 if("parameters".equals(name)) return true; 461 if( isOutputParameters) { 462 if(message.getElement().getLocalPart().equals(operationName+"Response")) return true; 463 464 } else { 465 if(message.getElement().getLocalPart().equals(operationName)) return true; 466 } 467 return false; 468 } 469 474 private BeehiveWsParameterMetadata elementToParamMetaData( 475 String targetNamespace, Element el) { 476 BeehiveWsParameterMetadata wpm = new Jsr181ParameterMetadataImpl(); 477 wpm.setWpTargetNamespace(targetNamespace); 483 boolean isArray = false; 484 if (el.isSetMaxOccurs()) { 485 if (0 != "1".compareTo(el.getMaxOccurs().toString())) 486 isArray = true; 487 } else if (el.isSetMinOccurs()) { 488 String minOccur = el.getMinOccurs().toString(); 489 if ("0" != minOccur && "1" != minOccur) 491 isArray = true; 492 } 493 494 String name = null; 495 QName xmlType = null; 496 if (el.isSetName() && el.isSetType()) { 497 498 name = el.getName(); 499 500 xmlType = el.getType(); 501 502 } else if (el.isSetRef()) { 503 QName ref = el.getRef(); 504 name = ref.getLocalPart(); 505 xmlType = ref; 506 507 } else 508 throw new RuntimeException ("invalid element: " + el); 509 Class javaType = findClassForQname(xmlType); 510 if (isArray) { 511 Object realType = Array.newInstance(javaType, 1); 513 javaType = realType.getClass(); 514 } 515 wpm.setWpName(name); 516 wpm.setXmlType(xmlType); 517 wpm.setJavaType(javaType); 518 return wpm; 519 } 520 521 524 private void doUnknownTypes(TTypes types) { 525 527 } 528 529 private void processTBinding(TBinding tBind, BeehiveWsTypeMetadata wsm) 530 throws IllegalAccessException , NoSuchFieldException { 531 532 org.xmlsoap.schemas.wsdl.soap.TBinding[] soapBinding = getSOAPBinding(tBind); 533 BeehiveWsSOAPBindingInfo soapInfo = new SOAPBindingInfo(); 534 if (soapBinding != null && soapBinding.length > 0) { 535 if (TStyleChoice.RPC.equals(soapBinding[0].getStyle())) { 536 soapInfo.setStyle(SOAPBinding.Style.RPC); 537 } 538 wsm.setSoapBinding(soapInfo); 539 } 540 } 541 542 private void processTBindingOperation(TBinding tBind, 543 BeehiveWsTypeMetadata wsm, 544 Map <String , BeehiveWsMethodMetadata> methodMap) 545 throws IllegalAccessException , NoSuchFieldException { 546 547 TBindingOperation[] tBops = tBind.getOperationArray(); 548 for (TBindingOperation tBop : tBops) { 549 BeehiveWsMethodMetadata wmm = methodMap.get(tBop.getName()); 550 if (wmm == null) 551 throw new RuntimeException ("Invalid method name: " 552 + tBop.getName()); 553 org.xmlsoap.schemas.wsdl.soap.TOperation[] soapOperations = getSOAPOperations(tBop); 554 if (soapOperations != null && soapOperations.length > 0) { 555 wmm.setWmAction(soapOperations[0].getSoapAction()); 556 } 557 TBindingOperationMessage tbMsg = tBop.getInput(); 558 if (tbMsg == null) { 559 tbMsg = tBop.getOutput(); 560 } 561 if (tbMsg != null) { 562 org.xmlsoap.schemas.wsdl.soap.TBody[] bodies = getSOAPBody(tbMsg); 563 if (bodies.length > 0) { 564 if (wsm.getWsTargetNamespace() == null) { 565 wsm.setWsTargetNamespace(bodies[0].getNamespace()); 566 } 567 BeehiveWsSOAPBindingInfo soapInfo = wsm.getSoapBinding(); 568 if (UseChoice.ENCODED.equals(bodies[0].getUse())) { 569 soapInfo.setUse(SOAPBinding.Use.ENCODED); 570 } 571 } 572 573 setSoapHeaders(wmm, tbMsg); 574 575 } 576 577 setSoapHeaders(wmm, tBop.getOutput()); 579 580 } 581 } 582 583 588 private void setSoapHeaders(BeehiveWsMethodMetadata wmm, 589 TBindingOperationMessage tbMsg) throws IllegalAccessException , 590 NoSuchFieldException { 591 if(null == tbMsg) return; 592 593 org.xmlsoap.schemas.wsdl.soap.THeader[] soapHeaders = getSOAPHeader(tbMsg); 595 if (soapHeaders != null && soapHeaders.length > 0) { for (org.xmlsoap.schemas.wsdl.soap.THeader nxtHeader : soapHeaders) { 598 String part = nxtHeader.getPart(); 599 if (part == null) 600 throw new RuntimeException ( 601 "Missing part attribute in soap:header method: " 602 + tbMsg.getName()); 603 BeehiveWsParameterMetadata argument = wmm.findParam(part); 604 if(argument == null) throw new RuntimeException ("Couldn't find part name: " + part + " in method " + wmm.getJavaMethodName()); 605 argument.setWpHeader(true); 606 } 607 608 } 609 } 610 611 612 613 618 public static DefinitionsDocument parseWSDL(String wsdlLocation) 619 throws IOException , MalformedURLException , XmlException { 620 if (wsdlLocation.indexOf("://") > 2) { 621 return parseWSDL(new URL (wsdlLocation)); 622 } else { 623 return parseWSDL(new File (wsdlLocation)); 624 } 625 } 626 627 public static DefinitionsDocument parseWSDL(File wsdlFile) 628 throws IOException , XmlException { 629 return DefinitionsDocument.Factory.parse(wsdlFile); 630 } 631 632 public static DefinitionsDocument parseWSDL(URL wsdlURL) throws IOException , 633 MalformedURLException , XmlException { 634 return DefinitionsDocument.Factory.parse(wsdlURL); 635 } 636 637 public static DefinitionsDocument parseWSDL(InputStream wsdlStream) 638 throws IOException , MalformedURLException , XmlException { 639 return DefinitionsDocument.Factory.parse(wsdlStream); 640 } 641 642 public static org.xmlsoap.schemas.wsdl.soap.TOperation[] getSOAPOperations( 643 TBindingOperation bo) throws IllegalAccessException , NoSuchFieldException { 644 return selectChildren(bo, org.xmlsoap.schemas.wsdl.soap.TOperation.class); 645 } 646 647 public static org.xmlsoap.schemas.wsdl.soap.TBinding[] getSOAPBinding( 648 TBinding b) throws IllegalAccessException , NoSuchFieldException { 649 XmlObject[] kids = b.selectChildren(new QName ( 650 "http://schemas.xmlsoap.org/wsdl/soap/", "binding")); 651 652 org.xmlsoap.schemas.wsdl.soap.TBinding[] res = new org.xmlsoap.schemas.wsdl.soap.TBinding[kids.length]; 653 for (int i = 0; i < kids.length; i++) 654 res[i] = (org.xmlsoap.schemas.wsdl.soap.TBinding) kids[i]; 655 656 return res; 657 } 658 659 public static org.xmlsoap.schemas.wsdl.soap.TBody[] getSOAPBody( 660 TBindingOperationMessage bom) throws IllegalAccessException , 661 NoSuchFieldException { 662 XmlObject[] kids = bom.selectChildren(new QName ( 663 "http://schemas.xmlsoap.org/wsdl/soap/", "body")); 664 665 org.xmlsoap.schemas.wsdl.soap.TBody[] res = new org.xmlsoap.schemas.wsdl.soap.TBody[kids.length]; 666 for (int i = 0; i < kids.length; i++) 667 res[i] = (org.xmlsoap.schemas.wsdl.soap.TBody) kids[i]; 668 669 return res; 670 } 671 672 public static org.xmlsoap.schemas.wsdl.soap.THeader[] getSOAPHeader( 673 TBindingOperationMessage bom) throws IllegalAccessException , 674 NoSuchFieldException { 675 XmlObject[] kids = bom.selectChildren(new QName ( 676 "http://schemas.xmlsoap.org/wsdl/soap/", "header")); 677 678 org.xmlsoap.schemas.wsdl.soap.THeader[] res = new org.xmlsoap.schemas.wsdl.soap.THeader[kids.length]; 679 for (int i = 0; i < kids.length; i++) 680 res[i] = (org.xmlsoap.schemas.wsdl.soap.THeader) kids[i]; 681 682 return res; 683 } 684 685 686 public static org.xmlsoap.schemas.wsdl.soap.TAddress[] getSOAPAddress( 687 TPort port) throws IllegalAccessException , NoSuchFieldException { 688 return selectChildren(port, org.xmlsoap.schemas.wsdl.soap.TAddress.class); 689 } 690 691 private static <T extends XmlObject> T[] selectChildren(XmlObject parent, 692 Class <T> childClass) throws IllegalAccessException , NoSuchFieldException { 693 if(parent == null) return null; 695 SchemaType st = (SchemaType) childClass.getField("type").get(null); 696 SchemaType originalType = null; 697 QName element; 698 if (st.isAnonymousType()) { 699 originalType = st; 700 st = st.getOuterType(); 701 } 702 if (st.isDocumentType()) { 703 element = st.getDocumentElementName(); 704 if (originalType != null) { 705 st = originalType; 706 } 707 } else { 708 element = st.getName(); 709 } 710 714 XmlObject[] kids = parent.selectChildren(element); 715 716 T[] castKids = (T[]) Array.newInstance(childClass, kids.length); 717 for (int j = 0; j < castKids.length; j++) { 718 719 if (!st.getJavaClass().isAssignableFrom(kids[j].getClass())) { 720 kids[j] = kids[j].changeType(st); 723 } else { 725 } 727 castKids[j] = childClass.cast(kids[j]); 728 } 729 return castKids; 730 } 731 732 public XmlBeanWSDLProcessor( InputStream wsdlStream) throws MalformedURLException , IOException , XmlException { 733 super(); 734 this.defDoc = parseWSDL(wsdlStream); 735 736 } 737 738 private XmlBeanWSDLProcessor() { 739 } 741 } 742 | Popular Tags |