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