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

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

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

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

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

mercurial