src/share/jaxws_classes/com/sun/xml/internal/ws/wsdl/writer/WSDLPatcher.java

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

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

merge

     1 /*
     2  * Copyright (c) 1997, 2012, 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  */
    26 package com.sun.xml.internal.ws.wsdl.writer;
    28 import com.sun.istack.internal.NotNull;
    29 import com.sun.xml.internal.ws.api.server.PortAddressResolver;
    30 import com.sun.xml.internal.ws.util.xml.XMLStreamReaderToXMLStreamWriter;
    31 import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants;
    32 import com.sun.xml.internal.ws.addressing.W3CAddressingConstants;
    33 import com.sun.xml.internal.ws.addressing.v200408.MemberSubmissionAddressingConstants;
    34 import com.sun.istack.internal.Nullable;
    36 import javax.xml.namespace.QName;
    37 import javax.xml.stream.XMLStreamException;
    38 import java.util.logging.Logger;
    40 /**
    41  * Patches WSDL with the correct endpoint address and the relative paths
    42  * to other documents.
    43  *
    44  * @author Jitendra Kotamraju
    45  * @author Kohsuke Kawaguchi
    46  */
    47 public final class WSDLPatcher extends XMLStreamReaderToXMLStreamWriter {
    49     private static final String NS_XSD = "http://www.w3.org/2001/XMLSchema";
    50     private static final QName SCHEMA_INCLUDE_QNAME = new QName(NS_XSD, "include");
    51     private static final QName SCHEMA_IMPORT_QNAME = new QName(NS_XSD, "import");
    52     private static final QName SCHEMA_REDEFINE_QNAME = new QName(NS_XSD, "redefine");
    54     private static final Logger logger = Logger.getLogger(
    55             com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".wsdl.patcher");
    57     private final DocumentLocationResolver docResolver;
    58     private final PortAddressResolver portAddressResolver;
    60     //
    61     // fields accumulated as we parse through documents
    62     //
    63     private String targetNamespace;
    64     private QName serviceName;
    65     private QName portName;
    66     private String portAddress;
    68     // true inside <wsdl:service>/<wsdl:part>/<wsa:EndpointReference>
    69     private boolean inEpr;
    70     // true inside <wsdl:service>/<wsdl:part>/<wsa:EndpointReference>/<wsa:Address>
    71     private boolean inEprAddress;
    73     /**
    74      * Creates a {@link WSDLPatcher} for patching WSDL.
    75      *
    76      * @param portAddressResolver
    77      *      address of the endpoint is resolved using this docResolver.
    78      * @param docResolver
    79      *      Consulted to get the import/include document locations.
    80      *      Must not be null.
    81      */
    82     public WSDLPatcher(@NotNull PortAddressResolver portAddressResolver,
    83             @NotNull DocumentLocationResolver docResolver) {
    84         this.portAddressResolver = portAddressResolver;
    85         this.docResolver = docResolver;
    86     }
    88     @Override
    89     protected void handleAttribute(int i) throws XMLStreamException {
    90         QName name = in.getName();
    91         String attLocalName = in.getAttributeLocalName(i);
    93         if((name.equals(SCHEMA_INCLUDE_QNAME) && attLocalName.equals("schemaLocation"))
    94         || (name.equals(SCHEMA_IMPORT_QNAME)  && attLocalName.equals("schemaLocation"))
    95         || (name.equals(SCHEMA_REDEFINE_QNAME)  && attLocalName.equals("schemaLocation"))
    96         || (name.equals(WSDLConstants.QNAME_IMPORT)  && attLocalName.equals("location"))) {
    97             // patch this attribute value.
    99             String relPath = in.getAttributeValue(i);
   100             String actualPath = getPatchedImportLocation(relPath);
   101             if (actualPath == null) {
   102                 return; // skip this attribute to leave it up to "implicit reference".
   103             }
   105             logger.fine("Fixing the relative location:"+relPath
   106                     +" with absolute location:"+actualPath);
   107             writeAttribute(i, actualPath);
   108             return;
   109         }
   111         if (name.equals(WSDLConstants.NS_SOAP_BINDING_ADDRESS) ||
   112             name.equals(WSDLConstants.NS_SOAP12_BINDING_ADDRESS)) {
   114             if(attLocalName.equals("location")) {
   115                 portAddress = in.getAttributeValue(i);
   116                 String value = getAddressLocation();
   117                 if (value != null) {
   118                     logger.fine("Service:"+serviceName+ " port:"+portName
   119                             + " current address "+portAddress+" Patching it with "+value);
   120                     writeAttribute(i, value);
   121                     return;
   122                 }
   123             }
   124         }
   126         super.handleAttribute(i);
   127     }
   129     /**
   130      * Writes out an {@code i}-th attribute but with a different value.
   131      * @param i attribute index
   132      * @param value attribute value
   133      * @throws XMLStreamException when an error encountered while writing attribute
   134      */
   135     private void writeAttribute(int i, String value) throws XMLStreamException {
   136         String nsUri = in.getAttributeNamespace(i);
   137         if(nsUri!=null)
   138             out.writeAttribute( in.getAttributePrefix(i), nsUri, in.getAttributeLocalName(i), value );
   139         else
   140             out.writeAttribute( in.getAttributeLocalName(i), value );
   141     }
   143     @Override
   144     protected void handleStartElement() throws XMLStreamException {
   145         QName name = in.getName();
   147         if (name.equals(WSDLConstants.QNAME_DEFINITIONS)) {
   148             String value = in.getAttributeValue(null,"targetNamespace");
   149             if (value != null) {
   150                 targetNamespace = value;
   151             }
   152         } else if (name.equals(WSDLConstants.QNAME_SERVICE)) {
   153             String value = in.getAttributeValue(null,"name");
   154             if (value != null) {
   155                 serviceName = new QName(targetNamespace, value);
   156             }
   157         } else if (name.equals(WSDLConstants.QNAME_PORT)) {
   158             String value = in.getAttributeValue(null,"name");
   159             if (value != null) {
   160                 portName = new QName(targetNamespace,value);
   161             }
   162         } else if (name.equals(W3CAddressingConstants.WSA_EPR_QNAME)
   163                         || name.equals(MemberSubmissionAddressingConstants.WSA_EPR_QNAME)) {
   164             if (serviceName != null && portName != null) {
   165                 inEpr = true;
   166             }
   167         } else if (name.equals(W3CAddressingConstants.WSA_ADDRESS_QNAME)
   168                         || name.equals(MemberSubmissionAddressingConstants.WSA_ADDRESS_QNAME)) {
   169             if (inEpr) {
   170                 inEprAddress = true;
   171             }
   172         }
   173         super.handleStartElement();
   174     }
   176     @Override
   177     protected void handleEndElement() throws XMLStreamException {
   178         QName name = in.getName();
   179         if (name.equals(WSDLConstants.QNAME_SERVICE)) {
   180             serviceName = null;
   181         } else if (name.equals(WSDLConstants.QNAME_PORT)) {
   182             portName = null;
   183         } else if (name.equals(W3CAddressingConstants.WSA_EPR_QNAME)
   184                         || name.equals(MemberSubmissionAddressingConstants.WSA_EPR_QNAME)) {
   185             if (inEpr) {
   186                 inEpr = false;
   187             }
   188                 } else if (name.equals(W3CAddressingConstants.WSA_ADDRESS_QNAME)
   189                                 || name.equals(MemberSubmissionAddressingConstants.WSA_ADDRESS_QNAME)) {
   190                         if (inEprAddress) {
   191                 String value = getAddressLocation();
   192                 if (value != null) {
   193                     logger.fine("Fixing EPR Address for service:"+serviceName+ " port:"+portName
   194                                 + " address with "+value);
   195                     out.writeCharacters(value);
   196                 }
   197                 inEprAddress = false;
   198             }
   199         }
   200         super.handleEndElement();
   201     }
   203     @Override
   204     protected void handleCharacters() throws XMLStreamException {
   205         // handleCharacters() may be called multiple times.
   206         if (inEprAddress) {
   207             String value = getAddressLocation();
   208             if (value != null) {
   209                 // will write the address with <wsa:Address> end element
   210                 return;
   211             }
   212         }
   213         super.handleCharacters();
   214     }
   216     /**
   217      * Returns the location to be placed into the generated document.
   218      *
   219      * @param relPath relative URI to be resolved
   220      * @return
   221      *      null to leave it to the "implicit reference".
   222      */
   223     private @Nullable String getPatchedImportLocation(String relPath) {
   224         return docResolver.getLocationFor(null, relPath);
   225     }
   227     /**
   228      * For the given service, port names it matches the correct endpoint and
   229      * reutrns its endpoint address
   230      *
   231      * @return returns the resolved endpoint address
   232      */
   233     private String getAddressLocation() {
   234         return (portAddressResolver == null || portName == null)
   235                 ? null : portAddressResolver.getAddressFor(serviceName, portName.getLocalPart(), portAddress);
   236     }
   237 }

mercurial