jaxws/src/java.xml.soap/share/classes/com/sun/xml/internal/messaging/saaj/soap/impl/FaultImpl.java
changeset 28644 a70f5680dbab
parent 28643 a665e19ca007
parent 28642 a42fefc69922
child 28647 f44908f03772
equal deleted inserted replaced
28643:a665e19ca007 28644:a70f5680dbab
     1 /*
       
     2  * Copyright (c) 1997, 2014, 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 package com.sun.xml.internal.messaging.saaj.soap.impl;
       
    27 
       
    28 import java.util.Locale;
       
    29 import java.util.logging.Level;
       
    30 
       
    31 import javax.xml.namespace.QName;
       
    32 import javax.xml.soap.*;
       
    33 
       
    34 import org.w3c.dom.Element;
       
    35 
       
    36 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl;
       
    37 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl;
       
    38 import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl;
       
    39 
       
    40 public abstract class FaultImpl extends ElementImpl implements SOAPFault {
       
    41 
       
    42     /* This can also represent a fault reason element */
       
    43     protected SOAPFaultElement faultStringElement;
       
    44 
       
    45     /* This can also represent a fault role element */
       
    46     protected SOAPFaultElement faultActorElement;
       
    47 
       
    48     protected SOAPFaultElement faultCodeElement;
       
    49 
       
    50     protected Detail detail;
       
    51 
       
    52     protected FaultImpl(SOAPDocumentImpl ownerDoc, NameImpl name) {
       
    53         super(ownerDoc, name);
       
    54     }
       
    55 
       
    56 
       
    57     protected abstract NameImpl getDetailName();
       
    58     protected abstract NameImpl getFaultCodeName();
       
    59     protected abstract NameImpl getFaultStringName();
       
    60     protected abstract NameImpl getFaultActorName();
       
    61     protected abstract DetailImpl createDetail();
       
    62     protected abstract FaultElementImpl createSOAPFaultElement(String localName);
       
    63     protected abstract FaultElementImpl createSOAPFaultElement(QName qname);
       
    64     protected abstract FaultElementImpl createSOAPFaultElement(Name qname);
       
    65     protected abstract void checkIfStandardFaultCode(String faultCode, String uri) throws SOAPException;
       
    66     protected abstract void finallySetFaultCode(String faultcode) throws SOAPException;
       
    67     protected abstract boolean isStandardFaultElement(String localName);
       
    68     protected abstract QName getDefaultFaultCode();
       
    69 
       
    70 
       
    71     protected void findFaultCodeElement() {
       
    72         this.faultCodeElement =
       
    73             (SOAPFaultElement) findAndConvertChildElement(getFaultCodeName());
       
    74     }
       
    75 
       
    76     protected void findFaultActorElement() {
       
    77         this.faultActorElement =
       
    78             (SOAPFaultElement) findAndConvertChildElement(getFaultActorName());
       
    79     }
       
    80 
       
    81     protected void findFaultStringElement() {
       
    82         this.faultStringElement =
       
    83             (SOAPFaultElement) findAndConvertChildElement(getFaultStringName());
       
    84     }
       
    85 
       
    86     public void setFaultCode(String faultCode) throws SOAPException {
       
    87         setFaultCode(
       
    88             NameImpl.getLocalNameFromTagName(faultCode),
       
    89             NameImpl.getPrefixFromTagName(faultCode),
       
    90             null);
       
    91     }
       
    92 
       
    93     public void setFaultCode(String faultCode, String prefix, String uri)
       
    94         throws SOAPException {
       
    95 
       
    96         if (prefix == null || "".equals(prefix)) {
       
    97             if (uri != null && !"".equals(uri)) {
       
    98                 prefix = getNamespacePrefix(uri);
       
    99                 if (prefix == null || "".equals(prefix)) {
       
   100                     prefix = "ns0";
       
   101                 }
       
   102             }
       
   103         }
       
   104         if (this.faultCodeElement == null)
       
   105             findFaultCodeElement();
       
   106 
       
   107         if (this.faultCodeElement == null)
       
   108             this.faultCodeElement = addFaultCodeElement();
       
   109         else
       
   110             this.faultCodeElement.removeContents();
       
   111 
       
   112         if (uri == null || "".equals(uri)) {
       
   113             uri = this.faultCodeElement.getNamespaceURI(prefix);
       
   114         }
       
   115         if (uri == null || "".equals(uri)) {
       
   116             if (prefix != null && !"".equals(prefix)) {
       
   117                 //cannot allow an empty URI for a non-Empty prefix
       
   118                 log.log(Level.SEVERE, "SAAJ0140.impl.no.ns.URI", new Object[]{prefix + ":" + faultCode});
       
   119                 throw new SOAPExceptionImpl("Empty/Null NamespaceURI specified for faultCode \"" + prefix + ":" + faultCode + "\"");
       
   120             } else {
       
   121                 uri = "";
       
   122             }
       
   123         }
       
   124         checkIfStandardFaultCode(faultCode, uri);
       
   125         ((FaultElementImpl) this.faultCodeElement).ensureNamespaceIsDeclared(prefix, uri);
       
   126 
       
   127         if (prefix == null || "".equals(prefix)) {
       
   128             finallySetFaultCode(faultCode);
       
   129         } else {
       
   130             finallySetFaultCode(prefix + ":" + faultCode);
       
   131         }
       
   132     }
       
   133 
       
   134     public void setFaultCode(Name faultCodeQName) throws SOAPException {
       
   135         setFaultCode(
       
   136             faultCodeQName.getLocalName(),
       
   137             faultCodeQName.getPrefix(),
       
   138             faultCodeQName.getURI());
       
   139     }
       
   140 
       
   141     public void setFaultCode(QName faultCodeQName) throws SOAPException {
       
   142         setFaultCode(
       
   143             faultCodeQName.getLocalPart(),
       
   144             faultCodeQName.getPrefix(),
       
   145             faultCodeQName.getNamespaceURI());
       
   146     }
       
   147 
       
   148     protected static QName convertCodeToQName(
       
   149         String code,
       
   150         SOAPElement codeContainingElement) {
       
   151 
       
   152         int prefixIndex = code.indexOf(':');
       
   153         if (prefixIndex == -1) {
       
   154             return new QName(code);
       
   155         }
       
   156 
       
   157         String prefix = code.substring(0, prefixIndex);
       
   158         String nsName =((ElementImpl) codeContainingElement).lookupNamespaceURI(prefix);
       
   159             //((ElementImpl) codeContainingElement).getNamespaceURI(prefix);
       
   160         return new QName(nsName, getLocalPart(code), prefix);
       
   161     }
       
   162 
       
   163     protected void initializeDetail() {
       
   164         NameImpl detailName = getDetailName();
       
   165         detail = (Detail) findAndConvertChildElement(detailName);
       
   166     }
       
   167 
       
   168     public Detail getDetail() {
       
   169         if (detail == null)
       
   170             initializeDetail();
       
   171         if ((detail != null) && (detail.getParentNode() == null)) {
       
   172         // a detach node was called on it
       
   173             detail = null;
       
   174         }
       
   175         return detail;
       
   176     }
       
   177 
       
   178     public Detail addDetail() throws SOAPException {
       
   179         if (detail == null)
       
   180             initializeDetail();
       
   181         if (detail == null) {
       
   182             detail = createDetail();
       
   183             addNode(detail);
       
   184             return detail;
       
   185         } else {
       
   186             // Log
       
   187             throw new SOAPExceptionImpl("Error: Detail already exists");
       
   188         }
       
   189     }
       
   190 
       
   191     public boolean hasDetail() {
       
   192         return (getDetail() != null);
       
   193     }
       
   194 
       
   195     public abstract void setFaultActor(String faultActor) throws SOAPException;
       
   196 
       
   197     public String getFaultActor() {
       
   198         if (this.faultActorElement == null)
       
   199             findFaultActorElement();
       
   200         if (this.faultActorElement != null) {
       
   201                 return this.faultActorElement.getValue();
       
   202         }
       
   203         return null;
       
   204     }
       
   205 
       
   206     public SOAPElement setElementQName(QName newName) throws SOAPException {
       
   207 
       
   208         log.log(
       
   209             Level.SEVERE,
       
   210             "SAAJ0146.impl.invalid.name.change.requested",
       
   211             new Object[] {elementQName.getLocalPart(), newName.getLocalPart()});
       
   212         throw new SOAPException(
       
   213             "Cannot change name for " + elementQName.getLocalPart() + " to " + newName.getLocalPart());
       
   214     }
       
   215 
       
   216     protected SOAPElement convertToSoapElement(Element element) {
       
   217         if (element instanceof SOAPFaultElement) {
       
   218             return (SOAPElement) element;
       
   219         } else if (element instanceof SOAPElement) {
       
   220             SOAPElement soapElement = (SOAPElement) element;
       
   221             if (getDetailName().equals(soapElement.getElementName())) {
       
   222                 return replaceElementWithSOAPElement(element, createDetail());
       
   223             } else {
       
   224                 String localName =
       
   225                     soapElement.getElementName().getLocalName();
       
   226                 if (isStandardFaultElement(localName))
       
   227                     return replaceElementWithSOAPElement(
       
   228                                element,
       
   229                                createSOAPFaultElement(soapElement.getElementQName()));
       
   230                 return soapElement;
       
   231             }
       
   232         } else {
       
   233             Name elementName = NameImpl.copyElementName(element);
       
   234             ElementImpl newElement;
       
   235             if (getDetailName().equals(elementName)) {
       
   236                 newElement = (ElementImpl) createDetail();
       
   237             } else {
       
   238                 String localName = elementName.getLocalName();
       
   239                 if (isStandardFaultElement(localName))
       
   240                     newElement =
       
   241                         (ElementImpl) createSOAPFaultElement(elementName);
       
   242                 else
       
   243                     newElement = (ElementImpl) createElement(elementName);
       
   244             }
       
   245             return replaceElementWithSOAPElement(element, newElement);
       
   246         }
       
   247     }
       
   248 
       
   249     protected SOAPFaultElement addFaultCodeElement() throws SOAPException {
       
   250         if (this.faultCodeElement == null)
       
   251             findFaultCodeElement();
       
   252         if (this.faultCodeElement == null) {
       
   253             this.faultCodeElement =
       
   254                 addSOAPFaultElement(getFaultCodeName().getLocalName());
       
   255             return this.faultCodeElement;
       
   256         } else {
       
   257             throw new SOAPExceptionImpl("Error: Faultcode already exists");
       
   258         }
       
   259     }
       
   260 
       
   261     private SOAPFaultElement addFaultStringElement() throws SOAPException {
       
   262         if (this.faultStringElement == null)
       
   263             findFaultStringElement();
       
   264         if (this.faultStringElement == null) {
       
   265             this.faultStringElement =
       
   266                 addSOAPFaultElement(getFaultStringName().getLocalName());
       
   267             return this.faultStringElement;
       
   268         } else {
       
   269             // Log
       
   270             throw new SOAPExceptionImpl("Error: Faultstring already exists");
       
   271         }
       
   272     }
       
   273 
       
   274     private SOAPFaultElement addFaultActorElement() throws SOAPException {
       
   275         if (this.faultActorElement == null)
       
   276             findFaultActorElement();
       
   277         if (this.faultActorElement == null) {
       
   278             this.faultActorElement =
       
   279                 addSOAPFaultElement(getFaultActorName().getLocalName());
       
   280             return this.faultActorElement;
       
   281         } else {
       
   282             // Log
       
   283             throw new SOAPExceptionImpl("Error: Faultactor already exists");
       
   284         }
       
   285     }
       
   286 
       
   287     protected SOAPElement addElement(Name name) throws SOAPException {
       
   288         if (getDetailName().equals(name)) {
       
   289             return addDetail();
       
   290         } else if(getFaultCodeName().equals(name)) {
       
   291             return addFaultCodeElement();
       
   292         } else if(getFaultStringName().equals(name)) {
       
   293             return addFaultStringElement();
       
   294         } else if(getFaultActorName().equals(name)) {
       
   295             return addFaultActorElement();
       
   296         }
       
   297         return super.addElement(name);
       
   298     }
       
   299 
       
   300     protected SOAPElement addElement(QName name) throws SOAPException {
       
   301         return addElement(NameImpl.convertToName(name));
       
   302     }
       
   303 
       
   304     protected FaultElementImpl addSOAPFaultElement(String localName)
       
   305         throws SOAPException {
       
   306 
       
   307         FaultElementImpl faultElem = createSOAPFaultElement(localName);
       
   308         addNode(faultElem);
       
   309         return faultElem;
       
   310     }
       
   311 
       
   312     /**
       
   313      * Convert an xml:lang attribute value into a Locale object
       
   314      */
       
   315     protected static Locale xmlLangToLocale(String xmlLang) {
       
   316         if (xmlLang == null) {
       
   317             return null;
       
   318         }
       
   319 
       
   320         // Spec uses hyphen as separator
       
   321         int index = xmlLang.indexOf("-");
       
   322 
       
   323         // Accept underscore as separator as well
       
   324         if (index == -1) {
       
   325             index = xmlLang.indexOf("_");
       
   326         }
       
   327 
       
   328         if (index == -1) {
       
   329             // No separator so assume only a language component
       
   330             return new Locale(xmlLang, "");
       
   331         }
       
   332 
       
   333         String language = xmlLang.substring(0, index);
       
   334         String country = xmlLang.substring(index + 1);
       
   335         return new Locale(language, country);
       
   336     }
       
   337 
       
   338     protected static String localeToXmlLang(Locale locale) {
       
   339         String xmlLang = locale.getLanguage();
       
   340         String country = locale.getCountry();
       
   341         if (!"".equals(country)) {
       
   342             xmlLang += "-" + country;
       
   343         }
       
   344         return xmlLang;
       
   345     }
       
   346 }