1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_forms.hxx"
26 
27 #include "serialization.hxx"
28 #include "serialization_app_xml.hxx"
29 
30 /** === begin UNO includes === **/
31 #include <com/sun/star/xml/dom/XNode.hpp>
32 #include <com/sun/star/xml/dom/XDocument.hpp>
33 #include <com/sun/star/xml/dom/XNodeList.hpp>
34 #include <com/sun/star/xml/dom/NodeType.hpp>
35 #include <com/sun/star/lang/XUnoTunnel.hpp>
36 #include <com/sun/star/xml/xpath/XPathObjectType.hpp>
37 #include <com/sun/star/xml/sax/XSAXSerializable.hpp>
38 #include <com/sun/star/beans/StringPair.hpp>
39 #include <com/sun/star/io/XActiveDataSource.hpp>
40 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
41 /** === end UNO includes === **/
42 
43 #include <tools/diagnose_ex.h>
44 #include <comphelper/processfactory.hxx>
45 
46 #include <boost/scoped_ptr.hpp>
47 #include <limits>
48 
49 /** === begin UNO using === **/
50 using ::com::sun::star::uno::Reference;
51 using ::com::sun::star::uno::Exception;
52 using ::com::sun::star::uno::Sequence;
53 using ::com::sun::star::uno::RuntimeException;
54 using ::com::sun::star::uno::UNO_QUERY;
55 using ::com::sun::star::uno::UNO_QUERY_THROW;
56 using ::com::sun::star::uno::UNO_SET_THROW;
57 using ::com::sun::star::xml::dom::XNode;
58 using ::com::sun::star::xml::dom::XDocument;
59 using ::com::sun::star::xml::sax::XSAXSerializable;
60 using ::com::sun::star::beans::StringPair;
61 using ::com::sun::star::io::XActiveDataSource;
62 using ::com::sun::star::xml::dom::NodeType_DOCUMENT_NODE;
63 using ::com::sun::star::xml::dom::NodeType_ELEMENT_NODE;
64 using ::com::sun::star::xml::dom::XDocumentBuilder;
65 using ::com::sun::star::xml::sax::XDocumentHandler;
66 /** === end UNO using === **/
67 
CSerializationAppXML()68 CSerializationAppXML::CSerializationAppXML()
69     :m_aContext( ::comphelper::getProcessServiceFactory() )
70 {
71     m_aContext.createComponent( "com.sun.star.io.Pipe", m_xBuffer );
72 }
73 
74 Reference< CSS::io::XInputStream >
getInputStream()75 CSerializationAppXML::getInputStream()
76 {
77     // The pipes output is provided through it's
78     // XOutputStream interface aspect
79     return Reference< CSS::io::XInputStream >(m_xBuffer, UNO_QUERY);
80 }
81 
82 void
serialize_node(const Reference<XNode> & rNode)83 CSerializationAppXML::serialize_node(const Reference< XNode >& rNode)
84 {
85     try
86     {
87         Reference< XSAXSerializable > xSerializer( rNode, UNO_QUERY );
88         if ( !xSerializer.is() )
89         {
90             // ensure we have a "real" node
91             Reference< XNode > xNode = rNode;
92             if ( xNode->getNodeType() == NodeType_DOCUMENT_NODE )
93             {
94                 Reference< XDocument > const xDoc( xNode, UNO_QUERY_THROW );
95                 xNode.set( xDoc->getDocumentElement(), UNO_QUERY_THROW );
96             }
97             ENSURE_OR_RETURN_VOID( xNode->getNodeType() == NodeType_ELEMENT_NODE,
98                 "CSerializationAppXML::serialize_node: invalid node type!" );
99 
100             // create a new document
101             Reference< XDocumentBuilder > const xDocBuilder(
102                 m_aContext.createComponent( "com.sun.star.xml.dom.DocumentBuilder" ), UNO_QUERY_THROW );
103             Reference< XDocument > const xDocument( xDocBuilder->newDocument(), UNO_SET_THROW );
104 
105             // copy the to-be-serialized node
106             Reference< XNode > const xImportedNode( xDocument->importNode( xNode, true ), UNO_SET_THROW );
107             xDocument->appendChild( xImportedNode );
108 
109             // ask the doc for the serializer
110             xSerializer.set( xDocument, UNO_QUERY );
111         }
112 
113         ENSURE_OR_RETURN_VOID( xSerializer.is(),
114             "CSerializationAppXML::serialize_node: no serialization access to the node/document!" );
115 
116         // create a SAXWriter to take the serialization events, and connect it to our pipe
117         Reference< XDocumentHandler > const xSaxWriter(
118             m_aContext.createComponent( "com.sun.star.xml.sax.Writer" ), UNO_QUERY_THROW );
119         Reference< XActiveDataSource > const xDataSource( xSaxWriter, UNO_QUERY_THROW );
120         xDataSource->setOutputStream( m_xBuffer );
121 
122         // do the serialization
123         xSerializer->serialize( xSaxWriter, Sequence< StringPair >() );
124     }
125     catch( const Exception& )
126     {
127     	DBG_UNHANDLED_EXCEPTION();
128     }
129 }
130 
131 void
serialize()132 CSerializationAppXML::serialize()
133 {
134     if (!m_aFragment.is()) return;
135 
136     Reference< XNode > cur = m_aFragment->getFirstChild();
137     while (cur.is())
138     {
139         serialize_node(cur);
140         cur = cur->getNextSibling();
141     }
142     m_xBuffer->closeOutput();
143 }
144