ohair@286: /* alanb@368: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. ohair@286: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohair@286: * ohair@286: * This code is free software; you can redistribute it and/or modify it ohair@286: * under the terms of the GNU General Public License version 2 only, as ohair@286: * published by the Free Software Foundation. Oracle designates this ohair@286: * particular file as subject to the "Classpath" exception as provided ohair@286: * by Oracle in the LICENSE file that accompanied this code. ohair@286: * ohair@286: * This code is distributed in the hope that it will be useful, but WITHOUT ohair@286: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohair@286: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohair@286: * version 2 for more details (a copy is included in the LICENSE file that ohair@286: * accompanied this code). ohair@286: * ohair@286: * You should have received a copy of the GNU General Public License version ohair@286: * 2 along with this work; if not, write to the Free Software Foundation, ohair@286: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohair@286: * ohair@286: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@286: * or visit www.oracle.com if you need additional information or have any ohair@286: * questions. ohair@286: */ ohair@286: ohair@286: package com.sun.xml.internal.messaging.saaj.soap.impl; ohair@286: ohair@286: import java.util.Locale; ohair@286: import java.util.logging.Level; ohair@286: ohair@286: import javax.xml.namespace.QName; ohair@286: import javax.xml.soap.*; ohair@286: ohair@286: import org.w3c.dom.Element; ohair@286: ohair@286: import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl; ohair@286: import com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl; ohair@286: import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl; ohair@286: ohair@286: public abstract class FaultImpl extends ElementImpl implements SOAPFault { ohair@286: ohair@286: /* This can also represent a fault reason element */ ohair@286: protected SOAPFaultElement faultStringElement; ohair@286: ohair@286: /* This can also represent a fault role element */ ohair@286: protected SOAPFaultElement faultActorElement; ohair@286: ohair@286: protected SOAPFaultElement faultCodeElement; ohair@286: ohair@286: protected Detail detail; ohair@286: ohair@286: protected FaultImpl(SOAPDocumentImpl ownerDoc, NameImpl name) { ohair@286: super(ownerDoc, name); ohair@286: } ohair@286: ohair@286: ohair@286: protected abstract NameImpl getDetailName(); ohair@286: protected abstract NameImpl getFaultCodeName(); ohair@286: protected abstract NameImpl getFaultStringName(); ohair@286: protected abstract NameImpl getFaultActorName(); ohair@286: protected abstract DetailImpl createDetail(); ohair@286: protected abstract FaultElementImpl createSOAPFaultElement(String localName); ohair@286: protected abstract FaultElementImpl createSOAPFaultElement(QName qname); ohair@286: protected abstract FaultElementImpl createSOAPFaultElement(Name qname); ohair@286: protected abstract void checkIfStandardFaultCode(String faultCode, String uri) throws SOAPException; ohair@286: protected abstract void finallySetFaultCode(String faultcode) throws SOAPException; ohair@286: protected abstract boolean isStandardFaultElement(String localName); ohair@286: protected abstract QName getDefaultFaultCode(); ohair@286: ohair@286: ohair@286: protected void findFaultCodeElement() { ohair@286: this.faultCodeElement = ohair@286: (SOAPFaultElement) findChild(getFaultCodeName()); ohair@286: } ohair@286: ohair@286: protected void findFaultActorElement() { ohair@286: this.faultActorElement = ohair@286: (SOAPFaultElement) findChild(getFaultActorName()); ohair@286: } ohair@286: ohair@286: protected void findFaultStringElement() { ohair@286: this.faultStringElement = ohair@286: (SOAPFaultElement) findChild(getFaultStringName()); ohair@286: } ohair@286: ohair@286: public void setFaultCode(String faultCode) throws SOAPException { ohair@286: setFaultCode( ohair@286: NameImpl.getLocalNameFromTagName(faultCode), ohair@286: NameImpl.getPrefixFromTagName(faultCode), ohair@286: null); ohair@286: } ohair@286: ohair@286: public void setFaultCode(String faultCode, String prefix, String uri) ohair@286: throws SOAPException { ohair@286: ohair@286: if (prefix == null || "".equals(prefix)) { ohair@286: if (uri != null && !"".equals(uri)) { ohair@286: prefix = getNamespacePrefix(uri); ohair@286: if (prefix == null || "".equals(prefix)) { ohair@286: prefix = "ns0"; ohair@286: } ohair@286: } ohair@286: } ohair@286: if (this.faultCodeElement == null) ohair@286: findFaultCodeElement(); ohair@286: ohair@286: if (this.faultCodeElement == null) ohair@286: this.faultCodeElement = addFaultCodeElement(); ohair@286: else ohair@286: this.faultCodeElement.removeContents(); ohair@286: ohair@286: if (uri == null || "".equals(uri)) { ohair@286: uri = this.faultCodeElement.getNamespaceURI(prefix); ohair@286: } ohair@286: if (uri == null || "".equals(uri)) { ohair@286: if (prefix != null && !"".equals(prefix)) { ohair@286: //cannot allow an empty URI for a non-Empty prefix ohair@286: log.log(Level.SEVERE, "SAAJ0140.impl.no.ns.URI", new Object[]{prefix + ":" + faultCode}); ohair@286: throw new SOAPExceptionImpl("Empty/Null NamespaceURI specified for faultCode \"" + prefix + ":" + faultCode + "\""); ohair@286: } else { ohair@286: uri = ""; ohair@286: } ohair@286: } ohair@286: checkIfStandardFaultCode(faultCode, uri); ohair@286: ((FaultElementImpl) this.faultCodeElement).ensureNamespaceIsDeclared(prefix, uri); ohair@286: ohair@286: if (prefix == null || "".equals(prefix)) { ohair@286: finallySetFaultCode(faultCode); ohair@286: } else { ohair@286: finallySetFaultCode(prefix + ":" + faultCode); ohair@286: } ohair@286: } ohair@286: ohair@286: public void setFaultCode(Name faultCodeQName) throws SOAPException { ohair@286: setFaultCode( ohair@286: faultCodeQName.getLocalName(), ohair@286: faultCodeQName.getPrefix(), ohair@286: faultCodeQName.getURI()); ohair@286: } ohair@286: ohair@286: public void setFaultCode(QName faultCodeQName) throws SOAPException { ohair@286: setFaultCode( ohair@286: faultCodeQName.getLocalPart(), ohair@286: faultCodeQName.getPrefix(), ohair@286: faultCodeQName.getNamespaceURI()); ohair@286: } ohair@286: ohair@286: protected static QName convertCodeToQName( ohair@286: String code, ohair@286: SOAPElement codeContainingElement) { ohair@286: ohair@286: int prefixIndex = code.indexOf(':'); ohair@286: if (prefixIndex == -1) { ohair@286: return new QName(code); ohair@286: } ohair@286: ohair@286: String prefix = code.substring(0, prefixIndex); ohair@286: String nsName =((ElementImpl) codeContainingElement).lookupNamespaceURI(prefix); ohair@286: //((ElementImpl) codeContainingElement).getNamespaceURI(prefix); ohair@286: return new QName(nsName, getLocalPart(code), prefix); ohair@286: } ohair@286: ohair@286: protected void initializeDetail() { ohair@286: NameImpl detailName = getDetailName(); ohair@286: detail = (Detail) findChild(detailName); ohair@286: } ohair@286: ohair@286: public Detail getDetail() { ohair@286: if (detail == null) ohair@286: initializeDetail(); ohair@286: if ((detail != null) && (detail.getParentNode() == null)) { ohair@286: // a detach node was called on it ohair@286: detail = null; ohair@286: } ohair@286: return detail; ohair@286: } ohair@286: ohair@286: public Detail addDetail() throws SOAPException { ohair@286: if (detail == null) ohair@286: initializeDetail(); ohair@286: if (detail == null) { ohair@286: detail = createDetail(); ohair@286: addNode(detail); ohair@286: return detail; ohair@286: } else { ohair@286: // Log ohair@286: throw new SOAPExceptionImpl("Error: Detail already exists"); ohair@286: } ohair@286: } ohair@286: ohair@286: public boolean hasDetail() { ohair@286: return (getDetail() != null); ohair@286: } ohair@286: ohair@286: public abstract void setFaultActor(String faultActor) throws SOAPException; ohair@286: ohair@286: public String getFaultActor() { ohair@286: if (this.faultActorElement == null) ohair@286: findFaultActorElement(); ohair@286: if (this.faultActorElement != null) { ohair@286: return this.faultActorElement.getValue(); ohair@286: } ohair@286: return null; ohair@286: } ohair@286: ohair@286: public SOAPElement setElementQName(QName newName) throws SOAPException { ohair@286: ohair@286: log.log( ohair@286: Level.SEVERE, ohair@286: "SAAJ0146.impl.invalid.name.change.requested", ohair@286: new Object[] {elementQName.getLocalPart(), newName.getLocalPart()}); ohair@286: throw new SOAPException( ohair@286: "Cannot change name for " + elementQName.getLocalPart() + " to " + newName.getLocalPart()); ohair@286: } ohair@286: ohair@286: protected SOAPElement convertToSoapElement(Element element) { ohair@286: if (element instanceof SOAPFaultElement) { ohair@286: return (SOAPElement) element; ohair@286: } else if (element instanceof SOAPElement) { ohair@286: SOAPElement soapElement = (SOAPElement) element; ohair@286: if (getDetailName().equals(soapElement.getElementName())) { ohair@286: return replaceElementWithSOAPElement(element, createDetail()); ohair@286: } else { ohair@286: String localName = ohair@286: soapElement.getElementName().getLocalName(); ohair@286: if (isStandardFaultElement(localName)) ohair@286: return replaceElementWithSOAPElement( ohair@286: element, ohair@286: createSOAPFaultElement(soapElement.getElementQName())); ohair@286: return soapElement; ohair@286: } ohair@286: } else { ohair@286: Name elementName = NameImpl.copyElementName(element); ohair@286: ElementImpl newElement; ohair@286: if (getDetailName().equals(elementName)) { ohair@286: newElement = (ElementImpl) createDetail(); ohair@286: } else { ohair@286: String localName = elementName.getLocalName(); ohair@286: if (isStandardFaultElement(localName)) ohair@286: newElement = ohair@286: (ElementImpl) createSOAPFaultElement(elementName); ohair@286: else ohair@286: newElement = (ElementImpl) createElement(elementName); ohair@286: } ohair@286: return replaceElementWithSOAPElement(element, newElement); ohair@286: } ohair@286: } ohair@286: ohair@286: protected SOAPFaultElement addFaultCodeElement() throws SOAPException { ohair@286: if (this.faultCodeElement == null) ohair@286: findFaultCodeElement(); ohair@286: if (this.faultCodeElement == null) { ohair@286: this.faultCodeElement = ohair@286: addSOAPFaultElement(getFaultCodeName().getLocalName()); ohair@286: return this.faultCodeElement; ohair@286: } else { ohair@286: throw new SOAPExceptionImpl("Error: Faultcode already exists"); ohair@286: } ohair@286: } ohair@286: ohair@286: private SOAPFaultElement addFaultStringElement() throws SOAPException { ohair@286: if (this.faultStringElement == null) ohair@286: findFaultStringElement(); ohair@286: if (this.faultStringElement == null) { ohair@286: this.faultStringElement = ohair@286: addSOAPFaultElement(getFaultStringName().getLocalName()); ohair@286: return this.faultStringElement; ohair@286: } else { ohair@286: // Log ohair@286: throw new SOAPExceptionImpl("Error: Faultstring already exists"); ohair@286: } ohair@286: } ohair@286: ohair@286: private SOAPFaultElement addFaultActorElement() throws SOAPException { ohair@286: if (this.faultActorElement == null) ohair@286: findFaultActorElement(); ohair@286: if (this.faultActorElement == null) { ohair@286: this.faultActorElement = ohair@286: addSOAPFaultElement(getFaultActorName().getLocalName()); ohair@286: return this.faultActorElement; ohair@286: } else { ohair@286: // Log ohair@286: throw new SOAPExceptionImpl("Error: Faultactor already exists"); ohair@286: } ohair@286: } ohair@286: ohair@286: protected SOAPElement addElement(Name name) throws SOAPException { ohair@286: if (getDetailName().equals(name)) { ohair@286: return addDetail(); ohair@286: } else if(getFaultCodeName().equals(name)) { ohair@286: return addFaultCodeElement(); ohair@286: } else if(getFaultStringName().equals(name)) { ohair@286: return addFaultStringElement(); ohair@286: } else if(getFaultActorName().equals(name)) { ohair@286: return addFaultActorElement(); ohair@286: } ohair@286: return super.addElement(name); ohair@286: } ohair@286: ohair@286: protected SOAPElement addElement(QName name) throws SOAPException { ohair@286: return addElement(NameImpl.convertToName(name)); ohair@286: } ohair@286: ohair@286: protected FaultElementImpl addSOAPFaultElement(String localName) ohair@286: throws SOAPException { ohair@286: ohair@286: FaultElementImpl faultElem = createSOAPFaultElement(localName); ohair@286: addNode(faultElem); ohair@286: return faultElem; ohair@286: } ohair@286: ohair@286: /** ohair@286: * Convert an xml:lang attribute value into a Locale object ohair@286: */ ohair@286: protected static Locale xmlLangToLocale(String xmlLang) { ohair@286: if (xmlLang == null) { ohair@286: return null; ohair@286: } ohair@286: ohair@286: // Spec uses hyphen as separator ohair@286: int index = xmlLang.indexOf("-"); ohair@286: ohair@286: // Accept underscore as separator as well ohair@286: if (index == -1) { ohair@286: index = xmlLang.indexOf("_"); ohair@286: } ohair@286: ohair@286: if (index == -1) { ohair@286: // No separator so assume only a language component ohair@286: return new Locale(xmlLang, ""); ohair@286: } ohair@286: ohair@286: String language = xmlLang.substring(0, index); ohair@286: String country = xmlLang.substring(index + 1); ohair@286: return new Locale(language, country); ohair@286: } ohair@286: ohair@286: protected static String localeToXmlLang(Locale locale) { ohair@286: String xmlLang = locale.getLanguage(); ohair@286: String country = locale.getCountry(); ohair@286: if (!"".equals(country)) { ohair@286: xmlLang += "-" + country; ohair@286: } ohair@286: return xmlLang; ohair@286: } ohair@286: }