1 /* 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.ws.addressing; 27 28 import com.sun.xml.internal.ws.api.server.*; 29 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; 30 import com.sun.xml.internal.ws.api.addressing.AddressingVersion; 31 import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory; 32 import com.sun.xml.internal.ws.util.xml.XMLStreamWriterFilter; 33 import com.sun.xml.internal.org.jvnet.staxex.util.XMLStreamReaderToXMLStreamWriter; 34 import com.sun.xml.internal.ws.server.WSEndpointImpl; 35 import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants; 36 import com.sun.istack.internal.Nullable; 37 import com.sun.istack.internal.NotNull; 38 39 import javax.xml.stream.XMLStreamWriter; 40 import javax.xml.stream.XMLStreamException; 41 import javax.xml.stream.XMLStreamReader; 42 import javax.xml.namespace.NamespaceContext; 43 import java.io.IOException; 44 import java.util.List; 45 import java.util.Collection; 46 import java.util.Collections; 47 48 /** 49 * This class acts as a filter for the Extension elements in the wsa:EndpointReference in the wsdl. 50 * In addition to filtering the EPR extensions from WSDL, it adds the extensions configured by the JAX-WS runtime 51 * specifc to an endpoint. 52 * 53 * @author Rama Pulavarthi 54 */ 55 public class EPRSDDocumentFilter implements SDDocumentFilter { 56 private final WSEndpointImpl<?> endpoint; 57 //initialize lazily 58 List<BoundEndpoint> beList; 59 public EPRSDDocumentFilter(@NotNull WSEndpointImpl<?> endpoint) { 60 this.endpoint = endpoint; 61 } 62 63 private @Nullable WSEndpointImpl<?> getEndpoint(String serviceName, String portName) { 64 if (serviceName == null || portName == null) 65 return null; 66 if (endpoint.getServiceName().getLocalPart().equals(serviceName) && endpoint.getPortName().getLocalPart().equals(portName)) 67 return endpoint; 68 69 if(beList == null) { 70 //check if it is run in a Java EE Container and get hold of other endpoints in the application 71 Module module = endpoint.getContainer().getSPI(Module.class); 72 if (module != null) { 73 beList = module.getBoundEndpoints(); 74 } else { 75 beList = Collections.<BoundEndpoint>emptyList(); 76 } 77 } 78 79 for (BoundEndpoint be : beList) { 80 WSEndpoint wse = be.getEndpoint(); 81 if (wse.getServiceName().getLocalPart().equals(serviceName) && wse.getPortName().getLocalPart().equals(portName)) { 82 return (WSEndpointImpl) wse; 83 } 84 } 85 86 return null; 87 88 } 89 90 public XMLStreamWriter filter(SDDocument doc, XMLStreamWriter w) throws XMLStreamException, IOException { 91 if (!doc.isWSDL()) { 92 return w; 93 } 94 95 return new XMLStreamWriterFilter(w) { 96 private boolean eprExtnFilterON = false; //when true, all writer events are filtered out 97 98 private boolean portHasEPR = false; 99 private int eprDepth = -1; // -1 -> outside wsa:epr, 0 -> on wsa:epr start/end , > 0 inside wsa:epr 100 101 private String serviceName = null; //non null when inside wsdl:service scope 102 private boolean onService = false; //flag to get service name when on wsdl:service element start 103 private int serviceDepth = -1; // -1 -> outside wsdl:service, 0 -> on wsdl:service start/end , > 0 inside wsdl:service 104 105 private String portName = null; //non null when inside wsdl:port scope 106 private boolean onPort = false; //flag to get port name when on wsdl:port element start 107 private int portDepth = -1; // -1 -> outside wsdl:port, 0 -> on wsdl:port start/end , > 0 inside wsdl:port 108 109 private String portAddress; // when a complete epr is written, endpoint address is used as epr address 110 private boolean onPortAddress = false; //flag to get endpoint address when on soap:address element start 111 112 private void handleStartElement(String localName, String namespaceURI) throws XMLStreamException { 113 resetOnElementFlags(); 114 if (serviceDepth >= 0) { 115 serviceDepth++; 116 } 117 if (portDepth >= 0) { 118 portDepth++; 119 } 120 if (eprDepth >= 0) { 121 eprDepth++; 122 } 123 124 if (namespaceURI.equals(WSDLConstants.QNAME_SERVICE.getNamespaceURI()) && localName.equals(WSDLConstants.QNAME_SERVICE.getLocalPart())) { 125 onService = true; 126 serviceDepth = 0; 127 } else if (namespaceURI.equals(WSDLConstants.QNAME_PORT.getNamespaceURI()) && localName.equals(WSDLConstants.QNAME_PORT.getLocalPart())) { 128 if (serviceDepth >= 1) { 129 onPort = true; 130 portDepth = 0; 131 } 132 } else if (namespaceURI.equals(W3CAddressingConstants.WSA_NAMESPACE_NAME) && localName.equals("EndpointReference")) { 133 if (serviceDepth >= 1 && portDepth >= 1) { 134 portHasEPR = true; 135 eprDepth = 0; 136 } 137 } else if ((namespaceURI.equals(WSDLConstants.NS_SOAP_BINDING_ADDRESS.getNamespaceURI()) || namespaceURI.equals(WSDLConstants.NS_SOAP12_BINDING_ADDRESS.getNamespaceURI())) 138 && localName.equals("address") && portDepth ==1) { 139 onPortAddress = true; 140 } 141 WSEndpoint endpoint = getEndpoint(serviceName,portName); 142 //filter epr for only for the port corresponding to this endpoint 143 //if (service.getLocalPart().equals(serviceName) && port.getLocalPart().equals(portName)) { 144 if ( endpoint != null) { 145 if ((eprDepth == 1) && !namespaceURI.equals(W3CAddressingConstants.WSA_NAMESPACE_NAME)) { 146 //epr extension element 147 eprExtnFilterON = true; 148 149 } 150 151 /* 152 if (eprExtnFilterON) { 153 writeEPRExtensions(); 154 } 155 */ 156 } 157 } 158 159 private void resetOnElementFlags() { 160 if (onService) { 161 onService = false; 162 } 163 if (onPort) { 164 onPort = false; 165 } 166 if (onPortAddress) { 167 onPortAddress = false; 168 } 169 170 } 171 172 173 private void writeEPRExtensions(Collection<WSEndpointReference.EPRExtension> eprExtns) throws XMLStreamException { 174 if (eprExtns != null) { 175 for (WSEndpointReference.EPRExtension e : eprExtns) { 176 XMLStreamReaderToXMLStreamWriter c = new XMLStreamReaderToXMLStreamWriter(); 177 XMLStreamReader r = e.readAsXMLStreamReader(); 178 c.bridge(r, writer); 179 XMLStreamReaderFactory.recycle(r); 180 } 181 } 182 } 183 184 @Override 185 public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { 186 handleStartElement(localName, namespaceURI); 187 if (!eprExtnFilterON) { 188 super.writeStartElement(prefix, localName, namespaceURI); 189 } 190 } 191 192 @Override 193 public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException { 194 handleStartElement(localName, namespaceURI); 195 if (!eprExtnFilterON) { 196 super.writeStartElement(namespaceURI, localName); 197 } 198 } 199 200 @Override 201 public void writeStartElement(String localName) throws XMLStreamException { 202 if (!eprExtnFilterON) { 203 super.writeStartElement(localName); 204 } 205 } 206 207 private void handleEndElement() throws XMLStreamException { 208 resetOnElementFlags(); 209 //End of wsdl:port, write complete EPR if not present. 210 if (portDepth == 0) { 211 212 if (!portHasEPR && getEndpoint(serviceName,portName) != null) { 213 214 //write the complete EPR with address. 215 writer.writeStartElement(AddressingVersion.W3C.getPrefix(),"EndpointReference", AddressingVersion.W3C.nsUri ); 216 writer.writeNamespace(AddressingVersion.W3C.getPrefix(), AddressingVersion.W3C.nsUri); 217 writer.writeStartElement(AddressingVersion.W3C.getPrefix(), AddressingVersion.W3C.eprType.address, AddressingVersion.W3C.nsUri); 218 writer.writeCharacters(portAddress); 219 writer.writeEndElement(); 220 writeEPRExtensions(getEndpoint(serviceName, portName).getEndpointReferenceExtensions()); 221 writer.writeEndElement(); 222 223 } 224 } 225 //End of wsa:EndpointReference, write EPR extension elements 226 if (eprDepth == 0) { 227 if (portHasEPR && getEndpoint(serviceName,portName) != null) { 228 writeEPRExtensions(getEndpoint(serviceName, portName).getEndpointReferenceExtensions()); 229 } 230 eprExtnFilterON = false; 231 } 232 233 if(serviceDepth >= 0 ) { 234 serviceDepth--; 235 } 236 if(portDepth >= 0) { 237 portDepth--; 238 } 239 if(eprDepth >=0) { 240 eprDepth--; 241 } 242 243 if (serviceDepth == -1) { 244 serviceName = null; 245 } 246 if (portDepth == -1) { 247 portHasEPR = false; 248 portAddress = null; 249 portName = null; 250 } 251 } 252 253 @Override 254 public void writeEndElement() throws XMLStreamException { 255 handleEndElement(); 256 if (!eprExtnFilterON) { 257 super.writeEndElement(); 258 } 259 } 260 261 private void handleAttribute(String localName, String value) { 262 if (localName.equals("name")) { 263 if (onService) { 264 serviceName = value; 265 onService = false; 266 } else if (onPort) { 267 portName = value; 268 onPort = false; 269 } 270 } 271 if (localName.equals("location") && onPortAddress) { 272 portAddress = value; 273 } 274 275 276 } 277 278 @Override 279 public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException { 280 handleAttribute(localName, value); 281 if (!eprExtnFilterON) { 282 super.writeAttribute(prefix, namespaceURI, localName, value); 283 } 284 } 285 286 @Override 287 public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException { 288 handleAttribute(localName, value); 289 if (!eprExtnFilterON) { 290 super.writeAttribute(namespaceURI, localName, value); 291 } 292 } 293 294 @Override 295 public void writeAttribute(String localName, String value) throws XMLStreamException { 296 handleAttribute(localName, value); 297 if (!eprExtnFilterON) { 298 super.writeAttribute(localName, value); 299 } 300 } 301 302 303 @Override 304 public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException { 305 if (!eprExtnFilterON) { 306 super.writeEmptyElement(namespaceURI, localName); 307 } 308 } 309 310 @Override 311 public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException { 312 if (!eprExtnFilterON) { 313 super.writeNamespace(prefix, namespaceURI); 314 } 315 } 316 317 @Override 318 public void setNamespaceContext(NamespaceContext context) throws XMLStreamException { 319 if (!eprExtnFilterON) { 320 super.setNamespaceContext(context); 321 } 322 } 323 324 @Override 325 public void setDefaultNamespace(String uri) throws XMLStreamException { 326 if (!eprExtnFilterON) { 327 super.setDefaultNamespace(uri); 328 } 329 } 330 331 @Override 332 public void setPrefix(String prefix, String uri) throws XMLStreamException { 333 if (!eprExtnFilterON) { 334 super.setPrefix(prefix, uri); 335 } 336 } 337 338 @Override 339 public void writeProcessingInstruction(String target, String data) throws XMLStreamException { 340 if (!eprExtnFilterON) { 341 super.writeProcessingInstruction(target, data); 342 } 343 } 344 345 @Override 346 public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { 347 if (!eprExtnFilterON) { 348 super.writeEmptyElement(prefix, localName, namespaceURI); 349 } 350 } 351 352 @Override 353 public void writeCData(String data) throws XMLStreamException { 354 if (!eprExtnFilterON) { 355 super.writeCData(data); 356 } 357 } 358 359 @Override 360 public void writeCharacters(String text) throws XMLStreamException { 361 if (!eprExtnFilterON) { 362 super.writeCharacters(text); 363 } 364 } 365 366 @Override 367 public void writeComment(String data) throws XMLStreamException { 368 if (!eprExtnFilterON) { 369 super.writeComment(data); 370 } 371 } 372 373 @Override 374 public void writeDTD(String dtd) throws XMLStreamException { 375 if (!eprExtnFilterON) { 376 super.writeDTD(dtd); 377 } 378 } 379 380 @Override 381 public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException { 382 if (!eprExtnFilterON) { 383 super.writeDefaultNamespace(namespaceURI); 384 } 385 } 386 387 @Override 388 public void writeEmptyElement(String localName) throws XMLStreamException { 389 if (!eprExtnFilterON) { 390 super.writeEmptyElement(localName); 391 } 392 } 393 394 @Override 395 public void writeEntityRef(String name) throws XMLStreamException { 396 if (!eprExtnFilterON) { 397 super.writeEntityRef(name); 398 } 399 } 400 401 @Override 402 public void writeProcessingInstruction(String target) throws XMLStreamException { 403 if (!eprExtnFilterON) { 404 super.writeProcessingInstruction(target); 405 } 406 } 407 408 409 @Override 410 public void writeCharacters(char[] text, int start, int len) throws XMLStreamException { 411 if (!eprExtnFilterON) { 412 super.writeCharacters(text, start, len); 413 } 414 } 415 416 }; 417 418 } 419 420 }