Wed, 27 Apr 2016 01:27:09 +0800
Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/jaxws/
changeset: 657:d47a47f961ee
tag: jdk8u25-b17
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 */
26 package com.sun.xml.internal.ws.server;
28 import com.sun.istack.internal.Nullable;
29 import com.sun.xml.internal.ws.api.server.*;
30 import com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory;
31 import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
32 import com.sun.xml.internal.ws.wsdl.SDDocumentResolver;
33 import com.sun.xml.internal.ws.util.RuntimeVersion;
34 import com.sun.xml.internal.ws.util.xml.XMLStreamReaderToXMLStreamWriter;
35 import com.sun.xml.internal.ws.wsdl.parser.ParserUtil;
36 import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants;
37 import com.sun.xml.internal.ws.wsdl.writer.DocumentLocationResolver;
38 import com.sun.xml.internal.ws.wsdl.writer.WSDLPatcher;
40 import javax.xml.namespace.QName;
41 import javax.xml.stream.*;
42 import javax.xml.ws.WebServiceException;
43 import java.io.IOException;
44 import java.io.OutputStream;
45 import java.net.MalformedURLException;
46 import java.net.URL;
47 import java.util.HashSet;
48 import java.util.List;
49 import java.util.Set;
51 /**
52 * {@link SDDocument} implmentation.
53 *
54 * <p>
55 * This extends from {@link SDDocumentSource} so that
56 * JAX-WS server runtime code can use {@link SDDocument}
57 * as {@link SDDocumentSource}.
58 *
59 * @author Kohsuke Kawaguchi
60 * @author Jitendra Kotamraju
61 */
62 public class SDDocumentImpl extends SDDocumentSource implements SDDocument {
64 private static final String NS_XSD = "http://www.w3.org/2001/XMLSchema";
65 private static final QName SCHEMA_INCLUDE_QNAME = new QName(NS_XSD, "include");
66 private static final QName SCHEMA_IMPORT_QNAME = new QName(NS_XSD, "import");
67 private static final QName SCHEMA_REDEFINE_QNAME = new QName(NS_XSD, "redefine");
68 private static final String VERSION_COMMENT =
69 " Published by JAX-WS RI (http://jax-ws.java.net). RI's version is "+RuntimeVersion.VERSION+". ";
71 private final QName rootName;
72 private final SDDocumentSource source;
74 /**
75 * Set when {@link ServiceDefinitionImpl} is constructed.
76 */
77 @Nullable List<SDDocumentFilter> filters;
78 @Nullable SDDocumentResolver sddocResolver;
81 /**
82 * The original system ID of this document.
83 *
84 * When this document contains relative references to other resources,
85 * this field is used to find which {@link com.sun.xml.internal.ws.server.SDDocumentImpl} it refers to.
86 *
87 * Must not be null.
88 */
89 private final URL url;
90 private final Set<String> imports;
92 /**
93 * Creates {@link SDDocument} from {@link SDDocumentSource}.
94 * @param src WSDL document infoset
95 * @param serviceName wsdl:service name
96 * @param portTypeName
97 * The information about the port of {@link WSEndpoint} to which this document is built for.
98 * These values are used to determine which document is the concrete and abstract WSDLs
99 * for this endpoint.
100 *
101 * @return null
102 * Always non-null.
103 */
104 public static SDDocumentImpl create(SDDocumentSource src, QName serviceName, QName portTypeName) {
105 URL systemId = src.getSystemId();
107 try {
108 // RuntimeWSDLParser parser = new RuntimeWSDLParser(null);
109 XMLStreamReader reader = src.read();
110 try {
111 XMLStreamReaderUtil.nextElementContent(reader);
113 QName rootName = reader.getName();
114 if(rootName.equals(WSDLConstants.QNAME_SCHEMA)) {
115 String tns = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_TNS);
116 Set<String> importedDocs = new HashSet<String>();
117 while (XMLStreamReaderUtil.nextContent(reader) != XMLStreamConstants.END_DOCUMENT) {
118 if (reader.getEventType() != XMLStreamConstants.START_ELEMENT)
119 continue;
120 QName name = reader.getName();
121 if (SCHEMA_INCLUDE_QNAME.equals(name) || SCHEMA_IMPORT_QNAME.equals(name) ||
122 SCHEMA_REDEFINE_QNAME.equals(name)) {
123 String importedDoc = reader.getAttributeValue(null, "schemaLocation");
124 if (importedDoc != null) {
125 importedDocs.add(new URL(src.getSystemId(), importedDoc).toString());
126 }
127 }
128 }
129 return new SchemaImpl(rootName,systemId,src,tns,importedDocs);
130 } else if (rootName.equals(WSDLConstants.QNAME_DEFINITIONS)) {
131 String tns = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_TNS);
133 boolean hasPortType = false;
134 boolean hasService = false;
135 Set<String> importedDocs = new HashSet<String>();
136 Set<QName> allServices = new HashSet<QName>();
138 // if WSDL, parse more
139 while (XMLStreamReaderUtil.nextContent(reader) != XMLStreamConstants.END_DOCUMENT) {
140 if(reader.getEventType() != XMLStreamConstants.START_ELEMENT)
141 continue;
143 QName name = reader.getName();
144 if (WSDLConstants.QNAME_PORT_TYPE.equals(name)) {
145 String pn = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME);
146 if (portTypeName != null) {
147 if(portTypeName.getLocalPart().equals(pn)&&portTypeName.getNamespaceURI().equals(tns)) {
148 hasPortType = true;
149 }
150 }
151 } else if (WSDLConstants.QNAME_SERVICE.equals(name)) {
152 String sn = ParserUtil.getMandatoryNonEmptyAttribute(reader, WSDLConstants.ATTR_NAME);
153 QName sqn = new QName(tns,sn);
154 allServices.add(sqn);
155 if(serviceName.equals(sqn)) {
156 hasService = true;
157 }
158 } else if (WSDLConstants.QNAME_IMPORT.equals(name)) {
159 String importedDoc = reader.getAttributeValue(null, "location");
160 if (importedDoc != null) {
161 importedDocs.add(new URL(src.getSystemId(), importedDoc).toString());
162 }
163 } else if (SCHEMA_INCLUDE_QNAME.equals(name) || SCHEMA_IMPORT_QNAME.equals(name) ||
164 SCHEMA_REDEFINE_QNAME.equals(name)) {
165 String importedDoc = reader.getAttributeValue(null, "schemaLocation");
166 if (importedDoc != null) {
167 importedDocs.add(new URL(src.getSystemId(), importedDoc).toString());
168 }
169 }
170 }
171 return new WSDLImpl(
172 rootName,systemId,src,tns,hasPortType,hasService,importedDocs,allServices);
173 } else {
174 return new SDDocumentImpl(rootName,systemId,src);
175 }
176 } finally {
177 reader.close();
178 }
179 } catch (WebServiceException e) {
180 throw new ServerRtException("runtime.parser.wsdl", systemId,e);
181 } catch (IOException e) {
182 throw new ServerRtException("runtime.parser.wsdl", systemId,e);
183 } catch (XMLStreamException e) {
184 throw new ServerRtException("runtime.parser.wsdl", systemId,e);
185 }
186 }
188 protected SDDocumentImpl(QName rootName, URL url, SDDocumentSource source) {
189 this(rootName, url, source, new HashSet<String>());
190 }
192 protected SDDocumentImpl(QName rootName, URL url, SDDocumentSource source, Set<String> imports) {
193 if (url == null) {
194 throw new IllegalArgumentException("Cannot construct SDDocument with null URL.");
195 }
196 this.rootName = rootName;
197 this.source = source;
198 this.url = url;
199 this.imports = imports;
200 }
202 void setFilters(List<SDDocumentFilter> filters) {
203 this.filters = filters;
204 }
206 void setResolver(SDDocumentResolver sddocResolver) {
207 this.sddocResolver = sddocResolver;
208 }
210 public QName getRootName() {
211 return rootName;
212 }
214 public boolean isWSDL() {
215 return false;
216 }
218 public boolean isSchema() {
219 return false;
220 }
222 public URL getURL() {
223 return url;
224 }
226 public XMLStreamReader read(XMLInputFactory xif) throws IOException, XMLStreamException {
227 return source.read(xif);
228 }
230 public XMLStreamReader read() throws IOException, XMLStreamException {
231 return source.read();
232 }
234 public URL getSystemId() {
235 return url;
236 }
238 public Set<String> getImports() {
239 return imports;
240 }
242 public void writeTo(OutputStream os) throws IOException {
243 XMLStreamWriter w = null;
244 try {
245 //generate the WSDL with utf-8 encoding and XML version 1.0
246 w = XMLStreamWriterFactory.create(os, "UTF-8");
247 w.writeStartDocument("UTF-8", "1.0");
248 new XMLStreamReaderToXMLStreamWriter().bridge(source.read(), w);
249 w.writeEndDocument();
250 } catch (XMLStreamException e) {
251 IOException ioe = new IOException(e.getMessage());
252 ioe.initCause(e);
253 throw ioe;
254 } finally {
255 try {
256 if (w != null)
257 w.close();
258 } catch (XMLStreamException e) {
259 IOException ioe = new IOException(e.getMessage());
260 ioe.initCause(e);
261 throw ioe;
262 }
263 }
264 }
267 public void writeTo(PortAddressResolver portAddressResolver, DocumentAddressResolver resolver, OutputStream os) throws IOException {
268 XMLStreamWriter w = null;
269 try {
270 //generate the WSDL with utf-8 encoding and XML version 1.0
271 w = XMLStreamWriterFactory.create(os, "UTF-8");
272 w.writeStartDocument("UTF-8", "1.0");
273 writeTo(portAddressResolver,resolver,w);
274 w.writeEndDocument();
275 } catch (XMLStreamException e) {
276 IOException ioe = new IOException(e.getMessage());
277 ioe.initCause(e);
278 throw ioe;
279 } finally {
280 try {
281 if (w != null)
282 w.close();
283 } catch (XMLStreamException e) {
284 IOException ioe = new IOException(e.getMessage());
285 ioe.initCause(e);
286 throw ioe;
287 }
288 }
289 }
291 public void writeTo(PortAddressResolver portAddressResolver, DocumentAddressResolver resolver, XMLStreamWriter out) throws XMLStreamException, IOException {
292 if (filters != null) {
293 for (SDDocumentFilter f : filters) {
294 out = f.filter(this,out);
295 }
296 }
298 XMLStreamReader xsr = source.read();
299 try {
300 out.writeComment(VERSION_COMMENT);
301 new WSDLPatcher(portAddressResolver, new DocumentLocationResolverImpl(resolver)).bridge(xsr,out);
302 } finally {
303 xsr.close();
304 }
305 }
308 /**
309 * {@link SDDocument.Schema} implementation.
310 *
311 * @author Kohsuke Kawaguchi
312 */
313 private static final class SchemaImpl extends SDDocumentImpl implements SDDocument.Schema {
314 private final String targetNamespace;
316 public SchemaImpl(QName rootName, URL url, SDDocumentSource source, String targetNamespace,
317 Set<String> imports) {
318 super(rootName, url, source, imports);
319 this.targetNamespace = targetNamespace;
320 }
322 public String getTargetNamespace() {
323 return targetNamespace;
324 }
326 public boolean isSchema() {
327 return true;
328 }
329 }
332 private static final class WSDLImpl extends SDDocumentImpl implements SDDocument.WSDL {
333 private final String targetNamespace;
334 private final boolean hasPortType;
335 private final boolean hasService;
336 private final Set<QName> allServices;
338 public WSDLImpl(QName rootName, URL url, SDDocumentSource source, String targetNamespace, boolean hasPortType,
339 boolean hasService, Set<String> imports,Set<QName> allServices) {
340 super(rootName, url, source, imports);
341 this.targetNamespace = targetNamespace;
342 this.hasPortType = hasPortType;
343 this.hasService = hasService;
344 this.allServices = allServices;
345 }
347 public String getTargetNamespace() {
348 return targetNamespace;
349 }
351 public boolean hasPortType() {
352 return hasPortType;
353 }
355 public boolean hasService() {
356 return hasService;
357 }
359 public Set<QName> getAllServices() {
360 return allServices;
361 }
363 public boolean isWSDL() {
364 return true;
365 }
366 }
368 private class DocumentLocationResolverImpl implements DocumentLocationResolver {
369 private DocumentAddressResolver delegate;
371 DocumentLocationResolverImpl(DocumentAddressResolver delegate) {
372 this.delegate = delegate;
373 }
375 public String getLocationFor(String namespaceURI, String systemId) {
376 if (sddocResolver == null) {
377 return systemId;
378 }
379 try {
380 URL ref = new URL(getURL(), systemId);
381 SDDocument refDoc = sddocResolver.resolve(ref.toExternalForm());
382 if (refDoc == null)
383 return systemId; // not something we know. just leave it as is.
385 return delegate.getRelativeAddressFor(SDDocumentImpl.this, refDoc);
386 } catch (MalformedURLException mue) {
387 return null;
388 }
389 }
390 }
392 }