src/share/jaxws_classes/com/sun/xml/internal/ws/wsdl/parser/RuntimeWSDLParser.java

Fri, 04 Oct 2013 16:21:34 +0100

author
mkos
date
Fri, 04 Oct 2013 16:21:34 +0100
changeset 408
b0610cd08440
parent 368
0989ad8c0860
child 637
9c07ef4934dd
permissions
-rw-r--r--

8025054: Update JAX-WS RI integration to 2.2.9-b130926.1035
Reviewed-by: chegar

     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  */
    26 package com.sun.xml.internal.ws.wsdl.parser;
    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;
    78 import org.xml.sax.EntityResolver;
    79 import org.xml.sax.SAXException;
    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;
    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;
    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 {
   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;
   119     private final PolicyResolver policyResolver;
   121     /**
   122      * The {@link WSDLParserExtension}. Always non-null.
   123      */
   124     private final WSDLParserExtension extensionFacade;
   126     private final WSDLParserExtensionContextImpl context;
   128     List<WSDLParserExtension> extensions;
   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>();
   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     }
   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     }
   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     }
   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     }
   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;
   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);
   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);
   239         if(wsdlParser.wsdlDoc.getServices().isEmpty())
   240             throw new WebServiceException(ClientMessages.WSDL_CONTAINS_NO_SERVICE(wsdlLoc));
   242         return wsdlParser.wsdlDoc;
   243     }
   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     }
   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;
   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);
   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         }
   300         if(wsdlParser == null)
   301             return null;
   303         wsdlParser.wsdlDoc.freeze();
   304         wsdlParser.extensionFacade.finished(wsdlParser.context);
   305         wsdlParser.extensionFacade.postFinished(wsdlParser.context);
   306         return wsdlParser.wsdlDoc;
   307     }
   309     private static boolean hasWSDLDefinitions(XMLStreamReader reader) {
   310         XMLStreamReaderUtil.nextElementContent(reader);
   311         return reader.getName().equals(WSDLConstants.QNAME_DEFINITIONS);
   312     }
   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     }
   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     }
   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);
   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         }
   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());
   357         this.extensionFacade =  new WSDLParserExtensionFacade(this.extensions.toArray(new WSDLParserExtension[0]));
   358     }
   360     private Parser resolveWSDL(@Nullable URL wsdlLoc, @NotNull Source wsdlSource, Class serviceClass) throws IOException, SAXException, XMLStreamException {
   361         String systemId = wsdlSource.getSystemId();
   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);
   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             }
   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     }
   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         }
   407     private XMLStreamReader createReader(@NotNull Source src) throws XMLStreamException {
   408         return new TidyXMLStreamReader(SourceReaderFactory.createSourceReader(src, true), null);
   409     }
   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     }
   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;
   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             }
   441             //get the targetNamespace of the service
   442             String tns = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_TNS);
   444             final String oldTargetNamespace = targetNamespace;
   445             targetNamespace = tns;
   447             while (XMLStreamReaderUtil.nextElementContent(reader) !=
   448                     XMLStreamConstants.END_ELEMENT) {
   449                 if (reader.getEventType() == XMLStreamConstants.END_DOCUMENT)
   450                     break;
   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     }
   474     private void parseService(XMLStreamReader reader) {
   475         service_nsdecl.putAll(wsdldef_nsdecl);
   476         readNSDecl(service_nsdecl,reader);
   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     }
   496     private void parsePort(XMLStreamReader reader, EditableWSDLService service) {
   497         port_nsdecl.putAll(service_nsdecl);
   498         readNSDecl(port_nsdecl,reader);
   500         String portName = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME);
   501         String binding = ParserUtil.getMandatoryNonEmptyAttribute(reader, "binding");
   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);
   507         extensionFacade.portAttributes(port, reader);
   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);
   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 {
   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     }
   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);
   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));
   580                 String style = reader.getAttributeValue(null, "style");
   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));
   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     }
   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     }
   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         }
   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);
   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");
   648                 if (soapAction != null)
   649                     bindingOp.setSoapAction(soapAction);
   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     }
   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     }
   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     }
   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);
   713         extensionFacade.bindingOperationFaultAttributes(wsdlBoundFault, reader);
   715         while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) {
   716             extensionFacade.bindingOperationFaultElements(wsdlBoundFault, reader);
   717         }
   718     }
   720     private enum BindingMode {
   721         INPUT, OUTPUT, FAULT}
   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     }
   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     }
   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         }
   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     }
   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     }
   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     }
   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     }
   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     }
   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         }
   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     }
   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     }
   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     }
   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     }
   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;
   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     }
   961     private static void goToEnd(XMLStreamReader reader) {
   962         while (XMLStreamReaderUtil.nextElementContent(reader) != XMLStreamConstants.END_ELEMENT) {
   963             XMLStreamReaderUtil.skipElement(reader);
   964         }
   965     }
   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     }
   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;
  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();
  1014                                                 };
  1015                                           break out;
  1019                         throw io;
  1020                 } while(true);
  1023         return new TidyXMLStreamReader(XMLStreamReaderFactory.create(wsdlLoc.toExternalForm(), stream, false), stream);
  1026     private void register(WSDLParserExtension e) {
  1027         // protect JAX-WS RI from broken parser extension
  1028         extensions.add(new FoolProofParserExtension(e));
  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.
  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));
  1046     private static final Logger LOGGER = Logger.getLogger(RuntimeWSDLParser.class.getName());

mercurial