1 /* 2 * Copyright (c) 2014, 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.org.jvnet.staxex.util; 27 28 import java.util.Arrays; 29 import java.util.Iterator; 30 31 import javax.xml.namespace.NamespaceContext; 32 import javax.xml.namespace.QName; 33 import javax.xml.soap.SOAPElement; 34 import javax.xml.soap.SOAPException; 35 import javax.xml.soap.SOAPMessage; 36 import javax.xml.stream.XMLStreamException; 37 import javax.xml.stream.XMLStreamWriter; 38 39 import org.w3c.dom.Comment; 40 import org.w3c.dom.Node; 41 42 /** 43 * SaajStaxWriter builds a SAAJ SOAPMessage by using XMLStreamWriter interface. 44 * 45 * @author shih-chang.chen@oracle.com 46 */ 47 public class SaajStaxWriter implements XMLStreamWriter { 48 49 protected SOAPMessage soap; 50 protected String envURI; 51 protected SOAPElement currentElement; 52 53 static final protected String Envelope = "Envelope"; 54 static final protected String Header = "Header"; 55 static final protected String Body = "Body"; 56 static final protected String xmlns = "xmlns"; 57 58 public SaajStaxWriter(final SOAPMessage msg, String uri) throws SOAPException { 59 soap = msg; 60 this.envURI = uri; 61 } 62 63 public SOAPMessage getSOAPMessage() { 64 return soap; 65 } 66 67 protected SOAPElement getEnvelope() throws SOAPException { 68 return soap.getSOAPPart().getEnvelope(); 69 } 70 71 @Override 72 public void writeStartElement(final String localName) throws XMLStreamException { 73 try { 74 currentElement = currentElement.addChildElement(localName); 75 } catch (SOAPException e) { 76 throw new XMLStreamException(e); 77 } 78 } 79 80 @Override 81 public void writeStartElement(final String ns, final String ln) throws XMLStreamException { 82 writeStartElement(null, ln, ns); 83 } 84 85 @Override 86 public void writeStartElement(final String prefix, final String ln, final String ns) throws XMLStreamException { 87 try { 88 if (envURI.equals(ns)) { 89 if (Envelope.equals(ln)) { 90 currentElement = getEnvelope(); 91 fixPrefix(prefix); 92 return; 93 } else if (Header.equals(ln)) { 94 currentElement = soap.getSOAPHeader(); 95 fixPrefix(prefix); 96 return; 97 } else if (Body.equals(ln)) { 98 currentElement = soap.getSOAPBody(); 99 fixPrefix(prefix); 100 return; 101 } 102 } 103 currentElement = (prefix == null) ? 104 currentElement.addChildElement(new QName(ns, ln)) : 105 currentElement.addChildElement(ln, prefix, ns); 106 } catch (SOAPException e) { 107 throw new XMLStreamException(e); 108 } 109 } 110 111 private void fixPrefix(final String prfx) throws XMLStreamException { 112 String oldPrfx = currentElement.getPrefix(); 113 if (prfx != null && !prfx.equals(oldPrfx)) { 114 currentElement.setPrefix(prfx); 115 } 116 } 117 118 @Override 119 public void writeEmptyElement(final String uri, final String ln) throws XMLStreamException { 120 writeStartElement(null, ln, uri); 121 } 122 123 @Override 124 public void writeEmptyElement(final String prefix, final String ln, final String uri) throws XMLStreamException { 125 writeStartElement(prefix, ln, uri); 126 } 127 128 @Override 129 public void writeEmptyElement(final String ln) throws XMLStreamException { 130 writeStartElement(null, ln, null); 131 } 132 133 @Override 134 public void writeEndElement() throws XMLStreamException { 135 if (currentElement != null) currentElement = currentElement.getParentElement(); 136 } 137 138 @Override 139 public void writeEndDocument() throws XMLStreamException { 140 } 141 142 @Override 143 public void close() throws XMLStreamException { 144 } 145 146 @Override 147 public void flush() throws XMLStreamException { 148 } 149 150 @Override 151 public void writeAttribute(final String ln, final String val) throws XMLStreamException { 152 writeAttribute(null, null, ln, val); 153 } 154 155 @Override 156 public void writeAttribute(final String prefix, final String ns, final String ln, final String value) throws XMLStreamException { 157 try { 158 if (ns == null) { 159 if (prefix == null && xmlns.equals(ln)) { 160 currentElement.addNamespaceDeclaration("", value); 161 } else { 162 currentElement.setAttributeNS("", ln, value); 163 } 164 } else { 165 QName name = (prefix == null) ? new QName(ns, ln) : new QName(ns, ln, prefix); 166 currentElement.addAttribute(name, value); 167 } 168 } catch (SOAPException e) { 169 throw new XMLStreamException(e); 170 } 171 } 172 173 @Override 174 public void writeAttribute(final String ns, final String ln, final String val) throws XMLStreamException { 175 writeAttribute(null, ns, ln, val); 176 } 177 178 @Override 179 public void writeNamespace(String prefix, final String uri) throws XMLStreamException { 180 181 // make prefix default if null or "xmlns" (according to javadoc) 182 if (prefix == null || "xmlns".equals(prefix)) { 183 prefix = ""; 184 } 185 186 try { 187 currentElement.addNamespaceDeclaration(prefix, uri); 188 } catch (SOAPException e) { 189 throw new XMLStreamException(e); 190 } 191 } 192 193 @Override 194 public void writeDefaultNamespace(final String uri) throws XMLStreamException { 195 writeNamespace("", uri); 196 } 197 198 @Override 199 public void writeComment(final String data) throws XMLStreamException { 200 Comment c = soap.getSOAPPart().createComment(data); 201 currentElement.appendChild(c); 202 } 203 204 @Override 205 public void writeProcessingInstruction(final String target) throws XMLStreamException { 206 Node n = soap.getSOAPPart().createProcessingInstruction(target, ""); 207 currentElement.appendChild(n); 208 } 209 210 @Override 211 public void writeProcessingInstruction(final String target, final String data) throws XMLStreamException { 212 Node n = soap.getSOAPPart().createProcessingInstruction(target, data); 213 currentElement.appendChild(n); 214 } 215 216 @Override 217 public void writeCData(final String data) throws XMLStreamException { 218 Node n = soap.getSOAPPart().createCDATASection(data); 219 currentElement.appendChild(n); 220 } 221 222 @Override 223 public void writeDTD(final String dtd) throws XMLStreamException { 224 //TODO ... Don't do anything here 225 } 226 227 @Override 228 public void writeEntityRef(final String name) throws XMLStreamException { 229 Node n = soap.getSOAPPart().createEntityReference(name); 230 currentElement.appendChild(n); 231 } 232 233 @Override 234 public void writeStartDocument() throws XMLStreamException { 235 } 236 237 @Override 238 public void writeStartDocument(final String version) throws XMLStreamException { 239 if (version != null) soap.getSOAPPart().setXmlVersion(version); 240 } 241 242 @Override 243 public void writeStartDocument(final String encoding, final String version) throws XMLStreamException { 244 if (version != null) soap.getSOAPPart().setXmlVersion(version); 245 if (encoding != null) { 246 try { 247 soap.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, encoding); 248 } catch (SOAPException e) { 249 throw new XMLStreamException(e); 250 } 251 } 252 } 253 254 @Override 255 public void writeCharacters(final String text) throws XMLStreamException { 256 try { 257 currentElement.addTextNode(text); 258 } catch (SOAPException e) { 259 throw new XMLStreamException(e); 260 } 261 } 262 263 @Override 264 public void writeCharacters(final char[] text, final int start, final int len) throws XMLStreamException { 265 char[] chr = (start == 0 && len == text.length) ? text : Arrays.copyOfRange(text, start, start + len); 266 try { 267 currentElement.addTextNode(new String(chr)); 268 } catch (SOAPException e) { 269 throw new XMLStreamException(e); 270 } 271 } 272 273 @Override 274 public String getPrefix(final String uri) throws XMLStreamException { 275 return currentElement.lookupPrefix(uri); 276 } 277 278 @Override 279 public void setPrefix(final String prefix, final String uri) throws XMLStreamException { 280 try { 281 this.currentElement.addNamespaceDeclaration(prefix, uri); 282 } catch (SOAPException e) { 283 throw new XMLStreamException(e); 284 } 285 } 286 287 @Override 288 public void setDefaultNamespace(final String uri) throws XMLStreamException { 289 setPrefix("", uri); 290 } 291 292 @Override 293 public void setNamespaceContext(final NamespaceContext context)throws XMLStreamException { 294 throw new UnsupportedOperationException(); 295 } 296 297 @Override 298 public Object getProperty(final String name) throws IllegalArgumentException { 299 //TODO the following line is to make eclipselink happy ... they are aware of this problem - 300 if (javax.xml.stream.XMLOutputFactory.IS_REPAIRING_NAMESPACES.equals(name)) return Boolean.FALSE; 301 return null; 302 } 303 304 @Override 305 public NamespaceContext getNamespaceContext() { 306 return new NamespaceContext() { 307 public String getNamespaceURI(final String prefix) { 308 return currentElement.getNamespaceURI(prefix); 309 } 310 public String getPrefix(final String namespaceURI) { 311 return currentElement.lookupPrefix(namespaceURI); 312 } 313 public Iterator getPrefixes(final String namespaceURI) { 314 return new Iterator() { 315 String prefix = getPrefix(namespaceURI); 316 public boolean hasNext() { 317 return (prefix != null); 318 } 319 public Object next() { 320 if (!hasNext()) throw new java.util.NoSuchElementException(); 321 String next = prefix; 322 prefix = null; 323 return next; 324 } 325 public void remove() {} 326 }; 327 } 328 }; 329 } 330 }