Fri, 23 Aug 2013 09:57:21 +0100
8022885: Update JAX-WS RI integration to 2.2.9-b14140
8013016: Rebase 8009009 against the latest jdk8/jaxws
Reviewed-by: alanb, chegar
ohair@286 | 1 | /* |
mkos@397 | 2 | * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
ohair@286 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
ohair@286 | 4 | * |
ohair@286 | 5 | * This code is free software; you can redistribute it and/or modify it |
ohair@286 | 6 | * under the terms of the GNU General Public License version 2 only, as |
ohair@286 | 7 | * published by the Free Software Foundation. Oracle designates this |
ohair@286 | 8 | * particular file as subject to the "Classpath" exception as provided |
ohair@286 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
ohair@286 | 10 | * |
ohair@286 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
ohair@286 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
ohair@286 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
ohair@286 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
ohair@286 | 15 | * accompanied this code). |
ohair@286 | 16 | * |
ohair@286 | 17 | * You should have received a copy of the GNU General Public License version |
ohair@286 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
ohair@286 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
ohair@286 | 20 | * |
ohair@286 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
ohair@286 | 22 | * or visit www.oracle.com if you need additional information or have any |
ohair@286 | 23 | * questions. |
ohair@286 | 24 | */ |
ohair@286 | 25 | |
ohair@286 | 26 | package com.sun.xml.internal.ws.server; |
ohair@286 | 27 | |
ohair@286 | 28 | import com.sun.istack.internal.Nullable; |
ohair@286 | 29 | import com.sun.xml.internal.ws.api.server.*; |
ohair@286 | 30 | import com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory; |
ohair@286 | 31 | import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil; |
ohair@286 | 32 | import com.sun.xml.internal.ws.wsdl.SDDocumentResolver; |
ohair@286 | 33 | import com.sun.xml.internal.ws.util.RuntimeVersion; |
ohair@286 | 34 | import com.sun.xml.internal.ws.util.xml.XMLStreamReaderToXMLStreamWriter; |
ohair@286 | 35 | import com.sun.xml.internal.ws.wsdl.parser.ParserUtil; |
ohair@286 | 36 | import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants; |
ohair@286 | 37 | import com.sun.xml.internal.ws.wsdl.writer.DocumentLocationResolver; |
ohair@286 | 38 | import com.sun.xml.internal.ws.wsdl.writer.WSDLPatcher; |
ohair@286 | 39 | |
ohair@286 | 40 | import javax.xml.namespace.QName; |
ohair@286 | 41 | import javax.xml.stream.*; |
ohair@286 | 42 | import javax.xml.ws.WebServiceException; |
ohair@286 | 43 | import java.io.IOException; |
ohair@286 | 44 | import java.io.OutputStream; |
ohair@286 | 45 | import java.net.MalformedURLException; |
ohair@286 | 46 | import java.net.URL; |
ohair@286 | 47 | import java.util.HashSet; |
ohair@286 | 48 | import java.util.List; |
ohair@286 | 49 | import java.util.Set; |
ohair@286 | 50 | |
ohair@286 | 51 | /** |
ohair@286 | 52 | * {@link SDDocument} implmentation. |
ohair@286 | 53 | * |
ohair@286 | 54 | * <p> |
ohair@286 | 55 | * This extends from {@link SDDocumentSource} so that |
ohair@286 | 56 | * JAX-WS server runtime code can use {@link SDDocument} |
ohair@286 | 57 | * as {@link SDDocumentSource}. |
ohair@286 | 58 | * |
ohair@286 | 59 | * @author Kohsuke Kawaguchi |
ohair@286 | 60 | * @author Jitendra Kotamraju |
ohair@286 | 61 | */ |
ohair@286 | 62 | public class SDDocumentImpl extends SDDocumentSource implements SDDocument { |
ohair@286 | 63 | |
ohair@286 | 64 | private static final String NS_XSD = "http://www.w3.org/2001/XMLSchema"; |
ohair@286 | 65 | private static final QName SCHEMA_INCLUDE_QNAME = new QName(NS_XSD, "include"); |
ohair@286 | 66 | private static final QName SCHEMA_IMPORT_QNAME = new QName(NS_XSD, "import"); |
ohair@286 | 67 | private static final QName SCHEMA_REDEFINE_QNAME = new QName(NS_XSD, "redefine"); |
ohair@286 | 68 | private static final String VERSION_COMMENT = |
mkos@397 | 69 | " Published by JAX-WS RI (http://jax-ws.java.net). RI's version is "+RuntimeVersion.VERSION+". "; |
ohair@286 | 70 | |
ohair@286 | 71 | private final QName rootName; |
ohair@286 | 72 | private final SDDocumentSource source; |
ohair@286 | 73 | |
ohair@286 | 74 | /** |
ohair@286 | 75 | * Set when {@link ServiceDefinitionImpl} is constructed. |
ohair@286 | 76 | */ |
ohair@286 | 77 | @Nullable List<SDDocumentFilter> filters; |
ohair@286 | 78 | @Nullable SDDocumentResolver sddocResolver; |
ohair@286 | 79 | |
ohair@286 | 80 | |
ohair@286 | 81 | /** |
ohair@286 | 82 | * The original system ID of this document. |
ohair@286 | 83 | * |
ohair@286 | 84 | * When this document contains relative references to other resources, |
ohair@286 | 85 | * this field is used to find which {@link com.sun.xml.internal.ws.server.SDDocumentImpl} it refers to. |
ohair@286 | 86 | * |
ohair@286 | 87 | * Must not be null. |
ohair@286 | 88 | */ |
ohair@286 | 89 | private final URL url; |
ohair@286 | 90 | private final Set<String> imports; |
ohair@286 | 91 | |
ohair@286 | 92 | /** |
ohair@286 | 93 | * Creates {@link SDDocument} from {@link SDDocumentSource}. |
ohair@286 | 94 | * @param src WSDL document infoset |
ohair@286 | 95 | * @param serviceName wsdl:service name |
ohair@286 | 96 | * @param portTypeName |
ohair@286 | 97 | * The information about the port of {@link WSEndpoint} to which this document is built for. |
ohair@286 | 98 | * These values are used to determine which document is the concrete and abstract WSDLs |
ohair@286 | 99 | * for this endpoint. |
ohair@286 | 100 | * |
ohair@286 | 101 | * @return null |
ohair@286 | 102 | * Always non-null. |
ohair@286 | 103 | */ |
ohair@286 | 104 | public static SDDocumentImpl create(SDDocumentSource src, QName serviceName, QName portTypeName) { |
ohair@286 | 105 | URL systemId = src.getSystemId(); |
ohair@286 | 106 | |
ohair@286 | 107 | try { |
ohair@286 | 108 | // RuntimeWSDLParser parser = new RuntimeWSDLParser(null); |
ohair@286 | 109 | XMLStreamReader reader = src.read(); |
ohair@286 | 110 | try { |
ohair@286 | 111 | XMLStreamReaderUtil.nextElementContent(reader); |
ohair@286 | 112 | |
ohair@286 | 113 | QName rootName = reader.getName(); |
ohair@286 | 114 | if(rootName.equals(WSDLConstants.QNAME_SCHEMA)) { |
ohair@286 | 115 | String tns = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_TNS); |
ohair@286 | 116 | Set<String> importedDocs = new HashSet<String>(); |
ohair@286 | 117 | while (XMLStreamReaderUtil.nextContent(reader) != XMLStreamConstants.END_DOCUMENT) { |
ohair@286 | 118 | if (reader.getEventType() != XMLStreamConstants.START_ELEMENT) |
ohair@286 | 119 | continue; |
ohair@286 | 120 | QName name = reader.getName(); |
ohair@286 | 121 | if (SCHEMA_INCLUDE_QNAME.equals(name) || SCHEMA_IMPORT_QNAME.equals(name) || |
ohair@286 | 122 | SCHEMA_REDEFINE_QNAME.equals(name)) { |
ohair@286 | 123 | String importedDoc = reader.getAttributeValue(null, "schemaLocation"); |
ohair@286 | 124 | if (importedDoc != null) { |
ohair@286 | 125 | importedDocs.add(new URL(src.getSystemId(), importedDoc).toString()); |
ohair@286 | 126 | } |
ohair@286 | 127 | } |
ohair@286 | 128 | } |
ohair@286 | 129 | return new SchemaImpl(rootName,systemId,src,tns,importedDocs); |
ohair@286 | 130 | } else if (rootName.equals(WSDLConstants.QNAME_DEFINITIONS)) { |
ohair@286 | 131 | String tns = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_TNS); |
ohair@286 | 132 | |
ohair@286 | 133 | boolean hasPortType = false; |
ohair@286 | 134 | boolean hasService = false; |
ohair@286 | 135 | Set<String> importedDocs = new HashSet<String>(); |
ohair@286 | 136 | Set<QName> allServices = new HashSet<QName>(); |
ohair@286 | 137 | |
ohair@286 | 138 | // if WSDL, parse more |
ohair@286 | 139 | while (XMLStreamReaderUtil.nextContent(reader) != XMLStreamConstants.END_DOCUMENT) { |
ohair@286 | 140 | if(reader.getEventType() != XMLStreamConstants.START_ELEMENT) |
ohair@286 | 141 | continue; |
ohair@286 | 142 | |
ohair@286 | 143 | QName name = reader.getName(); |
ohair@286 | 144 | if (WSDLConstants.QNAME_PORT_TYPE.equals(name)) { |
ohair@286 | 145 | String pn = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME); |
ohair@286 | 146 | if (portTypeName != null) { |
ohair@286 | 147 | if(portTypeName.getLocalPart().equals(pn)&&portTypeName.getNamespaceURI().equals(tns)) { |
ohair@286 | 148 | hasPortType = true; |
ohair@286 | 149 | } |
ohair@286 | 150 | } |
ohair@286 | 151 | } else if (WSDLConstants.QNAME_SERVICE.equals(name)) { |
ohair@286 | 152 | String sn = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME); |
ohair@286 | 153 | QName sqn = new QName(tns,sn); |
ohair@286 | 154 | allServices.add(sqn); |
ohair@286 | 155 | if(serviceName.equals(sqn)) { |
ohair@286 | 156 | hasService = true; |
ohair@286 | 157 | } |
ohair@286 | 158 | } else if (WSDLConstants.QNAME_IMPORT.equals(name)) { |
ohair@286 | 159 | String importedDoc = reader.getAttributeValue(null, "location"); |
ohair@286 | 160 | if (importedDoc != null) { |
ohair@286 | 161 | importedDocs.add(new URL(src.getSystemId(), importedDoc).toString()); |
ohair@286 | 162 | } |
ohair@286 | 163 | } else if (SCHEMA_INCLUDE_QNAME.equals(name) || SCHEMA_IMPORT_QNAME.equals(name) || |
ohair@286 | 164 | SCHEMA_REDEFINE_QNAME.equals(name)) { |
ohair@286 | 165 | String importedDoc = reader.getAttributeValue(null, "schemaLocation"); |
ohair@286 | 166 | if (importedDoc != null) { |
ohair@286 | 167 | importedDocs.add(new URL(src.getSystemId(), importedDoc).toString()); |
ohair@286 | 168 | } |
ohair@286 | 169 | } |
ohair@286 | 170 | } |
ohair@286 | 171 | return new WSDLImpl( |
ohair@286 | 172 | rootName,systemId,src,tns,hasPortType,hasService,importedDocs,allServices); |
ohair@286 | 173 | } else { |
ohair@286 | 174 | return new SDDocumentImpl(rootName,systemId,src); |
ohair@286 | 175 | } |
ohair@286 | 176 | } finally { |
ohair@286 | 177 | reader.close(); |
ohair@286 | 178 | } |
ohair@286 | 179 | } catch (WebServiceException e) { |
ohair@286 | 180 | throw new ServerRtException("runtime.parser.wsdl", systemId,e); |
ohair@286 | 181 | } catch (IOException e) { |
ohair@286 | 182 | throw new ServerRtException("runtime.parser.wsdl", systemId,e); |
ohair@286 | 183 | } catch (XMLStreamException e) { |
ohair@286 | 184 | throw new ServerRtException("runtime.parser.wsdl", systemId,e); |
ohair@286 | 185 | } |
ohair@286 | 186 | } |
ohair@286 | 187 | |
ohair@286 | 188 | protected SDDocumentImpl(QName rootName, URL url, SDDocumentSource source) { |
ohair@286 | 189 | this(rootName, url, source, new HashSet<String>()); |
ohair@286 | 190 | } |
ohair@286 | 191 | |
ohair@286 | 192 | protected SDDocumentImpl(QName rootName, URL url, SDDocumentSource source, Set<String> imports) { |
ohair@286 | 193 | if (url == null) { |
ohair@286 | 194 | throw new IllegalArgumentException("Cannot construct SDDocument with null URL."); |
ohair@286 | 195 | } |
ohair@286 | 196 | this.rootName = rootName; |
ohair@286 | 197 | this.source = source; |
ohair@286 | 198 | this.url = url; |
ohair@286 | 199 | this.imports = imports; |
ohair@286 | 200 | } |
ohair@286 | 201 | |
ohair@286 | 202 | void setFilters(List<SDDocumentFilter> filters) { |
ohair@286 | 203 | this.filters = filters; |
ohair@286 | 204 | } |
ohair@286 | 205 | |
ohair@286 | 206 | void setResolver(SDDocumentResolver sddocResolver) { |
ohair@286 | 207 | this.sddocResolver = sddocResolver; |
ohair@286 | 208 | } |
ohair@286 | 209 | |
ohair@286 | 210 | public QName getRootName() { |
ohair@286 | 211 | return rootName; |
ohair@286 | 212 | } |
ohair@286 | 213 | |
ohair@286 | 214 | public boolean isWSDL() { |
ohair@286 | 215 | return false; |
ohair@286 | 216 | } |
ohair@286 | 217 | |
ohair@286 | 218 | public boolean isSchema() { |
ohair@286 | 219 | return false; |
ohair@286 | 220 | } |
ohair@286 | 221 | |
ohair@286 | 222 | public URL getURL() { |
ohair@286 | 223 | return url; |
ohair@286 | 224 | } |
ohair@286 | 225 | |
ohair@286 | 226 | public XMLStreamReader read(XMLInputFactory xif) throws IOException, XMLStreamException { |
ohair@286 | 227 | return source.read(xif); |
ohair@286 | 228 | } |
ohair@286 | 229 | |
ohair@286 | 230 | public XMLStreamReader read() throws IOException, XMLStreamException { |
ohair@286 | 231 | return source.read(); |
ohair@286 | 232 | } |
ohair@286 | 233 | |
ohair@286 | 234 | public URL getSystemId() { |
ohair@286 | 235 | return url; |
ohair@286 | 236 | } |
ohair@286 | 237 | |
ohair@286 | 238 | public Set<String> getImports() { |
ohair@286 | 239 | return imports; |
ohair@286 | 240 | } |
ohair@286 | 241 | |
ohair@286 | 242 | public void writeTo(OutputStream os) throws IOException { |
ohair@286 | 243 | XMLStreamWriter w = null; |
ohair@286 | 244 | try { |
ohair@286 | 245 | //generate the WSDL with utf-8 encoding and XML version 1.0 |
ohair@286 | 246 | w = XMLStreamWriterFactory.create(os, "UTF-8"); |
ohair@286 | 247 | w.writeStartDocument("UTF-8", "1.0"); |
ohair@286 | 248 | new XMLStreamReaderToXMLStreamWriter().bridge(source.read(), w); |
ohair@286 | 249 | w.writeEndDocument(); |
ohair@286 | 250 | } catch (XMLStreamException e) { |
ohair@286 | 251 | IOException ioe = new IOException(e.getMessage()); |
ohair@286 | 252 | ioe.initCause(e); |
ohair@286 | 253 | throw ioe; |
ohair@286 | 254 | } finally { |
ohair@286 | 255 | try { |
ohair@286 | 256 | if (w != null) |
ohair@286 | 257 | w.close(); |
ohair@286 | 258 | } catch (XMLStreamException e) { |
ohair@286 | 259 | IOException ioe = new IOException(e.getMessage()); |
ohair@286 | 260 | ioe.initCause(e); |
ohair@286 | 261 | throw ioe; |
ohair@286 | 262 | } |
ohair@286 | 263 | } |
ohair@286 | 264 | } |
ohair@286 | 265 | |
ohair@286 | 266 | |
ohair@286 | 267 | public void writeTo(PortAddressResolver portAddressResolver, DocumentAddressResolver resolver, OutputStream os) throws IOException { |
ohair@286 | 268 | XMLStreamWriter w = null; |
ohair@286 | 269 | try { |
ohair@286 | 270 | //generate the WSDL with utf-8 encoding and XML version 1.0 |
ohair@286 | 271 | w = XMLStreamWriterFactory.create(os, "UTF-8"); |
ohair@286 | 272 | w.writeStartDocument("UTF-8", "1.0"); |
ohair@286 | 273 | writeTo(portAddressResolver,resolver,w); |
ohair@286 | 274 | w.writeEndDocument(); |
ohair@286 | 275 | } catch (XMLStreamException e) { |
ohair@286 | 276 | IOException ioe = new IOException(e.getMessage()); |
ohair@286 | 277 | ioe.initCause(e); |
ohair@286 | 278 | throw ioe; |
ohair@286 | 279 | } finally { |
ohair@286 | 280 | try { |
ohair@286 | 281 | if (w != null) |
ohair@286 | 282 | w.close(); |
ohair@286 | 283 | } catch (XMLStreamException e) { |
ohair@286 | 284 | IOException ioe = new IOException(e.getMessage()); |
ohair@286 | 285 | ioe.initCause(e); |
ohair@286 | 286 | throw ioe; |
ohair@286 | 287 | } |
ohair@286 | 288 | } |
ohair@286 | 289 | } |
ohair@286 | 290 | |
ohair@286 | 291 | public void writeTo(PortAddressResolver portAddressResolver, DocumentAddressResolver resolver, XMLStreamWriter out) throws XMLStreamException, IOException { |
ohair@286 | 292 | if (filters != null) { |
ohair@286 | 293 | for (SDDocumentFilter f : filters) { |
ohair@286 | 294 | out = f.filter(this,out); |
ohair@286 | 295 | } |
ohair@286 | 296 | } |
ohair@286 | 297 | |
ohair@286 | 298 | XMLStreamReader xsr = source.read(); |
ohair@286 | 299 | try { |
ohair@286 | 300 | out.writeComment(VERSION_COMMENT); |
ohair@286 | 301 | new WSDLPatcher(portAddressResolver, new DocumentLocationResolverImpl(resolver)).bridge(xsr,out); |
ohair@286 | 302 | } finally { |
ohair@286 | 303 | xsr.close(); |
ohair@286 | 304 | } |
ohair@286 | 305 | } |
ohair@286 | 306 | |
ohair@286 | 307 | |
ohair@286 | 308 | /** |
ohair@286 | 309 | * {@link SDDocument.Schema} implementation. |
ohair@286 | 310 | * |
ohair@286 | 311 | * @author Kohsuke Kawaguchi |
ohair@286 | 312 | */ |
ohair@286 | 313 | private static final class SchemaImpl extends SDDocumentImpl implements SDDocument.Schema { |
ohair@286 | 314 | private final String targetNamespace; |
ohair@286 | 315 | |
ohair@286 | 316 | public SchemaImpl(QName rootName, URL url, SDDocumentSource source, String targetNamespace, |
ohair@286 | 317 | Set<String> imports) { |
ohair@286 | 318 | super(rootName, url, source, imports); |
ohair@286 | 319 | this.targetNamespace = targetNamespace; |
ohair@286 | 320 | } |
ohair@286 | 321 | |
ohair@286 | 322 | public String getTargetNamespace() { |
ohair@286 | 323 | return targetNamespace; |
ohair@286 | 324 | } |
ohair@286 | 325 | |
ohair@286 | 326 | public boolean isSchema() { |
ohair@286 | 327 | return true; |
ohair@286 | 328 | } |
ohair@286 | 329 | } |
ohair@286 | 330 | |
ohair@286 | 331 | |
ohair@286 | 332 | private static final class WSDLImpl extends SDDocumentImpl implements SDDocument.WSDL { |
ohair@286 | 333 | private final String targetNamespace; |
ohair@286 | 334 | private final boolean hasPortType; |
ohair@286 | 335 | private final boolean hasService; |
ohair@286 | 336 | private final Set<QName> allServices; |
ohair@286 | 337 | |
ohair@286 | 338 | public WSDLImpl(QName rootName, URL url, SDDocumentSource source, String targetNamespace, boolean hasPortType, |
ohair@286 | 339 | boolean hasService, Set<String> imports,Set<QName> allServices) { |
ohair@286 | 340 | super(rootName, url, source, imports); |
ohair@286 | 341 | this.targetNamespace = targetNamespace; |
ohair@286 | 342 | this.hasPortType = hasPortType; |
ohair@286 | 343 | this.hasService = hasService; |
ohair@286 | 344 | this.allServices = allServices; |
ohair@286 | 345 | } |
ohair@286 | 346 | |
ohair@286 | 347 | public String getTargetNamespace() { |
ohair@286 | 348 | return targetNamespace; |
ohair@286 | 349 | } |
ohair@286 | 350 | |
ohair@286 | 351 | public boolean hasPortType() { |
ohair@286 | 352 | return hasPortType; |
ohair@286 | 353 | } |
ohair@286 | 354 | |
ohair@286 | 355 | public boolean hasService() { |
ohair@286 | 356 | return hasService; |
ohair@286 | 357 | } |
ohair@286 | 358 | |
ohair@286 | 359 | public Set<QName> getAllServices() { |
ohair@286 | 360 | return allServices; |
ohair@286 | 361 | } |
ohair@286 | 362 | |
ohair@286 | 363 | public boolean isWSDL() { |
ohair@286 | 364 | return true; |
ohair@286 | 365 | } |
ohair@286 | 366 | } |
ohair@286 | 367 | |
ohair@286 | 368 | private class DocumentLocationResolverImpl implements DocumentLocationResolver { |
ohair@286 | 369 | private DocumentAddressResolver delegate; |
ohair@286 | 370 | |
ohair@286 | 371 | DocumentLocationResolverImpl(DocumentAddressResolver delegate) { |
ohair@286 | 372 | this.delegate = delegate; |
ohair@286 | 373 | } |
ohair@286 | 374 | |
ohair@286 | 375 | public String getLocationFor(String namespaceURI, String systemId) { |
ohair@286 | 376 | if (sddocResolver == null) { |
ohair@286 | 377 | return systemId; |
ohair@286 | 378 | } |
ohair@286 | 379 | try { |
ohair@286 | 380 | URL ref = new URL(getURL(), systemId); |
ohair@286 | 381 | SDDocument refDoc = sddocResolver.resolve(ref.toExternalForm()); |
ohair@286 | 382 | if (refDoc == null) |
ohair@286 | 383 | return systemId; // not something we know. just leave it as is. |
ohair@286 | 384 | |
ohair@286 | 385 | return delegate.getRelativeAddressFor(SDDocumentImpl.this, refDoc); |
ohair@286 | 386 | } catch (MalformedURLException mue) { |
ohair@286 | 387 | return null; |
ohair@286 | 388 | } |
ohair@286 | 389 | } |
ohair@286 | 390 | } |
ohair@286 | 391 | |
ohair@286 | 392 | } |