Tue, 09 Apr 2013 14:51:13 +0100
8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com
1 /*
2 * Copyright (c) 1997, 2013, 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 */
26 package com.sun.xml.internal.ws.message.stream;
28 import com.sun.istack.internal.FinalArrayList;
29 import com.sun.istack.internal.NotNull;
30 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
31 import com.sun.xml.internal.stream.buffer.XMLStreamBufferSource;
32 import com.sun.xml.internal.ws.api.SOAPVersion;
33 import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
34 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
35 import com.sun.xml.internal.ws.api.message.Header;
36 import com.sun.xml.internal.ws.message.AbstractHeaderImpl;
37 import com.sun.xml.internal.ws.util.xml.XmlUtil;
38 import org.w3c.dom.Node;
39 import org.xml.sax.ContentHandler;
40 import org.xml.sax.ErrorHandler;
41 import org.xml.sax.SAXException;
43 import javax.xml.soap.SOAPException;
44 import javax.xml.soap.SOAPHeader;
45 import javax.xml.soap.SOAPMessage;
46 import javax.xml.stream.XMLStreamException;
47 import javax.xml.stream.XMLStreamReader;
48 import javax.xml.stream.XMLStreamWriter;
49 import javax.xml.transform.Transformer;
50 import javax.xml.transform.TransformerFactory;
51 import javax.xml.transform.dom.DOMResult;
52 import java.util.List;
53 import java.util.Set;
55 /**
56 * {@link Header} whose physical data representation is an XMLStreamBuffer.
57 *
58 * @author Paul.Sandoz@Sun.Com
59 */
60 public abstract class StreamHeader extends AbstractHeaderImpl {
61 protected final XMLStreamBuffer _mark;
63 protected boolean _isMustUnderstand;
65 /**
66 * Role or actor value.
67 */
68 protected @NotNull String _role;
70 protected boolean _isRelay;
72 protected String _localName;
74 protected String _namespaceURI;
76 /**
77 * Keep the information about an attribute on the header element.
78 *
79 * TODO: this whole attribute handling could be done better, I think.
80 */
81 protected static final class Attribute {
82 /**
83 * Can be empty but never null.
84 */
85 final String nsUri;
86 final String localName;
87 final String value;
89 public Attribute(String nsUri, String localName, String value) {
90 this.nsUri = fixNull(nsUri);
91 this.localName = localName;
92 this.value = value;
93 }
94 }
96 /**
97 * The attributes on the header element.
98 * We expect there to be only a small number of them,
99 * so the use of {@link List} would be justified.
100 *
101 * Null if no attribute is present.
102 */
103 private final FinalArrayList<Attribute> attributes;
105 /**
106 * Creates a {@link StreamHeader}.
107 *
108 * @param reader
109 * The parser pointing at the start of the mark.
110 * Technically this information is redundant,
111 * but it achieves a better performance.
112 * @param mark
113 * The start of the buffered header content.
114 */
115 protected StreamHeader(XMLStreamReader reader, XMLStreamBuffer mark) {
116 assert reader!=null && mark!=null;
117 _mark = mark;
118 _localName = reader.getLocalName();
119 _namespaceURI = reader.getNamespaceURI();
120 attributes = processHeaderAttributes(reader);
121 }
123 /**
124 * Creates a {@link StreamHeader}.
125 *
126 * @param reader
127 * The parser that points to the start tag of the header.
128 * By the end of this method, the parser will point at
129 * the end tag of this element.
130 */
131 protected StreamHeader(XMLStreamReader reader) throws XMLStreamException {
132 _localName = reader.getLocalName();
133 _namespaceURI = reader.getNamespaceURI();
134 attributes = processHeaderAttributes(reader);
135 // cache the body
136 _mark = XMLStreamBuffer.createNewBufferFromXMLStreamReader(reader);
137 }
139 public final boolean isIgnorable(@NotNull SOAPVersion soapVersion, @NotNull Set<String> roles) {
140 // check mustUnderstand
141 if(!_isMustUnderstand) return true;
143 if (roles == null)
144 return true;
146 // now role
147 return !roles.contains(_role);
148 }
150 public @NotNull String getRole(@NotNull SOAPVersion soapVersion) {
151 assert _role!=null;
152 return _role;
153 }
155 public boolean isRelay() {
156 return _isRelay;
157 }
159 public @NotNull String getNamespaceURI() {
160 return _namespaceURI;
161 }
163 public @NotNull String getLocalPart() {
164 return _localName;
165 }
167 public String getAttribute(String nsUri, String localName) {
168 if(attributes!=null) {
169 for(int i=attributes.size()-1; i>=0; i-- ) {
170 Attribute a = attributes.get(i);
171 if(a.localName.equals(localName) && a.nsUri.equals(nsUri))
172 return a.value;
173 }
174 }
175 return null;
176 }
178 /**
179 * Reads the header as a {@link XMLStreamReader}
180 */
181 public XMLStreamReader readHeader() throws XMLStreamException {
182 return _mark.readAsXMLStreamReader();
183 }
185 public void writeTo(XMLStreamWriter w) throws XMLStreamException {
186 if(_mark.getInscopeNamespaces().size() > 0)
187 _mark.writeToXMLStreamWriter(w,true);
188 else
189 _mark.writeToXMLStreamWriter(w);
190 }
192 public void writeTo(SOAPMessage saaj) throws SOAPException {
193 try {
194 // TODO what about in-scope namespaces
195 // Not very efficient consider implementing a stream buffer
196 // processor that produces a DOM node from the buffer.
197 TransformerFactory tf = XmlUtil.newTransformerFactory();
198 Transformer t = tf.newTransformer();
199 XMLStreamBufferSource source = new XMLStreamBufferSource(_mark);
200 DOMResult result = new DOMResult();
201 t.transform(source, result);
202 Node d = result.getNode();
203 if(d.getNodeType() == Node.DOCUMENT_NODE)
204 d = d.getFirstChild();
205 SOAPHeader header = saaj.getSOAPHeader();
206 if(header == null)
207 header = saaj.getSOAPPart().getEnvelope().addHeader();
208 Node node = header.getOwnerDocument().importNode(d, true);
209 header.appendChild(node);
210 } catch (Exception e) {
211 throw new SOAPException(e);
212 }
213 }
215 public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException {
216 _mark.writeTo(contentHandler);
217 }
219 /**
220 * Creates an EPR without copying infoset.
221 *
222 * This is the most common implementation on which {@link Header#readAsEPR(AddressingVersion)}
223 * is invoked on.
224 */
225 @Override @NotNull
226 public WSEndpointReference readAsEPR(AddressingVersion expected) throws XMLStreamException {
227 return new WSEndpointReference(_mark,expected);
228 }
230 protected abstract FinalArrayList<Attribute> processHeaderAttributes(XMLStreamReader reader);
232 /**
233 * Convert null to "".
234 */
235 private static String fixNull(String s) {
236 if(s==null) return "";
237 else return s;
238 }
239 }