001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the "License"). You may not use this file except
005: * in compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://jwsdp.dev.java.net/CDDLv1.0.html
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * HEADER in each file and include the License file at
014: * https://jwsdp.dev.java.net/CDDLv1.0.html If applicable,
015: * add the following below this CDDL HEADER, with the
016: * fields enclosed by brackets "[]" replaced with your
017: * own identifying information: Portions Copyright [yyyy]
018: * [name of copyright owner]
019: */
020: /*
021: * $Id: Fault1_2Impl.java,v 1.3 2007/07/16 16:41:24 ofung Exp $
022: */
023:
024: /*
025: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
026: *
027: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
028: *
029: * The contents of this file are subject to the terms of either the GNU
030: * General Public License Version 2 only ("GPL") or the Common Development
031: * and Distribution License("CDDL") (collectively, the "License"). You
032: * may not use this file except in compliance with the License. You can obtain
033: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
034: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
035: * language governing permissions and limitations under the License.
036: *
037: * When distributing the software, include this License Header Notice in each
038: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
039: * Sun designates this particular file as subject to the "Classpath" exception
040: * as provided by Sun in the GPL Version 2 section of the License file that
041: * accompanied this code. If applicable, add the following below the License
042: * Header, with the fields enclosed by brackets [] replaced by your own
043: * identifying information: "Portions Copyrighted [year]
044: * [name of copyright owner]"
045: *
046: * Contributor(s):
047: *
048: * If you wish your version of this file to be governed by only the CDDL or
049: * only the GPL Version 2, indicate your decision by adding "[Contributor]
050: * elects to include this software in this distribution under the [CDDL or GPL
051: * Version 2] license." If you don't indicate a single choice of license, a
052: * recipient has the option to distribute your version of this file under
053: * either the CDDL, the GPL Version 2 or to extend the choice of license to
054: * its licensees as provided above. However, if you add GPL Version 2 code
055: * and therefore, elected the GPL Version 2 license, then the option applies
056: * only if the new code is made subject to such option by the copyright
057: * holder.
058: */
059:
060: /**
061: *
062: * @author SAAJ RI Development Team
063: */package com.sun.xml.messaging.saaj.soap.ver1_2;
064:
065: import java.util.*;
066: import java.util.logging.Logger;
067: import java.util.logging.Level;
068:
069: import javax.xml.namespace.QName;
070: import javax.xml.soap.*;
071:
072: import com.sun.xml.messaging.saaj.SOAPExceptionImpl;
073: import com.sun.xml.messaging.saaj.soap.SOAPDocument;
074: import com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl;
075: import com.sun.xml.messaging.saaj.soap.impl.*;
076: import com.sun.xml.messaging.saaj.soap.name.NameImpl;
077: import com.sun.xml.messaging.saaj.util.LogDomainConstants;
078:
079: public class Fault1_2Impl extends FaultImpl {
080:
081: protected static Logger log = Logger.getLogger(
082: LogDomainConstants.SOAP_VER1_2_DOMAIN,
083: "com.sun.xml.messaging.saaj.soap.ver1_2.LocalStrings");
084:
085: private static final QName textName = new QName(
086: SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "Text");
087: private final QName valueName = new QName(
088: SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "Value",
089: getPrefix());
090: private final QName subcodeName = new QName(
091: SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "Subcode",
092: getPrefix());
093:
094: private SOAPElement innermostSubCodeElement = null;
095:
096: public Fault1_2Impl(SOAPDocumentImpl ownerDoc, String name,
097: String prefix) {
098: super (ownerDoc, NameImpl.createFault1_2Name(name, prefix));
099: }
100:
101: public Fault1_2Impl(SOAPDocumentImpl ownerDocument, String prefix) {
102: super (ownerDocument, NameImpl.createFault1_2Name(null, prefix));
103: }
104:
105: protected NameImpl getDetailName() {
106: return NameImpl.createSOAP12Name("Detail", getPrefix());
107: }
108:
109: protected NameImpl getFaultCodeName() {
110: return NameImpl.createSOAP12Name("Code", getPrefix());
111: }
112:
113: protected NameImpl getFaultStringName() {
114: return getFaultReasonName();
115: }
116:
117: protected NameImpl getFaultActorName() {
118: return getFaultRoleName();
119: }
120:
121: private NameImpl getFaultRoleName() {
122: return NameImpl.createSOAP12Name("Role", getPrefix());
123: }
124:
125: private NameImpl getFaultReasonName() {
126: return NameImpl.createSOAP12Name("Reason", getPrefix());
127: }
128:
129: private NameImpl getFaultReasonTextName() {
130: return NameImpl.createSOAP12Name("Text", getPrefix());
131: }
132:
133: private NameImpl getFaultNodeName() {
134: return NameImpl.createSOAP12Name("Node", getPrefix());
135: }
136:
137: private static NameImpl getXmlLangName() {
138: return NameImpl.createXmlName("lang");
139: }
140:
141: protected DetailImpl createDetail() {
142: return new Detail1_2Impl(((SOAPDocument) getOwnerDocument())
143: .getDocument());
144: }
145:
146: protected FaultElementImpl createSOAPFaultElement(String localName) {
147: return new FaultElement1_2Impl(
148: ((SOAPDocument) getOwnerDocument()).getDocument(),
149: localName);
150: }
151:
152: protected void checkIfStandardFaultCode(String faultCode, String uri)
153: throws SOAPException {
154: QName qname = new QName(uri, faultCode);
155: if (SOAPConstants.SOAP_DATAENCODINGUNKNOWN_FAULT.equals(qname)
156: || SOAPConstants.SOAP_MUSTUNDERSTAND_FAULT
157: .equals(qname)
158: || SOAPConstants.SOAP_RECEIVER_FAULT.equals(qname)
159: || SOAPConstants.SOAP_SENDER_FAULT.equals(qname)
160: || SOAPConstants.SOAP_VERSIONMISMATCH_FAULT
161: .equals(qname))
162: return;
163: log.log(Level.SEVERE, "SAAJ0435.ver1_2.code.not.standard",
164: qname);
165: throw new SOAPExceptionImpl(qname
166: + " is not a standard Code value");
167: }
168:
169: protected void finallySetFaultCode(String faultcode)
170: throws SOAPException {
171: SOAPElement value = this .faultCodeElement
172: .addChildElement(valueName);
173: value.addTextNode(faultcode);
174: }
175:
176: private void findReasonElement() {
177: findFaultStringElement();
178: }
179:
180: public Iterator getFaultReasonTexts() throws SOAPException {
181: // Fault Reason has similar semantics as faultstring
182: if (this .faultStringElement == null)
183: findReasonElement();
184: Iterator eachTextElement = this .faultStringElement
185: .getChildElements(textName);
186: List texts = new ArrayList();
187: while (eachTextElement.hasNext()) {
188: SOAPElement textElement = (SOAPElement) eachTextElement
189: .next();
190: Locale this Locale = getLocale(textElement);
191: if (this Locale == null) {
192: log.severe("SAAJ0431.ver1_2.xml.lang.missing");
193: throw new SOAPExceptionImpl(
194: "\"xml:lang\" attribute is not present on the Text element");
195: }
196: texts.add(textElement.getValue());
197: }
198: if (texts.isEmpty()) {
199: log.severe("SAAJ0434.ver1_2.text.element.not.present");
200: throw new SOAPExceptionImpl(
201: "env:Text must be present inside env:Reason");
202: }
203: return texts.iterator();
204: }
205:
206: public void addFaultReasonText(String text, java.util.Locale locale)
207: throws SOAPException {
208:
209: if (locale == null) {
210: log.severe("SAAJ0430.ver1_2.locale.required");
211: throw new SOAPException(
212: "locale is required and must not be null");
213: }
214:
215: // Fault Reason has similar semantics as faultstring
216: if (this .faultStringElement == null)
217: findReasonElement();
218: SOAPElement reasonText;
219:
220: if (this .faultStringElement == null) {
221: this .faultStringElement = addSOAPFaultElement("Reason");
222: reasonText = this .faultStringElement
223: .addChildElement(getFaultReasonTextName());
224: } else {
225: removeDefaultFaultString();
226: reasonText = getFaultReasonTextElement(locale);
227: if (reasonText != null) {
228: reasonText.removeContents();
229: } else {
230: reasonText = this .faultStringElement
231: .addChildElement(getFaultReasonTextName());
232: }
233: }
234:
235: String xmlLang = localeToXmlLang(locale);
236: reasonText.addAttribute(getXmlLangName(), xmlLang);
237: reasonText.addTextNode(text);
238: }
239:
240: private void removeDefaultFaultString() throws SOAPException {
241: SOAPElement reasonText = getFaultReasonTextElement(Locale
242: .getDefault());
243: if (reasonText != null) {
244: String defaultFaultString = "Fault string, and possibly fault code, not set";
245: if (defaultFaultString.equals(reasonText.getValue())) {
246: reasonText.detachNode();
247: }
248: }
249: }
250:
251: public String getFaultReasonText(Locale locale)
252: throws SOAPException {
253:
254: if (locale == null)
255: return null;
256:
257: // Fault Reason has similar semantics as faultstring
258: if (this .faultStringElement == null)
259: findReasonElement();
260:
261: if (this .faultStringElement != null) {
262: SOAPElement textElement = getFaultReasonTextElement(locale);
263: if (textElement != null) {
264: textElement.normalize();
265: return textElement.getFirstChild().getNodeValue();
266: }
267: }
268:
269: return null;
270: }
271:
272: public Iterator getFaultReasonLocales() throws SOAPException {
273: // Fault Reason has similar semantics as faultstring
274: if (this .faultStringElement == null)
275: findReasonElement();
276: Iterator eachTextElement = this .faultStringElement
277: .getChildElements(textName);
278: List localeSet = new ArrayList();
279: while (eachTextElement.hasNext()) {
280: SOAPElement textElement = (SOAPElement) eachTextElement
281: .next();
282: Locale this Locale = getLocale(textElement);
283: if (this Locale == null) {
284: log.severe("SAAJ0431.ver1_2.xml.lang.missing");
285: throw new SOAPExceptionImpl(
286: "\"xml:lang\" attribute is not present on the Text element");
287: }
288: localeSet.add(this Locale);
289: }
290: if (localeSet.isEmpty()) {
291: log.severe("SAAJ0434.ver1_2.text.element.not.present");
292: throw new SOAPExceptionImpl(
293: "env:Text elements with mandatory xml:lang attributes must be present inside env:Reason");
294: }
295: return localeSet.iterator();
296: }
297:
298: public Locale getFaultStringLocale() {
299: Locale locale = null;
300: try {
301: locale = (Locale) getFaultReasonLocales().next();
302: } catch (SOAPException e) {
303: }
304: return locale;
305: }
306:
307: /*
308: * This method assumes that locale and faultStringElement are non-null
309: */
310: private SOAPElement getFaultReasonTextElement(Locale locale)
311: throws SOAPException {
312:
313: // Fault Reason has similar semantics as faultstring
314: Iterator eachTextElement = this .faultStringElement
315: .getChildElements(textName);
316: while (eachTextElement.hasNext()) {
317: SOAPElement textElement = (SOAPElement) eachTextElement
318: .next();
319: Locale this Locale = getLocale(textElement);
320: if (this Locale == null) {
321: log.severe("SAAJ0431.ver1_2.xml.lang.missing");
322: throw new SOAPExceptionImpl(
323: "\"xml:lang\" attribute is not present on the Text element");
324: }
325: if (this Locale.equals(locale)) {
326: return textElement;
327: }
328: }
329: return null;
330: }
331:
332: public String getFaultNode() {
333: SOAPElement faultNode = findChild(getFaultNodeName());
334: if (faultNode == null) {
335: return null;
336: }
337: return faultNode.getValue();
338: }
339:
340: public void setFaultNode(String uri) throws SOAPException {
341: SOAPElement faultNode = findChild(getFaultNodeName());
342: if (faultNode != null) {
343: faultNode.detachNode();
344: }
345: faultNode = createSOAPFaultElement(getFaultNodeName());
346: faultNode = faultNode.addTextNode(uri);
347: if (getFaultRole() != null) {
348: insertBefore(faultNode, this .faultActorElement);
349: return;
350: }
351: if (hasDetail()) {
352: insertBefore(faultNode, this .detail);
353: return;
354: }
355: addNode(faultNode);
356: }
357:
358: public String getFaultRole() {
359: return getFaultActor();
360: }
361:
362: public void setFaultRole(String uri) throws SOAPException {
363: if (this .faultActorElement == null)
364: findFaultActorElement();
365: if (this .faultActorElement != null)
366: this .faultActorElement.detachNode();
367: this .faultActorElement = createSOAPFaultElement(getFaultActorName());
368: this .faultActorElement.addTextNode(uri);
369: if (hasDetail()) {
370: insertBefore(this .faultActorElement, this .detail);
371: return;
372: }
373: addNode(this .faultActorElement);
374: }
375:
376: public String getFaultCode() {
377: if (this .faultCodeElement == null)
378: findFaultCodeElement();
379: Iterator codeValues = this .faultCodeElement
380: .getChildElements(valueName);
381: return ((SOAPElement) codeValues.next()).getValue();
382: }
383:
384: public QName getFaultCodeAsQName() {
385: String faultcode = getFaultCode();
386: if (faultcode == null) {
387: return null;
388: }
389: if (this .faultCodeElement == null)
390: findFaultCodeElement();
391: Iterator valueElements = this .faultCodeElement
392: .getChildElements(valueName);
393: return convertCodeToQName(faultcode,
394: (SOAPElement) valueElements.next());
395: }
396:
397: public Name getFaultCodeAsName() {
398: String faultcode = getFaultCode();
399: if (faultcode == null) {
400: return null;
401: }
402: if (this .faultCodeElement == null)
403: findFaultCodeElement();
404: Iterator valueElements = this .faultCodeElement
405: .getChildElements(valueName);
406: return NameImpl.convertToName(convertCodeToQName(faultcode,
407: (SOAPElement) valueElements.next()));
408: }
409:
410: public String getFaultString() {
411: String reason = null;
412: try {
413: //reason = getFaultReasonText(Locale.getDefault());
414: //if (reason == null)
415: reason = (String) getFaultReasonTexts().next();
416: } catch (SOAPException e) {
417: }
418: return reason;
419: }
420:
421: public void setFaultString(String faultString) throws SOAPException {
422: addFaultReasonText(faultString, Locale.getDefault());
423: }
424:
425: public void setFaultString(String faultString, Locale locale)
426: throws SOAPException {
427: addFaultReasonText(faultString, locale);
428: }
429:
430: public void appendFaultSubcode(QName subcode) throws SOAPException {
431: if (subcode == null) {
432: return;
433: }
434: if (subcode.getNamespaceURI() == null
435: || "".equals(subcode.getNamespaceURI())) {
436:
437: log.severe("SAAJ0432.ver1_2.subcode.not.ns.qualified");
438: throw new SOAPExceptionImpl(
439: "A Subcode must be namespace-qualified");
440: }
441: if (innermostSubCodeElement == null) {
442: if (faultCodeElement == null)
443: findFaultCodeElement();
444: innermostSubCodeElement = faultCodeElement;
445: }
446: String prefix = null;
447: if (subcode.getPrefix() == null
448: || "".equals(subcode.getPrefix())) {
449: prefix = ((ElementImpl) innermostSubCodeElement)
450: .getNamespacePrefix(subcode.getNamespaceURI());
451: } else
452: prefix = subcode.getPrefix();
453: if (prefix == null || "".equals(prefix)) {
454: prefix = "ns1";
455: }
456: innermostSubCodeElement = innermostSubCodeElement
457: .addChildElement(subcodeName);
458: SOAPElement subcodeValueElement = innermostSubCodeElement
459: .addChildElement(valueName);
460: ((ElementImpl) subcodeValueElement).ensureNamespaceIsDeclared(
461: prefix, subcode.getNamespaceURI());
462: subcodeValueElement.addTextNode(prefix + ":"
463: + subcode.getLocalPart());
464: }
465:
466: public void removeAllFaultSubcodes() {
467: if (this .faultCodeElement == null)
468: findFaultCodeElement();
469: Iterator subcodeElements = this .faultCodeElement
470: .getChildElements(subcodeName);
471: if (subcodeElements.hasNext()) {
472: SOAPElement subcode = (SOAPElement) subcodeElements.next();
473: subcode.detachNode();
474: }
475: }
476:
477: public Iterator getFaultSubcodes() {
478: if (this .faultCodeElement == null)
479: findFaultCodeElement();
480: final List subcodeList = new ArrayList();
481: SOAPElement currentCodeElement = this .faultCodeElement;
482: Iterator subcodeElements = currentCodeElement
483: .getChildElements(subcodeName);
484: while (subcodeElements.hasNext()) {
485: currentCodeElement = (ElementImpl) subcodeElements.next();
486: Iterator valueElements = currentCodeElement
487: .getChildElements(valueName);
488: SOAPElement valueElement = (SOAPElement) valueElements
489: .next();
490: String code = valueElement.getValue();
491: subcodeList.add(convertCodeToQName(code, valueElement));
492: subcodeElements = currentCodeElement
493: .getChildElements(subcodeName);
494: }
495: //return subcodeList.iterator();
496: return new Iterator() {
497: Iterator subCodeIter = subcodeList.iterator();
498:
499: public boolean hasNext() {
500: return subCodeIter.hasNext();
501: }
502:
503: public Object next() {
504: return subCodeIter.next();
505: }
506:
507: public void remove() {
508: throw new UnsupportedOperationException(
509: "Method remove() not supported on SubCodes Iterator");
510: }
511: };
512: }
513:
514: private static Locale getLocale(SOAPElement reasonText) {
515: return xmlLangToLocale(reasonText
516: .getAttributeValue(getXmlLangName()));
517: }
518:
519: /*
520: * Override setEncodingStyle of ElementImpl to restrict adding encodingStyle
521: * attribute to SOAP Fault (SOAP 1.2 spec, part 1, section 5.1.1)
522: */
523: public void setEncodingStyle(String encodingStyle)
524: throws SOAPException {
525: log.severe("SAAJ0407.ver1_2.no.encodingStyle.in.fault");
526: throw new SOAPExceptionImpl(
527: "encodingStyle attribute cannot appear on Fault");
528: }
529:
530: public SOAPElement addAttribute(Name name, String value)
531: throws SOAPException {
532: if (name.getLocalName().equals("encodingStyle")
533: && name.getURI().equals(NameImpl.SOAP12_NAMESPACE)) {
534: setEncodingStyle(value);
535: }
536: return super .addAttribute(name, value);
537: }
538:
539: public SOAPElement addAttribute(QName name, String value)
540: throws SOAPException {
541: if (name.getLocalPart().equals("encodingStyle")
542: && name.getNamespaceURI().equals(
543: NameImpl.SOAP12_NAMESPACE)) {
544: setEncodingStyle(value);
545: }
546: return super .addAttribute(name, value);
547: }
548:
549: public SOAPElement addTextNode(String text) throws SOAPException {
550: log.log(Level.SEVERE, "SAAJ0416.ver1_2.adding.text.not.legal",
551: getElementQName());
552: throw new SOAPExceptionImpl(
553: "Adding text to SOAP 1.2 Fault is not legal");
554: }
555:
556: public SOAPElement addChildElement(SOAPElement element)
557: throws SOAPException {
558: String localName = element.getLocalName();
559: if ("Detail".equalsIgnoreCase(localName)) {
560: if (hasDetail()) {
561: log.severe("SAAJ0436.ver1_2.detail.exists.error");
562: throw new SOAPExceptionImpl(
563: "Cannot add Detail, Detail already exists");
564: }
565: String uri = element.getElementQName().getNamespaceURI();
566: if (!uri.equals(SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE)) {
567: log.severe("SAAJ0437.ver1_2.version.mismatch.error");
568: throw new SOAPExceptionImpl(
569: "Cannot add Detail, Incorrect SOAP version specified for Detail element");
570: }
571: }
572: if (element instanceof Detail1_2Impl) {
573: ElementImpl importedElement = (ElementImpl) importElement(element);
574: addNode(importedElement);
575: return convertToSoapElement(importedElement);
576: } else
577: return super .addChildElement(element);
578: }
579:
580: protected boolean isStandardFaultElement(String localName) {
581: if (localName.equalsIgnoreCase("code")
582: || localName.equalsIgnoreCase("reason")
583: || localName.equalsIgnoreCase("node")
584: || localName.equalsIgnoreCase("role")
585: || localName.equalsIgnoreCase("detail")) {
586: return true;
587: }
588: return false;
589: }
590:
591: protected QName getDefaultFaultCode() {
592: return SOAPConstants.SOAP_SENDER_FAULT;
593: }
594:
595: protected FaultElementImpl createSOAPFaultElement(QName qname) {
596: return new FaultElement1_2Impl(
597: ((SOAPDocument) getOwnerDocument()).getDocument(),
598: qname);
599: }
600:
601: protected FaultElementImpl createSOAPFaultElement(Name qname) {
602: return new FaultElement1_2Impl(
603: ((SOAPDocument) getOwnerDocument()).getDocument(),
604: (NameImpl) qname);
605: }
606:
607: }
|