author | mkos |
Mon, 31 Mar 2014 10:43:20 +0200 | |
changeset 23782 | 953bfc3fbe31 |
parent 22679 | d785acd84a14 |
permissions | -rw-r--r-- |
12009 | 1 |
/* |
23782
953bfc3fbe31
8036030: Update JAX-WS RI integration to latest version
mkos
parents:
22679
diff
changeset
|
2 |
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
12009 | 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.api.addressing; |
|
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.XMLStreamBufferResult; |
|
33 |
import com.sun.xml.internal.stream.buffer.XMLStreamBufferSource; |
|
34 |
import com.sun.xml.internal.stream.buffer.sax.SAXBufferProcessor; |
|
35 |
import com.sun.xml.internal.stream.buffer.stax.StreamReaderBufferProcessor; |
|
36 |
import com.sun.xml.internal.stream.buffer.stax.StreamWriterBufferCreator; |
|
37 |
import com.sun.xml.internal.ws.addressing.EndpointReferenceUtil; |
|
38 |
import com.sun.xml.internal.ws.addressing.W3CAddressingMetadataConstants; |
|
39 |
import com.sun.xml.internal.ws.addressing.WSEPRExtension; |
|
40 |
import com.sun.xml.internal.ws.addressing.model.InvalidAddressingHeaderException; |
|
41 |
import com.sun.xml.internal.ws.addressing.v200408.MemberSubmissionAddressingConstants; |
|
42 |
import com.sun.xml.internal.ws.api.message.Header; |
|
43 |
import com.sun.xml.internal.ws.api.message.HeaderList; |
|
44 |
import com.sun.xml.internal.ws.api.message.Message; |
|
16791 | 45 |
import com.sun.xml.internal.ws.api.message.MessageHeaders; |
12009 | 46 |
import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory; |
47 |
import com.sun.xml.internal.ws.api.model.wsdl.WSDLExtension; |
|
48 |
import com.sun.xml.internal.ws.resources.AddressingMessages; |
|
49 |
import com.sun.xml.internal.ws.resources.ClientMessages; |
|
50 |
import com.sun.xml.internal.ws.spi.ProviderImpl; |
|
51 |
import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil; |
|
52 |
import com.sun.xml.internal.ws.util.DOMUtil; |
|
53 |
import com.sun.xml.internal.ws.util.xml.XMLStreamWriterFilter; |
|
54 |
import com.sun.xml.internal.ws.util.xml.XmlUtil; |
|
23782
953bfc3fbe31
8036030: Update JAX-WS RI integration to latest version
mkos
parents:
22679
diff
changeset
|
55 |
import com.sun.xml.internal.org.jvnet.staxex.util.XMLStreamReaderToXMLStreamWriter; |
12009 | 56 |
import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants; |
57 |
import org.w3c.dom.Element; |
|
58 |
import org.xml.sax.*; |
|
59 |
import org.xml.sax.helpers.XMLFilterImpl; |
|
60 |
||
61 |
import javax.xml.bind.JAXBContext; |
|
62 |
import javax.xml.namespace.QName; |
|
63 |
import javax.xml.stream.XMLStreamException; |
|
64 |
import javax.xml.stream.XMLStreamReader; |
|
65 |
import javax.xml.stream.XMLStreamWriter; |
|
66 |
import javax.xml.transform.Source; |
|
67 |
import javax.xml.transform.TransformerException; |
|
68 |
import javax.xml.transform.sax.SAXSource; |
|
69 |
import javax.xml.transform.stream.StreamResult; |
|
70 |
import javax.xml.transform.stream.StreamSource; |
|
71 |
import javax.xml.ws.Dispatch; |
|
72 |
import javax.xml.ws.EndpointReference; |
|
73 |
import javax.xml.ws.Service; |
|
74 |
import javax.xml.ws.WebServiceException; |
|
75 |
import javax.xml.ws.WebServiceFeature; |
|
76 |
import java.io.InputStream; |
|
77 |
import java.io.StringWriter; |
|
78 |
import java.net.URI; |
|
79 |
import java.net.URL; |
|
80 |
import java.util.*; |
|
81 |
||
82 |
/** |
|
83 |
* Internal representation of the EPR. |
|
84 |
* |
|
85 |
* <p> |
|
86 |
* Instances of this class are immutable and thread-safe. |
|
87 |
* |
|
88 |
* @author Kohsuke Kawaguchi |
|
89 |
* @author Rama Pulavarthi |
|
90 |
* |
|
91 |
* @see AddressingVersion#anonymousEpr |
|
92 |
*/ |
|
93 |
public final class WSEndpointReference implements WSDLExtension { |
|
94 |
private final XMLStreamBuffer infoset; |
|
95 |
/** |
|
96 |
* Version of the addressing spec. |
|
97 |
*/ |
|
98 |
private final AddressingVersion version; |
|
99 |
||
100 |
/** |
|
101 |
* Marked Reference parameters inside this EPR. |
|
102 |
* |
|
103 |
* Parsed when the object is created. can be empty but never null. |
|
104 |
* @see #parse() |
|
105 |
*/ |
|
106 |
private @NotNull Header[] referenceParameters; |
|
107 |
private @NotNull String address; |
|
108 |
||
109 |
private @NotNull QName rootElement; |
|
110 |
/** |
|
111 |
* Creates from the spec version of {@link EndpointReference}. |
|
112 |
* |
|
113 |
* <p> |
|
114 |
* This method performs the data conversion, so it's slow. |
|
115 |
* Do not use this method in a performance critical path. |
|
116 |
*/ |
|
117 |
public WSEndpointReference(EndpointReference epr, AddressingVersion version) { |
|
118 |
try { |
|
119 |
MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer(); |
|
120 |
epr.writeTo(new XMLStreamBufferResult(xsb)); |
|
121 |
this.infoset = xsb; |
|
122 |
this.version = version; |
|
123 |
this.rootElement = new QName("EndpointReference", version.nsUri); |
|
124 |
parse(); |
|
125 |
} catch (XMLStreamException e) { |
|
126 |
throw new WebServiceException(ClientMessages.FAILED_TO_PARSE_EPR(epr),e); |
|
127 |
} |
|
128 |
} |
|
129 |
||
130 |
/** |
|
131 |
* Creates from the spec version of {@link EndpointReference}. |
|
132 |
* |
|
133 |
* <p> |
|
134 |
* This method performs the data conversion, so it's slow. |
|
135 |
* Do not use this method in a performance critical path. |
|
136 |
*/ |
|
137 |
public WSEndpointReference(EndpointReference epr) { |
|
138 |
this(epr,AddressingVersion.fromSpecClass(epr.getClass())); |
|
139 |
} |
|
140 |
||
141 |
/** |
|
142 |
* Creates a {@link WSEndpointReference} that wraps a given infoset. |
|
143 |
*/ |
|
144 |
public WSEndpointReference(XMLStreamBuffer infoset, AddressingVersion version) { |
|
145 |
try { |
|
146 |
this.infoset = infoset; |
|
147 |
this.version = version; |
|
148 |
this.rootElement = new QName("EndpointReference", version.nsUri); |
|
149 |
parse(); |
|
150 |
} catch (XMLStreamException e) { |
|
151 |
// this can never happen because XMLStreamBuffer never has underlying I/O error. |
|
152 |
throw new AssertionError(e); |
|
153 |
} |
|
154 |
} |
|
155 |
||
156 |
/** |
|
157 |
* Creates a {@link WSEndpointReference} by parsing an infoset. |
|
158 |
*/ |
|
159 |
public WSEndpointReference(InputStream infoset, AddressingVersion version) throws XMLStreamException { |
|
160 |
this(XMLStreamReaderFactory.create(null,infoset,false),version); |
|
161 |
} |
|
162 |
||
163 |
/** |
|
164 |
* Creates a {@link WSEndpointReference} from the given infoset. |
|
165 |
* The {@link XMLStreamReader} must point to either a document or an element. |
|
166 |
*/ |
|
167 |
public WSEndpointReference(XMLStreamReader in, AddressingVersion version) throws XMLStreamException { |
|
168 |
this(XMLStreamBuffer.createNewBufferFromXMLStreamReader(in), version); |
|
169 |
} |
|
170 |
||
171 |
/** |
|
172 |
* @see #WSEndpointReference(String, AddressingVersion) |
|
173 |
*/ |
|
174 |
public WSEndpointReference(URL address, AddressingVersion version) { |
|
175 |
this(address.toExternalForm(), version); |
|
176 |
} |
|
177 |
||
178 |
/** |
|
179 |
* @see #WSEndpointReference(String, AddressingVersion) |
|
180 |
*/ |
|
181 |
public WSEndpointReference(URI address, AddressingVersion version) { |
|
182 |
this(address.toString(), version); |
|
183 |
} |
|
184 |
||
185 |
/** |
|
186 |
* Creates a {@link WSEndpointReference} that only has an address. |
|
187 |
*/ |
|
188 |
public WSEndpointReference(String address, AddressingVersion version) { |
|
189 |
this.infoset = createBufferFromAddress(address,version); |
|
190 |
this.version = version; |
|
191 |
this.address = address; |
|
192 |
this.rootElement = new QName("EndpointReference", version.nsUri); |
|
193 |
this.referenceParameters = EMPTY_ARRAY; |
|
194 |
} |
|
195 |
||
196 |
private static XMLStreamBuffer createBufferFromAddress(String address, AddressingVersion version) { |
|
197 |
try { |
|
198 |
MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer(); |
|
199 |
StreamWriterBufferCreator w = new StreamWriterBufferCreator(xsb); |
|
200 |
w.writeStartDocument(); |
|
201 |
w.writeStartElement(version.getPrefix(), |
|
202 |
"EndpointReference", version.nsUri); |
|
203 |
w.writeNamespace(version.getPrefix(), version.nsUri); |
|
204 |
w.writeStartElement(version.getPrefix(),version.eprType.address, version.nsUri); |
|
205 |
w.writeCharacters(address); |
|
206 |
w.writeEndElement(); |
|
207 |
w.writeEndElement(); |
|
208 |
w.writeEndDocument(); |
|
209 |
w.close(); |
|
210 |
return xsb; |
|
211 |
} catch (XMLStreamException e) { |
|
212 |
// can never happen because we are writing to XSB |
|
213 |
throw new AssertionError(e); |
|
214 |
} |
|
215 |
} |
|
216 |
||
217 |
/** |
|
218 |
* Creates an EPR from individual components. |
|
219 |
* |
|
220 |
* <p> |
|
221 |
* This version takes various information about metadata, and creates an EPR that has |
|
222 |
* the necessary embedded WSDL. |
|
223 |
*/ |
|
224 |
public WSEndpointReference(@NotNull AddressingVersion version, |
|
225 |
@NotNull String address, |
|
226 |
@Nullable QName service, |
|
227 |
@Nullable QName port, |
|
228 |
@Nullable QName portType, |
|
229 |
@Nullable List<Element> metadata, |
|
230 |
@Nullable String wsdlAddress, |
|
231 |
@Nullable List<Element> referenceParameters) { |
|
232 |
this(version, address, service, port, portType, metadata, wsdlAddress, null, referenceParameters, null, null); |
|
233 |
} |
|
234 |
||
235 |
/** |
|
236 |
* Creates an EPR from individual components. |
|
237 |
* |
|
238 |
* <p> |
|
239 |
* This version takes various information about metadata, and creates an EPR that has |
|
240 |
* the necessary embedded WSDL. |
|
241 |
*/ |
|
242 |
public WSEndpointReference(@NotNull AddressingVersion version, |
|
243 |
@NotNull String address, |
|
244 |
@Nullable QName service, |
|
245 |
@Nullable QName port, |
|
246 |
@Nullable QName portType, |
|
247 |
@Nullable List<Element> metadata, |
|
248 |
@Nullable String wsdlAddress, |
|
249 |
@Nullable List<Element> referenceParameters, |
|
250 |
@Nullable Collection<EPRExtension> extns,@Nullable Map<QName, String> attributes) { |
|
251 |
this(createBufferFromData(version, address, referenceParameters, service, port, portType, metadata, wsdlAddress, null, extns, attributes), |
|
252 |
version ); |
|
253 |
} |
|
254 |
||
255 |
/** |
|
256 |
* Creates an EPR from individual components. |
|
257 |
* |
|
258 |
* <p> |
|
259 |
* This version takes various information about metadata, and creates an EPR that has |
|
260 |
* the necessary embedded WSDL. |
|
261 |
* @since JAX-WS 2.2 |
|
262 |
*/ |
|
263 |
public WSEndpointReference(@NotNull AddressingVersion version, |
|
264 |
@NotNull String address, |
|
265 |
@Nullable QName service, |
|
266 |
@Nullable QName port, |
|
267 |
@Nullable QName portType, |
|
268 |
@Nullable List<Element> metadata, |
|
269 |
@Nullable String wsdlAddress, |
|
270 |
@Nullable String wsdlTargetNamepsace, |
|
271 |
@Nullable List<Element> referenceParameters, |
|
272 |
@Nullable List<Element> elements, @Nullable Map<QName, String> attributes) { |
|
273 |
this( |
|
274 |
createBufferFromData(version, address, referenceParameters, service, port, portType, metadata, wsdlAddress,wsdlTargetNamepsace, elements, attributes), |
|
275 |
version ); |
|
276 |
} |
|
277 |
||
278 |
private static XMLStreamBuffer createBufferFromData(AddressingVersion version, String address, List<Element> referenceParameters, QName service, QName port, QName portType, |
|
279 |
List<Element> metadata, String wsdlAddress, String wsdlTargetNamespace, @Nullable List<Element> elements, @Nullable Map<QName, String> attributes) { |
|
280 |
||
281 |
StreamWriterBufferCreator writer = new StreamWriterBufferCreator(); |
|
282 |
||
283 |
try { |
|
284 |
writer.writeStartDocument(); |
|
285 |
writer.writeStartElement(version.getPrefix(),"EndpointReference", version.nsUri); |
|
286 |
writer.writeNamespace(version.getPrefix(),version.nsUri); |
|
287 |
||
288 |
writePartialEPRInfoset(writer, version, address, referenceParameters, service, port, portType, |
|
289 |
metadata,wsdlAddress, wsdlTargetNamespace, attributes); |
|
290 |
||
291 |
//write extensibility elements in the EPR element |
|
292 |
if (elements != null) { |
|
16791 | 293 |
for (Element e : elements) { |
12009 | 294 |
DOMUtil.serializeNode(e, writer); |
16791 | 295 |
} |
12009 | 296 |
} |
297 |
||
298 |
writer.writeEndElement(); |
|
299 |
writer.writeEndDocument(); |
|
300 |
writer.flush(); |
|
301 |
||
302 |
return writer.getXMLStreamBuffer(); |
|
303 |
} catch (XMLStreamException e) { |
|
304 |
throw new WebServiceException(e); |
|
305 |
} |
|
306 |
} |
|
307 |
||
308 |
private static XMLStreamBuffer createBufferFromData(AddressingVersion version, String address, List<Element> referenceParameters, QName service, QName port, QName portType, |
|
309 |
List<Element> metadata, String wsdlAddress, String wsdlTargetNamespace, @Nullable Collection<EPRExtension> extns, @Nullable Map<QName, String> attributes) { |
|
310 |
||
311 |
StreamWriterBufferCreator writer = new StreamWriterBufferCreator(); |
|
312 |
||
313 |
try { |
|
314 |
writer.writeStartDocument(); |
|
315 |
writer.writeStartElement(version.getPrefix(),"EndpointReference", version.nsUri); |
|
316 |
writer.writeNamespace(version.getPrefix(),version.nsUri); |
|
317 |
||
318 |
writePartialEPRInfoset(writer, version, address, referenceParameters, service, port, portType, |
|
319 |
metadata,wsdlAddress, wsdlTargetNamespace, attributes); |
|
320 |
||
321 |
//write extensibility elements in the EPR element |
|
322 |
if (extns != null) { |
|
323 |
for (EPRExtension e : extns) { |
|
324 |
XMLStreamReaderToXMLStreamWriter c = new XMLStreamReaderToXMLStreamWriter(); |
|
325 |
XMLStreamReader r = e.readAsXMLStreamReader(); |
|
326 |
c.bridge(r, writer); |
|
327 |
XMLStreamReaderFactory.recycle(r); |
|
328 |
} |
|
329 |
} |
|
330 |
||
331 |
writer.writeEndElement(); |
|
332 |
writer.writeEndDocument(); |
|
333 |
writer.flush(); |
|
334 |
||
335 |
return writer.getXMLStreamBuffer(); |
|
336 |
} catch (XMLStreamException e) { |
|
337 |
throw new WebServiceException(e); |
|
338 |
} |
|
339 |
} |
|
340 |
||
341 |
private static void writePartialEPRInfoset(StreamWriterBufferCreator writer, AddressingVersion version, String address, List<Element> referenceParameters, QName service, QName port, QName portType, |
|
342 |
List<Element> metadata, String wsdlAddress, String wsdlTargetNamespace, @Nullable Map<QName, String> attributes) throws XMLStreamException { |
|
343 |
//add extensibile attributes on the EPR element |
|
344 |
if (attributes != null) { |
|
345 |
for (Map.Entry<QName, String> entry : attributes.entrySet()) { |
|
346 |
QName qname = entry.getKey(); |
|
347 |
writer.writeAttribute(qname.getPrefix(), qname.getNamespaceURI(), qname.getLocalPart(), entry.getValue()); |
|
348 |
} |
|
349 |
} |
|
350 |
||
351 |
writer.writeStartElement(version.getPrefix(), version.eprType.address, version.nsUri); |
|
352 |
writer.writeCharacters(address); |
|
353 |
writer.writeEndElement(); |
|
354 |
//When the size of ReferenceParametes is zero, the ReferenceParametes element will not be written. |
|
355 |
if(referenceParameters != null && referenceParameters.size() > 0) { |
|
356 |
writer.writeStartElement(version.getPrefix(), version.eprType.referenceParameters, version.nsUri); |
|
16791 | 357 |
for (Element e : referenceParameters) { |
12009 | 358 |
DOMUtil.serializeNode(e, writer); |
16791 | 359 |
} |
12009 | 360 |
writer.writeEndElement(); |
361 |
} |
|
362 |
||
363 |
switch (version) { |
|
364 |
case W3C: |
|
365 |
writeW3CMetaData(writer, service, port, portType, metadata, wsdlAddress, wsdlTargetNamespace); |
|
366 |
break; |
|
367 |
||
368 |
case MEMBER: |
|
369 |
writeMSMetaData(writer, service, port, portType, metadata); |
|
370 |
if (wsdlAddress != null) { |
|
371 |
//Inline the wsdl as extensibility element |
|
372 |
//Write mex:Metadata wrapper |
|
373 |
writer.writeStartElement(MemberSubmissionAddressingConstants.MEX_METADATA.getPrefix(), |
|
374 |
MemberSubmissionAddressingConstants.MEX_METADATA.getLocalPart(), |
|
375 |
MemberSubmissionAddressingConstants.MEX_METADATA.getNamespaceURI()); |
|
376 |
writer.writeStartElement(MemberSubmissionAddressingConstants.MEX_METADATA_SECTION.getPrefix(), |
|
377 |
MemberSubmissionAddressingConstants.MEX_METADATA_SECTION.getLocalPart(), |
|
378 |
MemberSubmissionAddressingConstants.MEX_METADATA_SECTION.getNamespaceURI()); |
|
379 |
writer.writeAttribute(MemberSubmissionAddressingConstants.MEX_METADATA_DIALECT_ATTRIBUTE, |
|
380 |
MemberSubmissionAddressingConstants.MEX_METADATA_DIALECT_VALUE); |
|
381 |
||
382 |
writeWsdl(writer, service, wsdlAddress); |
|
383 |
||
384 |
writer.writeEndElement(); |
|
385 |
writer.writeEndElement(); |
|
386 |
} |
|
387 |
||
388 |
break; |
|
389 |
} |
|
390 |
} |
|
391 |
||
16791 | 392 |
private static boolean isEmty(QName qname) { |
393 |
return qname == null || qname.toString().trim().length()== 0; |
|
394 |
} |
|
12009 | 395 |
|
396 |
private static void writeW3CMetaData(StreamWriterBufferCreator writer, |
|
397 |
QName service, |
|
398 |
QName port, |
|
399 |
QName portType, List<Element> metadata, |
|
400 |
String wsdlAddress, String wsdlTargetNamespace) throws XMLStreamException { |
|
401 |
||
402 |
||
403 |
//.NET treate empty metaData element as bad request. |
|
16791 | 404 |
if (isEmty(service) && isEmty(port) && isEmty(portType) && metadata == null/* && wsdlAddress == null*/) { |
405 |
return; |
|
406 |
} |
|
407 |
||
12009 | 408 |
writer.writeStartElement(AddressingVersion.W3C.getPrefix(), |
409 |
AddressingVersion.W3C.eprType.wsdlMetadata.getLocalPart(), AddressingVersion.W3C.nsUri); |
|
410 |
writer.writeNamespace(AddressingVersion.W3C.getWsdlPrefix(), |
|
411 |
AddressingVersion.W3C.wsdlNsUri); |
|
412 |
//write wsdliLication as defined in WS-Addressing 1.0 Metadata spec |
|
16791 | 413 |
if(wsdlAddress != null) { |
414 |
writeWsdliLocation(writer, service, wsdlAddress, wsdlTargetNamespace); |
|
415 |
} |
|
12009 | 416 |
|
417 |
//Write Interface info |
|
418 |
if (portType != null) { |
|
419 |
writer.writeStartElement(W3CAddressingMetadataConstants.WSAM_PREFIX_NAME, |
|
420 |
AddressingVersion.W3C.eprType.portTypeName, |
|
421 |
W3CAddressingMetadataConstants.WSAM_NAMESPACE_NAME); |
|
422 |
writer.writeNamespace(W3CAddressingMetadataConstants.WSAM_PREFIX_NAME, |
|
423 |
W3CAddressingMetadataConstants.WSAM_NAMESPACE_NAME); |
|
424 |
String portTypePrefix = portType.getPrefix(); |
|
425 |
if (portTypePrefix == null || portTypePrefix.equals("")) { |
|
426 |
//TODO check prefix again |
|
427 |
portTypePrefix = "wsns"; |
|
428 |
} |
|
429 |
writer.writeNamespace(portTypePrefix, portType.getNamespaceURI()); |
|
430 |
writer.writeCharacters(portTypePrefix + ":" + portType.getLocalPart()); |
|
431 |
writer.writeEndElement(); |
|
432 |
} |
|
433 |
if (service != null) { |
|
434 |
//Write service and Port info |
|
435 |
if (!(service.getNamespaceURI().equals("") || service.getLocalPart().equals(""))) { |
|
436 |
writer.writeStartElement(W3CAddressingMetadataConstants.WSAM_PREFIX_NAME, |
|
437 |
AddressingVersion.W3C.eprType.serviceName, |
|
438 |
W3CAddressingMetadataConstants.WSAM_NAMESPACE_NAME); |
|
439 |
writer.writeNamespace(W3CAddressingMetadataConstants.WSAM_PREFIX_NAME, |
|
440 |
W3CAddressingMetadataConstants.WSAM_NAMESPACE_NAME); |
|
441 |
String servicePrefix = service.getPrefix(); |
|
442 |
if (servicePrefix == null || servicePrefix.equals("")) { |
|
443 |
//TODO check prefix again |
|
444 |
servicePrefix = "wsns"; |
|
445 |
} |
|
446 |
writer.writeNamespace(servicePrefix, service.getNamespaceURI()); |
|
447 |
if (port != null) { |
|
448 |
writer.writeAttribute(AddressingVersion.W3C.eprType.portName, port.getLocalPart()); |
|
449 |
} |
|
450 |
writer.writeCharacters(servicePrefix + ":" + service.getLocalPart()); |
|
451 |
writer.writeEndElement(); |
|
452 |
} |
|
453 |
} |
|
454 |
/* |
|
455 |
//Inline the wsdl |
|
456 |
if (wsdlAddress != null) { |
|
457 |
writeWsdl(writer, service, wsdlAddress); |
|
458 |
} |
|
459 |
*/ |
|
460 |
//Add the extra metadata Elements |
|
16791 | 461 |
if (metadata != null) { |
12009 | 462 |
for (Element e : metadata) { |
463 |
DOMUtil.serializeNode(e, writer); |
|
464 |
} |
|
16791 | 465 |
} |
12009 | 466 |
writer.writeEndElement(); |
467 |
||
468 |
} |
|
469 |
||
470 |
/** |
|
471 |
* @param writer the writer should be at the start of element. |
|
472 |
* @param service Namespace URI of servcie is used as targetNamespace of wsdl if wsdlTargetNamespace is not null |
|
473 |
* @param wsdlAddress wsdl location |
|
474 |
* @param wsdlTargetNamespace targetnamespace of wsdl to be put in wsdliLocation |
|
475 |
* |
|
476 |
*/ |
|
477 |
private static void writeWsdliLocation(StreamWriterBufferCreator writer, QName service,String wsdlAddress,String wsdlTargetNamespace) throws XMLStreamException { |
|
478 |
String wsdliLocation = ""; |
|
479 |
if(wsdlTargetNamespace != null) { |
|
480 |
wsdliLocation = wsdlTargetNamespace + " "; |
|
481 |
} else if (service != null) { |
|
482 |
wsdliLocation = service.getNamespaceURI() + " "; |
|
483 |
} else { |
|
484 |
throw new WebServiceException("WSDL target Namespace cannot be resolved"); |
|
485 |
} |
|
486 |
wsdliLocation += wsdlAddress; |
|
487 |
writer.writeNamespace(W3CAddressingMetadataConstants.WSAM_WSDLI_ATTRIBUTE_PREFIX, |
|
488 |
W3CAddressingMetadataConstants.WSAM_WSDLI_ATTRIBUTE_NAMESPACE); |
|
489 |
writer.writeAttribute(W3CAddressingMetadataConstants.WSAM_WSDLI_ATTRIBUTE_PREFIX, |
|
490 |
W3CAddressingMetadataConstants.WSAM_WSDLI_ATTRIBUTE_NAMESPACE, |
|
491 |
W3CAddressingMetadataConstants.WSAM_WSDLI_ATTRIBUTE_LOCALNAME, |
|
492 |
wsdliLocation); |
|
493 |
||
494 |
} |
|
495 |
private static void writeMSMetaData(StreamWriterBufferCreator writer, |
|
496 |
QName service, |
|
497 |
QName port, |
|
498 |
QName portType, List<Element> metadata) throws XMLStreamException { |
|
499 |
// TODO: write ReferenceProperties |
|
500 |
//TODO: write ReferenceParameters |
|
501 |
if (portType != null) { |
|
502 |
//Write Interface info |
|
503 |
writer.writeStartElement(AddressingVersion.MEMBER.getPrefix(), |
|
504 |
AddressingVersion.MEMBER.eprType.portTypeName, |
|
505 |
AddressingVersion.MEMBER.nsUri); |
|
506 |
||
507 |
||
508 |
String portTypePrefix = portType.getPrefix(); |
|
509 |
if (portTypePrefix == null || portTypePrefix.equals("")) { |
|
510 |
//TODO check prefix again |
|
511 |
portTypePrefix = "wsns"; |
|
512 |
} |
|
513 |
writer.writeNamespace(portTypePrefix, portType.getNamespaceURI()); |
|
514 |
writer.writeCharacters(portTypePrefix + ":" + portType.getLocalPart()); |
|
515 |
writer.writeEndElement(); |
|
516 |
} |
|
517 |
//Write service and Port info |
|
518 |
if (service != null) { |
|
519 |
if (!(service.getNamespaceURI().equals("") || service.getLocalPart().equals(""))) { |
|
520 |
writer.writeStartElement(AddressingVersion.MEMBER.getPrefix(), |
|
521 |
AddressingVersion.MEMBER.eprType.serviceName, |
|
522 |
AddressingVersion.MEMBER.nsUri); |
|
523 |
String servicePrefix = service.getPrefix(); |
|
524 |
if (servicePrefix == null || servicePrefix.equals("")) { |
|
525 |
//TODO check prefix again |
|
526 |
servicePrefix = "wsns"; |
|
527 |
} |
|
528 |
writer.writeNamespace(servicePrefix, service.getNamespaceURI()); |
|
529 |
if (port != null) { |
|
530 |
writer.writeAttribute(AddressingVersion.MEMBER.eprType.portName, |
|
531 |
port.getLocalPart()); |
|
532 |
} |
|
533 |
writer.writeCharacters(servicePrefix + ":" + service.getLocalPart()); |
|
534 |
writer.writeEndElement(); |
|
535 |
} |
|
536 |
} |
|
537 |
} |
|
538 |
||
539 |
private static void writeWsdl(StreamWriterBufferCreator writer, QName service, String wsdlAddress) throws XMLStreamException { |
|
540 |
// Inline-wsdl |
|
541 |
writer.writeStartElement(WSDLConstants.PREFIX_NS_WSDL, |
|
542 |
WSDLConstants.QNAME_DEFINITIONS.getLocalPart(), |
|
543 |
WSDLConstants.NS_WSDL); |
|
544 |
writer.writeNamespace(WSDLConstants.PREFIX_NS_WSDL, WSDLConstants.NS_WSDL); |
|
545 |
writer.writeStartElement(WSDLConstants.PREFIX_NS_WSDL, |
|
546 |
WSDLConstants.QNAME_IMPORT.getLocalPart(), |
|
547 |
WSDLConstants.NS_WSDL); |
|
548 |
writer.writeAttribute("namespace", service.getNamespaceURI()); |
|
549 |
writer.writeAttribute("location", wsdlAddress); |
|
550 |
writer.writeEndElement(); |
|
551 |
writer.writeEndElement(); |
|
552 |
} |
|
553 |
||
554 |
||
555 |
||
556 |
/** |
|
557 |
* Converts from {@link EndpointReference}. |
|
558 |
* |
|
559 |
* This handles null {@link EndpointReference} correctly. |
|
560 |
* Call {@link #WSEndpointReference(EndpointReference)} directly |
|
561 |
* if you know it's not null. |
|
562 |
*/ |
|
563 |
public static @Nullable |
|
564 |
WSEndpointReference create(@Nullable EndpointReference epr) { |
|
16791 | 565 |
if (epr != null) { |
12009 | 566 |
return new WSEndpointReference(epr); |
16791 | 567 |
} else { |
12009 | 568 |
return null; |
16791 | 569 |
} |
12009 | 570 |
} |
571 |
||
572 |
/** |
|
573 |
* @see #createWithAddress(String) |
|
574 |
*/ |
|
575 |
public @NotNull WSEndpointReference createWithAddress(@NotNull URI newAddress) { |
|
576 |
return createWithAddress(newAddress.toString()); |
|
577 |
} |
|
578 |
||
579 |
/** |
|
580 |
* @see #createWithAddress(String) |
|
581 |
*/ |
|
582 |
public @NotNull WSEndpointReference createWithAddress(@NotNull URL newAddress) { |
|
583 |
return createWithAddress(newAddress.toString()); |
|
584 |
} |
|
585 |
||
586 |
/** |
|
587 |
* Creates a new {@link WSEndpointReference} by replacing the address of this EPR |
|
588 |
* to the new one. |
|
589 |
* |
|
590 |
* <p> |
|
591 |
* The following example shows how you can use this to force an HTTPS EPR, |
|
592 |
* when the endpoint can serve both HTTP and HTTPS requests. |
|
593 |
* <pre> |
|
594 |
* if(epr.getAddress().startsWith("http:")) |
|
595 |
* epr = epr.createWithAddress("https:"+epr.getAddress().substring(5)); |
|
596 |
* </pre> |
|
597 |
* |
|
598 |
* @param newAddress |
|
599 |
* This is a complete URL to be written inside <Adress> element of the EPR, |
|
600 |
* such as "http://foo.bar/abc/def" |
|
601 |
*/ |
|
602 |
public @NotNull WSEndpointReference createWithAddress(@NotNull final String newAddress) { |
|
603 |
MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer(); |
|
604 |
XMLFilterImpl filter = new XMLFilterImpl() { |
|
605 |
private boolean inAddress = false; |
|
16791 | 606 |
@Override |
12009 | 607 |
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { |
16791 | 608 |
if (localName.equals("Address") && uri.equals(version.nsUri)) { |
12009 | 609 |
inAddress = true; |
16791 | 610 |
} |
12009 | 611 |
super.startElement(uri,localName,qName,atts); |
612 |
} |
|
613 |
||
16791 | 614 |
@Override |
12009 | 615 |
public void characters(char ch[], int start, int length) throws SAXException { |
16791 | 616 |
if (!inAddress) { |
12009 | 617 |
super.characters(ch, start, length); |
16791 | 618 |
} |
12009 | 619 |
} |
620 |
||
16791 | 621 |
@Override |
12009 | 622 |
public void endElement(String uri, String localName, String qName) throws SAXException { |
16791 | 623 |
if (inAddress) { |
12009 | 624 |
super.characters(newAddress.toCharArray(),0,newAddress.length()); |
16791 | 625 |
} |
12009 | 626 |
inAddress = false; |
627 |
super.endElement(uri, localName, qName); |
|
628 |
} |
|
629 |
}; |
|
630 |
filter.setContentHandler(xsb.createFromSAXBufferCreator()); |
|
631 |
try { |
|
632 |
infoset.writeTo(filter,false); |
|
633 |
} catch (SAXException e) { |
|
634 |
throw new AssertionError(e); // impossible since we are writing from XSB to XSB. |
|
635 |
} |
|
636 |
||
637 |
return new WSEndpointReference(xsb,version); |
|
638 |
} |
|
639 |
||
640 |
/** |
|
641 |
* Convert the EPR to the spec version. The actual type of |
|
642 |
* {@link EndpointReference} to be returned depends on which version |
|
643 |
* of the addressing spec this EPR conforms to. |
|
644 |
* |
|
645 |
* @throws WebServiceException |
|
646 |
* if the conversion fails, which can happen if the EPR contains |
|
647 |
* invalid infoset (wrong namespace URI, etc.) |
|
648 |
*/ |
|
649 |
public @NotNull EndpointReference toSpec() { |
|
650 |
return ProviderImpl.INSTANCE.readEndpointReference(asSource("EndpointReference")); |
|
651 |
} |
|
652 |
||
653 |
/** |
|
654 |
* Converts the EPR to the specified spec version. |
|
655 |
* |
|
656 |
* If the {@link #getVersion() the addressing version in use} and |
|
657 |
* the given class is different, then this may involve version conversion. |
|
658 |
*/ |
|
659 |
public @NotNull <T extends EndpointReference> T toSpec(Class<T> clazz) { |
|
660 |
return EndpointReferenceUtil.transform(clazz,toSpec()); |
|
661 |
} |
|
662 |
||
663 |
/** |
|
664 |
* Creates a proxy that can be used to talk to this EPR. |
|
665 |
* |
|
666 |
* <p> |
|
667 |
* All the normal WS-Addressing processing happens automatically, |
|
668 |
* such as setting the endpoint address to {@link #getAddress() the address}, |
|
669 |
* and sending the reference parameters associated with this EPR as |
|
670 |
* headers, etc. |
|
671 |
*/ |
|
672 |
public @NotNull <T> T getPort(@NotNull Service jaxwsService, |
|
673 |
@NotNull Class<T> serviceEndpointInterface, |
|
674 |
WebServiceFeature... features) { |
|
675 |
// TODO: implement it in a better way |
|
676 |
return jaxwsService.getPort(toSpec(),serviceEndpointInterface,features); |
|
677 |
} |
|
678 |
||
679 |
/** |
|
680 |
* Creates a {@link Dispatch} that can be used to talk to this EPR. |
|
681 |
* |
|
682 |
* <p> |
|
683 |
* All the normal WS-Addressing processing happens automatically, |
|
684 |
* such as setting the endpoint address to {@link #getAddress() the address}, |
|
685 |
* and sending the reference parameters associated with this EPR as |
|
686 |
* headers, etc. |
|
687 |
*/ |
|
688 |
public @NotNull <T> Dispatch<T> createDispatch( |
|
689 |
@NotNull Service jaxwsService, |
|
690 |
@NotNull Class<T> type, |
|
691 |
@NotNull Service.Mode mode, |
|
692 |
WebServiceFeature... features) { |
|
693 |
||
694 |
// TODO: implement it in a better way |
|
695 |
return jaxwsService.createDispatch(toSpec(),type,mode,features); |
|
696 |
} |
|
697 |
||
698 |
/** |
|
699 |
* Creates a {@link Dispatch} that can be used to talk to this EPR. |
|
700 |
* |
|
701 |
* <p> |
|
702 |
* All the normal WS-Addressing processing happens automatically, |
|
703 |
* such as setting the endpoint address to {@link #getAddress() the address}, |
|
704 |
* and sending the reference parameters associated with this EPR as |
|
705 |
* headers, etc. |
|
706 |
*/ |
|
707 |
public @NotNull Dispatch<Object> createDispatch( |
|
708 |
@NotNull Service jaxwsService, |
|
709 |
@NotNull JAXBContext context, |
|
710 |
@NotNull Service.Mode mode, |
|
711 |
WebServiceFeature... features) { |
|
712 |
||
713 |
// TODO: implement it in a better way |
|
714 |
return jaxwsService.createDispatch(toSpec(),context,mode,features); |
|
715 |
} |
|
716 |
||
717 |
/** |
|
718 |
* Gets the addressing version of this EPR. |
|
719 |
*/ |
|
720 |
public @NotNull AddressingVersion getVersion() { |
|
721 |
return version; |
|
722 |
} |
|
723 |
||
724 |
/** |
|
725 |
* The value of the <wsa:address> header. |
|
726 |
*/ |
|
727 |
public @NotNull String getAddress() { |
|
728 |
return address; |
|
729 |
} |
|
730 |
||
731 |
/** |
|
732 |
* Returns true if this has anonymous URI as the {@link #getAddress() address}. |
|
733 |
*/ |
|
734 |
public boolean isAnonymous() { |
|
735 |
return address.equals(version.anonymousUri); |
|
736 |
} |
|
737 |
||
738 |
/** |
|
739 |
* Returns true if this has {@link AddressingVersion#noneUri none URI} |
|
740 |
* as the {@link #getAddress() address}. |
|
741 |
*/ |
|
742 |
public boolean isNone() { |
|
743 |
return address.equals(version.noneUri); |
|
744 |
} |
|
745 |
||
746 |
/** |
|
747 |
* Parses inside EPR and mark all reference parameters. |
|
748 |
*/ |
|
749 |
private void parse() throws XMLStreamException { |
|
750 |
// TODO: validate the EPR structure. |
|
751 |
// check for non-existent Address, that sort of things. |
|
752 |
||
753 |
StreamReaderBufferProcessor xsr = infoset.readAsXMLStreamReader(); |
|
754 |
||
755 |
// parser should be either at the start element or the start document |
|
16791 | 756 |
if (xsr.getEventType()==XMLStreamReader.START_DOCUMENT) { |
12009 | 757 |
xsr.nextTag(); |
16791 | 758 |
} |
12009 | 759 |
assert xsr.getEventType()==XMLStreamReader.START_ELEMENT; |
760 |
||
761 |
String rootLocalName = xsr.getLocalName(); |
|
16791 | 762 |
if(!xsr.getNamespaceURI().equals(version.nsUri)) { |
12009 | 763 |
throw new WebServiceException(AddressingMessages.WRONG_ADDRESSING_VERSION( |
764 |
version.nsUri, xsr.getNamespaceURI())); |
|
16791 | 765 |
} |
12009 | 766 |
|
767 |
this.rootElement = new QName(xsr.getNamespaceURI(), rootLocalName); |
|
768 |
||
769 |
// since often EPR doesn't have a reference parameter, create array lazily |
|
770 |
List<Header> marks=null; |
|
771 |
||
772 |
while(xsr.nextTag()==XMLStreamReader.START_ELEMENT) { |
|
773 |
String localName = xsr.getLocalName(); |
|
774 |
if(version.isReferenceParameter(localName)) { |
|
775 |
XMLStreamBuffer mark; |
|
776 |
while((mark = xsr.nextTagAndMark())!=null) { |
|
16791 | 777 |
if (marks==null) { |
12009 | 778 |
marks = new ArrayList<Header>(); |
16791 | 779 |
} |
12009 | 780 |
|
781 |
// TODO: need a different header for member submission version |
|
782 |
marks.add(version.createReferenceParameterHeader( |
|
783 |
mark, xsr.getNamespaceURI(), xsr.getLocalName())); |
|
784 |
XMLStreamReaderUtil.skipElement(xsr); |
|
785 |
} |
|
786 |
} else |
|
787 |
if(localName.equals("Address")) { |
|
16791 | 788 |
if (address!=null) { |
12009 | 789 |
throw new InvalidAddressingHeaderException(new QName(version.nsUri,rootLocalName),AddressingVersion.fault_duplicateAddressInEpr); |
16791 | 790 |
} |
12009 | 791 |
address = xsr.getElementText().trim(); |
792 |
} else { |
|
793 |
XMLStreamReaderUtil.skipElement(xsr); |
|
794 |
} |
|
795 |
} |
|
796 |
||
797 |
// hit to </EndpointReference> by now |
|
798 |
||
16791 | 799 |
if (marks==null) { |
12009 | 800 |
this.referenceParameters = EMPTY_ARRAY; |
801 |
} else { |
|
802 |
this.referenceParameters = marks.toArray(new Header[marks.size()]); |
|
803 |
} |
|
804 |
||
16791 | 805 |
if (address==null) { |
12009 | 806 |
throw new InvalidAddressingHeaderException(new QName(version.nsUri,rootLocalName),version.fault_missingAddressInEpr); |
16791 | 807 |
} |
12009 | 808 |
} |
809 |
||
810 |
||
811 |
/** |
|
812 |
* Reads this EPR as {@link XMLStreamReader}. |
|
813 |
* |
|
814 |
* @param localName |
|
815 |
* EPR uses a different root tag name depending on the context. |
|
816 |
* The returned {@link XMLStreamReader} will use the given local name |
|
817 |
* for the root element name. |
|
818 |
*/ |
|
819 |
public XMLStreamReader read(final @NotNull String localName) throws XMLStreamException { |
|
820 |
return new StreamReaderBufferProcessor(infoset) { |
|
16791 | 821 |
@Override |
822 |
protected void processElement(String prefix, String uri, String _localName, boolean inScope) { |
|
823 |
if (_depth == 0) { |
|
12009 | 824 |
_localName = localName; |
16791 | 825 |
} |
12009 | 826 |
super.processElement(prefix, uri, _localName, isInscope(infoset,_depth)); |
827 |
} |
|
828 |
}; |
|
829 |
} |
|
830 |
||
831 |
private boolean isInscope(XMLStreamBuffer buffer, int depth) { |
|
832 |
return buffer.getInscopeNamespaces().size() > 0 && depth ==0; |
|
833 |
} |
|
834 |
||
835 |
/** |
|
836 |
* Returns a {@link Source} that represents this EPR. |
|
837 |
* |
|
838 |
* @param localName |
|
839 |
* EPR uses a different root tag name depending on the context. |
|
840 |
* The returned {@link Source} will use the given local name |
|
841 |
* for the root element name. |
|
842 |
*/ |
|
843 |
public Source asSource(@NotNull String localName) { |
|
844 |
return new SAXSource(new SAXBufferProcessorImpl(localName),new InputSource()); |
|
845 |
} |
|
846 |
||
847 |
/** |
|
848 |
* Writes this EPR to the given {@link ContentHandler}. |
|
849 |
* |
|
850 |
* @param localName |
|
851 |
* EPR uses a different root tag name depending on the context. |
|
852 |
* The returned {@link Source} will use the given local name |
|
853 |
* for the root element name. |
|
854 |
* @param fragment |
|
855 |
* If true, generate a fragment SAX events without start/endDocument callbacks. |
|
856 |
* If false, generate a full XML document event. |
|
857 |
*/ |
|
858 |
public void writeTo(@NotNull String localName, ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException { |
|
859 |
SAXBufferProcessorImpl p = new SAXBufferProcessorImpl(localName); |
|
860 |
p.setContentHandler(contentHandler); |
|
861 |
p.setErrorHandler(errorHandler); |
|
862 |
p.process(infoset,fragment); |
|
863 |
} |
|
864 |
||
865 |
/** |
|
866 |
* Writes this EPR into the given writer. |
|
867 |
* |
|
868 |
* @param localName |
|
869 |
* EPR uses a different root tag name depending on the context. |
|
870 |
* The returned {@link Source} will use the given local name |
|
871 |
*/ |
|
872 |
public void writeTo(final @NotNull String localName, @NotNull XMLStreamWriter w) throws XMLStreamException { |
|
873 |
infoset.writeToXMLStreamWriter(new XMLStreamWriterFilter(w) { |
|
874 |
private boolean root=true; |
|
875 |
||
876 |
@Override |
|
877 |
public void writeStartDocument() throws XMLStreamException { |
|
878 |
} |
|
879 |
||
880 |
@Override |
|
881 |
public void writeStartDocument(String encoding, String version) throws XMLStreamException { |
|
882 |
} |
|
883 |
||
884 |
@Override |
|
885 |
public void writeStartDocument(String version) throws XMLStreamException { |
|
886 |
} |
|
887 |
||
888 |
@Override |
|
889 |
public void writeEndDocument() throws XMLStreamException { |
|
890 |
} |
|
891 |
||
892 |
private String override(String ln) { |
|
893 |
if(root) { |
|
894 |
root = false; |
|
895 |
return localName; |
|
896 |
} |
|
897 |
return ln; |
|
898 |
} |
|
899 |
||
16791 | 900 |
@Override |
12009 | 901 |
public void writeStartElement(String localName) throws XMLStreamException { |
902 |
super.writeStartElement(override(localName)); |
|
903 |
} |
|
904 |
||
16791 | 905 |
@Override |
12009 | 906 |
public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException { |
907 |
super.writeStartElement(namespaceURI, override(localName)); |
|
908 |
} |
|
909 |
||
16791 | 910 |
@Override |
12009 | 911 |
public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { |
912 |
super.writeStartElement(prefix, override(localName), namespaceURI); |
|
913 |
} |
|
914 |
},true/*write as fragment*/); |
|
915 |
} |
|
916 |
||
917 |
/** |
|
918 |
* Returns a {@link Header} that wraps this {@link WSEndpointReference}. |
|
919 |
* |
|
920 |
* <p> |
|
921 |
* The returned header is immutable too, and can be reused with |
|
922 |
* many {@link Message}s. |
|
923 |
* |
|
924 |
* @param rootTagName |
|
925 |
* The header tag name to be used, such as <ReplyTo> or <FaultTo>. |
|
926 |
* (It's bit ugly that this method takes {@link QName} and not just local name, |
|
927 |
* unlike other methods. If it's making the caller's life miserable, then |
|
928 |
* we can talk.) |
|
929 |
*/ |
|
930 |
public Header createHeader(QName rootTagName) { |
|
931 |
return new EPRHeader(rootTagName,this); |
|
932 |
} |
|
933 |
||
934 |
/** |
|
935 |
* Copies all the reference parameters in this EPR as headers |
|
936 |
* to the given {@link HeaderList}. |
|
16791 | 937 |
* @deprecated - use addReferenceParametersToList(MessageHeaders) |
12009 | 938 |
*/ |
16791 | 939 |
@SuppressWarnings("ManualArrayToCollectionCopy") |
12009 | 940 |
public void addReferenceParametersToList(HeaderList outbound) { |
16791 | 941 |
// implemented through iteration because of unsupportedoperation exception thrown from addAll method on headerlist |
942 |
// do not change |
|
12009 | 943 |
for (Header header : referenceParameters) { |
944 |
outbound.add(header); |
|
945 |
} |
|
946 |
} |
|
947 |
||
948 |
/** |
|
16791 | 949 |
* Copies all the reference parameters in this EPR as headers |
950 |
* to the given {@link MessageHeaders}. |
|
951 |
*/ |
|
952 |
public void addReferenceParametersToList(MessageHeaders outbound) { |
|
953 |
for (Header header : referenceParameters) { |
|
954 |
outbound.add(header); |
|
955 |
} |
|
956 |
} |
|
957 |
/** |
|
12009 | 958 |
* Copies all the reference parameters from the given {@link HeaderList} |
959 |
* to this EPR |
|
960 |
*/ |
|
961 |
public void addReferenceParameters(HeaderList headers) { |
|
962 |
if (headers != null) { |
|
963 |
Header[] hs = new Header[referenceParameters.length + headers.size()]; |
|
964 |
System.arraycopy(referenceParameters, 0, hs, 0, referenceParameters.length); |
|
965 |
int i = referenceParameters.length; |
|
966 |
for (Header h : headers) { |
|
967 |
hs[i++] = h; |
|
968 |
} |
|
969 |
referenceParameters = hs; |
|
970 |
} |
|
971 |
} |
|
972 |
||
973 |
/** |
|
974 |
* Dumps the EPR infoset in a human-readable string. |
|
975 |
*/ |
|
976 |
@Override |
|
977 |
public String toString() { |
|
978 |
try { |
|
979 |
// debug convenience |
|
980 |
StringWriter sw = new StringWriter(); |
|
981 |
XmlUtil.newTransformer().transform(asSource("EndpointReference"),new StreamResult(sw)); |
|
982 |
return sw.toString(); |
|
983 |
} catch (TransformerException e) { |
|
984 |
return e.toString(); |
|
985 |
} |
|
986 |
} |
|
987 |
||
988 |
/** |
|
989 |
* Gets the QName of the EndpointReference element. |
|
990 |
* @return |
|
991 |
*/ |
|
16791 | 992 |
@Override |
12009 | 993 |
public QName getName() { |
994 |
return rootElement; |
|
995 |
} |
|
996 |
||
997 |
/** |
|
998 |
* Filtering {@link SAXBufferProcessor} that replaces the root tag name. |
|
999 |
*/ |
|
1000 |
class SAXBufferProcessorImpl extends SAXBufferProcessor { |
|
1001 |
private final String rootLocalName; |
|
1002 |
private boolean root=true; |
|
1003 |
||
1004 |
public SAXBufferProcessorImpl(String rootLocalName) { |
|
1005 |
super(infoset,false); |
|
1006 |
this.rootLocalName = rootLocalName; |
|
1007 |
} |
|
1008 |
||
16791 | 1009 |
@Override |
12009 | 1010 |
protected void processElement(String uri, String localName, String qName, boolean inscope) throws SAXException { |
1011 |
if(root) { |
|
1012 |
root = false; |
|
1013 |
||
1014 |
if(qName.equals(localName)) { |
|
1015 |
qName = localName = rootLocalName; |
|
1016 |
} else { |
|
1017 |
localName = rootLocalName; |
|
1018 |
int idx = qName.indexOf(':'); |
|
1019 |
qName = qName.substring(0,idx+1)+rootLocalName; |
|
1020 |
} |
|
1021 |
} |
|
1022 |
super.processElement(uri, localName, qName, inscope); |
|
1023 |
} |
|
1024 |
} |
|
1025 |
||
1026 |
private static final OutboundReferenceParameterHeader[] EMPTY_ARRAY = new OutboundReferenceParameterHeader[0]; |
|
1027 |
||
1028 |
private Map<QName, EPRExtension> rootEprExtensions; |
|
1029 |
||
1030 |
/** |
|
1031 |
* Represents an extensibility element inside an EndpointReference |
|
1032 |
*/ |
|
1033 |
public static abstract class EPRExtension { |
|
1034 |
public abstract XMLStreamReader readAsXMLStreamReader() throws XMLStreamException; |
|
1035 |
||
1036 |
public abstract QName getQName(); |
|
1037 |
} |
|
1038 |
||
1039 |
/** |
|
1040 |
* Returns the first extensibility element inside EPR root element with input QName. |
|
1041 |
*/ |
|
1042 |
public @Nullable |
|
1043 |
EPRExtension getEPRExtension(final QName extnQName) throws XMLStreamException { |
|
16791 | 1044 |
if (rootEprExtensions == null) { |
12009 | 1045 |
parseEPRExtensions(); |
16791 | 1046 |
} |
12009 | 1047 |
return rootEprExtensions.get(extnQName); |
1048 |
} |
|
1049 |
||
1050 |
public @NotNull Collection<EPRExtension> getEPRExtensions() throws XMLStreamException { |
|
16791 | 1051 |
if (rootEprExtensions == null) { |
12009 | 1052 |
parseEPRExtensions(); |
16791 | 1053 |
} |
12009 | 1054 |
return rootEprExtensions.values(); |
1055 |
} |
|
1056 |
||
1057 |
private void parseEPRExtensions() throws XMLStreamException { |
|
1058 |
||
1059 |
rootEprExtensions = new HashMap<QName, EPRExtension>(); |
|
1060 |
||
1061 |
||
1062 |
StreamReaderBufferProcessor xsr = infoset.readAsXMLStreamReader(); |
|
1063 |
||
1064 |
// parser should be either at the start element or the start document |
|
16791 | 1065 |
if (xsr.getEventType() == XMLStreamReader.START_DOCUMENT) { |
12009 | 1066 |
xsr.nextTag(); |
16791 | 1067 |
} |
12009 | 1068 |
assert xsr.getEventType() == XMLStreamReader.START_ELEMENT; |
1069 |
||
16791 | 1070 |
if (!xsr.getNamespaceURI().equals(version.nsUri)) { |
12009 | 1071 |
throw new WebServiceException(AddressingMessages.WRONG_ADDRESSING_VERSION( |
1072 |
version.nsUri, xsr.getNamespaceURI())); |
|
16791 | 1073 |
} |
12009 | 1074 |
|
1075 |
// since often EPR doesn't have extensions, create array lazily |
|
1076 |
XMLStreamBuffer mark; |
|
1077 |
String localName; |
|
1078 |
String ns; |
|
1079 |
while ((mark = xsr.nextTagAndMark()) != null) { |
|
1080 |
localName = xsr.getLocalName(); |
|
1081 |
ns = xsr.getNamespaceURI(); |
|
1082 |
if (version.nsUri.equals(ns)) { |
|
1083 |
//EPR extensions do not use the same namespace of the Addressing Version. |
|
1084 |
//Not an extension - SKIP |
|
1085 |
XMLStreamReaderUtil.skipElement(xsr); |
|
1086 |
} else { |
|
1087 |
QName qn = new QName(ns, localName); |
|
1088 |
rootEprExtensions.put(qn, new WSEPRExtension(mark,qn)); |
|
1089 |
XMLStreamReaderUtil.skipElement(xsr); |
|
1090 |
} |
|
1091 |
} |
|
1092 |
// hit to </EndpointReference> by now |
|
1093 |
} |
|
1094 |
||
1095 |
/** |
|
1096 |
* Parses the metadata inside this EPR and obtains it in a easy-to-process form. |
|
1097 |
* |
|
1098 |
* <p> |
|
1099 |
* See {@link Metadata} class for what's avaliable as "metadata". |
|
1100 |
*/ |
|
1101 |
public @NotNull Metadata getMetaData() { |
|
1102 |
return new Metadata(); |
|
1103 |
} |
|
1104 |
||
1105 |
/** |
|
1106 |
* Parses the Metadata in an EPR and provides convenience methods to access |
|
1107 |
* the metadata. |
|
1108 |
* |
|
1109 |
*/ |
|
1110 |
public class Metadata { |
|
1111 |
private @Nullable QName serviceName; |
|
1112 |
private @Nullable QName portName; |
|
1113 |
private @Nullable QName portTypeName; //interfaceName |
|
1114 |
private @Nullable Source wsdlSource; |
|
1115 |
private @Nullable String wsdliLocation; |
|
1116 |
||
1117 |
public @Nullable QName getServiceName(){ |
|
1118 |
return serviceName; |
|
1119 |
} |
|
1120 |
public @Nullable QName getPortName(){ |
|
1121 |
return portName; |
|
1122 |
} |
|
1123 |
public @Nullable QName getPortTypeName(){ |
|
1124 |
return portTypeName; |
|
1125 |
} |
|
1126 |
public @Nullable Source getWsdlSource(){ |
|
1127 |
return wsdlSource; |
|
1128 |
} |
|
1129 |
public @Nullable String getWsdliLocation(){ |
|
1130 |
return wsdliLocation; |
|
1131 |
} |
|
1132 |
||
1133 |
private Metadata() { |
|
1134 |
try { |
|
1135 |
parseMetaData(); |
|
1136 |
} catch (XMLStreamException e) { |
|
1137 |
throw new WebServiceException(e); |
|
1138 |
} |
|
1139 |
} |
|
1140 |
||
1141 |
/** |
|
1142 |
* Parses the Metadata section of the EPR. |
|
1143 |
*/ |
|
1144 |
private void parseMetaData() throws XMLStreamException { |
|
1145 |
StreamReaderBufferProcessor xsr = infoset.readAsXMLStreamReader(); |
|
1146 |
||
1147 |
// parser should be either at the start element or the start document |
|
16791 | 1148 |
if (xsr.getEventType() == XMLStreamReader.START_DOCUMENT) { |
1149 |
xsr.nextTag(); |
|
1150 |
} |
|
12009 | 1151 |
assert xsr.getEventType() == XMLStreamReader.START_ELEMENT; |
1152 |
String rootElement = xsr.getLocalName(); |
|
16791 | 1153 |
if (!xsr.getNamespaceURI().equals(version.nsUri)) { |
1154 |
throw new WebServiceException(AddressingMessages.WRONG_ADDRESSING_VERSION( |
|
1155 |
version.nsUri, xsr.getNamespaceURI())); |
|
1156 |
} |
|
12009 | 1157 |
String localName; |
1158 |
String ns; |
|
1159 |
if (version == AddressingVersion.W3C) { |
|
1160 |
do { |
|
1161 |
//If the current element is metadata enclosure, look inside |
|
1162 |
if (xsr.getLocalName().equals(version.eprType.wsdlMetadata.getLocalPart())) { |
|
1163 |
String wsdlLoc = xsr.getAttributeValue("http://www.w3.org/ns/wsdl-instance","wsdlLocation"); |
|
16791 | 1164 |
if (wsdlLoc != null) { |
12009 | 1165 |
wsdliLocation = wsdlLoc.trim(); |
16791 | 1166 |
} |
12009 | 1167 |
XMLStreamBuffer mark; |
1168 |
while ((mark = xsr.nextTagAndMark()) != null) { |
|
1169 |
localName = xsr.getLocalName(); |
|
1170 |
ns = xsr.getNamespaceURI(); |
|
1171 |
if (localName.equals(version.eprType.serviceName)) { |
|
1172 |
String portStr = xsr.getAttributeValue(null, version.eprType.portName); |
|
16791 | 1173 |
if (serviceName != null) { |
12009 | 1174 |
throw new RuntimeException("More than one "+ version.eprType.serviceName +" element in EPR Metadata"); |
16791 | 1175 |
} |
12009 | 1176 |
serviceName = getElementTextAsQName(xsr); |
16791 | 1177 |
if (serviceName != null && portStr != null) { |
12009 | 1178 |
portName = new QName(serviceName.getNamespaceURI(), portStr); |
16791 | 1179 |
} |
12009 | 1180 |
} else if (localName.equals(version.eprType.portTypeName)) { |
16791 | 1181 |
if (portTypeName != null) { |
12009 | 1182 |
throw new RuntimeException("More than one "+ version.eprType.portTypeName +" element in EPR Metadata"); |
16791 | 1183 |
} |
12009 | 1184 |
portTypeName = getElementTextAsQName(xsr); |
1185 |
} else if (ns.equals(WSDLConstants.NS_WSDL) |
|
1186 |
&& localName.equals(WSDLConstants.QNAME_DEFINITIONS.getLocalPart())) { |
|
1187 |
wsdlSource = new XMLStreamBufferSource(mark); |
|
1188 |
} else { |
|
1189 |
XMLStreamReaderUtil.skipElement(xsr); |
|
1190 |
} |
|
1191 |
} |
|
1192 |
} else { |
|
1193 |
//Skip is it is not root element |
|
16791 | 1194 |
if (!xsr.getLocalName().equals(rootElement)) { |
12009 | 1195 |
XMLStreamReaderUtil.skipElement(xsr); |
16791 | 1196 |
} |
12009 | 1197 |
} |
1198 |
} while (XMLStreamReaderUtil.nextElementContent(xsr) == XMLStreamReader.START_ELEMENT); |
|
1199 |
||
1200 |
if(wsdliLocation != null) { |
|
1201 |
String wsdlLocation = wsdliLocation.trim(); |
|
1202 |
wsdlLocation = wsdlLocation.substring(wsdliLocation.lastIndexOf(" ")); |
|
1203 |
wsdlSource = new StreamSource(wsdlLocation); |
|
1204 |
} |
|
1205 |
} else if (version == AddressingVersion.MEMBER) { |
|
1206 |
do { |
|
1207 |
localName = xsr.getLocalName(); |
|
1208 |
ns = xsr.getNamespaceURI(); |
|
1209 |
//If the current element is metadata enclosure, look inside |
|
1210 |
if (localName.equals(version.eprType.wsdlMetadata.getLocalPart()) && |
|
1211 |
ns.equals(version.eprType.wsdlMetadata.getNamespaceURI())) { |
|
1212 |
while (xsr.nextTag() == XMLStreamReader.START_ELEMENT) { |
|
1213 |
XMLStreamBuffer mark; |
|
1214 |
while ((mark = xsr.nextTagAndMark()) != null) { |
|
1215 |
localName = xsr.getLocalName(); |
|
1216 |
ns = xsr.getNamespaceURI(); |
|
1217 |
if (ns.equals(WSDLConstants.NS_WSDL) |
|
1218 |
&& localName.equals(WSDLConstants.QNAME_DEFINITIONS.getLocalPart())) { |
|
1219 |
wsdlSource = new XMLStreamBufferSource(mark); |
|
1220 |
} else { |
|
1221 |
XMLStreamReaderUtil.skipElement(xsr); |
|
1222 |
} |
|
1223 |
} |
|
1224 |
} |
|
1225 |
} else if (localName.equals(version.eprType.serviceName)) { |
|
1226 |
String portStr = xsr.getAttributeValue(null, version.eprType.portName); |
|
1227 |
serviceName = getElementTextAsQName(xsr); |
|
16791 | 1228 |
if (serviceName != null && portStr != null) { |
12009 | 1229 |
portName = new QName(serviceName.getNamespaceURI(), portStr); |
16791 | 1230 |
} |
12009 | 1231 |
} else if (localName.equals(version.eprType.portTypeName)) { |
1232 |
portTypeName = getElementTextAsQName(xsr); |
|
1233 |
} else { |
|
1234 |
//Skip is it is not root element |
|
16791 | 1235 |
if (!xsr.getLocalName().equals(rootElement)) { |
12009 | 1236 |
XMLStreamReaderUtil.skipElement(xsr); |
16791 | 1237 |
} |
12009 | 1238 |
} |
1239 |
} while (XMLStreamReaderUtil.nextElementContent(xsr) == XMLStreamReader.START_ELEMENT); |
|
1240 |
} |
|
1241 |
} |
|
1242 |
||
1243 |
private QName getElementTextAsQName(StreamReaderBufferProcessor xsr) throws XMLStreamException { |
|
1244 |
String text = xsr.getElementText().trim(); |
|
1245 |
String prefix = XmlUtil.getPrefix(text); |
|
1246 |
String name = XmlUtil.getLocalPart(text); |
|
1247 |
if (name != null) { |
|
1248 |
if (prefix != null) { |
|
1249 |
String ns = xsr.getNamespaceURI(prefix); |
|
16791 | 1250 |
if (ns != null) { |
12009 | 1251 |
return new QName(ns, name, prefix); |
16791 | 1252 |
} |
12009 | 1253 |
} else { |
1254 |
return new QName(null, name); |
|
1255 |
} |
|
1256 |
} |
|
1257 |
return null; |
|
1258 |
} |
|
1259 |
} |
|
1260 |
} |