src/share/jaxws_classes/com/sun/xml/internal/ws/api/addressing/OutboundReferenceParameterHeader.java

changeset 0
373ffda63c9a
child 637
9c07ef4934dd
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
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.api.addressing;
27
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.XMLStreamBufferException;
32 import com.sun.xml.internal.ws.api.message.Header;
33 import com.sun.xml.internal.ws.message.AbstractHeaderImpl;
34 import com.sun.xml.internal.ws.util.xml.XMLStreamWriterFilter;
35 import org.w3c.dom.Element;
36 import org.xml.sax.Attributes;
37 import org.xml.sax.ContentHandler;
38 import org.xml.sax.ErrorHandler;
39 import org.xml.sax.SAXException;
40 import org.xml.sax.helpers.AttributesImpl;
41 import org.xml.sax.helpers.XMLFilterImpl;
42
43 import javax.xml.namespace.QName;
44 import javax.xml.soap.SOAPException;
45 import javax.xml.soap.SOAPMessage;
46 import javax.xml.soap.SOAPHeader;
47 import javax.xml.stream.XMLStreamException;
48 import javax.xml.stream.XMLStreamReader;
49 import javax.xml.stream.XMLStreamWriter;
50 import javax.xml.stream.util.StreamReaderDelegate;
51 import javax.xml.ws.WebServiceException;
52
53 /**
54 * Used to represent outbound header created from {@link WSEndpointReference}'s
55 * referenec parameters.
56 *
57 * <p>
58 * This is optimized for outbound use, so it implements some of the methods lazily,
59 * in a slow way.
60 *
61 * <p>
62 * This header adds "wsa:IsReferenceParameter" and thus only used for the W3C version.
63 *
64 * @author Kohsuke Kawaguchi
65 */
66 final class OutboundReferenceParameterHeader extends AbstractHeaderImpl {
67 private final XMLStreamBuffer infoset;
68 private final String nsUri,localName;
69
70 /**
71 * The attributes on the header element.
72 * Lazily parsed.
73 * Null if not parsed yet.
74 */
75 private FinalArrayList<Attribute> attributes;
76
77 OutboundReferenceParameterHeader(XMLStreamBuffer infoset, String nsUri, String localName) {
78 this.infoset = infoset;
79 this.nsUri = nsUri;
80 this.localName = localName;
81 }
82
83 @Override
84 public @NotNull String getNamespaceURI() {
85 return nsUri;
86 }
87
88 @Override
89 public @NotNull String getLocalPart() {
90 return localName;
91 }
92
93 @Override
94 public String getAttribute(String nsUri, String localName) {
95 if(attributes==null) {
96 parseAttributes();
97 }
98 for(int i=attributes.size()-1; i>=0; i-- ) {
99 Attribute a = attributes.get(i);
100 if (a.localName.equals(localName) && a.nsUri.equals(nsUri)) {
101 return a.value;
102 }
103 }
104 return null;
105 }
106
107 /**
108 * We don't really expect this to be used, but just to satisfy
109 * the {@link Header} contract.
110 *
111 * So this is rather slow.
112 */
113 private void parseAttributes() {
114 try {
115 XMLStreamReader reader = readHeader();
116 reader.nextTag(); // move to the first element, which is the header element
117
118 attributes = new FinalArrayList<Attribute>();
119 boolean refParamAttrWritten = false;
120 for (int i = 0; i < reader.getAttributeCount(); i++) {
121 final String attrLocalName = reader.getAttributeLocalName(i);
122 final String namespaceURI = reader.getAttributeNamespace(i);
123 final String value = reader.getAttributeValue(i);
124 if (namespaceURI.equals(AddressingVersion.W3C.nsUri)&& attrLocalName.equals("IS_REFERENCE_PARAMETER")) {
125 refParamAttrWritten = true;
126 }
127 attributes.add(new Attribute(namespaceURI,attrLocalName,value));
128 }
129 // we are adding one more attribute "wsa:IsReferenceParameter", if its not alrady there
130 if (!refParamAttrWritten) {
131 attributes.add(new Attribute(AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER,TRUE_VALUE));
132 }
133 } catch (XMLStreamException e) {
134 throw new WebServiceException("Unable to read the attributes for {"+nsUri+"}"+localName+" header",e);
135 }
136 }
137
138 @Override
139 public XMLStreamReader readHeader() throws XMLStreamException {
140 return new StreamReaderDelegate(infoset.readAsXMLStreamReader()) {
141 int state=0; /* 0:expecting root, 1:in root, 2:past root */
142 @Override
143 public int next() throws XMLStreamException {
144 return check(super.next());
145 }
146
147 @Override
148 public int nextTag() throws XMLStreamException {
149 return check(super.nextTag());
150 }
151
152 private int check(int type) {
153 switch (state) {
154 case 0:
155 if (type == START_ELEMENT) {
156 state = 1;
157 }
158 break;
159 case 1:
160 state = 2;
161 break;
162 default:
163 break;
164 }
165
166 return type;
167 }
168
169 @Override
170 public int getAttributeCount() {
171 if (state == 1) {
172 return super.getAttributeCount()+1;
173 } else {
174 return super.getAttributeCount();
175 }
176 }
177
178 @Override
179 public String getAttributeLocalName(int index) {
180 if (state == 1 && index == super.getAttributeCount()) {
181 return IS_REFERENCE_PARAMETER;
182 } else {
183 return super.getAttributeLocalName(index);
184 }
185 }
186
187 @Override
188 public String getAttributeNamespace(int index) {
189 if (state == 1 && index==super.getAttributeCount()) {
190 return AddressingVersion.W3C.nsUri;
191 }
192 else {
193 return super.getAttributeNamespace(index);
194 }
195 }
196
197 @Override
198 public String getAttributePrefix(int index) {
199 if(state==1 && index==super.getAttributeCount()) {
200 return "wsa";
201 } else {
202 return super.getAttributePrefix(index);
203 }
204 }
205
206 @Override
207 public String getAttributeType(int index) {
208 if(state==1 && index==super.getAttributeCount()) {
209 return "CDATA";
210 } else {
211 return super.getAttributeType(index);
212 }
213 }
214
215 @Override
216 public String getAttributeValue(int index) {
217 if(state==1 && index==super.getAttributeCount()) {
218 return TRUE_VALUE;
219 } else {
220 return super.getAttributeValue(index);
221 }
222 }
223
224 @Override
225 public QName getAttributeName(int index) {
226 if(state==1 && index==super.getAttributeCount()) {
227 return new QName(AddressingVersion.W3C.nsUri, IS_REFERENCE_PARAMETER, "wsa");
228 } else {
229 return super.getAttributeName(index);
230 }
231 }
232
233 @Override
234 public String getAttributeValue(String namespaceUri, String localName) {
235 if(state==1 && localName.equals(IS_REFERENCE_PARAMETER) && namespaceUri.equals(AddressingVersion.W3C.nsUri)) {
236 return TRUE_VALUE;
237 } else {
238 return super.getAttributeValue(namespaceUri, localName);
239 }
240 }
241 };
242 }
243
244 @Override
245 public void writeTo(XMLStreamWriter w) throws XMLStreamException {
246 infoset.writeToXMLStreamWriter(new XMLStreamWriterFilter(w) {
247 private boolean root=true;
248 private boolean onRootEl = true;
249 @Override
250 public void writeStartElement(String localName) throws XMLStreamException {
251 super.writeStartElement(localName);
252 writeAddedAttribute();
253 }
254
255 private void writeAddedAttribute() throws XMLStreamException {
256 if(!root) {
257 onRootEl = false;
258 return;
259 }
260 root=false;
261 writeNamespace("wsa",AddressingVersion.W3C.nsUri);
262 super.writeAttribute("wsa",AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER,TRUE_VALUE);
263 }
264
265 @Override
266 public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
267 super.writeStartElement(namespaceURI, localName);
268 writeAddedAttribute();
269 }
270
271 @Override
272 public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
273 //TODO: Verify with KK later
274 //check if prefix is declared before writing start element.
275 boolean prefixDeclared = isPrefixDeclared(prefix,namespaceURI);
276 super.writeStartElement(prefix, localName, namespaceURI);
277 if (!prefixDeclared && !prefix.equals("")) {
278 super.writeNamespace(prefix,namespaceURI);
279 }
280 writeAddedAttribute();
281 }
282 @Override
283 public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException{
284 if (!isPrefixDeclared(prefix, namespaceURI)) {
285 super.writeNamespace(prefix,namespaceURI);
286 }
287 }
288
289 @Override
290 public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException {
291 //skip if its on root element and attribute is wsa;IsReferenceParameter, as we write it.
292 if(onRootEl && namespaceURI.equals(AddressingVersion.W3C.nsUri)
293 && localName.equals(IS_REFERENCE_PARAMETER)) {
294 return;
295 }
296 writer.writeAttribute(prefix, namespaceURI, localName, value);
297 }
298
299 @Override
300 public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
301 writer.writeAttribute(namespaceURI, localName, value);
302 }
303 private boolean isPrefixDeclared(String prefix, String namespaceURI ) {
304 return namespaceURI.equals(getNamespaceContext().getNamespaceURI(prefix));
305 }
306 },true);
307 }
308
309 @Override
310 public void writeTo(SOAPMessage saaj) throws SOAPException {
311 //TODO: SAAJ returns null instead of throwing SOAPException,
312 // when there is no SOAPHeader in the message,
313 // which leads to NPE.
314 try {
315 SOAPHeader header = saaj.getSOAPHeader();
316 if (header == null) {
317 header = saaj.getSOAPPart().getEnvelope().addHeader();
318 }
319 Element node = (Element)infoset.writeTo(header);
320 node.setAttributeNS(AddressingVersion.W3C.nsUri,AddressingVersion.W3C.getPrefix()+":"+IS_REFERENCE_PARAMETER,TRUE_VALUE);
321 } catch (XMLStreamBufferException e) {
322 throw new SOAPException(e);
323 }
324 }
325
326 @Override
327 public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException {
328 class Filter extends XMLFilterImpl {
329 Filter(ContentHandler ch) { setContentHandler(ch); }
330 private int depth=0;
331 @Override
332 public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
333 if(depth++==0) {
334 // add one more attribute
335 super.startPrefixMapping("wsa",AddressingVersion.W3C.nsUri);
336
337 //Add the attirbute wsa:IsReferenceParameter if not present already
338 if(atts.getIndex(AddressingVersion.W3C.nsUri,IS_REFERENCE_PARAMETER) == -1) {
339 AttributesImpl atts2 = new AttributesImpl(atts);
340 atts2.addAttribute(
341 AddressingVersion.W3C.nsUri,
342 IS_REFERENCE_PARAMETER,
343 "wsa:IsReferenceParameter",
344 "CDATA",
345 TRUE_VALUE);
346 atts = atts2;
347 }
348 }
349
350 super.startElement(uri, localName, qName, atts);
351 }
352
353 @Override
354 public void endElement(String uri, String localName, String qName) throws SAXException {
355 super.endElement(uri, localName, qName);
356 if (--depth == 0) {
357 super.endPrefixMapping("wsa");
358 }
359 }
360 }
361
362 infoset.writeTo(new Filter(contentHandler),errorHandler);
363 }
364
365
366 /**
367 * Keep the information about an attribute on the header element.
368 */
369 static final class Attribute {
370 /**
371 * Can be empty but never null.
372 */
373 final String nsUri;
374 final String localName;
375 final String value;
376
377 public Attribute(String nsUri, String localName, String value) {
378 this.nsUri = fixNull(nsUri);
379 this.localName = localName;
380 this.value = value;
381 }
382
383 /**
384 * Convert null to "".
385 */
386 private static String fixNull(String s) {
387 return s == null ? "" : s;
388 }
389 }
390
391 /**
392 * We the performance paranoid people in the JAX-WS RI thinks
393 * saving three bytes is worth while...
394 */
395 private static final String TRUE_VALUE = "1";
396 private static final String IS_REFERENCE_PARAMETER = "IsReferenceParameter";
397 }

mercurial