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

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 408
b0610cd08440
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

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

mercurial