Tue, 06 Mar 2012 16:09:35 -0800
7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom
1 /*
2 * Copyright (c) 1997, 2010, 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 org.w3c.dom.Node;
38 import org.xml.sax.ContentHandler;
39 import org.xml.sax.ErrorHandler;
40 import org.xml.sax.SAXException;
42 import javax.xml.soap.SOAPException;
43 import javax.xml.soap.SOAPHeader;
44 import javax.xml.soap.SOAPMessage;
45 import javax.xml.stream.XMLStreamException;
46 import javax.xml.stream.XMLStreamReader;
47 import javax.xml.stream.XMLStreamWriter;
48 import javax.xml.transform.Transformer;
49 import javax.xml.transform.TransformerFactory;
50 import javax.xml.transform.dom.DOMResult;
51 import java.util.List;
52 import java.util.Set;
54 /**
55 * {@link Header} whose physical data representation is an XMLStreamBuffer.
56 *
57 * @author Paul.Sandoz@Sun.Com
58 */
59 public abstract class StreamHeader extends AbstractHeaderImpl {
60 protected final XMLStreamBuffer _mark;
62 protected boolean _isMustUnderstand;
64 /**
65 * Role or actor value.
66 */
67 protected @NotNull String _role;
69 protected boolean _isRelay;
71 protected String _localName;
73 protected String _namespaceURI;
75 /**
76 * Keep the information about an attribute on the header element.
77 *
78 * TODO: this whole attribute handling could be done better, I think.
79 */
80 protected static final class Attribute {
81 /**
82 * Can be empty but never null.
83 */
84 final String nsUri;
85 final String localName;
86 final String value;
88 public Attribute(String nsUri, String localName, String value) {
89 this.nsUri = fixNull(nsUri);
90 this.localName = localName;
91 this.value = value;
92 }
93 }
95 /**
96 * The attributes on the header element.
97 * We expect there to be only a small number of them,
98 * so the use of {@link List} would be justified.
99 *
100 * Null if no attribute is present.
101 */
102 private final FinalArrayList<Attribute> attributes;
104 /**
105 * Creates a {@link StreamHeader}.
106 *
107 * @param reader
108 * The parser pointing at the start of the mark.
109 * Technically this information is redundant,
110 * but it achieves a better performance.
111 * @param mark
112 * The start of the buffered header content.
113 */
114 protected StreamHeader(XMLStreamReader reader, XMLStreamBuffer mark) {
115 assert reader!=null && mark!=null;
116 _mark = mark;
117 _localName = reader.getLocalName();
118 _namespaceURI = reader.getNamespaceURI();
119 attributes = processHeaderAttributes(reader);
120 }
122 /**
123 * Creates a {@link StreamHeader}.
124 *
125 * @param reader
126 * The parser that points to the start tag of the header.
127 * By the end of this method, the parser will point at
128 * the end tag of this element.
129 */
130 protected StreamHeader(XMLStreamReader reader) throws XMLStreamException {
131 _localName = reader.getLocalName();
132 _namespaceURI = reader.getNamespaceURI();
133 attributes = processHeaderAttributes(reader);
134 // cache the body
135 _mark = XMLStreamBuffer.createNewBufferFromXMLStreamReader(reader);
136 }
138 public final boolean isIgnorable(@NotNull SOAPVersion soapVersion, @NotNull Set<String> roles) {
139 // check mustUnderstand
140 if(!_isMustUnderstand) return true;
142 if (roles == null)
143 return true;
145 // now role
146 return !roles.contains(_role);
147 }
149 public @NotNull String getRole(@NotNull SOAPVersion soapVersion) {
150 assert _role!=null;
151 return _role;
152 }
154 public boolean isRelay() {
155 return _isRelay;
156 }
158 public @NotNull String getNamespaceURI() {
159 return _namespaceURI;
160 }
162 public @NotNull String getLocalPart() {
163 return _localName;
164 }
166 public String getAttribute(String nsUri, String localName) {
167 if(attributes!=null) {
168 for(int i=attributes.size()-1; i>=0; i-- ) {
169 Attribute a = attributes.get(i);
170 if(a.localName.equals(localName) && a.nsUri.equals(nsUri))
171 return a.value;
172 }
173 }
174 return null;
175 }
177 /**
178 * Reads the header as a {@link XMLStreamReader}
179 */
180 public XMLStreamReader readHeader() throws XMLStreamException {
181 return _mark.readAsXMLStreamReader();
182 }
184 public void writeTo(XMLStreamWriter w) throws XMLStreamException {
185 if(_mark.getInscopeNamespaces().size() > 0)
186 _mark.writeToXMLStreamWriter(w,true);
187 else
188 _mark.writeToXMLStreamWriter(w);
189 }
191 public void writeTo(SOAPMessage saaj) throws SOAPException {
192 try {
193 // TODO what about in-scope namespaces
194 // Not very efficient consider implementing a stream buffer
195 // processor that produces a DOM node from the buffer.
196 TransformerFactory tf = TransformerFactory.newInstance();
197 Transformer t = tf.newTransformer();
198 XMLStreamBufferSource source = new XMLStreamBufferSource(_mark);
199 DOMResult result = new DOMResult();
200 t.transform(source, result);
201 Node d = result.getNode();
202 if(d.getNodeType() == Node.DOCUMENT_NODE)
203 d = d.getFirstChild();
204 SOAPHeader header = saaj.getSOAPHeader();
205 if(header == null)
206 header = saaj.getSOAPPart().getEnvelope().addHeader();
207 Node node = header.getOwnerDocument().importNode(d, true);
208 header.appendChild(node);
209 } catch (Exception e) {
210 throw new SOAPException(e);
211 }
212 }
214 public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException {
215 _mark.writeTo(contentHandler);
216 }
218 /**
219 * Creates an EPR without copying infoset.
220 *
221 * This is the most common implementation on which {@link Header#readAsEPR(AddressingVersion)}
222 * is invoked on.
223 */
224 @Override @NotNull
225 public WSEndpointReference readAsEPR(AddressingVersion expected) throws XMLStreamException {
226 return new WSEndpointReference(_mark,expected);
227 }
229 protected abstract FinalArrayList<Attribute> processHeaderAttributes(XMLStreamReader reader);
231 /**
232 * Convert null to "".
233 */
234 private static String fixNull(String s) {
235 if(s==null) return "";
236 else return s;
237 }
238 }