/** * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * https://opensso.dev.java.net/public/CDDLv1.0.html or * opensso/legal/CDDLv1.0.txt * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at opensso/legal/CDDLv1.0.txt. * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * $Id: SOAPFaultDetail.java,v 1.2 2008/06/25 05:47:23 qcheng Exp $ * */ package com.sun.identity.liberty.ws.soapbinding; import java.lang.Object; import java.io.InputStream; import java.io.ByteArrayOutputStream; import java.io.StringReader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.security.cert.X509Certificate; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.soap.SOAPMessage; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.namespace.QName; import javax.xml.transform.stream.StreamSource; import com.sun.identity.saml.common.SAMLConstants; import com.sun.identity.saml.common.SAMLException; import com.sun.identity.saml.common.SAMLUtils; import com.sun.identity.shared.xml.XMLUtils; /** * The SOAPFaultDetail class represents the 'Detail' child element * of SOAP Fault element. Its children can be of any type. This class provides * specific methods to get and set the following children: Status element, * CorrelationHeader, ProviderHeader, * ConsentHeader, UsageDirectiveHeader and * ProcessingContextHeader. It also provides generic methods to * get and set other children. * * @supported.all.api */ public class SOAPFaultDetail { public static final QName BOGUS_ACTOR = new QName(SOAPBindingConstants.NS_SOAP_BINDING, "BogusActor"); public static final QName BOGUS_MUST_UNSTND = new QName(SOAPBindingConstants.NS_SOAP_BINDING, "BogusMustUnstnd"); public static final QName STALE_MSG = new QName(SOAPBindingConstants.NS_SOAP_BINDING, "StaleMsg"); public static final QName DUPLICATE_MSG = new QName(SOAPBindingConstants.NS_SOAP_BINDING, "DuplicateMsg"); public static final QName INVALID_REF_TO_MSG_ID = new QName(SOAPBindingConstants.NS_SOAP_BINDING, "invalidRefToMsgID"); public static final QName PROVIDER_ID_NOT_VALID = new QName(SOAPBindingConstants.NS_SOAP_BINDING, "ProviderIDNotValid"); public static final QName AFFILIATION_ID_NOT_VALID = new QName(SOAPBindingConstants.NS_SOAP_BINDING, "AffiliationIDNotValid"); public static final QName ID_STAR_MSG_NOT_UNSTD = new QName(SOAPBindingConstants.NS_SOAP_BINDING, "IDStarMsgNotUnstd"); public static final QName PROC_CTX_URI_NOT_UNSTD = new QName(SOAPBindingConstants.NS_SOAP_BINDING, "ProcCtxURINotUnstd"); public static final QName PROC_CTX_UNWILLING = new QName(SOAPBindingConstants.NS_SOAP_BINDING, "ProcCtxUnwilling"); public static final QName CAN_NOT_HONOUR_USAGE_DIRECTIVE = new QName(SOAPBindingConstants.NS_SOAP_BINDING, "CannotHonourUsageDirective"); public static final QName ENDPOINT_MOVED = new QName(SOAPBindingConstants.NS_SOAP_BINDING_11, "EndpointMoved"); public static final QName INAPPROPRIATE_CREDENTIALS = new QName(SOAPBindingConstants.NS_SOAP_BINDING_11, "InappropriateCredentials"); private QName statusCode = null; private String statusRef = null; private String statusComment = null; private CorrelationHeader correlationHeader = null; private ConsentHeader consentHeader = null; private List usageDirectiveHeaders = null; private ProviderHeader providerHeader = null; private ProcessingContextHeader processingContextHeader = null; private ServiceInstanceUpdateHeader serviceInstanceUpdateHeader = null; private List otherChildren = null; /** * This constructor takes a status code, a status ref and a status comment. * If the status code is not null, a Status child element will be created. * * @param statusCode the value of code attribute of the Status * element. * @param statusRef the value of ref attribute of the Status * element. * @param statusComment the value of comment attribute of the * Status element. */ public SOAPFaultDetail(QName statusCode,String statusRef, String statusComment) { this.statusCode = statusCode; this.statusRef = statusRef; this.statusComment = statusComment; } /** * This constructor takes a list of children except Status element, * CorrelationHeader, ProviderHeader * ConsentHeader, UsageDirectiveHeader, * ProcessingContextHeader and * ServiceInstanceUpdateHeader. * Each entry will be a org.w3c.dom.Element. * * @param otherChildren a list of children element */ public SOAPFaultDetail(List otherChildren) { this.otherChildren = otherChildren; } /** * Parses a org.w3c.dom.Document to construct this object. * * @param detailElement a org.w3c.dom.Document. * @throws SOAPBindingException if an error occurs while parsing * the document */ SOAPFaultDetail(Element detailElement) throws SOAPBindingException { NodeList nl = detailElement.getChildNodes(); int length = nl.getLength(); if (length == 0) { return; } otherChildren = new ArrayList(); for (int i = 0; i < length; i++) { Node child = nl.item(i); if (child.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element)child; String localName = element.getLocalName(); String ns = element.getNamespaceURI(); if (SOAPBindingConstants.NS_SOAP_BINDING.equals(ns)) { if (SOAPBindingConstants.TAG_STATUS.equals(localName)) { String value = XMLUtils.getNodeAttributeValue( element, SOAPBindingConstants.ATTR_CODE); if (value == null || value.length() ==0) { String msg = Utils.bundle .getString("missingFaultStatusCode"); Utils.debug.error("SOAPFaultException: " + msg); throw new SOAPBindingException(msg); } statusCode = Utils.convertStringToQName(value,element); statusRef = XMLUtils.getNodeAttributeValue( element, SOAPBindingConstants.ATTR_REF); statusComment = XMLUtils.getNodeAttributeValue( element, SOAPBindingConstants.ATTR_COMMENT); } else if (SOAPBindingConstants.TAG_CORRELATION .equals(localName)) { correlationHeader = new CorrelationHeader(element); } else if (SOAPBindingConstants.TAG_CONSENT .equals(localName)) { consentHeader = new ConsentHeader(element); } else if(SOAPBindingConstants.TAG_USAGE_DIRECTIVE .equals(localName)){ if (usageDirectiveHeaders == null) { usageDirectiveHeaders = new ArrayList(); } usageDirectiveHeaders.add( new UsageDirectiveHeader(element)); } else if (SOAPBindingConstants.TAG_PROVIDER .equals(localName)) { providerHeader = new ProviderHeader(element); } else if (SOAPBindingConstants.TAG_PROCESSING_CONTEXT .equals(localName)){ processingContextHeader = new ProcessingContextHeader(element); } else { otherChildren.add(element); } } else if (SOAPBindingConstants.NS_SOAP_BINDING_11.equals(ns)&& SOAPBindingConstants.TAG_SERVICE_INSTANCE_UPDATE .equals(localName)){ serviceInstanceUpdateHeader = new ServiceInstanceUpdateHeader(element); } else { otherChildren.add(element); } } } if (otherChildren.isEmpty()) { otherChildren = null; } } /** * Returns the CorrelationHeader. * * @return the CorrelationHeader. */ public CorrelationHeader getCorrelationHeader() { return correlationHeader; } /** * Returns the ConsentHeader. * * @return the ConsentHeader. */ public ConsentHeader getConsentHeader() { return consentHeader; } /** * Returns a list of UsageDirectiveHeader. * * @return a list of UsageDirectiveHeader. */ public List getUsageDirectiveHeaders() { return usageDirectiveHeaders; } /** * Returns the ProviderHeader. * * @return the ProviderHeader. */ public ProviderHeader getProviderHeader() { return providerHeader; } /** * Returns ProcessingContextHeader. * * @return ProcessingContextHeader. */ public ProcessingContextHeader getProcessingContextHeader() { return processingContextHeader; } /** * Returns ServiceInstanceUpdateHeader. * * @return ServiceInstanceUpdateHeader. */ public ServiceInstanceUpdateHeader getServiceInstanceUpdateHeader() { return serviceInstanceUpdateHeader; } /** * Returns a list of children except Status element, * CorrelationHeader, ProviderHeader * ConsentHeader, UsageDirectiveHeader, * ProcessingContextHeader and * ServiceInstanceUpdateHeader. * Each entry will be a org.w3c.dom.Element. * * @return a list of children element */ public List getOtherChildren() { return otherChildren; } /** * Returns value of code attribute of Status element. * * @return value of code attribute of Status element. */ public QName getStatusCode() { return statusCode; } /** * Returns value of ref attribute of Status element. * * @return value of ref attribute of Status element. */ public String getStatusRef() { return statusRef; } /** * Returns value of comment attribute of Status element. * * @return value of comment attribute of Status element. */ public String getStatusComment() { return statusComment; } /** * Sets the value of CorrelationHeader. * * @param correlationHeader the CorrelationHeader. */ public void setCorrelationHeader(CorrelationHeader correlationHeader) { if (correlationHeader != null) { this.correlationHeader = correlationHeader; } } /** * Sets ConsentHeader. * * @param consentHeader ConsentHeader. */ public void setConsentHeader(ConsentHeader consentHeader) { this.consentHeader = consentHeader; } /** * Sets a list of UsageDirectiveHeader. * * @param usageDirectiveHeaders a list of UsageDirectiveHeader. */ public void setUsageDirectiveHeaders(List usageDirectiveHeaders) { this.usageDirectiveHeaders = usageDirectiveHeaders; } /** * Sets ProviderHeader if it is not null. * * @param providerHeader ProviderHeader */ public void setProviderHeader(ProviderHeader providerHeader) { if (providerHeader != null) { this.providerHeader = providerHeader; } } /** * Sets ProcessingContextHeader. * * @param processingContextHeader ProcessingContextHeader */ public void setProcessingContextHeader( ProcessingContextHeader processingContextHeader) { this.processingContextHeader = processingContextHeader; } /** * Sets ServiceInstanceUpdateHeader. * * @param serviceInstanceUpdateHeader * ServiceInstanceUpdateHeader */ public void setServiceInstanceUpdateHeader( ServiceInstanceUpdateHeader serviceInstanceUpdateHeader) { this.serviceInstanceUpdateHeader = serviceInstanceUpdateHeader; } /** * Sets a list of children except Status element, * CorrelationHeader, ProviderHeader * ConsentHeader, UsageDirectiveHeader, * ProcessingContextHeader and * ServiceInstanceUpdateHeader. * Each entry will be a org.w3c.dom.Element. * * @param otherChildren a list of children element */ public void setOtherChildren(List otherChildren) { this.otherChildren = otherChildren; } /** * Sets a child except Status element, CorrelationHeader, * ProviderHeader, ConsentHeader, * UsageDirectiveHeader and * ProcessingContextHeader and * ServiceInstanceUpdateHeader. * * @param child the child element. */ public void setOtherChild(Element child) { otherChildren = new ArrayList(1); otherChildren.add(child); } /** * Sets value of code attribute of Status element. * * @param statusCode value of code attribute of Status element. */ public void setStatusCode(QName statusCode) { this.statusCode = statusCode; } /** * Sets value of ref attribute of Status element. * * @param statusRef value of ref attribute of Status element. */ public void setStatusRef(String statusRef) { this.statusRef = statusRef; } /** * Sets value of comment attribute of Status element. * * @param statusComment value of comment attribute in Status * element. */ public void setStatusComment(String statusComment) { this.statusComment = statusComment; } /** * Converts this header to org.w3c.dom.Element and add to * parent Fault Element. * * @param faultE the Fault Element object. */ void addToParent(Element faultE) { Document doc = faultE.getOwnerDocument(); Element detailE = doc.createElement(SOAPBindingConstants.TAG_DETAIL); faultE.appendChild(detailE); if (statusCode != null) { Element statusE = doc.createElementNS( SOAPBindingConstants.NS_SOAP_BINDING, SOAPBindingConstants.PTAG_STATUS); String localPart = statusCode.getLocalPart(); String ns = statusCode.getNamespaceURI(); if (ns != null && ns.length() > 0) { String prefix; if (ns.equals(SOAPBindingConstants.NS_SOAP)) { prefix = SOAPBindingConstants.PREFIX_SOAP; } else if (ns.equals(SOAPBindingConstants.NS_SOAP_BINDING)) { prefix = SOAPBindingConstants.PREFIX_SOAP_BINDING; } else if (ns.equals(SOAPBindingConstants.NS_SOAP_BINDING_11)){ prefix = SOAPBindingConstants.PREFIX_SOAP_BINDING_11; } else { prefix = SOAPBindingConstants.DEFAULT_PREFIX_FAULT_CODE_VALUE; statusE.setAttributeNS(SOAPBindingConstants.NS_XML, "xmlns:" + prefix, ns); } statusE.setAttributeNS(null, SOAPBindingConstants.ATTR_CODE, prefix +":" +localPart); } else { statusE.setAttributeNS(null, SOAPBindingConstants.ATTR_CODE, localPart); } if (statusRef != null) { statusE.setAttributeNS(null, SOAPBindingConstants.ATTR_REF, statusRef); } if (statusComment != null) { statusE.setAttributeNS(null, SOAPBindingConstants.ATTR_COMMENT, statusComment); } detailE.appendChild(statusE); } if (correlationHeader != null) { correlationHeader.addToParent(detailE); } if (consentHeader != null) { consentHeader.addToParent(detailE); } if (usageDirectiveHeaders != null && !usageDirectiveHeaders.isEmpty()) { Iterator iter = usageDirectiveHeaders.iterator(); while(iter.hasNext()) { ((UsageDirectiveHeader)iter.next()).addToParent(detailE); } } if (providerHeader != null) { providerHeader.addToParent(detailE); } if (processingContextHeader != null) { processingContextHeader.addToParent(detailE); } if (serviceInstanceUpdateHeader != null) { serviceInstanceUpdateHeader.addToParent(detailE); } if (otherChildren != null && !otherChildren.isEmpty()) { Iterator iter = otherChildren.iterator(); while(iter.hasNext()) { Element childE = (Element)iter.next(); detailE.appendChild(doc.importNode(childE, true)); } } } }