1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.ws.wsdl.parser; 27 28 import com.sun.istack.internal.NotNull; 29 import com.sun.istack.internal.Nullable; 30 import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer; 31 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer; 32 import com.sun.xml.internal.stream.buffer.XMLStreamBufferMark; 33 import com.sun.xml.internal.stream.buffer.stax.StreamReaderBufferCreator; 34 import com.sun.xml.internal.ws.api.BindingID; 35 import com.sun.xml.internal.ws.api.BindingIDFactory; 36 import com.sun.xml.internal.ws.api.SOAPVersion; 37 import com.sun.xml.internal.ws.api.EndpointAddress; 38 import com.sun.xml.internal.ws.api.WSDLLocator; 39 import com.sun.xml.internal.ws.api.policy.PolicyResolver; 40 import com.sun.xml.internal.ws.api.policy.PolicyResolverFactory; 41 import com.sun.xml.internal.ws.api.addressing.AddressingVersion; 42 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; 43 import com.sun.xml.internal.ws.api.model.ParameterBinding; 44 import com.sun.xml.internal.ws.api.model.wsdl.WSDLDescriptorKind; 45 import com.sun.xml.internal.ws.api.model.wsdl.WSDLModel; 46 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundFault; 47 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundOperation; 48 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundPortType; 49 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLFault; 50 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLInput; 51 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLMessage; 52 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLModel; 53 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLOperation; 54 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLOutput; 55 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPart; 56 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPort; 57 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPortType; 58 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLService; 59 import com.sun.xml.internal.ws.api.server.Container; 60 import com.sun.xml.internal.ws.api.server.ContainerResolver; 61 import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory; 62 import com.sun.xml.internal.ws.api.wsdl.parser.MetaDataResolver; 63 import com.sun.xml.internal.ws.api.wsdl.parser.MetadataResolverFactory; 64 import com.sun.xml.internal.ws.api.wsdl.parser.ServiceDescriptor; 65 import com.sun.xml.internal.ws.api.wsdl.parser.WSDLParserExtension; 66 import com.sun.xml.internal.ws.api.wsdl.parser.XMLEntityResolver; 67 import com.sun.xml.internal.ws.api.wsdl.parser.XMLEntityResolver.Parser; 68 import com.sun.xml.internal.ws.model.wsdl.*; 69 import com.sun.xml.internal.ws.resources.ClientMessages; 70 import com.sun.xml.internal.ws.resources.WsdlmodelMessages; 71 import com.sun.xml.internal.ws.streaming.SourceReaderFactory; 72 import com.sun.xml.internal.ws.streaming.TidyXMLStreamReader; 73 import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil; 74 import com.sun.xml.internal.ws.util.ServiceFinder; 75 import com.sun.xml.internal.ws.util.xml.XmlUtil; 76 import com.sun.xml.internal.ws.policy.jaxws.PolicyWSDLParserExtension; 77 78 import org.xml.sax.EntityResolver; 79 import org.xml.sax.SAXException; 80 81 import javax.jws.soap.SOAPBinding.Style; 82 import javax.xml.namespace.QName; 83 import javax.xml.stream.*; 84 import javax.xml.transform.Source; 85 import javax.xml.transform.stream.StreamSource; 86 import javax.xml.ws.Service; 87 import javax.xml.ws.WebServiceException; 88 89 import java.io.IOException; 90 import java.io.InputStream; 91 import java.io.FilterInputStream; 92 import java.net.URISyntaxException; 93 import java.net.URL; 94 import java.util.*; 95 import java.util.logging.Logger; 96 97 /** 98 * Parses WSDL and builds {@link com.sun.xml.internal.ws.api.model.wsdl.WSDLModel}. 99 * 100 * @author Vivek Pandey 101 * @author Rama Pulavarthi 102 */ 103 public class RuntimeWSDLParser { 104 105 private final EditableWSDLModel wsdlDoc; 106 /** 107 * Target namespace URI of the WSDL that we are currently parsing. 108 */ 109 private String targetNamespace; 110 /** 111 * System IDs of WSDLs that are already read. 112 */ 113 private final Set<String> importedWSDLs = new HashSet<String>(); 114 /** 115 * Must not be null. 116 */ 117 private final XMLEntityResolver resolver; 118 119 private final PolicyResolver policyResolver; 120 121 /** 122 * The {@link WSDLParserExtension}. Always non-null. 123 */ 124 private final WSDLParserExtension extensionFacade; 125 126 private final WSDLParserExtensionContextImpl context; 127 128 List<WSDLParserExtension> extensions; 129 130 //Capture namespaces declared on the ancestors of wsa:EndpointReference, so that valid XmlStreamBuffer is created 131 // from the EndpointReference fragment. 132 Map<String, String> wsdldef_nsdecl = new HashMap<String, String>(); 133 Map<String, String> service_nsdecl = new HashMap<String, String>(); 134 Map<String, String> port_nsdecl = new HashMap<String, String>(); 135 136 /** 137 * Parses the WSDL and gives WSDLModel. If wsdl parameter is null, then wsdlLoc is used to get the WSDL. If the WSDL 138 * document could not be obtained then {@link MetadataResolverFactory} is tried to get the WSDL document, if not found 139 * then as last option, if the wsdlLoc has no '?wsdl' as query parameter then it is tried by appending '?wsdl'. 140 * 141 * @param wsdlLoc 142 * Either this or <tt>wsdl</tt> parameter must be given. 143 * Null location means the system won't be able to resolve relative references in the WSDL, 144 */ 145 public static WSDLModel parse(@Nullable URL wsdlLoc, @NotNull Source wsdlSource, @NotNull EntityResolver resolver, 146 boolean isClientSide, Container container, 147 WSDLParserExtension... extensions) throws IOException, XMLStreamException, SAXException { 148 return parse(wsdlLoc, wsdlSource, resolver, isClientSide, container, Service.class, PolicyResolverFactory.create(),extensions); 149 } 150 151 /** 152 * Parses the WSDL and gives WSDLModel. If wsdl parameter is null, then wsdlLoc is used to get the WSDL. If the WSDL 153 * document could not be obtained then {@link MetadataResolverFactory} is tried to get the WSDL document, if not found 154 * then as last option, if the wsdlLoc has no '?wsdl' as query parameter then it is tried by appending '?wsdl'. 155 * 156 * @param wsdlLoc 157 * Either this or <tt>wsdl</tt> parameter must be given. 158 * Null location means the system won't be able to resolve relative references in the WSDL, 159 */ 160 public static WSDLModel parse(@Nullable URL wsdlLoc, @NotNull Source wsdlSource, @NotNull EntityResolver resolver, 161 boolean isClientSide, Container container, Class serviceClass, 162 WSDLParserExtension... extensions) throws IOException, XMLStreamException, SAXException { 163 return parse(wsdlLoc, wsdlSource, resolver, isClientSide, container, serviceClass, PolicyResolverFactory.create(),extensions); 164 } 165 166 /** 167 * Parses the WSDL and gives WSDLModel. If wsdl parameter is null, then wsdlLoc is used to get the WSDL. If the WSDL 168 * document could not be obtained then {@link MetadataResolverFactory} is tried to get the WSDL document, if not found 169 * then as last option, if the wsdlLoc has no '?wsdl' as query parameter then it is tried by appending '?wsdl'. 170 * 171 * @param wsdlLoc 172 * Either this or <tt>wsdl</tt> parameter must be given. 173 * Null location means the system won't be able to resolve relative references in the WSDL, 174 */ 175 public static WSDLModel parse(@Nullable URL wsdlLoc, @NotNull Source wsdlSource, @NotNull EntityResolver resolver, 176 boolean isClientSide, Container container, @NotNull PolicyResolver policyResolver, 177 WSDLParserExtension... extensions) throws IOException, XMLStreamException, SAXException { 178 return parse(wsdlLoc, wsdlSource, resolver, isClientSide, container, Service.class, policyResolver, extensions); 179 } 180 181 /** 182 * Parses the WSDL and gives WSDLModel. If wsdl parameter is null, then wsdlLoc is used to get the WSDL. If the WSDL 183 * document could not be obtained then {@link MetadataResolverFactory} is tried to get the WSDL document, if not found 184 * then as last option, if the wsdlLoc has no '?wsdl' as query parameter then it is tried by appending '?wsdl'. 185 * 186 * @param wsdlLoc 187 * Either this or <tt>wsdl</tt> parameter must be given. 188 * Null location means the system won't be able to resolve relative references in the WSDL, 189 */ 190 public static WSDLModel parse(@Nullable URL wsdlLoc, @NotNull Source wsdlSource, @NotNull EntityResolver resolver, 191 boolean isClientSide, Container container, Class serviceClass, 192 @NotNull PolicyResolver policyResolver, 193 WSDLParserExtension... extensions) throws IOException, XMLStreamException, SAXException { 194 return parse(wsdlLoc, wsdlSource, resolver, isClientSide, container, serviceClass, policyResolver, false, extensions); 195 } 196 197 /** 198 * Parses the WSDL and gives WSDLModel. If wsdl parameter is null, then wsdlLoc is used to get the WSDL. If the WSDL 199 * document could not be obtained then {@link MetadataResolverFactory} is tried to get the WSDL document, if not found 200 * then as last option, if the wsdlLoc has no '?wsdl' as query parameter then it is tried by appending '?wsdl'. 201 * 202 * @param wsdlLoc 203 * Either this or <tt>wsdl</tt> parameter must be given. 204 * Null location means the system won't be able to resolve relative references in the WSDL, 205 */ 206 public static WSDLModel parse(@Nullable URL wsdlLoc, @NotNull Source wsdlSource, @NotNull EntityResolver resolver, 207 boolean isClientSide, Container container, Class serviceClass, 208 @NotNull PolicyResolver policyResolver, 209 boolean isUseStreamFromEntityResolverWrapper, 210 WSDLParserExtension... extensions) throws IOException, XMLStreamException, SAXException { 211 assert resolver != null; 212 213 RuntimeWSDLParser wsdlParser = new RuntimeWSDLParser(wsdlSource.getSystemId(), new EntityResolverWrapper(resolver, isUseStreamFromEntityResolverWrapper), isClientSide, container, policyResolver, extensions); 214 Parser parser; 215 try{ 216 parser = wsdlParser.resolveWSDL(wsdlLoc, wsdlSource, serviceClass); 217 if(!hasWSDLDefinitions(parser.parser)){ 218 throw new XMLStreamException(ClientMessages.RUNTIME_WSDLPARSER_INVALID_WSDL(parser.systemId, 219 WSDLConstants.QNAME_DEFINITIONS, parser.parser.getName(), parser.parser.getLocation())); 220 } 221 }catch(XMLStreamException e){ 222 //Try MEX if there is WSDLLoc available 223 if(wsdlLoc == null) 224 throw e; 225 return tryWithMex(wsdlParser, wsdlLoc, resolver, isClientSide, container, e, serviceClass, policyResolver, extensions); 226 227 }catch(IOException e){ 228 //Try MEX if there is WSDLLoc available 229 if(wsdlLoc == null) 230 throw e; 231 return tryWithMex(wsdlParser, wsdlLoc, resolver, isClientSide, container, e, serviceClass, policyResolver, extensions); 232 } 233 wsdlParser.extensionFacade.start(wsdlParser.context); 234 wsdlParser.parseWSDL(parser, false); 235 wsdlParser.wsdlDoc.freeze(); 236 wsdlParser.extensionFacade.finished(wsdlParser.context); 237 wsdlParser.extensionFacade.postFinished(wsdlParser.context); 238 239 if(wsdlParser.wsdlDoc.getServices().isEmpty()) 240 throw new WebServiceException(ClientMessages.WSDL_CONTAINS_NO_SERVICE(wsdlLoc)); 241 242 return wsdlParser.wsdlDoc; 243 } 244 245 private static WSDLModel tryWithMex(@NotNull RuntimeWSDLParser wsdlParser, @NotNull URL wsdlLoc, @NotNull EntityResolver resolver, boolean isClientSide, Container container, Throwable e, Class serviceClass, PolicyResolver policyResolver, WSDLParserExtension... extensions) throws SAXException, XMLStreamException { 246 ArrayList<Throwable> exceptions = new ArrayList<Throwable>(); 247 try { 248 WSDLModel wsdlModel = wsdlParser.parseUsingMex(wsdlLoc, resolver, isClientSide, container, serviceClass, policyResolver,extensions); 249 if(wsdlModel == null){ 250 throw new WebServiceException(ClientMessages.FAILED_TO_PARSE(wsdlLoc.toExternalForm(), e.getMessage()), e); 251 } 252 return wsdlModel; 253 } catch (URISyntaxException e1) { 254 exceptions.add(e); 255 exceptions.add(e1); 256 } catch(IOException e1){ 257 exceptions.add(e); 258 exceptions.add(e1); 259 } 260 throw new InaccessibleWSDLException(exceptions); 261 } 262 263 private WSDLModel parseUsingMex(@NotNull URL wsdlLoc, @NotNull EntityResolver resolver, boolean isClientSide, Container container, Class serviceClass, PolicyResolver policyResolver, WSDLParserExtension[] extensions) throws IOException, SAXException, XMLStreamException, URISyntaxException { 264 //try MEX 265 MetaDataResolver mdResolver = null; 266 ServiceDescriptor serviceDescriptor = null; 267 RuntimeWSDLParser wsdlParser = null; 268 269 //Currently we try the first available MetadataResolverFactory that gives us a WSDL document 270 for (MetadataResolverFactory resolverFactory : ServiceFinder.find(MetadataResolverFactory.class)) { 271 mdResolver = resolverFactory.metadataResolver(resolver); 272 serviceDescriptor = mdResolver.resolve(wsdlLoc.toURI()); 273 //we got the ServiceDescriptor, now break 274 if (serviceDescriptor != null) 275 break; 276 } 277 if (serviceDescriptor != null) { 278 List<? extends Source> wsdls = serviceDescriptor.getWSDLs(); 279 wsdlParser = new RuntimeWSDLParser(wsdlLoc.toExternalForm(), new MexEntityResolver(wsdls), isClientSide, container, policyResolver, extensions); 280 wsdlParser.extensionFacade.start(wsdlParser.context); 281 282 for(Source src: wsdls ) { 283 String systemId = src.getSystemId(); 284 Parser parser = wsdlParser.resolver.resolveEntity(null, systemId); 285 wsdlParser.parseWSDL(parser, false); 286 } 287 } 288 //Incase that mex is not present or it couldn't get the metadata, try by appending ?wsdl and give 289 // it a last shot else fail 290 if ((mdResolver == null || serviceDescriptor == null) && (wsdlLoc.getProtocol().equals("http") || wsdlLoc.getProtocol().equals("https")) && (wsdlLoc.getQuery() == null)) { 291 String urlString = wsdlLoc.toExternalForm(); 292 urlString += "?wsdl"; 293 wsdlLoc = new URL(urlString); 294 wsdlParser = new RuntimeWSDLParser(wsdlLoc.toExternalForm(),new EntityResolverWrapper(resolver), isClientSide, container, policyResolver, extensions); 295 wsdlParser.extensionFacade.start(wsdlParser.context); 296 Parser parser = resolveWSDL(wsdlLoc, new StreamSource(wsdlLoc.toExternalForm()), serviceClass); 297 wsdlParser.parseWSDL(parser, false); 298 } 299 300 if(wsdlParser == null) 301 return null; 302 303 wsdlParser.wsdlDoc.freeze(); 304 wsdlParser.extensionFacade.finished(wsdlParser.context); 305 wsdlParser.extensionFacade.postFinished(wsdlParser.context); 306 return wsdlParser.wsdlDoc; 307 } 308 309 private static boolean hasWSDLDefinitions(XMLStreamReader reader) { 310 XMLStreamReaderUtil.nextElementContent(reader); 311 return reader.getName().equals(WSDLConstants.QNAME_DEFINITIONS); 312 } 313 314 public static WSDLModel parse(XMLEntityResolver.Parser wsdl, XMLEntityResolver resolver, boolean isClientSide, Container container, PolicyResolver policyResolver, WSDLParserExtension... extensions) throws IOException, XMLStreamException, SAXException { 315 assert resolver != null; 316 RuntimeWSDLParser parser = new RuntimeWSDLParser( wsdl.systemId.toExternalForm(), resolver, isClientSide, container, policyResolver, extensions); 317 parser.extensionFacade.start(parser.context); 318 parser.parseWSDL(wsdl, false); 319 parser.wsdlDoc.freeze(); 320 parser.extensionFacade.finished(parser.context); 321 parser.extensionFacade.postFinished(parser.context); 322 return parser.wsdlDoc; 323 } 324 325 public static WSDLModel parse(XMLEntityResolver.Parser wsdl, XMLEntityResolver resolver, boolean isClientSide, Container container, WSDLParserExtension... extensions) throws IOException, XMLStreamException, SAXException { 326 assert resolver != null; 327 RuntimeWSDLParser parser = new RuntimeWSDLParser( wsdl.systemId.toExternalForm(), resolver, isClientSide, container, PolicyResolverFactory.create(), extensions); 328 parser.extensionFacade.start(parser.context); 329 parser.parseWSDL(wsdl, false); 330 parser.wsdlDoc.freeze(); 331 parser.extensionFacade.finished(parser.context); 332 parser.extensionFacade.postFinished(parser.context); 333 return parser.wsdlDoc; 334 } 335 336 private RuntimeWSDLParser(@NotNull String sourceLocation, XMLEntityResolver resolver, boolean isClientSide, Container container, PolicyResolver policyResolver, WSDLParserExtension... extensions) { 337 this.wsdlDoc = sourceLocation!=null ? new WSDLModelImpl(sourceLocation) : new WSDLModelImpl(); 338 this.resolver = resolver; 339 this.policyResolver = policyResolver; 340 this.extensions = new ArrayList<WSDLParserExtension>(); 341 this.context = new WSDLParserExtensionContextImpl(wsdlDoc, isClientSide, container, policyResolver); 342 343 boolean isPolicyExtensionFound = false; 344 for (WSDLParserExtension e : extensions) { 345 if (e instanceof com.sun.xml.internal.ws.api.wsdl.parser.PolicyWSDLParserExtension) 346 isPolicyExtensionFound = true; 347 register(e); 348 } 349 350 // register handlers for default extensions 351 if (!isPolicyExtensionFound) 352 register(new PolicyWSDLParserExtension()); 353 register(new MemberSubmissionAddressingWSDLParserExtension()); 354 register(new W3CAddressingWSDLParserExtension()); 355 register(new W3CAddressingMetadataWSDLParserExtension()); 356 357 this.extensionFacade = new WSDLParserExtensionFacade(this.extensions.toArray(new WSDLParserExtension[0])); 358 } 359 360 private Parser resolveWSDL(@Nullable URL wsdlLoc, @NotNull Source wsdlSource, Class serviceClass) throws IOException, SAXException, XMLStreamException { 361 String systemId = wsdlSource.getSystemId(); 362 363 XMLEntityResolver.Parser parser = resolver.resolveEntity(null, systemId); 364 if (parser == null && wsdlLoc != null) { 365 String exForm = wsdlLoc.toExternalForm(); 366 parser = resolver.resolveEntity(null, exForm); 367 368 if (parser == null && serviceClass != null) { 369 URL ru = serviceClass.getResource("."); 370 if (ru != null) { 371 String ruExForm = ru.toExternalForm(); 372 if (exForm.startsWith(ruExForm)) { 373 parser = resolver.resolveEntity(null, exForm.substring(ruExForm.length())); 374 } 375 } 376 } 377 } 378 if (parser == null) { 379 //If a WSDL source is provided that is known to be readable, then 380 //prioritize that over the URL - this avoids going over the network 381 //an additional time if a valid WSDL Source is provided - Deva Sagar 09/20/2011 382 if (isKnownReadableSource(wsdlSource)) { 383 parser = new Parser(wsdlLoc, createReader(wsdlSource)); 384 } else if (wsdlLoc != null) { 385 parser = new Parser(wsdlLoc, createReader(wsdlLoc, serviceClass)); 386 } 387 388 //parser could still be null if isKnownReadableSource returns 389 //false and wsdlLoc is also null. Fall back to using Source based 390 //parser since Source is not null 391 if (parser == null) { 392 parser = new Parser(wsdlLoc, createReader(wsdlSource)); 393 } 394 } 395 return parser; 396 } 397 398 private boolean isKnownReadableSource(Source wsdlSource) { 399 if (wsdlSource instanceof StreamSource) { 400 return (((StreamSource) wsdlSource).getInputStream() != null || 401 ((StreamSource) wsdlSource).getReader() != null); 402 } else { 403 return false; 404 } 405 } 406 407 private XMLStreamReader createReader(@NotNull Source src) throws XMLStreamException { 408 return new TidyXMLStreamReader(SourceReaderFactory.createSourceReader(src, true), null); 409 } 410 411 private void parseImport(@NotNull URL wsdlLoc) throws XMLStreamException, IOException, SAXException { 412 String systemId = wsdlLoc.toExternalForm(); 413 XMLEntityResolver.Parser parser = resolver.resolveEntity(null, systemId); 414 if (parser == null) { 415 parser = new Parser(wsdlLoc, createReader(wsdlLoc)); 416 } 417 parseWSDL(parser, true); 418 } 419 420 private void parseWSDL(Parser parser, boolean imported) throws XMLStreamException, IOException, SAXException { 421 XMLStreamReader reader = parser.parser; 422 try { 423 // avoid processing the same WSDL twice. 424 // if no system ID is given, the check won't work 425 if (parser.systemId != null && !importedWSDLs.add(parser.systemId.toExternalForm())) 426 return; 427 428 if(reader.getEventType() == XMLStreamConstants.START_DOCUMENT) 429 XMLStreamReaderUtil.nextElementContent(reader); 430 if (WSDLConstants.QNAME_DEFINITIONS.equals(reader.getName())) { 431 readNSDecl(wsdldef_nsdecl, reader); 432 } 433 if (reader.getEventType()!= XMLStreamConstants.END_DOCUMENT && reader.getName().equals(WSDLConstants.QNAME_SCHEMA)) { 434 if (imported) { 435 // wsdl:import could be a schema. Relaxing BP R2001 requirement. 436 LOGGER.warning(WsdlmodelMessages.WSDL_IMPORT_SHOULD_BE_WSDL(parser.systemId)); 437 return; 438 } 439 } 440 441 //get the targetNamespace of the service 442 String tns = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_TNS); 443 444 final String oldTargetNamespace = targetNamespace; 445 targetNamespace = tns; 446 447 while (XMLStreamReaderUtil.nextElementContent(reader) != 448 XMLStreamConstants.END_ELEMENT) { 449 if (reader.getEventType() == XMLStreamConstants.END_DOCUMENT) 450 break; 451 452 QName name = reader.getName(); 453 if (WSDLConstants.QNAME_IMPORT.equals(name)) { 454 parseImport(parser.systemId, reader); 455 } else if (WSDLConstants.QNAME_MESSAGE.equals(name)) { 456 parseMessage(reader); 457 } else if (WSDLConstants.QNAME_PORT_TYPE.equals(name)) { 458 parsePortType(reader); 459 } else if (WSDLConstants.QNAME_BINDING.equals(name)) { 460 parseBinding(reader); 461 } else if (WSDLConstants.QNAME_SERVICE.equals(name)) { 462 parseService(reader); 463 } else { 464 extensionFacade.definitionsElements(reader); 465 } 466 } 467 targetNamespace = oldTargetNamespace; 468 } finally { 469 this.wsdldef_nsdecl = new HashMap<String,String>(); 470 reader.close(); 471 } 472 } 473 474 private void parseService(XMLStreamReader reader) { 475 service_nsdecl.putAll(wsdldef_nsdecl); 476 readNSDecl(service_nsdecl,reader); 477 478 String serviceName = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME); 479 EditableWSDLService service = new WSDLServiceImpl(reader,wsdlDoc,new QName(targetNamespace, serviceName)); 480 extensionFacade.serviceAttributes(service, reader); 481 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 482 QName name = reader.getName(); 483 if (WSDLConstants.QNAME_PORT.equals(name)) { 484 parsePort(reader, service); 485 if (reader.getEventType() != XMLStreamConstants.END_ELEMENT) { 486 XMLStreamReaderUtil.next(reader); 487 } 488 } else { 489 extensionFacade.serviceElements(service, reader); 490 } 491 } 492 wsdlDoc.addService(service); 493 service_nsdecl = new HashMap<String, String>(); 494 } 495 496 private void parsePort(XMLStreamReader reader, EditableWSDLService service) { 497 port_nsdecl.putAll(service_nsdecl); 498 readNSDecl(port_nsdecl,reader); 499 500 String portName = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME); 501 String binding = ParserUtil.getMandatoryNonEmptyAttribute(reader, "binding"); 502 503 QName bindingName = ParserUtil.getQName(reader, binding); 504 QName portQName = new QName(service.getName().getNamespaceURI(), portName); 505 EditableWSDLPort port = new WSDLPortImpl(reader,service, portQName, bindingName); 506 507 extensionFacade.portAttributes(port, reader); 508 509 String location; 510 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 511 QName name = reader.getName(); 512 if (SOAPConstants.QNAME_ADDRESS.equals(name) || SOAPConstants.QNAME_SOAP12ADDRESS.equals(name)) { 513 location = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_LOCATION); 514 if (location != null) { 515 try { 516 port.setAddress(new EndpointAddress(location)); 517 } catch (URISyntaxException e) { 518 //Lets not throw any exception, latter on it should be thrown when invocation happens. At this 519 // time user has option to set the endopint address using request contexxt property. 520 } 521 } 522 XMLStreamReaderUtil.next(reader); 523 } else if (AddressingVersion.W3C.nsUri.equals(name.getNamespaceURI()) && 524 "EndpointReference".equals(name.getLocalPart())) { 525 try { 526 StreamReaderBufferCreator creator = new StreamReaderBufferCreator(new MutableXMLStreamBuffer()); 527 XMLStreamBuffer eprbuffer = new XMLStreamBufferMark(port_nsdecl, creator); 528 creator.createElementFragment(reader, false); 529 530 WSEndpointReference wsepr = new WSEndpointReference(eprbuffer, AddressingVersion.W3C); 531 //wsepr.toSpec().writeTo(new StreamResult(System.out)); 532 port.setEPR(wsepr); 533 /** XMLStreamBuffer.createNewBufferFromXMLStreamReader(reader) called from inside WSEndpointReference() 534 * consumes the complete EPR infoset and moves to the next element. This breaks the normal wsdl parser 535 * processing where it expects anyone reading the infoset to move to the end of the element that its reading 536 * and not to the next element. 537 */ 538 if(reader.getEventType() == XMLStreamConstants.END_ELEMENT && reader.getName().equals(WSDLConstants.QNAME_PORT)) 539 break; 540 } catch (XMLStreamException e) { 541 throw new WebServiceException(e); 542 } 543 } else { 544 545 extensionFacade.portElements(port, reader); 546 } 547 } 548 if (port.getAddress() == null) { 549 try { 550 port.setAddress(new EndpointAddress("")); 551 } catch (URISyntaxException e) { 552 //Lets not throw any exception, latter on it should be thrown when invocation happens. At this 553 //time user has option to set the endopint address using request contexxt property. 554 } 555 } 556 service.put(portQName, port); 557 port_nsdecl =new HashMap<String, String>(); 558 } 559 560 private void parseBinding(XMLStreamReader reader) { 561 String bindingName = ParserUtil.getMandatoryNonEmptyAttribute(reader, "name"); 562 String portTypeName = ParserUtil.getMandatoryNonEmptyAttribute(reader, "type"); 563 if ((bindingName == null) || (portTypeName == null)) { 564 //TODO: throw exception? 565 // 566 // wsdl:binding element for now 567 XMLStreamReaderUtil.skipElement(reader); 568 return; 569 } 570 EditableWSDLBoundPortType binding = new WSDLBoundPortTypeImpl(reader,wsdlDoc, new QName(targetNamespace, bindingName), 571 ParserUtil.getQName(reader, portTypeName)); 572 extensionFacade.bindingAttributes(binding, reader); 573 574 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 575 QName name = reader.getName(); 576 if (WSDLConstants.NS_SOAP_BINDING.equals(name)) { 577 String transport = reader.getAttributeValue(null, WSDLConstants.ATTR_TRANSPORT); 578 binding.setBindingId(createBindingId(transport, SOAPVersion.SOAP_11)); 579 580 String style = reader.getAttributeValue(null, "style"); 581 582 if ((style != null) && (style.equals("rpc"))) { 583 binding.setStyle(Style.RPC); 584 } else { 585 binding.setStyle(Style.DOCUMENT); 586 } 587 goToEnd(reader); 588 } else if (WSDLConstants.NS_SOAP12_BINDING.equals(name)) { 589 String transport = reader.getAttributeValue(null, WSDLConstants.ATTR_TRANSPORT); 590 binding.setBindingId(createBindingId(transport, SOAPVersion.SOAP_12)); 591 592 String style = reader.getAttributeValue(null, "style"); 593 if ((style != null) && (style.equals("rpc"))) { 594 binding.setStyle(Style.RPC); 595 } else { 596 binding.setStyle(Style.DOCUMENT); 597 } 598 goToEnd(reader); 599 } else if (WSDLConstants.QNAME_OPERATION.equals(name)) { 600 parseBindingOperation(reader, binding); 601 } else { 602 extensionFacade.bindingElements(binding, reader); 603 } 604 } 605 } 606 607 private static BindingID createBindingId(String transport, SOAPVersion soapVersion) { 608 if (!transport.equals(SOAPConstants.URI_SOAP_TRANSPORT_HTTP)) { 609 for( BindingIDFactory f : ServiceFinder.find(BindingIDFactory.class) ) { 610 BindingID bindingId = f.create(transport, soapVersion); 611 if(bindingId!=null) { 612 return bindingId; 613 } 614 } 615 } 616 return soapVersion.equals(SOAPVersion.SOAP_11)?BindingID.SOAP11_HTTP:BindingID.SOAP12_HTTP; 617 } 618 619 620 private void parseBindingOperation(XMLStreamReader reader, EditableWSDLBoundPortType binding) { 621 String bindingOpName = ParserUtil.getMandatoryNonEmptyAttribute(reader, "name"); 622 if (bindingOpName == null) { 623 //TODO: throw exception? 624 //skip wsdl:binding element for now 625 XMLStreamReaderUtil.skipElement(reader); 626 return; 627 } 628 629 QName opName = new QName(binding.getPortTypeName().getNamespaceURI(), bindingOpName); 630 EditableWSDLBoundOperation bindingOp = new WSDLBoundOperationImpl(reader,binding, opName); 631 binding.put(opName, bindingOp); 632 extensionFacade.bindingOperationAttributes(bindingOp, reader); 633 634 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 635 QName name = reader.getName(); 636 String style = null; 637 if (WSDLConstants.QNAME_INPUT.equals(name)) { 638 parseInputBinding(reader, bindingOp); 639 } else if (WSDLConstants.QNAME_OUTPUT.equals(name)) { 640 parseOutputBinding(reader, bindingOp); 641 } else if (WSDLConstants.QNAME_FAULT.equals(name)) { 642 parseFaultBinding(reader, bindingOp); 643 } else if (SOAPConstants.QNAME_OPERATION.equals(name) || 644 SOAPConstants.QNAME_SOAP12OPERATION.equals(name)) { 645 style = reader.getAttributeValue(null, "style"); 646 String soapAction = reader.getAttributeValue(null, "soapAction"); 647 648 if (soapAction != null) 649 bindingOp.setSoapAction(soapAction); 650 651 goToEnd(reader); 652 } else { 653 extensionFacade.bindingOperationElements(bindingOp, reader); 654 } 655 /** 656 * If style attribute is present set it otherwise set the style as defined 657 * on the <soap:binding> element 658 */ 659 if (style != null) { 660 if (style.equals("rpc")) 661 bindingOp.setStyle(Style.RPC); 662 else 663 bindingOp.setStyle(Style.DOCUMENT); 664 } else { 665 bindingOp.setStyle(binding.getStyle()); 666 } 667 } 668 } 669 670 private void parseInputBinding(XMLStreamReader reader, EditableWSDLBoundOperation bindingOp) { 671 boolean bodyFound = false; 672 extensionFacade.bindingOperationInputAttributes(bindingOp, reader); 673 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 674 QName name = reader.getName(); 675 if ((SOAPConstants.QNAME_BODY.equals(name) || SOAPConstants.QNAME_SOAP12BODY.equals(name)) && !bodyFound) { 676 bodyFound = true; 677 bindingOp.setInputExplicitBodyParts(parseSOAPBodyBinding(reader, bindingOp, BindingMode.INPUT)); 678 goToEnd(reader); 679 } else if ((SOAPConstants.QNAME_HEADER.equals(name) || SOAPConstants.QNAME_SOAP12HEADER.equals(name))) { 680 parseSOAPHeaderBinding(reader, bindingOp.getInputParts()); 681 } else if (MIMEConstants.QNAME_MULTIPART_RELATED.equals(name)) { 682 parseMimeMultipartBinding(reader, bindingOp, BindingMode.INPUT); 683 } else { 684 extensionFacade.bindingOperationInputElements(bindingOp, reader); 685 } 686 } 687 } 688 689 private void parseOutputBinding(XMLStreamReader reader, EditableWSDLBoundOperation bindingOp) { 690 boolean bodyFound = false; 691 extensionFacade.bindingOperationOutputAttributes(bindingOp, reader); 692 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 693 QName name = reader.getName(); 694 if ((SOAPConstants.QNAME_BODY.equals(name) || SOAPConstants.QNAME_SOAP12BODY.equals(name)) && !bodyFound) { 695 bodyFound = true; 696 bindingOp.setOutputExplicitBodyParts(parseSOAPBodyBinding(reader, bindingOp, BindingMode.OUTPUT)); 697 goToEnd(reader); 698 } else if ((SOAPConstants.QNAME_HEADER.equals(name) || SOAPConstants.QNAME_SOAP12HEADER.equals(name))) { 699 parseSOAPHeaderBinding(reader, bindingOp.getOutputParts()); 700 } else if (MIMEConstants.QNAME_MULTIPART_RELATED.equals(name)) { 701 parseMimeMultipartBinding(reader, bindingOp, BindingMode.OUTPUT); 702 } else { 703 extensionFacade.bindingOperationOutputElements(bindingOp, reader); 704 } 705 } 706 } 707 708 private void parseFaultBinding(XMLStreamReader reader, EditableWSDLBoundOperation bindingOp) { 709 String faultName = ParserUtil.getMandatoryNonEmptyAttribute(reader, "name"); 710 EditableWSDLBoundFault wsdlBoundFault = new WSDLBoundFaultImpl(reader, faultName, bindingOp); 711 bindingOp.addFault(wsdlBoundFault); 712 713 extensionFacade.bindingOperationFaultAttributes(wsdlBoundFault, reader); 714 715 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 716 extensionFacade.bindingOperationFaultElements(wsdlBoundFault, reader); 717 } 718 } 719 720 private enum BindingMode { 721 INPUT, OUTPUT, FAULT} 722 723 private static boolean parseSOAPBodyBinding(XMLStreamReader reader, EditableWSDLBoundOperation op, BindingMode mode) { 724 String namespace = reader.getAttributeValue(null, "namespace"); 725 if (mode == BindingMode.INPUT) { 726 op.setRequestNamespace(namespace); 727 return parseSOAPBodyBinding(reader, op.getInputParts()); 728 } 729 //resp 730 op.setResponseNamespace(namespace); 731 return parseSOAPBodyBinding(reader, op.getOutputParts()); 732 } 733 734 /** 735 * Returns true if body has explicit parts declaration 736 */ 737 private static boolean parseSOAPBodyBinding(XMLStreamReader reader, Map<String, ParameterBinding> parts) { 738 String partsString = reader.getAttributeValue(null, "parts"); 739 if (partsString != null) { 740 List<String> partsList = XmlUtil.parseTokenList(partsString); 741 if (partsList.isEmpty()) { 742 parts.put(" ", ParameterBinding.BODY); 743 } else { 744 for (String part : partsList) { 745 parts.put(part, ParameterBinding.BODY); 746 } 747 } 748 return true; 749 } 750 return false; 751 } 752 753 private static void parseSOAPHeaderBinding(XMLStreamReader reader, Map<String, ParameterBinding> parts) { 754 String part = reader.getAttributeValue(null, "part"); 755 //if(part == null| part.equals("")||message == null || message.equals("")){ 756 if (part == null || part.equals("")) { 757 return; 758 } 759 760 //lets not worry about message attribute for now, probably additional headers wont be there 761 //String message = reader.getAttributeValue(null, "message"); 762 //QName msgName = ParserUtil.getQName(reader, message); 763 parts.put(part, ParameterBinding.HEADER); 764 goToEnd(reader); 765 } 766 767 768 private static void parseMimeMultipartBinding(XMLStreamReader reader, EditableWSDLBoundOperation op, BindingMode mode) { 769 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 770 QName name = reader.getName(); 771 if (MIMEConstants.QNAME_PART.equals(name)) { 772 parseMIMEPart(reader, op, mode); 773 } else { 774 XMLStreamReaderUtil.skipElement(reader); 775 } 776 } 777 } 778 779 private static void parseMIMEPart(XMLStreamReader reader, EditableWSDLBoundOperation op, BindingMode mode) { 780 boolean bodyFound = false; 781 Map<String, ParameterBinding> parts = null; 782 if (mode == BindingMode.INPUT) { 783 parts = op.getInputParts(); 784 } else if (mode == BindingMode.OUTPUT) { 785 parts = op.getOutputParts(); 786 } else if (mode == BindingMode.FAULT) { 787 parts = op.getFaultParts(); 788 } 789 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 790 QName name = reader.getName(); 791 if (SOAPConstants.QNAME_BODY.equals(name) && !bodyFound) { 792 bodyFound = true; 793 parseSOAPBodyBinding(reader, op, mode); 794 XMLStreamReaderUtil.next(reader); 795 } else if (SOAPConstants.QNAME_HEADER.equals(name)) { 796 bodyFound = true; 797 parseSOAPHeaderBinding(reader, parts); 798 XMLStreamReaderUtil.next(reader); 799 } else if (MIMEConstants.QNAME_CONTENT.equals(name)) { 800 String part = reader.getAttributeValue(null, "part"); 801 String type = reader.getAttributeValue(null, "type"); 802 if ((part == null) || (type == null)) { 803 XMLStreamReaderUtil.skipElement(reader); 804 continue; 805 } 806 ParameterBinding sb = ParameterBinding.createAttachment(type); 807 if (parts != null && sb != null && part != null) 808 parts.put(part, sb); 809 XMLStreamReaderUtil.next(reader); 810 } else { 811 XMLStreamReaderUtil.skipElement(reader); 812 } 813 } 814 } 815 816 protected void parseImport(@Nullable URL baseURL, XMLStreamReader reader) throws IOException, SAXException, XMLStreamException { 817 // expand to the absolute URL of the imported WSDL. 818 String importLocation = 819 ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_LOCATION); 820 URL importURL; 821 if(baseURL!=null) 822 importURL = new URL(baseURL, importLocation); 823 else // no base URL. this better be absolute 824 importURL = new URL(importLocation); 825 parseImport(importURL); 826 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 827 XMLStreamReaderUtil.skipElement(reader); 828 } 829 } 830 831 private void parsePortType(XMLStreamReader reader) { 832 String portTypeName = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME); 833 if (portTypeName == null) { 834 //TODO: throw exception? 835 //skip wsdl:portType element for now 836 XMLStreamReaderUtil.skipElement(reader); 837 return; 838 } 839 EditableWSDLPortType portType = new WSDLPortTypeImpl(reader,wsdlDoc, new QName(targetNamespace, portTypeName)); 840 extensionFacade.portTypeAttributes(portType, reader); 841 wsdlDoc.addPortType(portType); 842 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 843 QName name = reader.getName(); 844 if (WSDLConstants.QNAME_OPERATION.equals(name)) { 845 parsePortTypeOperation(reader, portType); 846 } else { 847 extensionFacade.portTypeElements(portType, reader); 848 } 849 } 850 } 851 852 853 private void parsePortTypeOperation(XMLStreamReader reader, EditableWSDLPortType portType) { 854 String operationName = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME); 855 if (operationName == null) { 856 //TODO: throw exception? 857 //skip wsdl:portType element for now 858 XMLStreamReaderUtil.skipElement(reader); 859 return; 860 } 861 862 QName operationQName = new QName(portType.getName().getNamespaceURI(), operationName); 863 EditableWSDLOperation operation = new WSDLOperationImpl(reader,portType, operationQName); 864 extensionFacade.portTypeOperationAttributes(operation, reader); 865 String parameterOrder = ParserUtil.getAttribute(reader, "parameterOrder"); 866 operation.setParameterOrder(parameterOrder); 867 portType.put(operationName, operation); 868 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 869 QName name = reader.getName(); 870 if (name.equals(WSDLConstants.QNAME_INPUT)) { 871 parsePortTypeOperationInput(reader, operation); 872 } else if (name.equals(WSDLConstants.QNAME_OUTPUT)) { 873 parsePortTypeOperationOutput(reader, operation); 874 } else if (name.equals(WSDLConstants.QNAME_FAULT)) { 875 parsePortTypeOperationFault(reader, operation); 876 } else { 877 extensionFacade.portTypeOperationElements(operation, reader); 878 } 879 } 880 } 881 882 883 private void parsePortTypeOperationFault(XMLStreamReader reader, EditableWSDLOperation operation) { 884 String msg = ParserUtil.getMandatoryNonEmptyAttribute(reader, "message"); 885 QName msgName = ParserUtil.getQName(reader, msg); 886 String name = ParserUtil.getMandatoryNonEmptyAttribute(reader, "name"); 887 EditableWSDLFault fault = new WSDLFaultImpl(reader,name, msgName, operation); 888 operation.addFault(fault); 889 extensionFacade.portTypeOperationFaultAttributes(fault, reader); 890 extensionFacade.portTypeOperationFault(operation, reader); 891 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 892 extensionFacade.portTypeOperationFaultElements(fault, reader); 893 } 894 } 895 896 private void parsePortTypeOperationInput(XMLStreamReader reader, EditableWSDLOperation operation) { 897 String msg = ParserUtil.getMandatoryNonEmptyAttribute(reader, "message"); 898 QName msgName = ParserUtil.getQName(reader, msg); 899 String name = ParserUtil.getAttribute(reader, "name"); 900 EditableWSDLInput input = new WSDLInputImpl(reader, name, msgName, operation); 901 operation.setInput(input); 902 extensionFacade.portTypeOperationInputAttributes(input, reader); 903 extensionFacade.portTypeOperationInput(operation, reader); 904 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 905 extensionFacade.portTypeOperationInputElements(input, reader); 906 } 907 } 908 909 private void parsePortTypeOperationOutput(XMLStreamReader reader, EditableWSDLOperation operation) { 910 String msg = ParserUtil.getAttribute(reader, "message"); 911 QName msgName = ParserUtil.getQName(reader, msg); 912 String name = ParserUtil.getAttribute(reader, "name"); 913 EditableWSDLOutput output = new WSDLOutputImpl(reader,name, msgName, operation); 914 operation.setOutput(output); 915 extensionFacade.portTypeOperationOutputAttributes(output, reader); 916 extensionFacade.portTypeOperationOutput(operation, reader); 917 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 918 extensionFacade.portTypeOperationOutputElements(output, reader); 919 } 920 } 921 922 private void parseMessage(XMLStreamReader reader) { 923 String msgName = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME); 924 EditableWSDLMessage msg = new WSDLMessageImpl(reader,new QName(targetNamespace, msgName)); 925 extensionFacade.messageAttributes(msg, reader); 926 int partIndex = 0; 927 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 928 QName name = reader.getName(); 929 if (WSDLConstants.QNAME_PART.equals(name)) { 930 String part = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME); 931 String desc = null; 932 int index = reader.getAttributeCount(); 933 WSDLDescriptorKind kind = WSDLDescriptorKind.ELEMENT; 934 for (int i = 0; i < index; i++) { 935 QName descName = reader.getAttributeName(i); 936 if (descName.getLocalPart().equals("element")) 937 kind = WSDLDescriptorKind.ELEMENT; 938 else if (descName.getLocalPart().equals("type")) 939 kind = WSDLDescriptorKind.TYPE; 940 941 if (descName.getLocalPart().equals("element") || descName.getLocalPart().equals("type")) { 942 desc = reader.getAttributeValue(i); 943 break; 944 } 945 } 946 if (desc != null) { 947 EditableWSDLPart wsdlPart = new WSDLPartImpl(reader, part, partIndex, new WSDLPartDescriptorImpl(reader,ParserUtil.getQName(reader, desc), kind)); 948 msg.add(wsdlPart); 949 } 950 if (reader.getEventType() != XMLStreamConstants.END_ELEMENT) 951 goToEnd(reader); 952 } else { 953 extensionFacade.messageElements(msg, reader); 954 } 955 } 956 wsdlDoc.addMessage(msg); 957 if (reader.getEventType() != XMLStreamConstants.END_ELEMENT) 958 goToEnd(reader); 959 } 960 961 private static void goToEnd(XMLStreamReader reader) { 962 while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) { 963 XMLStreamReaderUtil.skipElement(reader); 964 } 965 } 966 967 /** 968 * Make sure to return a "fresh" reader each time it is called because 969 * more than one active reader may be needed within a single thread 970 * to parse a WSDL file. 971 */ 972 private static XMLStreamReader createReader(URL wsdlLoc) throws IOException, XMLStreamException { 973 return createReader(wsdlLoc, null); 974 } 975 976 /** 977 * Make sure to return a "fresh" reader each time it is called because 978 * more than one active reader may be needed within a single thread 979 * to parse a WSDL file. 980 */ 981 private static XMLStreamReader createReader(URL wsdlLoc, Class<Service> serviceClass) throws IOException, XMLStreamException { 982 InputStream stream; 983 try { 984 stream = wsdlLoc.openStream(); 985 } catch (IOException io) { 986 out: 987 do { 988 if (serviceClass != null) { 989 WSDLLocator locator = ContainerResolver.getInstance().getContainer().getSPI(WSDLLocator.class); 990 if (locator != null) { 991 String exForm = wsdlLoc.toExternalForm(); 992 URL ru = serviceClass.getResource("."); 993 String loc = wsdlLoc.getPath(); 994 if (ru != null) { 995 String ruExForm = ru.toExternalForm(); 996 if (exForm.startsWith(ruExForm)) { 997 loc = exForm.substring(ruExForm.length()); 998 } 999 } 1000 wsdlLoc = locator.locateWSDL(serviceClass, loc); 1001 if (wsdlLoc != null) { 1002 stream = new FilterInputStream(wsdlLoc.openStream()) { 1003 boolean closed; 1004 1005 @Override 1006 public void close() throws IOException { 1007 if (!closed) { 1008 closed = true; 1009 byte[] buf = new byte[8192]; 1010 while(read(buf) != -1); 1011 super.close(); 1012 } 1013 } 1014 }; 1015 break out; 1016 } 1017 } 1018 } 1019 throw io; 1020 } while(true); 1021 } 1022 1023 return new TidyXMLStreamReader(XMLStreamReaderFactory.create(wsdlLoc.toExternalForm(), stream, false), stream); 1024 } 1025 1026 private void register(WSDLParserExtension e) { 1027 // protect JAX-WS RI from broken parser extension 1028 extensions.add(new FoolProofParserExtension(e)); 1029 } 1030 1031 /** 1032 * Reads the namespace declarations from the reader's current position in to the map. The reader is expected to be 1033 * on the start element. 1034 * 1035 * @param ns_map 1036 * @param reader 1037 */ 1038 private static void readNSDecl(Map<String, String> ns_map, XMLStreamReader reader) { 1039 if (reader.getNamespaceCount() > 0) { 1040 for (int i = 0; i < reader.getNamespaceCount(); i++) { 1041 ns_map.put(reader.getNamespacePrefix(i), reader.getNamespaceURI(i)); 1042 } 1043 } 1044 } 1045 1046 private static final Logger LOGGER = Logger.getLogger(RuntimeWSDLParser.class.getName()); 1047 }