001: /*
002: * Portions Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.xml.internal.ws.client.dispatch.impl.encoding;
027:
028: import com.sun.xml.internal.ws.encoding.jaxb.JAXBBeanInfo;
029: import com.sun.xml.internal.ws.encoding.soap.SOAP12Constants;
030: import com.sun.xml.internal.ws.encoding.soap.SOAPConstants;
031: import com.sun.xml.internal.ws.encoding.soap.SerializationException;
032: import com.sun.xml.internal.ws.streaming.Attributes;
033: import com.sun.xml.internal.ws.streaming.SourceReaderFactory;
034: import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
035: import com.sun.xml.internal.ws.streaming.XMLStreamWriterFactory;
036: import com.sun.xml.internal.ws.util.ByteArrayBuffer;
037:
038: import javax.xml.bind.JAXBContext;
039: import javax.xml.namespace.QName;
040: import static javax.xml.stream.XMLStreamConstants.*;
041: import javax.xml.stream.XMLStreamException;
042: import javax.xml.stream.XMLStreamReader;
043: import javax.xml.stream.XMLStreamWriter;
044: import javax.xml.stream.XMLStreamConstants;
045: import javax.xml.transform.Source;
046: import javax.xml.transform.stream.StreamSource;
047: import javax.xml.ws.WebServiceException;
048: import java.io.ByteArrayInputStream;
049: import java.io.ByteArrayOutputStream;
050: import java.io.IOException;
051: import java.util.logging.Logger;
052: import java.util.Iterator;
053: import java.util.Map;
054: import java.util.Set;
055: import java.util.HashMap;
056:
057: /**
058: * @author WS Development Team
059: */
060: public final class DispatchSerializer {
061:
062: private static final Logger logger = Logger
063: .getLogger(new StringBuffer()
064: .append(
065: com.sun.xml.internal.ws.util.Constants.LoggingDomain)
066: .append(".client.dispatch").toString());
067:
068: private final QName bodyTagName;
069:
070: /**
071: * For SOAP 1.0.
072: */
073: public static final DispatchSerializer SOAP_1_0 = new DispatchSerializer(
074: SOAPConstants.QNAME_SOAP_BODY);
075:
076: /**
077: * For SOAP 1.2.
078: */
079: public static final DispatchSerializer SOAP_1_2 = new DispatchSerializer(
080: SOAP12Constants.QNAME_SOAP_BODY);
081:
082: private DispatchSerializer(QName soapBodyTagName) {
083: bodyTagName = soapBodyTagName;
084: }
085:
086: public void serialize(Object obj, XMLStreamWriter writer,
087: JAXBContext context) {
088: if (obj instanceof Source)
089: serializeSource(obj, writer);
090: else if (obj instanceof JAXBBeanInfo) {
091: ((JAXBBeanInfo) obj).writeTo(writer);
092: } else
093: throw new WebServiceException(
094: "Unable to serialize object type "
095: + obj.getClass().getName());
096: //should not happen
097: }
098:
099: private static String convertNull(String s) {
100: return (s != null) ? s : "";
101: }
102:
103: // this is very very inefficient.
104: //kw-needs lots of cleanup
105: //kw-modifying this in any way will cause dispatch tests sqe failures
106: public Source deserializeSource(XMLStreamReader reader,
107: DispatchUtil dispatchUtil) {
108:
109: ByteArrayBuffer baos = new ByteArrayBuffer();
110: XMLStreamWriter writer = XMLStreamWriterFactory
111: .createXMLStreamWriter(baos);
112: dispatchUtil.populatePrefixes(writer);
113: try {
114: while (reader.hasNext()) {
115: int state = reader.getEventType();
116: switch (state) {
117: case START_ELEMENT:
118:
119: String uri = reader.getNamespaceURI();
120: String rprefix = reader.getPrefix();
121: String nlocal = reader.getLocalName();
122: setWriterPrefixes(rprefix, uri, writer);
123:
124: String prefix = null;
125: String wprefix = writer.getNamespaceContext()
126: .getPrefix(uri);
127: if ((wprefix != null && !"".equals(wprefix))
128: && wprefix.length() > 0) {
129: prefix = wprefix;
130: } else if ((rprefix != null && !"".equals(rprefix))
131: && (uri != null && !"null".equals(uri))) {
132: prefix = setWriterPrefixes(reader, uri, writer);
133: } else {
134: prefix = convertNull(prefix);
135: uri = convertNull(uri);
136: }
137:
138: writer.writeStartElement(prefix, nlocal, uri);
139: writer.writeNamespace(prefix, uri);
140:
141: Attributes atts = XMLStreamReaderUtil
142: .getAttributes(reader);
143: writer.flush();
144: writeAttributes(atts, writer, prefix, uri);
145: break;
146: case END_ELEMENT:
147: writer.writeEndElement();
148: break;
149: case CHARACTERS:
150: writer.writeCharacters(reader.getText());
151:
152: }
153: state = XMLStreamReaderUtil.next(reader);
154: if ((reader.getEventType() == END_ELEMENT)
155: && (reader.getName().equals(bodyTagName)))
156: break;
157: }
158: writer.flush();
159: writer.close();
160: reader.close();
161: } catch (XMLStreamException ex) {
162: ex.printStackTrace();
163: }
164:
165: return new StreamSource(baos.newInputStream());
166: }
167:
168: private void writeAttributes(Attributes atts,
169: XMLStreamWriter writer, String prefix, String uri)
170: throws XMLStreamException {
171: for (int i = 0; i < atts.getLength(); i++) {
172:
173: String value = atts.getValue(i);
174: String localName = atts.getName(i).getLocalPart();
175: String aprefix = atts.getPrefix(i);
176: String auri = atts.getURI(i);
177:
178: setWriterPrefix(localName, value, aprefix, writer);
179: if (atts.isNamespaceDeclaration(i)) {
180: writeAttrNamespace(aprefix, auri, writer, localName,
181: prefix, uri, value);
182: } else {
183: writeAttribute(atts, i, writer);
184: }
185: }
186: }
187:
188: private void setWriterPrefix(String localName, String value,
189: String aprefix, XMLStreamWriter writer)
190: throws XMLStreamException {
191: if (localName.equals("xsi")
192: && value
193: .equals("http://www.w3.org/2001/XMLSchema-instance")
194: && aprefix.equals("xmlns")) {
195: //kw was aa prefix
196: writer.setPrefix(localName, value);
197: }
198: }
199:
200: private String setWriterPrefixes(XMLStreamReader reader,
201: String nuri, XMLStreamWriter writer) {
202:
203: String prefix = reader.getNamespaceContext().getPrefix(nuri);
204: if (prefix == null)
205: prefix = convertNull(prefix);
206: if (prefix != null && prefix.length() > 0 && nuri != null
207: && !prefix.equals("xmlns")) {
208: try {
209: writer.setPrefix(prefix, nuri);
210: } catch (Exception e) {
211: e.printStackTrace();
212: }
213: }
214: return prefix;
215: }
216:
217: private void setWriterPrefixes(String npre, String nuri,
218: XMLStreamWriter writer) throws XMLStreamException {
219: if ((npre != null && npre.length() > 0)
220: && (nuri.length() > 0 && nuri != null)) {
221: if ((npre.equals("null") || nuri.equals("null"))) {
222: writer.setPrefix(npre, nuri);
223: }
224: }
225: }
226:
227: private void writeAttrNamespace(String aprefix, String auri,
228: XMLStreamWriter writer, String localName, String prefix,
229: String nuri, String value) throws XMLStreamException {
230: if (aprefix == null || !aprefix.equals("")
231: || (aprefix.equals("xmlns"))) {
232: String temp = aprefix;
233: if (auri != null) {
234: String wprefix = writer.getNamespaceContext()
235: .getPrefix(auri);
236: if (aprefix.equals("xmlns")
237: && !(localName.equals("xsi"))) {
238: aprefix = prefix;
239: auri = nuri;
240: } else {
241: if (wprefix != null && !wprefix.equals("xmlns")) {
242: aprefix = wprefix;
243: }
244: }
245: if (aprefix == null)
246: convertNull(aprefix);
247: }
248:
249: writeNamespace(aprefix, prefix, auri, nuri, writer);
250: writeXSINamspece(localName, value, temp, writer, aprefix,
251: auri);
252: }
253: }
254:
255: private void writeNamespace(String aprefix, String prefix,
256: String auri, String nuri, XMLStreamWriter writer)
257: throws XMLStreamException {
258: if (!(aprefix.equals(prefix) && auri.equals(nuri))) {
259: if (!aprefix.equals("xmlns")) {
260: writer.writeNamespace(aprefix, auri);
261: }
262: }
263: }
264:
265: private void writeXSINamspece(String localName, String value,
266: String temp, XMLStreamWriter writer, String aprefix,
267: String auri) throws XMLStreamException {
268: if (localName.equals("xsi")
269: && value
270: .equals("http://www.w3.org/2001/XMLSchema-instance")
271: && temp.equals("xmlns")) {
272: writer.setPrefix(localName, value);
273: writer.writeAttribute(aprefix, auri, localName, value);
274: }
275: }
276:
277: private void writeAttribute(Attributes atts, int i,
278: XMLStreamWriter writer) throws XMLStreamException {
279: if ((atts.getURI(i) == null) && (atts.getPrefix(i) != null)) {
280: String ns = writer.getNamespaceContext().getNamespaceURI(
281: atts.getURI(i));
282: writer.writeAttribute(atts.getPrefix(i), ns, atts
283: .getLocalName(i), atts.getValue(i));
284: }
285: writer.writeAttribute(atts.getPrefix(i), atts.getURI(i), atts
286: .getLocalName(i), atts.getValue(i));
287: }
288:
289: void serializeSource(Object source, XMLStreamWriter writer) {
290: try {
291: XMLStreamReader reader = SourceReaderFactory
292: .createSourceReader((Source) source, true);
293:
294: int state;
295: do {
296: state = XMLStreamReaderUtil.next(reader);
297: switch (state) {
298: case START_ELEMENT:
299: QName elementName = reader.getName();
300: String localPart = elementName.getLocalPart();
301: String namespaceURI = elementName.getNamespaceURI();
302: String prefix = elementName.getPrefix();
303:
304: writer.writeStartElement(prefix, localPart,
305: namespaceURI);
306:
307: Attributes atts = XMLStreamReaderUtil
308: .getAttributes(reader);
309: writer.flush();
310: for (int i = 0; i < atts.getLength(); i++) {
311: if (atts.isNamespaceDeclaration(i)) {
312: String value = atts.getValue(i);
313: String localName = atts.getName(i)
314: .getLocalPart();
315: writer.setPrefix(localName, value);
316: writer.writeNamespace(localName, value);
317: } else {
318: writer.writeAttribute(atts.getPrefix(i),
319: atts.getURI(i), atts
320: .getLocalName(i), atts
321: .getValue(i));
322: }
323: }
324: break;
325: case END_ELEMENT:
326: writer.writeEndElement();
327: break;
328: case CHARACTERS:
329: writer.writeCharacters(reader.getText());
330: }
331: } while (state != END_DOCUMENT);
332: } catch (XMLStreamException e) {
333: throw new SerializationException(e);
334: }
335: }
336:
337: // private void displayDOM(Node node, java.io.OutputStream ostream) {
338: // try {
339: // System.out.println("\n====\n");
340: // javax.xml.transform.TransformerFactory.newInstance().newTransformer().transform(new javax.xml.transform.dom.DOMSource(node),
341: // new javax.xml.transform.stream.StreamResult(ostream));
342: // System.out.println("\n====\n");
343: // } catch (Exception e) {
344: // e.printStackTrace();
345: // }
346: // }
347:
348: // private String sourceToXMLString(Source result) {
349: // String xmlResult = null;
350: // try {
351: // TransformerFactory factory = TransformerFactory.newInstance();
352: // Transformer transformer = factory.newTransformer();
353: // transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
354: // transformer.setOutputProperty(OutputKeys.METHOD, "xml");
355: // OutputStream out = new ByteArrayOutputStream();
356: // StreamResult streamResult = new StreamResult();
357: // streamResult.setOutputStream(out);
358: // transformer.transform(result, streamResult);
359: // xmlResult = streamResult.getOutputStream().toString();
360: // } catch (TransformerException e) {
361: // e.printStackTrace();
362: // }
363: // return xmlResult;
364: // }
365:
366: }
|