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

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 368
0989ad8c0860
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

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

mercurial