src/share/jaxws_classes/com/sun/xml/internal/ws/api/addressing/WSEndpointReference.java

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

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

merge

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

mercurial