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