1 /* 2 * Copyright (c) 1997, 2010, 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.ws.util.xml.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.ArrayList; 47 import java.util.Collections; 48 49 /** 50 * This class acts as a filter for the Extension elements in the wsa:EndpointReference in the wsdl. 51 * In addition to filtering the EPR extensions from WSDL, it adds the extensions configured by the JAX-WS runtime 52 * specifc to an endpoint. 53 * 54 * @author Rama Pulavarthi 55 */ 56 public class EPRSDDocumentFilter implements SDDocumentFilter { 57 private final WSEndpointImpl<?> endpoint; 58 //initialize lazily 59 List<BoundEndpoint> beList; 60 public EPRSDDocumentFilter(@NotNull WSEndpointImpl<?> endpoint) { 61 this.endpoint = endpoint; 62 } 63 64 private @Nullable WSEndpointImpl<?> getEndpoint(String serviceName, String portName) { 65 if (serviceName == null || portName == null) 66 return null; 67 if (endpoint.getServiceName().getLocalPart().equals(serviceName) && endpoint.getPortName().getLocalPart().equals(portName)) 68 return endpoint; 69 70 if(beList == null) { 71 //check if it is run in a Java EE Container and get hold of other endpoints in the application 72 Module module = endpoint.getContainer().getSPI(Module.class); 73 if (module != null) { 74 beList = module.getBoundEndpoints(); 75 } else { 76 beList = Collections.<BoundEndpoint>emptyList(); 77 } 78 } 79 80 for (BoundEndpoint be : beList) { 81 WSEndpoint wse = be.getEndpoint(); 82 if (wse.getServiceName().getLocalPart().equals(serviceName) && wse.getPortName().getLocalPart().equals(portName)) { 83 return (WSEndpointImpl) wse; 84 } 85 } 86 87 return null; 88 89 } 90 91 public XMLStreamWriter filter(SDDocument doc, XMLStreamWriter w) throws XMLStreamException, IOException { 92 if (!doc.isWSDL()) { 93 return w; 94 } 95 96 return new XMLStreamWriterFilter(w) { 97 private boolean eprExtnFilterON = false; //when true, all writer events are filtered out 98 99 private boolean portHasEPR = false; 100 private int eprDepth = -1; // -1 -> outside wsa:epr, 0 -> on wsa:epr start/end , > 0 inside wsa:epr 101 102 private String serviceName = null; //non null when inside wsdl:service scope 103 private boolean onService = false; //flag to get service name when on wsdl:service element start 104 private int serviceDepth = -1; // -1 -> outside wsdl:service, 0 -> on wsdl:service start/end , > 0 inside wsdl:service 105 106 private String portName = null; //non null when inside wsdl:port scope 107 private boolean onPort = false; //flag to get port name when on wsdl:port element start 108 private int portDepth = -1; // -1 -> outside wsdl:port, 0 -> on wsdl:port start/end , > 0 inside wsdl:port 109 110 private String portAddress; // when a complete epr is written, endpoint address is used as epr address 111 private boolean onPortAddress = false; //flag to get endpoint address when on soap:address element start 112 113 private void handleStartElement(String localName, String namespaceURI) throws XMLStreamException { 114 resetOnElementFlags(); 115 if (serviceDepth >= 0) { 116 serviceDepth++; 117 } 118 if (portDepth >= 0) { 119 portDepth++; 120 } 121 if (eprDepth >= 0) { 122 eprDepth++; 123 } 124 125 if (namespaceURI.equals(WSDLConstants.QNAME_SERVICE.getNamespaceURI()) && localName.equals(WSDLConstants.QNAME_SERVICE.getLocalPart())) { 126 onService = true; 127 serviceDepth = 0; 128 } else if (namespaceURI.equals(WSDLConstants.QNAME_PORT.getNamespaceURI()) && localName.equals(WSDLConstants.QNAME_PORT.getLocalPart())) { 129 if (serviceDepth >= 1) { 130 onPort = true; 131 portDepth = 0; 132 } 133 } else if (namespaceURI.equals(W3CAddressingConstants.WSA_NAMESPACE_NAME) && localName.equals("EndpointReference")) { 134 if (serviceDepth >= 1 && portDepth >= 1) { 135 portHasEPR = true; 136 eprDepth = 0; 137 } 138 } else if ((namespaceURI.equals(WSDLConstants.NS_SOAP_BINDING_ADDRESS.getNamespaceURI()) || namespaceURI.equals(WSDLConstants.NS_SOAP12_BINDING_ADDRESS.getNamespaceURI())) 139 && localName.equals("address") && portDepth ==1) { 140 onPortAddress = true; 141 } 142 WSEndpoint endpoint = getEndpoint(serviceName,portName); 143 //filter epr for only for the port corresponding to this endpoint 144 //if (service.getLocalPart().equals(serviceName) && port.getLocalPart().equals(portName)) { 145 if ( endpoint != null) { 146 if ((eprDepth == 1) && !namespaceURI.equals(W3CAddressingConstants.WSA_NAMESPACE_NAME)) { 147 //epr extension element 148 eprExtnFilterON = true; 149 150 } 151 152 /* 153 if (eprExtnFilterON) { 154 writeEPRExtensions(); 155 } 156 */ 157 } 158 } 159 160 private void resetOnElementFlags() { 161 if (onService) { 162 onService = false; 163 } 164 if (onPort) { 165 onPort = false; 166 } 167 if (onPortAddress) { 168 onPortAddress = false; 169 } 170 171 } 172 173 174 private void writeEPRExtensions(Collection<WSEndpointReference.EPRExtension> eprExtns) throws XMLStreamException { 175 if (eprExtns != null) { 176 for (WSEndpointReference.EPRExtension e : eprExtns) { 177 XMLStreamReaderToXMLStreamWriter c = new XMLStreamReaderToXMLStreamWriter(); 178 XMLStreamReader r = e.readAsXMLStreamReader(); 179 c.bridge(r, writer); 180 XMLStreamReaderFactory.recycle(r); 181 } 182 } 183 } 184 185 @Override 186 public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { 187 handleStartElement(localName, namespaceURI); 188 if (!eprExtnFilterON) { 189 super.writeStartElement(prefix, localName, namespaceURI); 190 } 191 } 192 193 @Override 194 public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException { 195 handleStartElement(localName, namespaceURI); 196 if (!eprExtnFilterON) { 197 super.writeStartElement(namespaceURI, localName); 198 } 199 } 200 201 @Override 202 public void writeStartElement(String localName) throws XMLStreamException { 203 if (!eprExtnFilterON) { 204 super.writeStartElement(localName); 205 } 206 } 207 208 private void handleEndElement() throws XMLStreamException { 209 resetOnElementFlags(); 210 //End of wsdl:port, write complete EPR if not present. 211 if (portDepth == 0) { 212 213 if (!portHasEPR && getEndpoint(serviceName,portName) != null) { 214 215 //write the complete EPR with address. 216 writer.writeStartElement(AddressingVersion.W3C.getPrefix(),"EndpointReference", AddressingVersion.W3C.nsUri ); 217 writer.writeNamespace(AddressingVersion.W3C.getPrefix(), AddressingVersion.W3C.nsUri); 218 writer.writeStartElement(AddressingVersion.W3C.getPrefix(), AddressingVersion.W3C.eprType.address, AddressingVersion.W3C.nsUri); 219 writer.writeCharacters(portAddress); 220 writer.writeEndElement(); 221 writeEPRExtensions(getEndpoint(serviceName, portName).getEndpointReferenceExtensions()); 222 writer.writeEndElement(); 223 224 } 225 } 226 //End of wsa:EndpointReference, write EPR extension elements 227 if (eprDepth == 0) { 228 if (portHasEPR && getEndpoint(serviceName,portName) != null) { 229 writeEPRExtensions(getEndpoint(serviceName, portName).getEndpointReferenceExtensions()); 230 } 231 eprExtnFilterON = false; 232 } 233 234 if(serviceDepth >= 0 ) { 235 serviceDepth--; 236 } 237 if(portDepth >= 0) { 238 portDepth--; 239 } 240 if(eprDepth >=0) { 241 eprDepth--; 242 } 243 244 if (serviceDepth == -1) { 245 serviceName = null; 246 } 247 if (portDepth == -1) { 248 portHasEPR = false; 249 portAddress = null; 250 portName = null; 251 } 252 } 253 254 @Override 255 public void writeEndElement() throws XMLStreamException { 256 handleEndElement(); 257 if (!eprExtnFilterON) { 258 super.writeEndElement(); 259 } 260 } 261 262 private void handleAttribute(String localName, String value) { 263 if (localName.equals("name")) { 264 if (onService) { 265 serviceName = value; 266 onService = false; 267 } else if (onPort) { 268 portName = value; 269 onPort = false; 270 } 271 } 272 if (localName.equals("location") && onPortAddress) { 273 portAddress = value; 274 } 275 276 277 } 278 279 @Override 280 public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException { 281 handleAttribute(localName, value); 282 if (!eprExtnFilterON) { 283 super.writeAttribute(prefix, namespaceURI, localName, value); 284 } 285 } 286 287 @Override 288 public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException { 289 handleAttribute(localName, value); 290 if (!eprExtnFilterON) { 291 super.writeAttribute(namespaceURI, localName, value); 292 } 293 } 294 295 @Override 296 public void writeAttribute(String localName, String value) throws XMLStreamException { 297 handleAttribute(localName, value); 298 if (!eprExtnFilterON) { 299 super.writeAttribute(localName, value); 300 } 301 } 302 303 304 @Override 305 public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException { 306 if (!eprExtnFilterON) { 307 super.writeEmptyElement(namespaceURI, localName); 308 } 309 } 310 311 @Override 312 public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException { 313 if (!eprExtnFilterON) { 314 super.writeNamespace(prefix, namespaceURI); 315 } 316 } 317 318 @Override 319 public void setNamespaceContext(NamespaceContext context) throws XMLStreamException { 320 if (!eprExtnFilterON) { 321 super.setNamespaceContext(context); 322 } 323 } 324 325 @Override 326 public void setDefaultNamespace(String uri) throws XMLStreamException { 327 if (!eprExtnFilterON) { 328 super.setDefaultNamespace(uri); 329 } 330 } 331 332 @Override 333 public void setPrefix(String prefix, String uri) throws XMLStreamException { 334 if (!eprExtnFilterON) { 335 super.setPrefix(prefix, uri); 336 } 337 } 338 339 @Override 340 public void writeProcessingInstruction(String target, String data) throws XMLStreamException { 341 if (!eprExtnFilterON) { 342 super.writeProcessingInstruction(target, data); 343 } 344 } 345 346 @Override 347 public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { 348 if (!eprExtnFilterON) { 349 super.writeEmptyElement(prefix, localName, namespaceURI); 350 } 351 } 352 353 @Override 354 public void writeCData(String data) throws XMLStreamException { 355 if (!eprExtnFilterON) { 356 super.writeCData(data); 357 } 358 } 359 360 @Override 361 public void writeCharacters(String text) throws XMLStreamException { 362 if (!eprExtnFilterON) { 363 super.writeCharacters(text); 364 } 365 } 366 367 @Override 368 public void writeComment(String data) throws XMLStreamException { 369 if (!eprExtnFilterON) { 370 super.writeComment(data); 371 } 372 } 373 374 @Override 375 public void writeDTD(String dtd) throws XMLStreamException { 376 if (!eprExtnFilterON) { 377 super.writeDTD(dtd); 378 } 379 } 380 381 @Override 382 public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException { 383 if (!eprExtnFilterON) { 384 super.writeDefaultNamespace(namespaceURI); 385 } 386 } 387 388 @Override 389 public void writeEmptyElement(String localName) throws XMLStreamException { 390 if (!eprExtnFilterON) { 391 super.writeEmptyElement(localName); 392 } 393 } 394 395 @Override 396 public void writeEntityRef(String name) throws XMLStreamException { 397 if (!eprExtnFilterON) { 398 super.writeEntityRef(name); 399 } 400 } 401 402 @Override 403 public void writeProcessingInstruction(String target) throws XMLStreamException { 404 if (!eprExtnFilterON) { 405 super.writeProcessingInstruction(target); 406 } 407 } 408 409 410 @Override 411 public void writeCharacters(char[] text, int start, int len) throws XMLStreamException { 412 if (!eprExtnFilterON) { 413 super.writeCharacters(text, start, len); 414 } 415 } 416 417 }; 418 419 } 420 421 }