aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.ws.message.source; aoqi@0: aoqi@0: import com.sun.xml.internal.ws.message.RootElementSniffer; aoqi@0: import com.sun.xml.internal.ws.streaming.SourceReaderFactory; aoqi@0: import com.sun.xml.internal.ws.util.xml.XmlUtil; aoqi@0: import org.w3c.dom.Document; aoqi@0: import org.w3c.dom.Node; aoqi@0: aoqi@0: import javax.xml.namespace.QName; aoqi@0: import javax.xml.stream.XMLStreamConstants; aoqi@0: import javax.xml.stream.XMLStreamException; aoqi@0: import javax.xml.stream.XMLStreamReader; aoqi@0: import javax.xml.stream.XMLStreamWriter; aoqi@0: import javax.xml.transform.Source; aoqi@0: import javax.xml.transform.Transformer; aoqi@0: import javax.xml.transform.TransformerConfigurationException; aoqi@0: import javax.xml.transform.TransformerException; aoqi@0: import javax.xml.transform.dom.DOMSource; aoqi@0: import javax.xml.transform.sax.SAXResult; aoqi@0: import javax.xml.transform.sax.SAXSource; aoqi@0: import javax.xml.transform.stream.StreamSource; aoqi@0: import javax.xml.ws.WebServiceException; aoqi@0: aoqi@0: /** aoqi@0: * aoqi@0: * @author Vivek Pandey aoqi@0: */ aoqi@0: final class SourceUtils { aoqi@0: aoqi@0: int srcType; aoqi@0: aoqi@0: private static final int domSource = 1; aoqi@0: private static final int streamSource = 2; aoqi@0: private static final int saxSource=4; aoqi@0: aoqi@0: public SourceUtils(Source src) { aoqi@0: if(src instanceof StreamSource){ aoqi@0: srcType = streamSource; aoqi@0: }else if(src instanceof DOMSource){ aoqi@0: srcType = domSource; aoqi@0: }else if(src instanceof SAXSource){ aoqi@0: srcType = saxSource; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: public boolean isDOMSource(){ aoqi@0: return (srcType&domSource) == domSource; aoqi@0: } aoqi@0: aoqi@0: public boolean isStreamSource(){ aoqi@0: return (srcType&streamSource) == streamSource; aoqi@0: } aoqi@0: aoqi@0: public boolean isSaxSource(){ aoqi@0: return (srcType&saxSource) == saxSource; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * This would peek into the Source (DOMSource and SAXSource) for the localName and NamespaceURI aoqi@0: * of the top-level element. aoqi@0: * @param src aoqi@0: * @return QName of the payload aoqi@0: */ aoqi@0: public QName sniff(Source src) { aoqi@0: return sniff(src, new RootElementSniffer()); aoqi@0: } aoqi@0: aoqi@0: public QName sniff(Source src, RootElementSniffer sniffer){ aoqi@0: String localName = null; aoqi@0: String namespaceUri = null; aoqi@0: aoqi@0: if(isDOMSource()){ aoqi@0: DOMSource domSrc = (DOMSource)src; aoqi@0: Node n = domSrc.getNode(); aoqi@0: if(n.getNodeType()== Node.DOCUMENT_NODE) { aoqi@0: n = ((Document)n).getDocumentElement(); aoqi@0: } aoqi@0: localName = n.getLocalName(); aoqi@0: namespaceUri = n.getNamespaceURI(); aoqi@0: }else if(isSaxSource()){ aoqi@0: SAXSource saxSrc = (SAXSource)src; aoqi@0: SAXResult saxResult = new SAXResult(sniffer); aoqi@0: try { aoqi@0: Transformer tr = XmlUtil.newTransformer(); aoqi@0: tr.transform(saxSrc, saxResult); aoqi@0: } catch (TransformerConfigurationException e) { aoqi@0: throw new WebServiceException(e); aoqi@0: } catch (TransformerException e) { aoqi@0: // if it's due to aborting the processing after the first element, aoqi@0: // we can safely ignore this exception. aoqi@0: // aoqi@0: // if it's due to error in the object, the same error will be reported aoqi@0: // when the readHeader() method is used, so we don't have to report aoqi@0: // an error right now. aoqi@0: localName = sniffer.getLocalName(); aoqi@0: namespaceUri = sniffer.getNsUri(); aoqi@0: } aoqi@0: } aoqi@0: return new QName(namespaceUri, localName); aoqi@0: } aoqi@0: aoqi@0: public static void serializeSource(Source src, XMLStreamWriter writer) throws XMLStreamException { aoqi@0: XMLStreamReader reader = SourceReaderFactory.createSourceReader(src, true); aoqi@0: int state; aoqi@0: do { aoqi@0: state = reader.next(); aoqi@0: switch (state) { aoqi@0: case XMLStreamConstants.START_ELEMENT: aoqi@0: /* aoqi@0: * TODO: Is this necessary, shouldn't zephyr return "" instead of aoqi@0: * null for getNamespaceURI() and getPrefix()? aoqi@0: */ aoqi@0: String uri = reader.getNamespaceURI(); aoqi@0: String prefix = reader.getPrefix(); aoqi@0: String localName = reader.getLocalName(); aoqi@0: aoqi@0: if (prefix == null) { aoqi@0: if (uri == null) { aoqi@0: writer.writeStartElement(localName); aoqi@0: } else { aoqi@0: writer.writeStartElement(uri, localName); aoqi@0: } aoqi@0: } else { aoqi@0: // assert uri != null; aoqi@0: aoqi@0: if(prefix.length() > 0){ aoqi@0: /** aoqi@0: * Before we write the aoqi@0: */ aoqi@0: String writerURI = null; aoqi@0: if (writer.getNamespaceContext() != null) { aoqi@0: writerURI = writer.getNamespaceContext().getNamespaceURI(prefix); aoqi@0: } aoqi@0: String writerPrefix = writer.getPrefix(uri); aoqi@0: if(declarePrefix(prefix, uri, writerPrefix, writerURI)){ aoqi@0: writer.writeStartElement(prefix, localName, uri); aoqi@0: writer.setPrefix(prefix, uri != null ? uri : ""); aoqi@0: writer.writeNamespace(prefix, uri); aoqi@0: }else{ aoqi@0: writer.writeStartElement(prefix, localName, uri); aoqi@0: } aoqi@0: }else{ aoqi@0: writer.writeStartElement(prefix, localName, uri); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: int n = reader.getNamespaceCount(); aoqi@0: // Write namespace declarations aoqi@0: for (int i = 0; i < n; i++) { aoqi@0: String nsPrefix = reader.getNamespacePrefix(i); aoqi@0: if (nsPrefix == null) { aoqi@0: nsPrefix = ""; aoqi@0: } aoqi@0: // StAX returns null for default ns aoqi@0: String writerURI = null; aoqi@0: if (writer.getNamespaceContext() != null) { aoqi@0: writerURI = writer.getNamespaceContext().getNamespaceURI(nsPrefix); aoqi@0: } aoqi@0: aoqi@0: // Zephyr: Why is this returning null? aoqi@0: // Compare nsPrefix with prefix because of [1] (above) aoqi@0: String readerURI = reader.getNamespaceURI(i); aoqi@0: aoqi@0: /** aoqi@0: * write the namespace in 3 conditions aoqi@0: * - when the namespace URI is not bound to the prefix in writer(writerURI == 0) aoqi@0: * - when the readerPrefix and writerPrefix are "" aoqi@0: * - when readerPrefix and writerPrefix are not equal and the URI bound to them aoqi@0: * are different aoqi@0: */ aoqi@0: if (writerURI == null || ((nsPrefix.length() == 0) || (prefix.length() == 0)) || aoqi@0: (!nsPrefix.equals(prefix) && !writerURI.equals(readerURI))) { aoqi@0: writer.setPrefix(nsPrefix, readerURI != null ? readerURI : ""); aoqi@0: writer.writeNamespace(nsPrefix, readerURI != null ? readerURI : ""); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: // Write attributes aoqi@0: n = reader.getAttributeCount(); aoqi@0: for (int i = 0; i < n; i++) { aoqi@0: String attrPrefix = reader.getAttributePrefix(i); aoqi@0: String attrURI = reader.getAttributeNamespace(i); aoqi@0: aoqi@0: writer.writeAttribute(attrPrefix != null ? attrPrefix : "", aoqi@0: attrURI != null ? attrURI : "", aoqi@0: reader.getAttributeLocalName(i), aoqi@0: reader.getAttributeValue(i)); aoqi@0: // if the attribute prefix is undeclared in current writer scope then declare it aoqi@0: setUndeclaredPrefix(attrPrefix, attrURI, writer); aoqi@0: } aoqi@0: break; aoqi@0: case XMLStreamConstants.END_ELEMENT: aoqi@0: writer.writeEndElement(); aoqi@0: break; aoqi@0: case XMLStreamConstants.CHARACTERS: aoqi@0: writer.writeCharacters(reader.getText()); aoqi@0: break; aoqi@0: default: aoqi@0: break; aoqi@0: } aoqi@0: } while (state != XMLStreamConstants.END_DOCUMENT); aoqi@0: reader.close(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * sets undeclared prefixes on the writer aoqi@0: * @param prefix aoqi@0: * @param writer aoqi@0: * @throws XMLStreamException aoqi@0: */ aoqi@0: private static void setUndeclaredPrefix(String prefix, String readerURI, XMLStreamWriter writer) throws XMLStreamException { aoqi@0: String writerURI = null; aoqi@0: if (writer.getNamespaceContext() != null) { aoqi@0: writerURI = writer.getNamespaceContext().getNamespaceURI(prefix); aoqi@0: } aoqi@0: aoqi@0: if (writerURI == null) { aoqi@0: writer.setPrefix(prefix, readerURI != null ? readerURI : ""); aoqi@0: writer.writeNamespace(prefix, readerURI != null ? readerURI : ""); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * check if we need to declare aoqi@0: * @param rPrefix aoqi@0: * @param rUri aoqi@0: * @param wPrefix aoqi@0: * @param wUri aoqi@0: */ aoqi@0: private static boolean declarePrefix(String rPrefix, String rUri, String wPrefix, String wUri){ aoqi@0: if (wUri == null ||((wPrefix != null) && !rPrefix.equals(wPrefix))|| aoqi@0: (rUri != null && !wUri.equals(rUri))) { aoqi@0: return true; aoqi@0: } aoqi@0: return false; aoqi@0: } aoqi@0: }