1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_forms.hxx" 30 31 #include "serialization.hxx" 32 #include "serialization_app_xml.hxx" 33 34 /** === begin UNO includes === **/ 35 #include <com/sun/star/xml/dom/XNode.hpp> 36 #include <com/sun/star/xml/dom/XDocument.hpp> 37 #include <com/sun/star/xml/dom/XNodeList.hpp> 38 #include <com/sun/star/xml/dom/NodeType.hpp> 39 #include <com/sun/star/lang/XUnoTunnel.hpp> 40 #include <com/sun/star/xml/xpath/XPathObjectType.hpp> 41 #include <com/sun/star/xml/sax/XSAXSerializable.hpp> 42 #include <com/sun/star/beans/StringPair.hpp> 43 #include <com/sun/star/io/XActiveDataSource.hpp> 44 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp> 45 /** === end UNO includes === **/ 46 47 #include <tools/diagnose_ex.h> 48 #include <comphelper/processfactory.hxx> 49 50 #include <boost/scoped_ptr.hpp> 51 #include <limits> 52 53 /** === begin UNO using === **/ 54 using ::com::sun::star::uno::Reference; 55 using ::com::sun::star::uno::Exception; 56 using ::com::sun::star::uno::Sequence; 57 using ::com::sun::star::uno::RuntimeException; 58 using ::com::sun::star::uno::UNO_QUERY; 59 using ::com::sun::star::uno::UNO_QUERY_THROW; 60 using ::com::sun::star::uno::UNO_SET_THROW; 61 using ::com::sun::star::xml::dom::XNode; 62 using ::com::sun::star::xml::dom::XDocument; 63 using ::com::sun::star::xml::sax::XSAXSerializable; 64 using ::com::sun::star::beans::StringPair; 65 using ::com::sun::star::io::XActiveDataSource; 66 using ::com::sun::star::xml::dom::NodeType_DOCUMENT_NODE; 67 using ::com::sun::star::xml::dom::NodeType_ELEMENT_NODE; 68 using ::com::sun::star::xml::dom::XDocumentBuilder; 69 using ::com::sun::star::xml::sax::XDocumentHandler; 70 /** === end UNO using === **/ 71 72 CSerializationAppXML::CSerializationAppXML() 73 :m_aContext( ::comphelper::getProcessServiceFactory() ) 74 { 75 m_aContext.createComponent( "com.sun.star.io.Pipe", m_xBuffer ); 76 } 77 78 Reference< CSS::io::XInputStream > 79 CSerializationAppXML::getInputStream() 80 { 81 // The pipes output is provided through it's 82 // XOutputStream interface aspect 83 return Reference< CSS::io::XInputStream >(m_xBuffer, UNO_QUERY); 84 } 85 86 void 87 CSerializationAppXML::serialize_node(const Reference< XNode >& rNode) 88 { 89 try 90 { 91 Reference< XSAXSerializable > xSerializer( rNode, UNO_QUERY ); 92 if ( !xSerializer.is() ) 93 { 94 // ensure we have a "real" node 95 Reference< XNode > xNode = rNode; 96 if ( xNode->getNodeType() == NodeType_DOCUMENT_NODE ) 97 { 98 Reference< XDocument > const xDoc( xNode, UNO_QUERY_THROW ); 99 xNode.set( xDoc->getDocumentElement(), UNO_QUERY_THROW ); 100 } 101 ENSURE_OR_RETURN_VOID( xNode->getNodeType() == NodeType_ELEMENT_NODE, 102 "CSerializationAppXML::serialize_node: invalid node type!" ); 103 104 // create a new document 105 Reference< XDocumentBuilder > const xDocBuilder( 106 m_aContext.createComponent( "com.sun.star.xml.dom.DocumentBuilder" ), UNO_QUERY_THROW ); 107 Reference< XDocument > const xDocument( xDocBuilder->newDocument(), UNO_SET_THROW ); 108 109 // copy the to-be-serialized node 110 Reference< XNode > const xImportedNode( xDocument->importNode( xNode, true ), UNO_SET_THROW ); 111 xDocument->appendChild( xImportedNode ); 112 113 // ask the doc for the serializer 114 xSerializer.set( xDocument, UNO_QUERY ); 115 } 116 117 ENSURE_OR_RETURN_VOID( xSerializer.is(), 118 "CSerializationAppXML::serialize_node: no serialization access to the node/document!" ); 119 120 // create a SAXWriter to take the serialization events, and connect it to our pipe 121 Reference< XDocumentHandler > const xSaxWriter( 122 m_aContext.createComponent( "com.sun.star.xml.sax.Writer" ), UNO_QUERY_THROW ); 123 Reference< XActiveDataSource > const xDataSource( xSaxWriter, UNO_QUERY_THROW ); 124 xDataSource->setOutputStream( m_xBuffer ); 125 126 // do the serialization 127 xSerializer->serialize( xSaxWriter, Sequence< StringPair >() ); 128 } 129 catch( const Exception& ) 130 { 131 DBG_UNHANDLED_EXCEPTION(); 132 } 133 } 134 135 void 136 CSerializationAppXML::serialize() 137 { 138 if (!m_aFragment.is()) return; 139 140 Reference< XNode > cur = m_aFragment->getFirstChild(); 141 while (cur.is()) 142 { 143 serialize_node(cur); 144 cur = cur->getNextSibling(); 145 } 146 m_xBuffer->closeOutput(); 147 } 148