001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: SOAPFaultDetail.java,v 1.2 2008/06/25 05:47:23 qcheng Exp $
026 *
027 */
028
029
030package com.sun.identity.liberty.ws.soapbinding; 
031
032import java.lang.Object;
033
034import java.io.InputStream;
035import java.io.ByteArrayOutputStream;
036import java.io.StringReader;
037
038import java.util.ArrayList;
039import java.util.Iterator;
040import java.util.List;
041
042import java.security.cert.X509Certificate;
043
044import org.w3c.dom.Document;
045import org.w3c.dom.Element;
046import org.w3c.dom.Node;
047import org.w3c.dom.NodeList;
048
049import javax.xml.soap.SOAPMessage;
050import javax.xml.bind.JAXBContext;
051import javax.xml.bind.JAXBException;
052import javax.xml.bind.Marshaller;
053import javax.xml.bind.Unmarshaller;
054import javax.xml.namespace.QName;
055import javax.xml.transform.stream.StreamSource;
056
057import com.sun.identity.saml.common.SAMLConstants;
058import com.sun.identity.saml.common.SAMLException;
059import com.sun.identity.saml.common.SAMLUtils;
060
061import com.sun.identity.shared.xml.XMLUtils;
062
063/**
064 * The <code>SOAPFaultDetail</code> class represents the 'Detail' child element
065 * of SOAP Fault element. Its children can be of any type. This class provides
066 * specific methods to get and set the following children: Status element,
067 * <code>CorrelationHeader</code>, <code>ProviderHeader</code>,
068 * <code>ConsentHeader</code>, <code>UsageDirectiveHeader</code> and
069 * <code>ProcessingContextHeader</code>. It also provides generic methods to
070 * get and set other children.
071 *
072 * @supported.all.api
073 */
074public class SOAPFaultDetail {
075    public static final QName BOGUS_ACTOR =
076              new QName(SOAPBindingConstants.NS_SOAP_BINDING, "BogusActor");
077    public static final QName BOGUS_MUST_UNSTND =
078              new QName(SOAPBindingConstants.NS_SOAP_BINDING,
079                        "BogusMustUnstnd");
080    public static final QName STALE_MSG =
081              new QName(SOAPBindingConstants.NS_SOAP_BINDING, "StaleMsg");
082    public static final QName DUPLICATE_MSG =
083              new QName(SOAPBindingConstants.NS_SOAP_BINDING, "DuplicateMsg");
084    public static final QName INVALID_REF_TO_MSG_ID =
085              new QName(SOAPBindingConstants.NS_SOAP_BINDING,
086                        "invalidRefToMsgID");
087    public static final QName PROVIDER_ID_NOT_VALID =
088              new QName(SOAPBindingConstants.NS_SOAP_BINDING,
089                        "ProviderIDNotValid");
090    public static final QName AFFILIATION_ID_NOT_VALID =
091              new QName(SOAPBindingConstants.NS_SOAP_BINDING,
092                        "AffiliationIDNotValid");
093    public static final QName ID_STAR_MSG_NOT_UNSTD =
094              new QName(SOAPBindingConstants.NS_SOAP_BINDING,
095                        "IDStarMsgNotUnstd");
096    public static final QName PROC_CTX_URI_NOT_UNSTD =
097              new QName(SOAPBindingConstants.NS_SOAP_BINDING,
098                        "ProcCtxURINotUnstd");
099    public static final QName PROC_CTX_UNWILLING =
100              new QName(SOAPBindingConstants.NS_SOAP_BINDING,
101                        "ProcCtxUnwilling");
102    public static final QName CAN_NOT_HONOUR_USAGE_DIRECTIVE =
103              new QName(SOAPBindingConstants.NS_SOAP_BINDING,
104                        "CannotHonourUsageDirective");
105    public static final QName ENDPOINT_MOVED =
106              new QName(SOAPBindingConstants.NS_SOAP_BINDING_11,
107                        "EndpointMoved");
108    public static final QName INAPPROPRIATE_CREDENTIALS =
109              new QName(SOAPBindingConstants.NS_SOAP_BINDING_11,
110                        "InappropriateCredentials");
111
112    private QName  statusCode = null;
113    private String statusRef = null;
114    private String statusComment = null;
115    private CorrelationHeader correlationHeader = null;
116    private ConsentHeader consentHeader = null;
117    private List usageDirectiveHeaders = null;
118    private ProviderHeader providerHeader = null;
119    private ProcessingContextHeader processingContextHeader = null;
120    private ServiceInstanceUpdateHeader serviceInstanceUpdateHeader = null;
121    private List otherChildren = null;
122    
123    /**
124     * This constructor takes a status code, a status ref and a status comment.
125     * If the status code is not null, a Status child element will be created.
126     *
127     * @param statusCode the value of <code>code</code> attribute of the Status
128     *                   element.
129     * @param statusRef the value of <code>ref</code> attribute of the Status
130     *                  element.
131     * @param statusComment the value of <code>comment</code> attribute of the
132     *                      Status element.
133     */
134    public SOAPFaultDetail(QName statusCode,String statusRef,
135            String statusComment) {
136        this.statusCode = statusCode;
137        this.statusRef = statusRef;
138        this.statusComment = statusComment;
139    }
140
141    /**
142     * This constructor takes a list of children except Status element,
143     * <code>CorrelationHeader</code>, <code>ProviderHeader</code>
144     * <code>ConsentHeader</code>, <code>UsageDirectiveHeader</code>,
145     * <code>ProcessingContextHeader</code> and
146     * <code>ServiceInstanceUpdateHeader</code>.
147     * Each entry will be a <code>org.w3c.dom.Element</code>.
148     *
149     * @param otherChildren a list of children element
150     */
151    public SOAPFaultDetail(List otherChildren) {
152        this.otherChildren = otherChildren;
153    }
154
155    /**
156     * Parses a <code>org.w3c.dom.Document</code> to construct this object.
157     *
158     * @param detailElement a <code>org.w3c.dom.Document</code>.
159     * @throws SOAPBindingException if an error occurs while parsing
160     *                                 the document
161     */
162    SOAPFaultDetail(Element detailElement) throws SOAPBindingException {
163        NodeList nl = detailElement.getChildNodes();
164        int length = nl.getLength();
165
166        if (length == 0) {
167            return;
168        }
169
170        otherChildren = new ArrayList();
171        for (int i = 0; i < length; i++) {
172            Node child = nl.item(i);
173            if (child.getNodeType() == Node.ELEMENT_NODE) {
174                Element element = (Element)child;
175                String localName = element.getLocalName();
176                String ns = element.getNamespaceURI();
177
178                if (SOAPBindingConstants.NS_SOAP_BINDING.equals(ns)) {
179                    if (SOAPBindingConstants.TAG_STATUS.equals(localName)) {
180                        String value = XMLUtils.getNodeAttributeValue(
181                                               element,
182                                               SOAPBindingConstants.ATTR_CODE);
183                        if (value == null || value.length() ==0) {
184                            String msg = Utils.bundle
185                                          .getString("missingFaultStatusCode");
186                            Utils.debug.error("SOAPFaultException: " + msg);
187                            throw new SOAPBindingException(msg);
188                        }
189                        statusCode = Utils.convertStringToQName(value,element);
190                        statusRef = XMLUtils.getNodeAttributeValue(
191                                                element,
192                                                SOAPBindingConstants.ATTR_REF);
193                        statusComment = XMLUtils.getNodeAttributeValue(
194                                            element,
195                                            SOAPBindingConstants.ATTR_COMMENT);
196                    } else if (SOAPBindingConstants.TAG_CORRELATION
197                                                   .equals(localName)) {
198                        correlationHeader = new CorrelationHeader(element);
199                    } else if (SOAPBindingConstants.TAG_CONSENT
200                                                   .equals(localName)) {
201                        consentHeader = new ConsentHeader(element);
202                    } else if(SOAPBindingConstants.TAG_USAGE_DIRECTIVE
203                                                  .equals(localName)){
204                        if (usageDirectiveHeaders == null) {
205                            usageDirectiveHeaders = new ArrayList();
206                        }
207                        usageDirectiveHeaders.add(
208                                    new UsageDirectiveHeader(element));
209                    } else if (SOAPBindingConstants.TAG_PROVIDER
210                                                   .equals(localName)) {
211                        providerHeader = new ProviderHeader(element);
212                    } else if (SOAPBindingConstants.TAG_PROCESSING_CONTEXT
213                                                   .equals(localName)){
214                            processingContextHeader =
215                                    new ProcessingContextHeader(element);
216                    } else {
217                        otherChildren.add(element);
218                    }
219                } else if (SOAPBindingConstants.NS_SOAP_BINDING_11.equals(ns)&&
220                           SOAPBindingConstants.TAG_SERVICE_INSTANCE_UPDATE
221                                               .equals(localName)){
222                    serviceInstanceUpdateHeader =
223                                    new ServiceInstanceUpdateHeader(element);
224                } else {
225                    otherChildren.add(element);
226                }
227            }
228        }
229        if (otherChildren.isEmpty()) {
230            otherChildren = null;
231        }
232    }
233
234    /**
235     * Returns the <code>CorrelationHeader</code>.
236     *
237     * @return the <code>CorrelationHeader</code>.
238     */
239    public CorrelationHeader getCorrelationHeader() {
240        return correlationHeader;
241    }
242
243    /**
244     * Returns the <code>ConsentHeader</code>.
245     *
246     * @return the <code>ConsentHeader</code>.
247     */
248    public ConsentHeader getConsentHeader() {
249        return consentHeader;
250    }
251
252    /**
253     * Returns a list of <code>UsageDirectiveHeader</code>.
254     *
255     * @return a list of <code>UsageDirectiveHeader</code>.
256     */
257    public List getUsageDirectiveHeaders() {
258        return usageDirectiveHeaders;
259    }
260
261    /**
262     * Returns the <code>ProviderHeader</code>.
263     *
264     * @return the <code>ProviderHeader</code>.
265     */
266    public ProviderHeader getProviderHeader() {
267        return providerHeader;
268    }
269
270    /**
271     * Returns <code>ProcessingContextHeader</code>.
272     *
273     * @return <code>ProcessingContextHeader</code>.
274     */
275    public ProcessingContextHeader getProcessingContextHeader() {
276        return processingContextHeader;
277    }
278
279    /**
280     * Returns <code>ServiceInstanceUpdateHeader</code>.
281     *
282     * @return <code>ServiceInstanceUpdateHeader</code>.
283     */
284    public ServiceInstanceUpdateHeader getServiceInstanceUpdateHeader() {
285        return serviceInstanceUpdateHeader;
286    }
287
288    /**
289     * Returns a list of children except Status element,
290     * <code>CorrelationHeader</code>, <code>ProviderHeader</code>
291     * <code>ConsentHeader</code>, <code>UsageDirectiveHeader</code>,
292     * <code>ProcessingContextHeader</code> and
293     * <code>ServiceInstanceUpdateHeader</code>.
294     * Each entry will be a <code>org.w3c.dom.Element</code>.
295     *
296     * @return a list of children element
297     */
298    public List getOtherChildren() {
299        return otherChildren;
300    }
301
302    /**
303     * Returns value of <code>code</code> attribute of Status element.
304     *
305     * @return value of <code>code</code> attribute of Status element.
306     */
307    public QName getStatusCode() {
308        return statusCode;
309    }
310
311    /**
312     * Returns value of <code>ref</code> attribute of Status element.
313     *
314     * @return value of <code>ref</code> attribute of Status element.
315     */
316    public String getStatusRef() {
317        return statusRef;
318    }
319
320    /**
321     * Returns value of <code>comment</code> attribute of Status element.
322     *
323     * @return value of <code>comment</code> attribute of Status element.
324     */
325    public String getStatusComment() {
326        return statusComment;
327    }
328
329    /**
330     * Sets the value of <code>CorrelationHeader</code>.
331     *
332     * @param correlationHeader the <code>CorrelationHeader</code>.
333     */
334    public void setCorrelationHeader(CorrelationHeader correlationHeader) {
335        if (correlationHeader != null) {
336            this.correlationHeader = correlationHeader;
337        }
338    }
339
340    /**
341     * Sets <code>ConsentHeader</code>.
342     *
343     * @param consentHeader <code>ConsentHeader</code>.
344     */
345    public void setConsentHeader(ConsentHeader consentHeader) {
346        this.consentHeader = consentHeader;
347    }
348    
349    /**
350     * Sets a list of <code>UsageDirectiveHeader</code>.
351     *
352     * @param usageDirectiveHeaders a list of <code>UsageDirectiveHeader</code>.
353     */
354    public void setUsageDirectiveHeaders(List usageDirectiveHeaders) {
355        this.usageDirectiveHeaders = usageDirectiveHeaders;
356    }
357    
358    /**
359     * Sets <code>ProviderHeader</code> if it is not null.
360     *
361     * @param providerHeader <code>ProviderHeader</code>
362     */
363    public void setProviderHeader(ProviderHeader providerHeader) {
364        if (providerHeader != null) {
365            this.providerHeader = providerHeader;
366        }
367    }
368    
369    /**
370     * Sets <code>ProcessingContextHeader</code>.
371     *
372     * @param processingContextHeader <code>ProcessingContextHeader</code>
373     */
374    public void setProcessingContextHeader( 
375            ProcessingContextHeader processingContextHeader) {
376        this.processingContextHeader = processingContextHeader;
377    }
378
379    /**
380     * Sets <code>ServiceInstanceUpdateHeader</code>.
381     *
382     * @param serviceInstanceUpdateHeader
383     *        <code>ServiceInstanceUpdateHeader</code>
384     */
385    public void setServiceInstanceUpdateHeader(
386        ServiceInstanceUpdateHeader serviceInstanceUpdateHeader) {
387        this.serviceInstanceUpdateHeader = serviceInstanceUpdateHeader;
388    }
389
390    /**
391     * Sets a list of children except Status element,
392     * <code>CorrelationHeader</code>, <code>ProviderHeader</code>
393     * <code>ConsentHeader</code>, <code>UsageDirectiveHeader</code>,
394     * <code>ProcessingContextHeader</code> and
395     * <code>ServiceInstanceUpdateHeader</code>.
396     * Each entry will be a <code>org.w3c.dom.Element</code>.
397     *
398     * @param otherChildren a list of children element
399     */
400    public void setOtherChildren(List otherChildren) {
401        this.otherChildren = otherChildren;
402    }
403
404    /**
405     * Sets a child except Status element, <code>CorrelationHeader</code>,
406     * <code>ProviderHeader</code>, <code>ConsentHeader</code>,
407     * <code>UsageDirectiveHeader</code> and
408     * <code>ProcessingContextHeader</code> and
409     * <code>ServiceInstanceUpdateHeader</code>.
410     *
411     * @param child the child element.
412     */
413    public void setOtherChild(Element child) {
414        otherChildren = new ArrayList(1);
415        otherChildren.add(child);
416    }
417
418    /**
419     * Sets value of <code>code</code> attribute of Status element.
420     *
421     * @param statusCode value of <code>code</code> attribute of Status element.
422     */
423    public void setStatusCode(QName statusCode) {
424        this.statusCode = statusCode;
425    }
426
427    /**
428     * Sets value of <code>ref</code> attribute of Status element.
429     *
430     * @param statusRef value of <code>ref</code> attribute of Status element.
431     */
432    public void setStatusRef(String statusRef) {
433        this.statusRef = statusRef;
434    }
435
436    /**
437     * Sets value of <code>comment</code> attribute of Status element.
438     *
439     * @param statusComment value of <code>comment</code> attribute in Status 
440     *        element.
441     */
442    public void setStatusComment(String statusComment) {
443        this.statusComment = statusComment;
444    }
445
446    /**
447     * Converts this header to <code>org.w3c.dom.Element</code> and add to
448     * parent Fault Element.
449     *
450     * @param faultE the Fault Element object.
451     */
452    void addToParent(Element faultE) {
453        Document doc = faultE.getOwnerDocument();
454        Element detailE = doc.createElement(SOAPBindingConstants.TAG_DETAIL);
455        faultE.appendChild(detailE);
456
457        if (statusCode != null) {
458            Element statusE = doc.createElementNS(
459                                          SOAPBindingConstants.NS_SOAP_BINDING,
460                                          SOAPBindingConstants.PTAG_STATUS);
461            String localPart = statusCode.getLocalPart();
462            String ns = statusCode.getNamespaceURI();
463            if (ns != null && ns.length() > 0) {
464                String prefix;
465                if (ns.equals(SOAPBindingConstants.NS_SOAP)) {
466                    prefix = SOAPBindingConstants.PREFIX_SOAP;
467                } else if (ns.equals(SOAPBindingConstants.NS_SOAP_BINDING)) {
468                    prefix = SOAPBindingConstants.PREFIX_SOAP_BINDING;
469                } else if (ns.equals(SOAPBindingConstants.NS_SOAP_BINDING_11)){
470                    prefix = SOAPBindingConstants.PREFIX_SOAP_BINDING_11;
471                } else {
472                    prefix =
473                        SOAPBindingConstants.DEFAULT_PREFIX_FAULT_CODE_VALUE;
474                    statusE.setAttributeNS(SOAPBindingConstants.NS_XML,
475                                           "xmlns:" + prefix, ns);
476                }
477                statusE.setAttributeNS(null, SOAPBindingConstants.ATTR_CODE,
478                                       prefix +":" +localPart);
479            } else {
480                statusE.setAttributeNS(null, SOAPBindingConstants.ATTR_CODE,
481                                       localPart);
482            }
483
484            if (statusRef != null) {
485                statusE.setAttributeNS(null, SOAPBindingConstants.ATTR_REF,
486                                       statusRef);
487            }
488            if (statusComment != null) {
489                statusE.setAttributeNS(null, SOAPBindingConstants.ATTR_COMMENT,
490                                       statusComment);
491            }
492            detailE.appendChild(statusE);
493        }
494        if (correlationHeader != null) {
495            correlationHeader.addToParent(detailE);
496        }
497        if (consentHeader != null) {
498            consentHeader.addToParent(detailE);
499        }
500        if (usageDirectiveHeaders != null &&
501            !usageDirectiveHeaders.isEmpty()) {
502            Iterator iter = usageDirectiveHeaders.iterator();
503            while(iter.hasNext()) {
504                ((UsageDirectiveHeader)iter.next()).addToParent(detailE);
505            }
506        }
507        if (providerHeader != null) {
508            providerHeader.addToParent(detailE);
509        }
510        if (processingContextHeader != null) {
511            processingContextHeader.addToParent(detailE);
512        }
513        if (serviceInstanceUpdateHeader != null) {
514            serviceInstanceUpdateHeader.addToParent(detailE);
515        }
516
517        if (otherChildren != null && !otherChildren.isEmpty()) {
518            Iterator iter = otherChildren.iterator();
519            while(iter.hasNext()) {
520                Element childE = (Element)iter.next();
521                detailE.appendChild(doc.importNode(childE, true));
522            }
523        }
524    }
525}




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.