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

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

mercurial