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

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 408
b0610cd08440
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

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

mercurial