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