ohair@286: /* alanb@368: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. ohair@286: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohair@286: * ohair@286: * This code is free software; you can redistribute it and/or modify it ohair@286: * under the terms of the GNU General Public License version 2 only, as ohair@286: * published by the Free Software Foundation. Oracle designates this ohair@286: * particular file as subject to the "Classpath" exception as provided ohair@286: * by Oracle in the LICENSE file that accompanied this code. ohair@286: * ohair@286: * This code is distributed in the hope that it will be useful, but WITHOUT ohair@286: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohair@286: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohair@286: * version 2 for more details (a copy is included in the LICENSE file that ohair@286: * accompanied this code). ohair@286: * ohair@286: * You should have received a copy of the GNU General Public License version ohair@286: * 2 along with this work; if not, write to the Free Software Foundation, ohair@286: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohair@286: * ohair@286: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@286: * or visit www.oracle.com if you need additional information or have any ohair@286: * questions. ohair@286: */ ohair@286: ohair@286: package com.sun.xml.internal.ws.addressing; ohair@286: ohair@286: import com.sun.xml.internal.ws.api.server.*; ohair@286: import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; ohair@286: import com.sun.xml.internal.ws.api.addressing.AddressingVersion; ohair@286: import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory; ohair@286: import com.sun.xml.internal.ws.util.xml.XMLStreamWriterFilter; ohair@286: import com.sun.xml.internal.ws.util.xml.XMLStreamReaderToXMLStreamWriter; ohair@286: import com.sun.xml.internal.ws.server.WSEndpointImpl; ohair@286: import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants; ohair@286: import com.sun.istack.internal.Nullable; ohair@286: import com.sun.istack.internal.NotNull; ohair@286: ohair@286: import javax.xml.stream.XMLStreamWriter; ohair@286: import javax.xml.stream.XMLStreamException; ohair@286: import javax.xml.stream.XMLStreamReader; ohair@286: import javax.xml.namespace.NamespaceContext; ohair@286: import java.io.IOException; ohair@286: import java.util.List; ohair@286: import java.util.Collection; ohair@286: import java.util.Collections; ohair@286: ohair@286: /** ohair@286: * This class acts as a filter for the Extension elements in the wsa:EndpointReference in the wsdl. ohair@286: * In addition to filtering the EPR extensions from WSDL, it adds the extensions configured by the JAX-WS runtime ohair@286: * specifc to an endpoint. ohair@286: * ohair@286: * @author Rama Pulavarthi ohair@286: */ ohair@286: public class EPRSDDocumentFilter implements SDDocumentFilter { ohair@286: private final WSEndpointImpl endpoint; ohair@286: //initialize lazily ohair@286: List beList; ohair@286: public EPRSDDocumentFilter(@NotNull WSEndpointImpl endpoint) { ohair@286: this.endpoint = endpoint; ohair@286: } ohair@286: ohair@286: private @Nullable WSEndpointImpl getEndpoint(String serviceName, String portName) { ohair@286: if (serviceName == null || portName == null) ohair@286: return null; ohair@286: if (endpoint.getServiceName().getLocalPart().equals(serviceName) && endpoint.getPortName().getLocalPart().equals(portName)) ohair@286: return endpoint; ohair@286: ohair@286: if(beList == null) { ohair@286: //check if it is run in a Java EE Container and get hold of other endpoints in the application ohair@286: Module module = endpoint.getContainer().getSPI(Module.class); ohair@286: if (module != null) { ohair@286: beList = module.getBoundEndpoints(); ohair@286: } else { ohair@286: beList = Collections.emptyList(); ohair@286: } ohair@286: } ohair@286: ohair@286: for (BoundEndpoint be : beList) { ohair@286: WSEndpoint wse = be.getEndpoint(); ohair@286: if (wse.getServiceName().getLocalPart().equals(serviceName) && wse.getPortName().getLocalPart().equals(portName)) { ohair@286: return (WSEndpointImpl) wse; ohair@286: } ohair@286: } ohair@286: ohair@286: return null; ohair@286: ohair@286: } ohair@286: ohair@286: public XMLStreamWriter filter(SDDocument doc, XMLStreamWriter w) throws XMLStreamException, IOException { ohair@286: if (!doc.isWSDL()) { ohair@286: return w; ohair@286: } ohair@286: ohair@286: return new XMLStreamWriterFilter(w) { ohair@286: private boolean eprExtnFilterON = false; //when true, all writer events are filtered out ohair@286: ohair@286: private boolean portHasEPR = false; ohair@286: private int eprDepth = -1; // -1 -> outside wsa:epr, 0 -> on wsa:epr start/end , > 0 inside wsa:epr ohair@286: ohair@286: private String serviceName = null; //non null when inside wsdl:service scope ohair@286: private boolean onService = false; //flag to get service name when on wsdl:service element start ohair@286: private int serviceDepth = -1; // -1 -> outside wsdl:service, 0 -> on wsdl:service start/end , > 0 inside wsdl:service ohair@286: ohair@286: private String portName = null; //non null when inside wsdl:port scope ohair@286: private boolean onPort = false; //flag to get port name when on wsdl:port element start ohair@286: private int portDepth = -1; // -1 -> outside wsdl:port, 0 -> on wsdl:port start/end , > 0 inside wsdl:port ohair@286: ohair@286: private String portAddress; // when a complete epr is written, endpoint address is used as epr address ohair@286: private boolean onPortAddress = false; //flag to get endpoint address when on soap:address element start ohair@286: ohair@286: private void handleStartElement(String localName, String namespaceURI) throws XMLStreamException { ohair@286: resetOnElementFlags(); ohair@286: if (serviceDepth >= 0) { ohair@286: serviceDepth++; ohair@286: } ohair@286: if (portDepth >= 0) { ohair@286: portDepth++; ohair@286: } ohair@286: if (eprDepth >= 0) { ohair@286: eprDepth++; ohair@286: } ohair@286: ohair@286: if (namespaceURI.equals(WSDLConstants.QNAME_SERVICE.getNamespaceURI()) && localName.equals(WSDLConstants.QNAME_SERVICE.getLocalPart())) { ohair@286: onService = true; ohair@286: serviceDepth = 0; ohair@286: } else if (namespaceURI.equals(WSDLConstants.QNAME_PORT.getNamespaceURI()) && localName.equals(WSDLConstants.QNAME_PORT.getLocalPart())) { ohair@286: if (serviceDepth >= 1) { ohair@286: onPort = true; ohair@286: portDepth = 0; ohair@286: } ohair@286: } else if (namespaceURI.equals(W3CAddressingConstants.WSA_NAMESPACE_NAME) && localName.equals("EndpointReference")) { ohair@286: if (serviceDepth >= 1 && portDepth >= 1) { ohair@286: portHasEPR = true; ohair@286: eprDepth = 0; ohair@286: } ohair@286: } else if ((namespaceURI.equals(WSDLConstants.NS_SOAP_BINDING_ADDRESS.getNamespaceURI()) || namespaceURI.equals(WSDLConstants.NS_SOAP12_BINDING_ADDRESS.getNamespaceURI())) ohair@286: && localName.equals("address") && portDepth ==1) { ohair@286: onPortAddress = true; ohair@286: } ohair@286: WSEndpoint endpoint = getEndpoint(serviceName,portName); ohair@286: //filter epr for only for the port corresponding to this endpoint ohair@286: //if (service.getLocalPart().equals(serviceName) && port.getLocalPart().equals(portName)) { ohair@286: if ( endpoint != null) { ohair@286: if ((eprDepth == 1) && !namespaceURI.equals(W3CAddressingConstants.WSA_NAMESPACE_NAME)) { ohair@286: //epr extension element ohair@286: eprExtnFilterON = true; ohair@286: ohair@286: } ohair@286: ohair@286: /* ohair@286: if (eprExtnFilterON) { ohair@286: writeEPRExtensions(); ohair@286: } ohair@286: */ ohair@286: } ohair@286: } ohair@286: ohair@286: private void resetOnElementFlags() { ohair@286: if (onService) { ohair@286: onService = false; ohair@286: } ohair@286: if (onPort) { ohair@286: onPort = false; ohair@286: } ohair@286: if (onPortAddress) { ohair@286: onPortAddress = false; ohair@286: } ohair@286: ohair@286: } ohair@286: ohair@286: ohair@286: private void writeEPRExtensions(Collection eprExtns) throws XMLStreamException { ohair@286: if (eprExtns != null) { ohair@286: for (WSEndpointReference.EPRExtension e : eprExtns) { ohair@286: XMLStreamReaderToXMLStreamWriter c = new XMLStreamReaderToXMLStreamWriter(); ohair@286: XMLStreamReader r = e.readAsXMLStreamReader(); ohair@286: c.bridge(r, writer); ohair@286: XMLStreamReaderFactory.recycle(r); ohair@286: } ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { ohair@286: handleStartElement(localName, namespaceURI); ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeStartElement(prefix, localName, namespaceURI); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException { ohair@286: handleStartElement(localName, namespaceURI); ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeStartElement(namespaceURI, localName); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeStartElement(String localName) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeStartElement(localName); ohair@286: } ohair@286: } ohair@286: ohair@286: private void handleEndElement() throws XMLStreamException { ohair@286: resetOnElementFlags(); ohair@286: //End of wsdl:port, write complete EPR if not present. ohair@286: if (portDepth == 0) { ohair@286: ohair@286: if (!portHasEPR && getEndpoint(serviceName,portName) != null) { ohair@286: ohair@286: //write the complete EPR with address. ohair@286: writer.writeStartElement(AddressingVersion.W3C.getPrefix(),"EndpointReference", AddressingVersion.W3C.nsUri ); ohair@286: writer.writeNamespace(AddressingVersion.W3C.getPrefix(), AddressingVersion.W3C.nsUri); ohair@286: writer.writeStartElement(AddressingVersion.W3C.getPrefix(), AddressingVersion.W3C.eprType.address, AddressingVersion.W3C.nsUri); ohair@286: writer.writeCharacters(portAddress); ohair@286: writer.writeEndElement(); ohair@286: writeEPRExtensions(getEndpoint(serviceName, portName).getEndpointReferenceExtensions()); ohair@286: writer.writeEndElement(); ohair@286: ohair@286: } ohair@286: } ohair@286: //End of wsa:EndpointReference, write EPR extension elements ohair@286: if (eprDepth == 0) { ohair@286: if (portHasEPR && getEndpoint(serviceName,portName) != null) { ohair@286: writeEPRExtensions(getEndpoint(serviceName, portName).getEndpointReferenceExtensions()); ohair@286: } ohair@286: eprExtnFilterON = false; ohair@286: } ohair@286: ohair@286: if(serviceDepth >= 0 ) { ohair@286: serviceDepth--; ohair@286: } ohair@286: if(portDepth >= 0) { ohair@286: portDepth--; ohair@286: } ohair@286: if(eprDepth >=0) { ohair@286: eprDepth--; ohair@286: } ohair@286: ohair@286: if (serviceDepth == -1) { ohair@286: serviceName = null; ohair@286: } ohair@286: if (portDepth == -1) { ohair@286: portHasEPR = false; ohair@286: portAddress = null; ohair@286: portName = null; ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeEndElement() throws XMLStreamException { ohair@286: handleEndElement(); ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeEndElement(); ohair@286: } ohair@286: } ohair@286: ohair@286: private void handleAttribute(String localName, String value) { ohair@286: if (localName.equals("name")) { ohair@286: if (onService) { ohair@286: serviceName = value; ohair@286: onService = false; ohair@286: } else if (onPort) { ohair@286: portName = value; ohair@286: onPort = false; ohair@286: } ohair@286: } ohair@286: if (localName.equals("location") && onPortAddress) { ohair@286: portAddress = value; ohair@286: } ohair@286: ohair@286: ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException { ohair@286: handleAttribute(localName, value); ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeAttribute(prefix, namespaceURI, localName, value); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException { ohair@286: handleAttribute(localName, value); ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeAttribute(namespaceURI, localName, value); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeAttribute(String localName, String value) throws XMLStreamException { ohair@286: handleAttribute(localName, value); ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeAttribute(localName, value); ohair@286: } ohair@286: } ohair@286: ohair@286: ohair@286: @Override ohair@286: public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeEmptyElement(namespaceURI, localName); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeNamespace(prefix, namespaceURI); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void setNamespaceContext(NamespaceContext context) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.setNamespaceContext(context); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void setDefaultNamespace(String uri) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.setDefaultNamespace(uri); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void setPrefix(String prefix, String uri) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.setPrefix(prefix, uri); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeProcessingInstruction(String target, String data) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeProcessingInstruction(target, data); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeEmptyElement(prefix, localName, namespaceURI); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeCData(String data) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeCData(data); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeCharacters(String text) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeCharacters(text); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeComment(String data) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeComment(data); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeDTD(String dtd) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeDTD(dtd); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeDefaultNamespace(namespaceURI); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeEmptyElement(String localName) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeEmptyElement(localName); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeEntityRef(String name) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeEntityRef(name); ohair@286: } ohair@286: } ohair@286: ohair@286: @Override ohair@286: public void writeProcessingInstruction(String target) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeProcessingInstruction(target); ohair@286: } ohair@286: } ohair@286: ohair@286: ohair@286: @Override ohair@286: public void writeCharacters(char[] text, int start, int len) throws XMLStreamException { ohair@286: if (!eprExtnFilterON) { ohair@286: super.writeCharacters(text, start, len); ohair@286: } ohair@286: } ohair@286: ohair@286: }; ohair@286: ohair@286: } ohair@286: ohair@286: }