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_2; 31 32 import java.util.*; 33 import java.util.logging.Logger; 34 import java.util.logging.Level; 35 36 import javax.xml.namespace.QName; 37 import javax.xml.soap.*; 38 39 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl; 40 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocument; 41 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl; 42 import com.sun.xml.internal.messaging.saaj.soap.impl.*; 43 import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl; 44 import com.sun.xml.internal.messaging.saaj.util.LogDomainConstants; 45 import org.w3c.dom.Element; 46 47 48 public class Fault1_2Impl extends FaultImpl { 49 50 protected static final Logger log = 51 Logger.getLogger( 52 LogDomainConstants.SOAP_VER1_2_DOMAIN, 53 "com.sun.xml.internal.messaging.saaj.soap.ver1_2.LocalStrings"); 54 55 private static final QName textName = 56 new QName(SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "Text"); 57 private final QName valueName = 58 new QName(SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "Value", getPrefix()); 59 private final QName subcodeName = 60 new QName(SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "Subcode", getPrefix()); 61 62 private SOAPElement innermostSubCodeElement = null; 63 64 public Fault1_2Impl(SOAPDocumentImpl ownerDoc, String name, String prefix) { 65 super(ownerDoc, NameImpl.createFault1_2Name(name, prefix)); 66 } 67 68 public Fault1_2Impl(SOAPDocumentImpl ownerDocument, String prefix) { 69 super(ownerDocument, NameImpl.createFault1_2Name(null, prefix)); 70 } 71 72 public Fault1_2Impl(Element domElement, SOAPDocumentImpl ownerDoc) { 73 super(ownerDoc, domElement); 74 } 75 76 protected NameImpl getDetailName() { 77 return NameImpl.createSOAP12Name("Detail", getPrefix()); 78 } 79 80 protected NameImpl getFaultCodeName() { 81 return NameImpl.createSOAP12Name("Code", getPrefix()); 82 } 83 84 protected NameImpl getFaultStringName() { 85 return getFaultReasonName(); 86 } 87 88 protected NameImpl getFaultActorName() { 89 return getFaultRoleName(); 90 } 91 92 private NameImpl getFaultRoleName() { 93 return NameImpl.createSOAP12Name("Role", getPrefix()); 94 } 95 96 private NameImpl getFaultReasonName() { 97 return NameImpl.createSOAP12Name("Reason", getPrefix()); 98 } 99 100 private NameImpl getFaultReasonTextName() { 101 return NameImpl.createSOAP12Name("Text", getPrefix()); 102 } 103 104 private NameImpl getFaultNodeName() { 105 return NameImpl.createSOAP12Name("Node", getPrefix()); 106 } 107 108 private static NameImpl getXmlLangName() { 109 return NameImpl.createXmlName("lang"); 110 } 111 112 protected DetailImpl createDetail() { 113 return new Detail1_2Impl( 114 ((SOAPDocument) getOwnerDocument()).getDocument()); 115 } 116 117 protected FaultElementImpl createSOAPFaultElement(String localName) { 118 return new FaultElement1_2Impl( 119 ((SOAPDocument) getOwnerDocument()).getDocument(), 120 localName); 121 } 122 123 protected void checkIfStandardFaultCode(String faultCode, String uri) 124 throws SOAPException { 125 QName qname = new QName(uri, faultCode); 126 if (SOAPConstants.SOAP_DATAENCODINGUNKNOWN_FAULT.equals(qname) || 127 SOAPConstants.SOAP_MUSTUNDERSTAND_FAULT.equals(qname) || 128 SOAPConstants.SOAP_RECEIVER_FAULT.equals(qname) || 129 SOAPConstants.SOAP_SENDER_FAULT.equals(qname) || 130 SOAPConstants.SOAP_VERSIONMISMATCH_FAULT.equals(qname)) 131 return; 132 log.log( 133 Level.SEVERE, 134 "SAAJ0435.ver1_2.code.not.standard", 135 qname); 136 throw new SOAPExceptionImpl(qname + " is not a standard Code value"); 137 } 138 139 protected void finallySetFaultCode(String faultcode) throws SOAPException { 140 SOAPElement value = this.faultCodeElement.addChildElement(valueName); 141 value.addTextNode(faultcode); 142 } 143 144 private void findReasonElement() { 145 findFaultStringElement(); 146 } 147 148 public Iterator getFaultReasonTexts() throws SOAPException { 149 // Fault Reason has similar semantics as faultstring 150 if (this.faultStringElement == null) 151 findReasonElement(); 152 Iterator eachTextElement = 153 this.faultStringElement.getChildElements(textName); 154 List<String> texts = new ArrayList<String>(); 155 while (eachTextElement.hasNext()) { 156 SOAPElement textElement = (SOAPElement) eachTextElement.next(); 157 Locale thisLocale = getLocale(textElement); 158 if (thisLocale == null) { 159 log.severe("SAAJ0431.ver1_2.xml.lang.missing"); 160 throw new SOAPExceptionImpl("\"xml:lang\" attribute is not present on the Text element"); 161 } 162 texts.add(textElement.getValue()); 163 } 164 if (texts.isEmpty()) { 165 log.severe("SAAJ0434.ver1_2.text.element.not.present"); 166 throw new SOAPExceptionImpl("env:Text must be present inside env:Reason"); 167 } 168 return texts.iterator(); 169 } 170 171 public void addFaultReasonText(String text, java.util.Locale locale) 172 throws SOAPException { 173 174 if (locale == null) { 175 log.severe("SAAJ0430.ver1_2.locale.required"); 176 throw new SOAPException("locale is required and must not be null"); 177 } 178 179 // Fault Reason has similar semantics as faultstring 180 if (this.faultStringElement == null) 181 findReasonElement(); 182 SOAPElement reasonText; 183 184 if (this.faultStringElement == null) { 185 this.faultStringElement = addSOAPFaultElement("Reason"); 186 reasonText = 187 this.faultStringElement.addChildElement( 188 getFaultReasonTextName()); 189 } else { 190 removeDefaultFaultString(); 197 getFaultReasonTextName()); 198 } 199 } 200 201 String xmlLang = localeToXmlLang(locale); 202 reasonText.addAttribute(getXmlLangName(), xmlLang); 203 reasonText.addTextNode(text); 204 } 205 206 private void removeDefaultFaultString() throws SOAPException { 207 SOAPElement reasonText = getFaultReasonTextElement(Locale.getDefault()); 208 if (reasonText != null) { 209 String defaultFaultString = 210 "Fault string, and possibly fault code, not set"; 211 if (defaultFaultString.equals(reasonText.getValue())) { 212 reasonText.detachNode(); 213 } 214 } 215 } 216 217 public String getFaultReasonText(Locale locale) throws SOAPException { 218 219 if (locale == null) 220 return null; 221 222 // Fault Reason has similar semantics as faultstring 223 if (this.faultStringElement == null) 224 findReasonElement(); 225 226 if (this.faultStringElement != null) { 227 SOAPElement textElement = getFaultReasonTextElement(locale); 228 if (textElement != null) { 229 textElement.normalize(); 230 return textElement.getFirstChild().getNodeValue(); 231 } 232 } 233 234 return null; 235 } 236 237 public Iterator getFaultReasonLocales() throws SOAPException { 238 // Fault Reason has similar semantics as faultstring 239 if (this.faultStringElement == null) 240 findReasonElement(); 241 Iterator eachTextElement = 242 this.faultStringElement.getChildElements(textName); 243 List<Locale> localeSet = new ArrayList<Locale>(); 244 while (eachTextElement.hasNext()) { 245 SOAPElement textElement = (SOAPElement) eachTextElement.next(); 246 Locale thisLocale = getLocale(textElement); 247 if (thisLocale == null) { 248 log.severe("SAAJ0431.ver1_2.xml.lang.missing"); 249 throw new SOAPExceptionImpl("\"xml:lang\" attribute is not present on the Text element"); 250 } 251 localeSet.add(thisLocale); 252 } 253 if (localeSet.isEmpty()) { 254 log.severe("SAAJ0434.ver1_2.text.element.not.present"); 255 throw new SOAPExceptionImpl("env:Text elements with mandatory xml:lang attributes must be present inside env:Reason"); 256 } 257 return localeSet.iterator(); 258 } 259 260 public Locale getFaultStringLocale() { 261 Locale locale = null; 262 try { 263 locale = (Locale) getFaultReasonLocales().next(); 264 } catch (SOAPException e) {} 265 return locale; 266 } 267 268 /* 269 * This method assumes that locale and faultStringElement are non-null 270 */ 271 private SOAPElement getFaultReasonTextElement(Locale locale) 272 throws SOAPException { 273 274 // Fault Reason has similar semantics as faultstring 275 Iterator eachTextElement = 276 this.faultStringElement.getChildElements(textName); 277 while (eachTextElement.hasNext()) { 278 SOAPElement textElement = (SOAPElement) eachTextElement.next(); 279 Locale thisLocale = getLocale(textElement); 280 if (thisLocale == null) { 281 log.severe("SAAJ0431.ver1_2.xml.lang.missing"); 282 throw new SOAPExceptionImpl("\"xml:lang\" attribute is not present on the Text element"); 283 } 284 if (thisLocale.equals(locale)) { 285 return textElement; 286 } 287 } 288 return null; 289 } 290 291 public String getFaultNode() { 292 SOAPElement faultNode = findAndConvertChildElement(getFaultNodeName()); 293 if (faultNode == null) { 294 return null; 295 } 296 return faultNode.getValue(); 297 } 298 299 public void setFaultNode(String uri) throws SOAPException { 300 SOAPElement faultNode = findAndConvertChildElement(getFaultNodeName()); 301 if (faultNode != null) { 302 faultNode.detachNode(); 303 } 304 faultNode = createSOAPFaultElement(getFaultNodeName()); 305 faultNode = faultNode.addTextNode(uri); 306 if (getFaultRole() != null) { 307 insertBefore(faultNode, this.faultActorElement); 308 return; 309 } 310 if (hasDetail()) { 311 insertBefore(faultNode, this.detail); 312 return; 313 } 314 addNode(faultNode); 315 } 316 317 public String getFaultRole() { 318 return getFaultActor(); 319 } 320 321 public void setFaultRole(String uri) throws SOAPException { 322 if (this.faultActorElement == null) 323 findFaultActorElement(); 324 if (this.faultActorElement != null) 325 this.faultActorElement.detachNode(); 326 this.faultActorElement = 327 createSOAPFaultElement(getFaultActorName()); 328 this.faultActorElement.addTextNode(uri); 329 if (hasDetail()) { 330 insertBefore(this.faultActorElement, this.detail); 331 return; 332 } 333 addNode(this.faultActorElement); 334 } 335 336 public String getFaultCode() { 337 if (this.faultCodeElement == null) 338 findFaultCodeElement(); 339 Iterator codeValues = 340 this.faultCodeElement.getChildElements(valueName); 341 return ((SOAPElement) codeValues.next()).getValue(); 342 } 343 344 public QName getFaultCodeAsQName() { 345 String faultcode = getFaultCode(); 346 if (faultcode == null) { 347 return null; 348 } 349 if (this.faultCodeElement == null) 350 findFaultCodeElement(); 351 Iterator valueElements = 352 this.faultCodeElement.getChildElements(valueName); 353 return convertCodeToQName( 354 faultcode, 355 (SOAPElement) valueElements.next()); 356 } 357 358 public Name getFaultCodeAsName() { 359 String faultcode = getFaultCode(); 360 if (faultcode == null) { 361 return null; 362 } 363 if (this.faultCodeElement == null) 364 findFaultCodeElement(); 365 Iterator valueElements = 366 this.faultCodeElement.getChildElements(valueName); 367 return NameImpl.convertToName( 368 convertCodeToQName( 369 faultcode, 370 (SOAPElement) valueElements.next())); 371 } 372 373 public String getFaultString() { 374 String reason = null; 375 try { 376 //reason = getFaultReasonText(Locale.getDefault()); 377 //if (reason == null) 378 reason = (String) getFaultReasonTexts().next(); 379 } catch (SOAPException e) {} 380 return reason; 381 } 382 383 public void setFaultString(String faultString) throws SOAPException { 384 addFaultReasonText(faultString, Locale.getDefault()); 385 } 386 387 public void setFaultString( 388 String faultString, 389 Locale locale) 390 throws SOAPException { 391 addFaultReasonText(faultString, locale); 392 } 393 394 public void appendFaultSubcode(QName subcode) throws SOAPException { 395 if (subcode == null) { 396 return; 397 } 398 if (subcode.getNamespaceURI() == null || 399 "".equals(subcode.getNamespaceURI())) { 400 401 log.severe("SAAJ0432.ver1_2.subcode.not.ns.qualified"); 402 throw new SOAPExceptionImpl("A Subcode must be namespace-qualified"); 403 } 404 if (innermostSubCodeElement == null) { 405 if (faultCodeElement == null) 406 findFaultCodeElement(); 407 innermostSubCodeElement = faultCodeElement; 408 } 409 String prefix = null; 410 if (subcode.getPrefix() == null || "".equals(subcode.getPrefix())) { 411 prefix = 412 ((ElementImpl) innermostSubCodeElement).getNamespacePrefix( 413 subcode.getNamespaceURI()); 414 } else 415 prefix = subcode.getPrefix(); 416 if (prefix == null || "".equals(prefix)) { 417 prefix = "ns1"; 418 } 419 innermostSubCodeElement = 420 innermostSubCodeElement.addChildElement(subcodeName); 421 SOAPElement subcodeValueElement = 422 innermostSubCodeElement.addChildElement(valueName); 423 ((ElementImpl) subcodeValueElement).ensureNamespaceIsDeclared( 424 prefix, 425 subcode.getNamespaceURI()); 426 subcodeValueElement.addTextNode(prefix + ":" + subcode.getLocalPart()); 427 } 428 429 public void removeAllFaultSubcodes() { 430 if (this.faultCodeElement == null) 431 findFaultCodeElement(); 432 Iterator subcodeElements = 433 this.faultCodeElement.getChildElements(subcodeName); 434 if (subcodeElements.hasNext()) { 435 SOAPElement subcode = (SOAPElement) subcodeElements.next(); 436 subcode.detachNode(); 437 } 438 } 439 440 public Iterator getFaultSubcodes() { 441 if (this.faultCodeElement == null) 442 findFaultCodeElement(); 443 final List<QName> subcodeList = new ArrayList<QName>(); 444 SOAPElement currentCodeElement = this.faultCodeElement; 445 Iterator subcodeElements = 446 currentCodeElement.getChildElements(subcodeName); 447 while (subcodeElements.hasNext()) { 448 currentCodeElement = (ElementImpl) subcodeElements.next(); 449 Iterator valueElements = 450 currentCodeElement.getChildElements(valueName); 451 SOAPElement valueElement = (SOAPElement) valueElements.next(); 452 String code = valueElement.getValue(); 453 subcodeList.add(convertCodeToQName(code, valueElement)); 454 subcodeElements = currentCodeElement.getChildElements(subcodeName); 455 } 456 //return subcodeList.iterator(); 457 return new Iterator<QName>() { 458 Iterator<QName> subCodeIter = subcodeList.iterator(); 459 460 public boolean hasNext() { 461 return subCodeIter.hasNext(); 462 } 463 464 public QName next() { 465 return subCodeIter.next(); 466 } 467 468 public void remove() { 469 throw new UnsupportedOperationException( 470 "Method remove() not supported on SubCodes Iterator"); 471 } 472 }; 473 } 474 475 private static Locale getLocale(SOAPElement reasonText) { 476 return xmlLangToLocale(reasonText.getAttributeValue(getXmlLangName())); 477 } 478 479 /* 480 * Override setEncodingStyle of ElementImpl to restrict adding encodingStyle 481 * attribute to SOAP Fault (SOAP 1.2 spec, part 1, section 5.1.1) 482 */ 483 public void setEncodingStyle(String encodingStyle) throws SOAPException { 484 log.severe("SAAJ0407.ver1_2.no.encodingStyle.in.fault"); 485 throw new SOAPExceptionImpl("encodingStyle attribute cannot appear on Fault"); 486 } 487 488 public SOAPElement addAttribute(Name name, String value) 489 throws SOAPException { 490 if (name.getLocalName().equals("encodingStyle") 491 && name.getURI().equals(NameImpl.SOAP12_NAMESPACE)) { 492 setEncodingStyle(value); 493 } 494 return super.addAttribute(name, value); 495 } 496 497 public SOAPElement addAttribute(QName name, String value) 498 throws SOAPException { 499 if (name.getLocalPart().equals("encodingStyle") 500 && name.getNamespaceURI().equals(NameImpl.SOAP12_NAMESPACE)) { 501 setEncodingStyle(value); 502 } 503 return super.addAttribute(name, value); 504 } 505 506 public SOAPElement addTextNode(String text) throws SOAPException { 507 log.log( 508 Level.SEVERE, 509 "SAAJ0416.ver1_2.adding.text.not.legal", 510 getElementQName()); 511 throw new SOAPExceptionImpl("Adding text to SOAP 1.2 Fault is not legal"); 512 } 513 514 public SOAPElement addChildElement(SOAPElement element) 515 throws SOAPException { 516 String localName = element.getLocalName(); 517 if ("Detail".equalsIgnoreCase(localName)) { 518 if (hasDetail()) { 519 log.severe("SAAJ0436.ver1_2.detail.exists.error"); 520 throw new SOAPExceptionImpl("Cannot add Detail, Detail already exists"); 521 } 522 String uri = element.getElementQName().getNamespaceURI(); 523 if (!uri.equals(SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE)) { 524 log.severe("SAAJ0437.ver1_2.version.mismatch.error"); 525 throw new SOAPExceptionImpl("Cannot add Detail, Incorrect SOAP version specified for Detail element"); 526 } 527 } 528 if (element instanceof Detail1_2Impl) { 529 Element importedElement = importElement(element); 530 addNode(importedElement); 531 return convertToSoapElement(importedElement); 532 } else 533 return super.addChildElement(element); 534 } 535 536 protected boolean isStandardFaultElement(String localName) { 537 if (localName.equalsIgnoreCase("code") || 538 localName.equalsIgnoreCase("reason") || 539 localName.equalsIgnoreCase("node") || 540 localName.equalsIgnoreCase("role") || 541 localName.equalsIgnoreCase("detail")) { 542 return true; 543 } 544 return false; 545 } 546 547 protected QName getDefaultFaultCode() { 548 return SOAPConstants.SOAP_SENDER_FAULT; 549 } 550 551 protected FaultElementImpl createSOAPFaultElement(QName qname) { 552 return new FaultElement1_2Impl( 553 ((SOAPDocument) getOwnerDocument()).getDocument(), 554 qname); 555 } 556 557 protected FaultElementImpl createSOAPFaultElement(Name qname) { 558 return new FaultElement1_2Impl( 559 ((SOAPDocument) getOwnerDocument()).getDocument(), 560 (NameImpl)qname); 561 } 562 563 public void setFaultActor(String faultActor) throws SOAPException { 564 this.setFaultRole(faultActor); 565 } 566 567 } | 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_2; 31 32 import java.util.logging.Logger; 33 import java.util.logging.Level; 34 35 import javax.xml.namespace.QName; 36 37 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl; 38 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocument; 39 import com.sun.xml.internal.messaging.saaj.soap.SOAPDocumentImpl; 40 import com.sun.xml.internal.messaging.saaj.soap.impl.*; 41 import com.sun.xml.internal.messaging.saaj.soap.name.NameImpl; 42 import com.sun.xml.internal.messaging.saaj.util.LogDomainConstants; 43 import java.util.ArrayList; 44 import java.util.Iterator; 45 import java.util.List; 46 import java.util.Locale; 47 import javax.xml.soap.Name; 48 import javax.xml.soap.SOAPConstants; 49 import javax.xml.soap.SOAPElement; 50 import javax.xml.soap.SOAPException; 51 import org.w3c.dom.Element; 52 53 54 public class Fault1_2Impl extends FaultImpl { 55 56 protected static final Logger log = 57 Logger.getLogger( 58 LogDomainConstants.SOAP_VER1_2_DOMAIN, 59 "com.sun.xml.internal.messaging.saaj.soap.ver1_2.LocalStrings"); 60 61 private static final QName textName = 62 new QName(SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "Text"); 63 private final QName valueName = 64 new QName(SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "Value", getPrefix()); 65 private final QName subcodeName = 66 new QName(SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "Subcode", getPrefix()); 67 68 private SOAPElement innermostSubCodeElement = null; 69 70 public Fault1_2Impl(SOAPDocumentImpl ownerDoc, String name, String prefix) { 71 super(ownerDoc, NameImpl.createFault1_2Name(name, prefix)); 72 } 73 74 public Fault1_2Impl(SOAPDocumentImpl ownerDocument, String prefix) { 75 super(ownerDocument, NameImpl.createFault1_2Name(null, prefix)); 76 } 77 78 public Fault1_2Impl(Element domElement, SOAPDocumentImpl ownerDoc) { 79 super(ownerDoc, domElement); 80 } 81 82 @Override 83 protected NameImpl getDetailName() { 84 return NameImpl.createSOAP12Name("Detail", getPrefix()); 85 } 86 87 @Override 88 protected NameImpl getFaultCodeName() { 89 return NameImpl.createSOAP12Name("Code", getPrefix()); 90 } 91 92 @Override 93 protected NameImpl getFaultStringName() { 94 return getFaultReasonName(); 95 } 96 97 @Override 98 protected NameImpl getFaultActorName() { 99 return getFaultRoleName(); 100 } 101 102 private NameImpl getFaultRoleName() { 103 return NameImpl.createSOAP12Name("Role", getPrefix()); 104 } 105 106 private NameImpl getFaultReasonName() { 107 return NameImpl.createSOAP12Name("Reason", getPrefix()); 108 } 109 110 private NameImpl getFaultReasonTextName() { 111 return NameImpl.createSOAP12Name("Text", getPrefix()); 112 } 113 114 private NameImpl getFaultNodeName() { 115 return NameImpl.createSOAP12Name("Node", getPrefix()); 116 } 117 118 private static NameImpl getXmlLangName() { 119 return NameImpl.createXmlName("lang"); 120 } 121 122 @Override 123 protected DetailImpl createDetail() { 124 return new Detail1_2Impl( 125 ((SOAPDocument) getOwnerDocument()).getDocument()); 126 } 127 128 @Override 129 protected FaultElementImpl createSOAPFaultElement(String localName) { 130 return new FaultElement1_2Impl( 131 ((SOAPDocument) getOwnerDocument()).getDocument(), 132 localName); 133 } 134 135 @Override 136 protected void checkIfStandardFaultCode(String faultCode, String uri) 137 throws SOAPException { 138 QName qname = new QName(uri, faultCode); 139 if (SOAPConstants.SOAP_DATAENCODINGUNKNOWN_FAULT.equals(qname) || 140 SOAPConstants.SOAP_MUSTUNDERSTAND_FAULT.equals(qname) || 141 SOAPConstants.SOAP_RECEIVER_FAULT.equals(qname) || 142 SOAPConstants.SOAP_SENDER_FAULT.equals(qname) || 143 SOAPConstants.SOAP_VERSIONMISMATCH_FAULT.equals(qname)) 144 return; 145 log.log( 146 Level.SEVERE, 147 "SAAJ0435.ver1_2.code.not.standard", 148 qname); 149 throw new SOAPExceptionImpl(qname + " is not a standard Code value"); 150 } 151 152 @Override 153 protected void finallySetFaultCode(String faultcode) throws SOAPException { 154 SOAPElement value = this.faultCodeElement.addChildElement(valueName); 155 value.addTextNode(faultcode); 156 } 157 158 private void findReasonElement() { 159 findFaultStringElement(); 160 } 161 162 @Override 163 public Iterator<String> getFaultReasonTexts() throws SOAPException { 164 // Fault Reason has similar semantics as faultstring 165 if (this.faultStringElement == null) 166 findReasonElement(); 167 Iterator eachTextElement = 168 this.faultStringElement.getChildElements(textName); 169 List<String> texts = new ArrayList<>(); 170 while (eachTextElement.hasNext()) { 171 SOAPElement textElement = (SOAPElement) eachTextElement.next(); 172 Locale thisLocale = getLocale(textElement); 173 if (thisLocale == null) { 174 log.severe("SAAJ0431.ver1_2.xml.lang.missing"); 175 throw new SOAPExceptionImpl("\"xml:lang\" attribute is not present on the Text element"); 176 } 177 texts.add(textElement.getValue()); 178 } 179 if (texts.isEmpty()) { 180 log.severe("SAAJ0434.ver1_2.text.element.not.present"); 181 throw new SOAPExceptionImpl("env:Text must be present inside env:Reason"); 182 } 183 return texts.iterator(); 184 } 185 186 @Override 187 public void addFaultReasonText(String text, java.util.Locale locale) 188 throws SOAPException { 189 190 if (locale == null) { 191 log.severe("SAAJ0430.ver1_2.locale.required"); 192 throw new SOAPException("locale is required and must not be null"); 193 } 194 195 // Fault Reason has similar semantics as faultstring 196 if (this.faultStringElement == null) 197 findReasonElement(); 198 SOAPElement reasonText; 199 200 if (this.faultStringElement == null) { 201 this.faultStringElement = addSOAPFaultElement("Reason"); 202 reasonText = 203 this.faultStringElement.addChildElement( 204 getFaultReasonTextName()); 205 } else { 206 removeDefaultFaultString(); 213 getFaultReasonTextName()); 214 } 215 } 216 217 String xmlLang = localeToXmlLang(locale); 218 reasonText.addAttribute(getXmlLangName(), xmlLang); 219 reasonText.addTextNode(text); 220 } 221 222 private void removeDefaultFaultString() throws SOAPException { 223 SOAPElement reasonText = getFaultReasonTextElement(Locale.getDefault()); 224 if (reasonText != null) { 225 String defaultFaultString = 226 "Fault string, and possibly fault code, not set"; 227 if (defaultFaultString.equals(reasonText.getValue())) { 228 reasonText.detachNode(); 229 } 230 } 231 } 232 233 @Override 234 public String getFaultReasonText(Locale locale) throws SOAPException { 235 236 if (locale == null) 237 return null; 238 239 // Fault Reason has similar semantics as faultstring 240 if (this.faultStringElement == null) 241 findReasonElement(); 242 243 if (this.faultStringElement != null) { 244 SOAPElement textElement = getFaultReasonTextElement(locale); 245 if (textElement != null) { 246 textElement.normalize(); 247 return textElement.getFirstChild().getNodeValue(); 248 } 249 } 250 251 return null; 252 } 253 254 @Override 255 public Iterator<Locale> getFaultReasonLocales() throws SOAPException { 256 // Fault Reason has similar semantics as faultstring 257 if (this.faultStringElement == null) 258 findReasonElement(); 259 Iterator eachTextElement = 260 this.faultStringElement.getChildElements(textName); 261 List<Locale> localeSet = new ArrayList<>(); 262 while (eachTextElement.hasNext()) { 263 SOAPElement textElement = (SOAPElement) eachTextElement.next(); 264 Locale thisLocale = getLocale(textElement); 265 if (thisLocale == null) { 266 log.severe("SAAJ0431.ver1_2.xml.lang.missing"); 267 throw new SOAPExceptionImpl("\"xml:lang\" attribute is not present on the Text element"); 268 } 269 localeSet.add(thisLocale); 270 } 271 if (localeSet.isEmpty()) { 272 log.severe("SAAJ0434.ver1_2.text.element.not.present"); 273 throw new SOAPExceptionImpl("env:Text elements with mandatory xml:lang attributes must be present inside env:Reason"); 274 } 275 return localeSet.iterator(); 276 } 277 278 @Override 279 public Locale getFaultStringLocale() { 280 Locale locale = null; 281 try { 282 locale = (Locale) getFaultReasonLocales().next(); 283 } catch (SOAPException e) {} 284 return locale; 285 } 286 287 /* 288 * This method assumes that locale and faultStringElement are non-null 289 */ 290 private SOAPElement getFaultReasonTextElement(Locale locale) 291 throws SOAPException { 292 293 // Fault Reason has similar semantics as faultstring 294 Iterator eachTextElement = 295 this.faultStringElement.getChildElements(textName); 296 while (eachTextElement.hasNext()) { 297 SOAPElement textElement = (SOAPElement) eachTextElement.next(); 298 Locale thisLocale = getLocale(textElement); 299 if (thisLocale == null) { 300 log.severe("SAAJ0431.ver1_2.xml.lang.missing"); 301 throw new SOAPExceptionImpl("\"xml:lang\" attribute is not present on the Text element"); 302 } 303 if (thisLocale.equals(locale)) { 304 return textElement; 305 } 306 } 307 return null; 308 } 309 310 @Override 311 public String getFaultNode() { 312 SOAPElement faultNode = findAndConvertChildElement(getFaultNodeName()); 313 if (faultNode == null) { 314 return null; 315 } 316 return faultNode.getValue(); 317 } 318 319 @Override 320 public void setFaultNode(String uri) throws SOAPException { 321 SOAPElement faultNode = findAndConvertChildElement(getFaultNodeName()); 322 if (faultNode != null) { 323 faultNode.detachNode(); 324 } 325 faultNode = createSOAPFaultElement(getFaultNodeName()); 326 faultNode = faultNode.addTextNode(uri); 327 if (getFaultRole() != null) { 328 insertBefore(faultNode, this.faultActorElement); 329 return; 330 } 331 if (hasDetail()) { 332 insertBefore(faultNode, this.detail); 333 return; 334 } 335 addNode(faultNode); 336 } 337 338 @Override 339 public String getFaultRole() { 340 return getFaultActor(); 341 } 342 343 @Override 344 public void setFaultRole(String uri) throws SOAPException { 345 if (this.faultActorElement == null) 346 findFaultActorElement(); 347 if (this.faultActorElement != null) 348 this.faultActorElement.detachNode(); 349 this.faultActorElement = 350 createSOAPFaultElement(getFaultActorName()); 351 this.faultActorElement.addTextNode(uri); 352 if (hasDetail()) { 353 insertBefore(this.faultActorElement, this.detail); 354 return; 355 } 356 addNode(this.faultActorElement); 357 } 358 359 @Override 360 public String getFaultCode() { 361 if (this.faultCodeElement == null) 362 findFaultCodeElement(); 363 Iterator codeValues = 364 this.faultCodeElement.getChildElements(valueName); 365 return ((SOAPElement) codeValues.next()).getValue(); 366 } 367 368 @Override 369 public QName getFaultCodeAsQName() { 370 String faultcode = getFaultCode(); 371 if (faultcode == null) { 372 return null; 373 } 374 if (this.faultCodeElement == null) 375 findFaultCodeElement(); 376 Iterator valueElements = 377 this.faultCodeElement.getChildElements(valueName); 378 return convertCodeToQName( 379 faultcode, 380 (SOAPElement) valueElements.next()); 381 } 382 383 @Override 384 public Name getFaultCodeAsName() { 385 String faultcode = getFaultCode(); 386 if (faultcode == null) { 387 return null; 388 } 389 if (this.faultCodeElement == null) 390 findFaultCodeElement(); 391 Iterator valueElements = 392 this.faultCodeElement.getChildElements(valueName); 393 return NameImpl.convertToName( 394 convertCodeToQName( 395 faultcode, 396 (SOAPElement) valueElements.next())); 397 } 398 399 @Override 400 public String getFaultString() { 401 String reason = null; 402 try { 403 //reason = getFaultReasonText(Locale.getDefault()); 404 //if (reason == null) 405 reason = (String) getFaultReasonTexts().next(); 406 } catch (SOAPException e) {} 407 return reason; 408 } 409 410 @Override 411 public void setFaultString(String faultString) throws SOAPException { 412 addFaultReasonText(faultString, Locale.getDefault()); 413 } 414 415 @Override 416 public void setFaultString( 417 String faultString, 418 Locale locale) 419 throws SOAPException { 420 addFaultReasonText(faultString, locale); 421 } 422 423 @Override 424 public void appendFaultSubcode(QName subcode) throws SOAPException { 425 if (subcode == null) { 426 return; 427 } 428 if (subcode.getNamespaceURI() == null || 429 "".equals(subcode.getNamespaceURI())) { 430 431 log.severe("SAAJ0432.ver1_2.subcode.not.ns.qualified"); 432 throw new SOAPExceptionImpl("A Subcode must be namespace-qualified"); 433 } 434 if (innermostSubCodeElement == null) { 435 if (faultCodeElement == null) 436 findFaultCodeElement(); 437 innermostSubCodeElement = faultCodeElement; 438 } 439 String prefix = null; 440 if (subcode.getPrefix() == null || "".equals(subcode.getPrefix())) { 441 prefix = 442 ((ElementImpl) innermostSubCodeElement).getNamespacePrefix( 443 subcode.getNamespaceURI()); 444 } else 445 prefix = subcode.getPrefix(); 446 if (prefix == null || "".equals(prefix)) { 447 prefix = "ns1"; 448 } 449 innermostSubCodeElement = 450 innermostSubCodeElement.addChildElement(subcodeName); 451 SOAPElement subcodeValueElement = 452 innermostSubCodeElement.addChildElement(valueName); 453 ((ElementImpl) subcodeValueElement).ensureNamespaceIsDeclared( 454 prefix, 455 subcode.getNamespaceURI()); 456 subcodeValueElement.addTextNode(prefix + ":" + subcode.getLocalPart()); 457 } 458 459 @Override 460 public void removeAllFaultSubcodes() { 461 if (this.faultCodeElement == null) 462 findFaultCodeElement(); 463 Iterator subcodeElements = 464 this.faultCodeElement.getChildElements(subcodeName); 465 if (subcodeElements.hasNext()) { 466 SOAPElement subcode = (SOAPElement) subcodeElements.next(); 467 subcode.detachNode(); 468 } 469 } 470 471 @Override 472 public Iterator<QName> getFaultSubcodes() { 473 if (this.faultCodeElement == null) 474 findFaultCodeElement(); 475 final List<QName> subcodeList = new ArrayList<>(); 476 SOAPElement currentCodeElement = this.faultCodeElement; 477 Iterator subcodeElements = 478 currentCodeElement.getChildElements(subcodeName); 479 while (subcodeElements.hasNext()) { 480 currentCodeElement = (ElementImpl) subcodeElements.next(); 481 Iterator valueElements = 482 currentCodeElement.getChildElements(valueName); 483 SOAPElement valueElement = (SOAPElement) valueElements.next(); 484 String code = valueElement.getValue(); 485 subcodeList.add(convertCodeToQName(code, valueElement)); 486 subcodeElements = currentCodeElement.getChildElements(subcodeName); 487 } 488 //return subcodeList.iterator(); 489 return new Iterator<QName>() { 490 Iterator<QName> subCodeIter = subcodeList.iterator(); 491 492 @Override 493 public boolean hasNext() { 494 return subCodeIter.hasNext(); 495 } 496 497 @Override 498 public QName next() { 499 return subCodeIter.next(); 500 } 501 502 @Override 503 public void remove() { 504 throw new UnsupportedOperationException( 505 "Method remove() not supported on SubCodes Iterator"); 506 } 507 }; 508 } 509 510 private static Locale getLocale(SOAPElement reasonText) { 511 return xmlLangToLocale(reasonText.getAttributeValue(getXmlLangName())); 512 } 513 514 /* 515 * Override setEncodingStyle of ElementImpl to restrict adding encodingStyle 516 * attribute to SOAP Fault (SOAP 1.2 spec, part 1, section 5.1.1) 517 */ 518 @Override 519 public void setEncodingStyle(String encodingStyle) throws SOAPException { 520 log.severe("SAAJ0407.ver1_2.no.encodingStyle.in.fault"); 521 throw new SOAPExceptionImpl("encodingStyle attribute cannot appear on Fault"); 522 } 523 524 @Override 525 public SOAPElement addAttribute(Name name, String value) 526 throws SOAPException { 527 if (name.getLocalName().equals("encodingStyle") 528 && name.getURI().equals(NameImpl.SOAP12_NAMESPACE)) { 529 setEncodingStyle(value); 530 } 531 return super.addAttribute(name, value); 532 } 533 534 @Override 535 public SOAPElement addAttribute(QName name, String value) 536 throws SOAPException { 537 if (name.getLocalPart().equals("encodingStyle") 538 && name.getNamespaceURI().equals(NameImpl.SOAP12_NAMESPACE)) { 539 setEncodingStyle(value); 540 } 541 return super.addAttribute(name, value); 542 } 543 544 @Override 545 public SOAPElement addTextNode(String text) throws SOAPException { 546 log.log( 547 Level.SEVERE, 548 "SAAJ0416.ver1_2.adding.text.not.legal", 549 getElementQName()); 550 throw new SOAPExceptionImpl("Adding text to SOAP 1.2 Fault is not legal"); 551 } 552 553 @Override 554 public SOAPElement addChildElement(SOAPElement element) 555 throws SOAPException { 556 String localName = element.getLocalName(); 557 if ("Detail".equalsIgnoreCase(localName)) { 558 if (hasDetail()) { 559 log.severe("SAAJ0436.ver1_2.detail.exists.error"); 560 throw new SOAPExceptionImpl("Cannot add Detail, Detail already exists"); 561 } 562 String uri = element.getElementQName().getNamespaceURI(); 563 if (!uri.equals(SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE)) { 564 log.severe("SAAJ0437.ver1_2.version.mismatch.error"); 565 throw new SOAPExceptionImpl("Cannot add Detail, Incorrect SOAP version specified for Detail element"); 566 } 567 } 568 if (element instanceof Detail1_2Impl) { 569 Element importedElement = importElement(element); 570 addNode(importedElement); 571 return convertToSoapElement(importedElement); 572 } else 573 return super.addChildElement(element); 574 } 575 576 @Override 577 protected boolean isStandardFaultElement(String localName) { 578 if (localName.equalsIgnoreCase("code") || 579 localName.equalsIgnoreCase("reason") || 580 localName.equalsIgnoreCase("node") || 581 localName.equalsIgnoreCase("role") || 582 localName.equalsIgnoreCase("detail")) { 583 return true; 584 } 585 return false; 586 } 587 588 @Override 589 protected QName getDefaultFaultCode() { 590 return SOAPConstants.SOAP_SENDER_FAULT; 591 } 592 593 @Override 594 protected FaultElementImpl createSOAPFaultElement(QName qname) { 595 return new FaultElement1_2Impl( 596 ((SOAPDocument) getOwnerDocument()).getDocument(), 597 qname); 598 } 599 600 @Override 601 protected FaultElementImpl createSOAPFaultElement(Name qname) { 602 return new FaultElement1_2Impl( 603 ((SOAPDocument) getOwnerDocument()).getDocument(), 604 (NameImpl)qname); 605 } 606 607 @Override 608 public void setFaultActor(String faultActor) throws SOAPException { 609 this.setFaultRole(faultActor); 610 } 611 612 } |