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