1 /*
   2  * Copyright (c) 1997, 2017, 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 /**
  27 *
  28 * @author SAAJ RI Development Team
  29 */
  30 package com.sun.xml.internal.messaging.saaj.soap.ver1_1;
  31 
  32 import java.util.Iterator;
  33 import java.util.Locale;
  34 import java.util.logging.Logger;
  35 import java.util.logging.Level;
  36 
  37 import javax.xml.namespace.QName;
  38 import javax.xml.soap.SOAPElement;
  39 import javax.xml.soap.SOAPException;
  40 import javax.xml.soap.SOAPConstants;
  41 import javax.xml.soap.Name;
  42 
  43 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocument;
  44 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl;
  45 import com.sun.xml.internal.messaging.saaj.soap.impl.*;
  46 import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl;
  47 import com.sun.xml.internal.messaging.saaj.util.LogDomainConstants;
  48 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl;
  49 import org.w3c.dom.Element;
  50 
  51 
  52 public class Fault1_1Impl extends FaultImpl {
  53 
  54     protected static final Logger log =
  55         Logger.getLogger(
  56             LogDomainConstants.SOAP_VER1_1_DOMAIN,
  57             "com.sun.xml.internal.messaging.saaj.soap.ver1_1.LocalStrings");
  58 
  59     public Fault1_1Impl(SOAPDocumentImpl ownerDocument, String prefix) {
  60        super(ownerDocument, NameImpl.createFault1_1Name(prefix));
  61     }
  62 
  63     public Fault1_1Impl(SOAPDocumentImpl ownerDoc, Element domElement) {
  64         super(ownerDoc, domElement);
  65     }
  66 
  67     public Fault1_1Impl(SOAPDocumentImpl ownerDoc) {
  68         super(ownerDoc, NameImpl.createFault1_1Name(null));
  69     }
  70 
  71     @Override
  72     protected NameImpl getDetailName() {
  73         return NameImpl.createDetail1_1Name();
  74     }
  75 
  76     @Override
  77     protected NameImpl getFaultCodeName() {
  78         return NameImpl.createFromUnqualifiedName("faultcode");
  79     }
  80 
  81     @Override
  82     protected NameImpl getFaultStringName() {
  83         return NameImpl.createFromUnqualifiedName("faultstring");
  84     }
  85 
  86     @Override
  87     protected NameImpl getFaultActorName() {
  88         return NameImpl.createFromUnqualifiedName("faultactor");
  89     }
  90 
  91     @Override
  92     protected DetailImpl createDetail() {
  93         return new Detail1_1Impl(
  94                        ((SOAPDocument) getOwnerDocument()).getDocument());
  95     }
  96 
  97     @Override
  98     protected FaultElementImpl createSOAPFaultElement(String localName) {
  99         return new FaultElement1_1Impl(
 100                        ((SOAPDocument) getOwnerDocument()).getDocument(),
 101                        localName);
 102     }
 103 
 104     @Override
 105     protected void checkIfStandardFaultCode(String faultCode, String uri)
 106         throws SOAPException {
 107         // SOAP 1.1 doesn't seem to mandate using faultcode from a particular
 108         // set of values.
 109         // Also need to be backward compatible.
 110     }
 111 
 112     @Override
 113     protected void finallySetFaultCode(String faultcode) throws SOAPException {
 114         this.faultCodeElement.addTextNode(faultcode);
 115     }
 116 
 117     @Override
 118     public String getFaultCode() {
 119         if (this.faultCodeElement == null)
 120             findFaultCodeElement();
 121         return this.faultCodeElement.getValue();
 122     }
 123 
 124     @Override
 125     public Name getFaultCodeAsName() {
 126 
 127         String faultcodeString = getFaultCode();
 128         if (faultcodeString == null) {
 129             return null;
 130         }
 131         int prefixIndex = faultcodeString.indexOf(':');
 132         if (prefixIndex == -1) {
 133             // Not a valid SOAP message, but we return the unqualified name
 134             // anyway since some apps do not strictly conform to SOAP
 135             // specs.  A message that does not contain a <faultcode>
 136             // element itself is also not valid in which case we return
 137             // null instead of throwing an exception so this is consistent.
 138             return NameImpl.createFromUnqualifiedName(faultcodeString);
 139         }
 140 
 141         // Get the prefix and map it to a namespace name (AKA namespace URI)
 142         String prefix = faultcodeString.substring(0, prefixIndex);
 143         if (this.faultCodeElement == null)
 144             findFaultCodeElement();
 145         String nsName = this.faultCodeElement.getNamespaceURI(prefix);
 146         return NameImpl.createFromQualifiedName(faultcodeString, nsName);
 147     }
 148 
 149     @Override
 150     public QName getFaultCodeAsQName() {
 151         String faultcodeString = getFaultCode();
 152         if (faultcodeString == null) {
 153             return null;
 154         }
 155         if (this.faultCodeElement == null)
 156             findFaultCodeElement();
 157         return convertCodeToQName(faultcodeString, this.faultCodeElement);
 158     }
 159 
 160     @Override
 161     public void setFaultString(String faultString) throws SOAPException {
 162 
 163         if (this.faultStringElement == null)
 164             findFaultStringElement();
 165 
 166         if (this.faultStringElement == null)
 167             this.faultStringElement = addSOAPFaultElement("faultstring");
 168         else {
 169             this.faultStringElement.removeContents();
 170             //this.faultStringElement.removeAttributeNS("http://www.w3.org/XML/1998/namespace", "lang");
 171             this.faultStringElement.removeAttribute("xml:lang");
 172         }
 173 
 174         this.faultStringElement.addTextNode(faultString);
 175     }
 176 
 177     @Override
 178     public String getFaultString() {
 179         if (this.faultStringElement == null)
 180             findFaultStringElement();
 181         return this.faultStringElement.getValue();
 182 
 183     }
 184 
 185     @Override
 186     public Locale getFaultStringLocale() {
 187         if (this.faultStringElement == null)
 188             findFaultStringElement();
 189         if (this.faultStringElement != null) {
 190             String xmlLangAttr =
 191                 this.faultStringElement.getAttributeValue(
 192                     NameImpl.createFromUnqualifiedName("xml:lang"));
 193             if (xmlLangAttr != null)
 194                 return xmlLangToLocale(xmlLangAttr);
 195         }
 196         return null;
 197     }
 198 
 199     @Override
 200     public void setFaultString(String faultString, Locale locale)
 201         throws SOAPException {
 202         setFaultString(faultString);
 203         this.faultStringElement.addAttribute(
 204             NameImpl.createFromTagName("xml:lang"),
 205             localeToXmlLang(locale));
 206     }
 207 
 208     @Override
 209     protected boolean isStandardFaultElement(String localName) {
 210         if (localName.equalsIgnoreCase("detail") ||
 211             localName.equalsIgnoreCase("faultcode") ||
 212             localName.equalsIgnoreCase("faultstring") ||
 213             localName.equalsIgnoreCase("faultactor")) {
 214             return true;
 215         }
 216         return false;
 217     }
 218 
 219     @Override
 220     public void appendFaultSubcode(QName subcode) {
 221         log.log(
 222             Level.SEVERE,
 223             "SAAJ0303.ver1_1.msg.op.unsupported.in.SOAP1.1",
 224             "appendFaultSubcode");
 225         throw new UnsupportedOperationException("Not supported in SOAP 1.1");
 226     }
 227 
 228     @Override
 229     public void removeAllFaultSubcodes() {
 230         log.log(
 231             Level.SEVERE,
 232             "SAAJ0303.ver1_1.msg.op.unsupported.in.SOAP1.1",
 233             "removeAllFaultSubcodes");
 234         throw new UnsupportedOperationException("Not supported in SOAP 1.1");
 235     }
 236 
 237     @Override
 238     public Iterator<QName> getFaultSubcodes() {
 239         log.log(
 240             Level.SEVERE,
 241             "SAAJ0303.ver1_1.msg.op.unsupported.in.SOAP1.1",
 242             "getFaultSubcodes");
 243         throw new UnsupportedOperationException("Not supported in SOAP 1.1");
 244     }
 245 
 246     @Override
 247     public String getFaultReasonText(Locale locale) {
 248         log.log(
 249             Level.SEVERE,
 250             "SAAJ0303.ver1_1.msg.op.unsupported.in.SOAP1.1",
 251             "getFaultReasonText");
 252         throw new UnsupportedOperationException("Not supported in SOAP 1.1");
 253     }
 254 
 255     @Override
 256     public Iterator<String> getFaultReasonTexts() {
 257         log.log(
 258             Level.SEVERE,
 259             "SAAJ0303.ver1_1.msg.op.unsupported.in.SOAP1.1",
 260             "getFaultReasonTexts");
 261         throw new UnsupportedOperationException("Not supported in SOAP 1.1");
 262     }
 263 
 264     @Override
 265     public Iterator<Locale> getFaultReasonLocales() {
 266         log.log(
 267             Level.SEVERE,
 268             "SAAJ0303.ver1_1.msg.op.unsupported.in.SOAP1.1",
 269             "getFaultReasonLocales");
 270         throw new UnsupportedOperationException("Not supported in SOAP 1.1");
 271     }
 272 
 273     @Override
 274     public void addFaultReasonText(String text, java.util.Locale locale)
 275         throws SOAPException {
 276         log.log(
 277             Level.SEVERE,
 278             "SAAJ0303.ver1_1.msg.op.unsupported.in.SOAP1.1",
 279             "addFaultReasonText");
 280         throw new UnsupportedOperationException("Not supported in SOAP 1.1");
 281     }
 282 
 283     @Override
 284     public String getFaultRole() {
 285         log.log(
 286             Level.SEVERE,
 287             "SAAJ0303.ver1_1.msg.op.unsupported.in.SOAP1.1",
 288             "getFaultRole");
 289         throw new UnsupportedOperationException("Not supported in SOAP 1.1");
 290     }
 291 
 292     @Override
 293     public void setFaultRole(String uri) {
 294         log.log(
 295             Level.SEVERE,
 296             "SAAJ0303.ver1_1.msg.op.unsupported.in.SOAP1.1",
 297             "setFaultRole");
 298         throw new UnsupportedOperationException("Not supported in SOAP 1.1");
 299     }
 300 
 301     @Override
 302     public String getFaultNode() {
 303         log.log(
 304             Level.SEVERE,
 305             "SAAJ0303.ver1_1.msg.op.unsupported.in.SOAP1.1",
 306             "getFaultNode");
 307         throw new UnsupportedOperationException("Not supported in SOAP 1.1");
 308     }
 309 
 310     @Override
 311     public void setFaultNode(String uri) {
 312         log.log(
 313             Level.SEVERE,
 314             "SAAJ0303.ver1_1.msg.op.unsupported.in.SOAP1.1",
 315             "setFaultNode");
 316         throw new UnsupportedOperationException("Not supported in SOAP 1.1");
 317     }
 318 
 319     @Override
 320     protected QName getDefaultFaultCode() {
 321         return new QName(SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE, "Server");
 322     }
 323 
 324     @Override
 325     public SOAPElement addChildElement(SOAPElement element)
 326         throws SOAPException {
 327         String localName = element.getLocalName();
 328         if ("Detail".equalsIgnoreCase(localName)) {
 329             if (hasDetail()) {
 330                 log.severe("SAAJ0305.ver1_2.detail.exists.error");
 331                 throw new SOAPExceptionImpl("Cannot add Detail, Detail already exists");
 332             }
 333         }
 334         return super.addChildElement(element);
 335     }
 336 
 337     @Override
 338     protected FaultElementImpl createSOAPFaultElement(QName qname) {
 339          return new FaultElement1_1Impl(
 340                        ((SOAPDocument) getOwnerDocument()).getDocument(),
 341                        qname);
 342     }
 343 
 344     @Override
 345     protected FaultElementImpl createSOAPFaultElement(Name qname) {
 346          return new FaultElement1_1Impl(
 347                        ((SOAPDocument) getOwnerDocument()).getDocument(),
 348                        (NameImpl)qname);
 349     }
 350 
 351     @Override
 352     public void setFaultCode(String faultCode, String prefix, String uri)
 353         throws SOAPException {
 354         if (prefix == null || "".equals(prefix)) {
 355             if (uri != null && !"".equals(uri)) {
 356                 prefix = getNamespacePrefix(uri);
 357                 if (prefix == null || "".equals(prefix)) {
 358                     prefix = "ns0";
 359                 }
 360             }
 361         }
 362 
 363         if (this.faultCodeElement == null)
 364             findFaultCodeElement();
 365 
 366         if (this.faultCodeElement == null)
 367             this.faultCodeElement = addFaultCodeElement();
 368         else
 369             this.faultCodeElement.removeContents();
 370 
 371         if (uri == null || "".equals(uri)) {
 372             if (prefix != null && !"".equals("prefix")) {
 373                 uri = this.faultCodeElement.getNamespaceURI(prefix);
 374             }
 375         }
 376 
 377         if (uri == null || "".equals(uri)) {
 378             if (prefix != null && !"".equals(prefix)) {
 379                 //cannot allow an empty URI for a non-Empty prefix
 380                 log.log(Level.SEVERE, "SAAJ0307.impl.no.ns.URI", new Object[]{prefix + ":" + faultCode});
 381                 throw new SOAPExceptionImpl("Empty/Null NamespaceURI specified for faultCode \"" + prefix + ":" + faultCode + "\"");
 382             } else {
 383                 uri = "";
 384             }
 385         }
 386 
 387         checkIfStandardFaultCode(faultCode, uri);
 388         ((FaultElementImpl) this.faultCodeElement).ensureNamespaceIsDeclared(prefix, uri);
 389 
 390         if (prefix == null || "".equals(prefix)) {
 391             finallySetFaultCode(faultCode);
 392         } else {
 393             finallySetFaultCode(prefix + ":" + faultCode);
 394         }
 395     }
 396 
 397     private boolean standardFaultCode(String faultCode) {
 398         if (faultCode.equals("VersionMismatch") || faultCode.equals("MustUnderstand")
 399             || faultCode.equals("Client") || faultCode.equals("Server")) {
 400             return true;
 401         }
 402         if (faultCode.startsWith("VersionMismatch.") || faultCode.startsWith("MustUnderstand.")
 403             || faultCode.startsWith("Client.") || faultCode.startsWith("Server.")) {
 404             return true;
 405         }
 406         return false;
 407     }
 408 
 409     @Override
 410      public void setFaultActor(String faultActor) throws SOAPException {
 411         if (this.faultActorElement == null)
 412             findFaultActorElement();
 413         if (this.faultActorElement != null)
 414             this.faultActorElement.detachNode();
 415         if (faultActor == null)
 416             return;
 417         this.faultActorElement =
 418             createSOAPFaultElement(getFaultActorName());
 419         this.faultActorElement.addTextNode(faultActor);
 420         if (hasDetail()) {
 421             insertBefore(this.faultActorElement, this.detail);
 422             return;
 423         }
 424         addNode(this.faultActorElement);
 425 
 426     }
 427 }