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