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 }