1 /*
2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.xml.internal.ws.message;
27 
28 import com.sun.istack.internal.NotNull;
29 import com.sun.istack.internal.Nullable;
30 import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer;
31 import com.sun.xml.internal.ws.api.SOAPVersion;
32 import com.sun.xml.internal.ws.api.message.Header;
33 import org.xml.sax.ContentHandler;
34 import org.xml.sax.ErrorHandler;
35 import org.xml.sax.SAXException;
36 import org.xml.sax.helpers.AttributesImpl;
37 
38 import javax.xml.namespace.QName;
39 import javax.xml.soap.SOAPException;
40 import javax.xml.soap.SOAPHeader;
41 import javax.xml.soap.SOAPHeaderElement;
42 import javax.xml.soap.SOAPMessage;
43 import javax.xml.stream.XMLStreamException;
44 import javax.xml.stream.XMLStreamReader;
45 import javax.xml.stream.XMLStreamWriter;
46 
47 /**
48  * {@link Header} that has a single text value in it
49  * (IOW, of the form <foo>text</foo>.)
50  *
51  * @author Rama Pulavarthi
52  * @author Arun Gupta
53  */
54 public class StringHeader extends AbstractHeaderImpl {
55     /**
56      * Tag name.
57      */
58     protected final QName name;
59     /**
60      * Header value.
61      */
62     protected final String value;
63 
64     protected boolean mustUnderstand = false;
65     protected SOAPVersion soapVersion;
66 
StringHeader(@otNull QName name, @NotNull String value)67     public StringHeader(@NotNull QName name, @NotNull String value) {
68         assert name != null;
69         assert value != null;
70         this.name = name;
71         this.value = value;
72     }
73 
StringHeader(@otNull QName name, @NotNull String value, @NotNull SOAPVersion soapVersion, boolean mustUnderstand )74     public StringHeader(@NotNull QName name, @NotNull String value, @NotNull SOAPVersion soapVersion, boolean mustUnderstand ) {
75         this.name = name;
76         this.value = value;
77         this.soapVersion = soapVersion;
78         this.mustUnderstand = mustUnderstand;
79     }
80 
getNamespaceURI()81     public @NotNull String getNamespaceURI() {
82         return name.getNamespaceURI();
83     }
84 
getLocalPart()85     public @NotNull String getLocalPart() {
86         return name.getLocalPart();
87     }
88 
getAttribute(@otNull String nsUri, @NotNull String localName)89     @Nullable public String getAttribute(@NotNull String nsUri, @NotNull String localName) {
90         if(mustUnderstand && soapVersion.nsUri.equals(nsUri) && MUST_UNDERSTAND.equals(localName)) {
91             return getMustUnderstandLiteral(soapVersion);
92         }
93         return null;
94     }
95 
readHeader()96     public XMLStreamReader readHeader() throws XMLStreamException {
97         MutableXMLStreamBuffer buf = new MutableXMLStreamBuffer();
98         XMLStreamWriter w = buf.createFromXMLStreamWriter();
99         writeTo(w);
100         return buf.readAsXMLStreamReader();
101     }
102 
writeTo(XMLStreamWriter w)103     public void writeTo(XMLStreamWriter w) throws XMLStreamException {
104         w.writeStartElement("", name.getLocalPart(), name.getNamespaceURI());
105         w.writeDefaultNamespace(name.getNamespaceURI());
106         if (mustUnderstand) {
107             //Writing the ns declaration conditionally checking in the NSContext breaks XWSS. as readHeader() adds ns declaration,
108             // where as writing alonf with the soap envelope does n't add it.
109             //Looks like they expect the readHeader() and writeTo() produce the same infoset, Need to understand their usage
110 
111             //if(w.getNamespaceContext().getPrefix(soapVersion.nsUri) == null) {
112             w.writeNamespace("S", soapVersion.nsUri);
113             w.writeAttribute("S", soapVersion.nsUri, MUST_UNDERSTAND, getMustUnderstandLiteral(soapVersion));
114             // } else {
115             // w.writeAttribute(soapVersion.nsUri,MUST_UNDERSTAND, getMustUnderstandLiteral(soapVersion));
116             // }
117         }
118         w.writeCharacters(value);
119         w.writeEndElement();
120     }
121 
writeTo(SOAPMessage saaj)122     public void writeTo(SOAPMessage saaj) throws SOAPException {
123         SOAPHeader header = saaj.getSOAPHeader();
124         if(header == null)
125             header = saaj.getSOAPPart().getEnvelope().addHeader();
126         SOAPHeaderElement she = header.addHeaderElement(name);
127         if(mustUnderstand) {
128             she.setMustUnderstand(true);
129         }
130         she.addTextNode(value);
131     }
132 
writeTo(ContentHandler h, ErrorHandler errorHandler)133     public void writeTo(ContentHandler h, ErrorHandler errorHandler) throws SAXException {
134         String nsUri = name.getNamespaceURI();
135         String ln = name.getLocalPart();
136 
137         h.startPrefixMapping("",nsUri);
138         if(mustUnderstand) {
139             AttributesImpl attributes = new AttributesImpl();
140             attributes.addAttribute(soapVersion.nsUri,MUST_UNDERSTAND,"S:"+MUST_UNDERSTAND,"CDATA", getMustUnderstandLiteral(soapVersion));
141             h.startElement(nsUri,ln,ln,attributes);
142         } else {
143             h.startElement(nsUri,ln,ln,EMPTY_ATTS);
144         }
145         h.characters(value.toCharArray(),0,value.length());
146         h.endElement(nsUri,ln,ln);
147     }
148 
getMustUnderstandLiteral(SOAPVersion sv)149     private static String getMustUnderstandLiteral(SOAPVersion sv) {
150         if(sv == SOAPVersion.SOAP_12) {
151             return S12_MUST_UNDERSTAND_TRUE;
152         } else {
153             return S11_MUST_UNDERSTAND_TRUE;
154         }
155 
156     }
157 
158     protected static final String MUST_UNDERSTAND = "mustUnderstand";
159     protected static final String S12_MUST_UNDERSTAND_TRUE ="true";
160     protected static final String S11_MUST_UNDERSTAND_TRUE ="1";
161 }
162