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

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 637
9c07ef4934dd
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

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

mercurial