1 /*
   2  * Copyright (c) 1997, 2013, 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.tools.internal.ws.wsdl.parser;
  27 
  28 import com.sun.tools.internal.ws.api.wsdl.TWSDLExtensible;
  29 import com.sun.tools.internal.ws.api.wsdl.TWSDLParserContext;
  30 import com.sun.tools.internal.ws.util.xml.XmlUtil;
  31 import com.sun.tools.internal.ws.wsdl.document.soap.*;
  32 import com.sun.tools.internal.ws.wsdl.framework.TWSDLParserContextImpl;
  33 import org.w3c.dom.Element;
  34 import org.xml.sax.Locator;
  35 
  36 import javax.xml.namespace.QName;
  37 import java.util.Iterator;
  38 import java.util.Map;
  39 
  40 /**
  41  * The SOAP extension handler for WSDL.
  42  *
  43  * @author WS Development Team
  44  */
  45 public class SOAPExtensionHandler extends AbstractExtensionHandler {
  46 
  47     public SOAPExtensionHandler(Map<String, AbstractExtensionHandler> extensionHandlerMap) {
  48         super(extensionHandlerMap);
  49     }
  50 
  51     public String getNamespaceURI() {
  52         return Constants.NS_WSDL_SOAP;
  53     }
  54 
  55     public boolean handleDefinitionsExtension(
  56         TWSDLParserContext context,
  57         TWSDLExtensible parent,
  58         Element e) {
  59         Util.fail(
  60             "parsing.invalidExtensionElement",
  61             e.getTagName(),
  62             e.getNamespaceURI());
  63         return false; // keep compiler happy
  64     }
  65 
  66     public boolean handleTypesExtension(
  67         com.sun.tools.internal.ws.api.wsdl.TWSDLParserContext context,
  68         TWSDLExtensible parent,
  69         Element e) {
  70         Util.fail(
  71             "parsing.invalidExtensionElement",
  72             e.getTagName(),
  73             e.getNamespaceURI());
  74         return false; // keep compiler happy
  75     }
  76 
  77     protected SOAPBinding getSOAPBinding(Locator location){
  78         return new SOAPBinding(location);
  79     }
  80 
  81     public boolean handleBindingExtension(
  82         TWSDLParserContext context,
  83         TWSDLExtensible parent,
  84         Element e) {
  85         if (XmlUtil.matchesTagNS(e, getBindingQName())) {
  86             context.push();
  87             context.registerNamespaces(e);
  88 
  89             SOAPBinding binding = getSOAPBinding(context.getLocation(e));
  90 
  91             // NOTE - the "transport" attribute is required according to section 3.3 of the WSDL 1.1 spec,
  92             // but optional according to the schema in appendix A 4.2 of the same document!
  93             String transport =
  94                 Util.getRequiredAttribute(e, Constants.ATTR_TRANSPORT);
  95             binding.setTransport(transport);
  96 
  97             String style = XmlUtil.getAttributeOrNull(e, Constants.ATTR_STYLE);
  98             if (style != null) {
  99                 if (style.equals(Constants.ATTRVALUE_RPC)) {
 100                     binding.setStyle(SOAPStyle.RPC);
 101                 } else if (style.equals(Constants.ATTRVALUE_DOCUMENT)) {
 102                     binding.setStyle(SOAPStyle.DOCUMENT);
 103                 } else {
 104                     Util.fail(
 105                         "parsing.invalidAttributeValue",
 106                         Constants.ATTR_STYLE,
 107                         style);
 108                 }
 109             }
 110             parent.addExtension(binding);
 111             context.pop();
 112 //            context.fireDoneParsingEntity(getBindingQName(), binding);
 113             return true;
 114         } else {
 115             Util.fail(
 116                 "parsing.invalidExtensionElement",
 117                 e.getTagName(),
 118                 e.getNamespaceURI());
 119             return false; // keep compiler happy
 120         }
 121     }
 122 
 123     public boolean handleOperationExtension(
 124         TWSDLParserContext context,
 125         TWSDLExtensible parent,
 126         Element e) {
 127         if (XmlUtil.matchesTagNS(e, getOperationQName())) {
 128             context.push();
 129             context.registerNamespaces(e);
 130 
 131             SOAPOperation operation = new SOAPOperation(context.getLocation(e));
 132 
 133             String soapAction =
 134                 XmlUtil.getAttributeOrNull(e, Constants.ATTR_SOAP_ACTION);
 135             if (soapAction != null) {
 136                 operation.setSOAPAction(soapAction);
 137             }
 138 
 139             String style = XmlUtil.getAttributeOrNull(e, Constants.ATTR_STYLE);
 140             if (style != null) {
 141                 if (style.equals(Constants.ATTRVALUE_RPC)) {
 142                     operation.setStyle(SOAPStyle.RPC);
 143                 } else if (style.equals(Constants.ATTRVALUE_DOCUMENT)) {
 144                     operation.setStyle(SOAPStyle.DOCUMENT);
 145                 } else {
 146                     Util.fail(
 147                         "parsing.invalidAttributeValue",
 148                         Constants.ATTR_STYLE,
 149                         style);
 150                 }
 151             }
 152             parent.addExtension(operation);
 153             context.pop();
 154 //            context.fireDoneParsingEntity(
 155 //                getOperationQName(),
 156 //                operation);
 157             return true;
 158         } else {
 159             Util.fail(
 160                 "parsing.invalidExtensionElement",
 161                 e.getTagName(),
 162                 e.getNamespaceURI());
 163             return false; // keep compiler happy
 164         }
 165     }
 166 
 167     public boolean handleInputExtension(
 168         TWSDLParserContext context,
 169         TWSDLExtensible parent,
 170         Element e) {
 171         return handleInputOutputExtension(context, parent, e);
 172     }
 173     public boolean handleOutputExtension(
 174         TWSDLParserContext context,
 175         TWSDLExtensible parent,
 176         Element e) {
 177         return handleInputOutputExtension(context, parent, e);
 178     }
 179 
 180     @Override
 181     protected boolean handleMIMEPartExtension(
 182         TWSDLParserContext context,
 183         TWSDLExtensible parent,
 184         Element e) {
 185         return handleInputOutputExtension(context, parent, e);
 186     }
 187 
 188     protected boolean handleInputOutputExtension(
 189         TWSDLParserContext contextif,
 190         TWSDLExtensible parent,
 191         Element e) {
 192         TWSDLParserContextImpl context = (TWSDLParserContextImpl)contextif;
 193         if (XmlUtil.matchesTagNS(e, getBodyQName())) {
 194             context.push();
 195             context.registerNamespaces(e);
 196 
 197             SOAPBody body = new SOAPBody(context.getLocation(e));
 198 
 199             String use = XmlUtil.getAttributeOrNull(e, Constants.ATTR_USE);
 200             if (use != null) {
 201                 if (use.equals(Constants.ATTRVALUE_LITERAL)) {
 202                     body.setUse(SOAPUse.LITERAL);
 203                 } else if (use.equals(Constants.ATTRVALUE_ENCODED)) {
 204                     body.setUse(SOAPUse.ENCODED);
 205                 } else {
 206                     Util.fail(
 207                         "parsing.invalidAttributeValue",
 208                         Constants.ATTR_USE,
 209                         use);
 210                 }
 211             }
 212 
 213             String namespace =
 214                 XmlUtil.getAttributeOrNull(e, Constants.ATTR_NAMESPACE);
 215             if (namespace != null) {
 216                 body.setNamespace(namespace);
 217             }
 218 
 219             String encodingStyle =
 220                 XmlUtil.getAttributeOrNull(e, Constants.ATTR_ENCODING_STYLE);
 221             if (encodingStyle != null) {
 222                 body.setEncodingStyle(encodingStyle);
 223             }
 224 
 225             String parts = XmlUtil.getAttributeOrNull(e, Constants.ATTR_PARTS);
 226             if (parts != null) {
 227                 body.setParts(parts);
 228             }
 229 
 230             parent.addExtension(body);
 231             context.pop();
 232 //            context.fireDoneParsingEntity(getBodyQName(), body);
 233             return true;
 234         } else if (XmlUtil.matchesTagNS(e, getHeaderQName())) {
 235             return handleHeaderElement(parent, e, context);
 236         } else {
 237             Util.fail("parsing.invalidExtensionElement", e.getTagName(), e.getNamespaceURI());
 238             return false; // keep compiler happy
 239         }
 240     }
 241 
 242     private boolean handleHeaderElement(TWSDLExtensible parent, Element e, TWSDLParserContextImpl context) {
 243         context.push();
 244         context.registerNamespaces(e);
 245 
 246         SOAPHeader header = new SOAPHeader(context.getLocation(e));
 247 
 248         String use = XmlUtil.getAttributeOrNull(e, Constants.ATTR_USE);
 249         if (use != null) {
 250             if (use.equals(Constants.ATTRVALUE_LITERAL)) {
 251                 header.setUse(SOAPUse.LITERAL);
 252             } else if (use.equals(Constants.ATTRVALUE_ENCODED)) {
 253                 header.setUse(SOAPUse.ENCODED);
 254             } else {
 255                 Util.fail("parsing.invalidAttributeValue", Constants.ATTR_USE, use);
 256             }
 257         }
 258 
 259         String namespace = XmlUtil.getAttributeOrNull(e, Constants.ATTR_NAMESPACE);
 260         if (namespace != null) {
 261             header.setNamespace(namespace);
 262         }
 263 
 264         String encodingStyle = XmlUtil.getAttributeOrNull(e, Constants.ATTR_ENCODING_STYLE);
 265         if (encodingStyle != null) {
 266             header.setEncodingStyle(encodingStyle);
 267         }
 268 
 269         String part = XmlUtil.getAttributeOrNull(e, Constants.ATTR_PART);
 270         if (part != null) {
 271             header.setPart(part);
 272         }
 273 
 274         String messageAttr = XmlUtil.getAttributeOrNull(e, Constants.ATTR_MESSAGE);
 275         if (messageAttr != null) {
 276             header.setMessage(context.translateQualifiedName(context.getLocation(e), messageAttr));
 277         }
 278 
 279         for (Iterator iter = XmlUtil.getAllChildren(e); iter.hasNext();) {
 280             Element e2 = Util.nextElement(iter);
 281             if (e2 == null)
 282                 break;
 283 
 284             if (XmlUtil.matchesTagNS(e2, getHeaderfaultQName())) {
 285                 handleHeaderFaultElement(e, context, header, use, e2);
 286             } else {
 287                 Util.fail("parsing.invalidElement", e2.getTagName(), e2.getNamespaceURI());
 288             }
 289         }
 290 
 291         parent.addExtension(header);
 292         context.pop();
 293         context.fireDoneParsingEntity(getHeaderQName(), header);
 294         return true;
 295     }
 296 
 297     private void handleHeaderFaultElement(Element e, TWSDLParserContextImpl context, SOAPHeader header, String use, Element e2) {
 298         context.push();
 299         context.registerNamespaces(e);
 300 
 301         SOAPHeaderFault headerfault = new SOAPHeaderFault(context.getLocation(e));
 302 
 303         String use2 = XmlUtil.getAttributeOrNull(e2, Constants.ATTR_USE);
 304         if (use2 != null) {
 305             if (use2.equals(Constants.ATTRVALUE_LITERAL)) {
 306                 headerfault.setUse(SOAPUse.LITERAL);
 307             } else if (use.equals(Constants.ATTRVALUE_ENCODED)) {
 308                 headerfault.setUse(SOAPUse.ENCODED);
 309             } else {
 310                 Util.fail("parsing.invalidAttributeValue", Constants.ATTR_USE, use2);
 311             }
 312         }
 313 
 314         String namespace2 = XmlUtil.getAttributeOrNull(e2, Constants.ATTR_NAMESPACE);
 315         if (namespace2 != null) {
 316             headerfault.setNamespace(namespace2);
 317         }
 318 
 319         String encodingStyle2 = XmlUtil.getAttributeOrNull(e2, Constants.ATTR_ENCODING_STYLE);
 320         if (encodingStyle2 != null) {
 321             headerfault.setEncodingStyle(encodingStyle2);
 322         }
 323 
 324         String part2 = XmlUtil.getAttributeOrNull(e2, Constants.ATTR_PART);
 325         if (part2 != null) {
 326             headerfault.setPart(part2);
 327         }
 328 
 329         String messageAttr2 = XmlUtil.getAttributeOrNull(e2, Constants.ATTR_MESSAGE);
 330         if (messageAttr2 != null) {
 331             headerfault.setMessage(
 332                 context.translateQualifiedName(context.getLocation(e2), messageAttr2));
 333         }
 334 
 335         header.add(headerfault);
 336         context.pop();
 337     }
 338 
 339     public boolean handleFaultExtension(
 340         TWSDLParserContext context,
 341         TWSDLExtensible parent,
 342         Element e) {
 343         if (XmlUtil.matchesTagNS(e, getFaultQName())) {
 344             context.push();
 345             context.registerNamespaces(e);
 346 
 347             SOAPFault fault = new SOAPFault(context.getLocation(e));
 348 
 349             String name = XmlUtil.getAttributeOrNull(e, Constants.ATTR_NAME);
 350             if (name != null) {
 351                 fault.setName(name);
 352             }
 353 
 354             String use = XmlUtil.getAttributeOrNull(e, Constants.ATTR_USE);
 355             if (use != null) {
 356                 if (use.equals(Constants.ATTRVALUE_LITERAL)) {
 357                     fault.setUse(SOAPUse.LITERAL);
 358                 } else if (use.equals(Constants.ATTRVALUE_ENCODED)) {
 359                     fault.setUse(SOAPUse.ENCODED);
 360                 } else {
 361                     Util.fail(
 362                         "parsing.invalidAttributeValue",
 363                         Constants.ATTR_USE,
 364                         use);
 365                 }
 366             }
 367 
 368             String namespace =
 369                 XmlUtil.getAttributeOrNull(e, Constants.ATTR_NAMESPACE);
 370             if (namespace != null) {
 371                 fault.setNamespace(namespace);
 372             }
 373 
 374             String encodingStyle =
 375                 XmlUtil.getAttributeOrNull(e, Constants.ATTR_ENCODING_STYLE);
 376             if (encodingStyle != null) {
 377                 fault.setEncodingStyle(encodingStyle);
 378             }
 379 
 380             parent.addExtension(fault);
 381             context.pop();
 382 //            context.fireDoneParsingEntity(getFaultQName(), fault);
 383             return true;
 384         } else if (XmlUtil.matchesTagNS(e, getHeaderQName())) {
 385             // although SOAP spec doesn't define meaning of this extension; it is allowed
 386             // to be here, so we have to accept it, not fail (bug 13576977)
 387             return handleHeaderElement(parent, e, (TWSDLParserContextImpl) context);
 388         } else {
 389             Util.fail(
 390                 "parsing.invalidExtensionElement",
 391                 e.getTagName(),
 392                 e.getNamespaceURI());
 393             return false; // keep compiler happy
 394         }
 395     }
 396 
 397     public boolean handleServiceExtension(
 398         TWSDLParserContext context,
 399         TWSDLExtensible parent,
 400         Element e) {
 401         Util.fail(
 402             "parsing.invalidExtensionElement",
 403             e.getTagName(),
 404             e.getNamespaceURI());
 405         return false; // keep compiler happy
 406     }
 407 
 408     @Override
 409     public boolean handlePortExtension(
 410         TWSDLParserContext context,
 411         TWSDLExtensible parent,
 412         Element e) {
 413         if (XmlUtil.matchesTagNS(e, getAddressQName())) {
 414             context.push();
 415             context.registerNamespaces(e);
 416 
 417             SOAPAddress address = new SOAPAddress(context.getLocation(e));
 418 
 419             String location =
 420                 Util.getRequiredAttribute(e, Constants.ATTR_LOCATION);
 421             address.setLocation(location);
 422 
 423             parent.addExtension(address);
 424             context.pop();
 425 //            context.fireDoneParsingEntity(getAddressQName(), address);
 426             return true;
 427         } else {
 428             Util.fail(
 429                 "parsing.invalidExtensionElement",
 430                 e.getTagName(),
 431                 e.getNamespaceURI());
 432             return false; // keep compiler happy
 433         }
 434     }
 435 
 436     public boolean handlePortTypeExtension(TWSDLParserContext context, TWSDLExtensible parent, Element e) {
 437        Util.fail(
 438             "parsing.invalidExtensionElement",
 439             e.getTagName(),
 440             e.getNamespaceURI());
 441         return false; // keep compiler happy
 442     }
 443 
 444     protected QName getBodyQName(){
 445         return SOAPConstants.QNAME_BODY;
 446     }
 447 
 448     protected QName getHeaderQName(){
 449         return SOAPConstants.QNAME_HEADER;
 450     }
 451 
 452     protected QName getHeaderfaultQName(){
 453         return SOAPConstants.QNAME_HEADERFAULT;
 454     }
 455 
 456     protected QName getOperationQName(){
 457         return SOAPConstants.QNAME_OPERATION;
 458     }
 459 
 460     protected QName getFaultQName(){
 461         return SOAPConstants.QNAME_FAULT;
 462     }
 463 
 464     protected QName getAddressQName(){
 465         return SOAPConstants.QNAME_ADDRESS;
 466     }
 467 
 468     protected QName getBindingQName(){
 469         return SOAPConstants.QNAME_BINDING;
 470     }
 471 }