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 #include "precompiled_dbaccess.hxx"
25 
26 #include "storagexmlstream.hxx"
27 
28 /** === begin UNO includes === **/
29 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
30 #include <com/sun/star/io/XActiveDataSource.hpp>
31 #include <com/sun/star/xml/sax/XParser.hpp>
32 /** === end UNO includes === **/
33 
34 #include <comphelper/componentcontext.hxx>
35 #include <cppuhelper/implbase1.hxx>
36 #include <rtl/ref.hxx>
37 #include <tools/diagnose_ex.h>
38 #include <xmloff/attrlist.hxx>
39 
40 #include <stack>
41 
42 //......................................................................................................................
43 namespace dbaccess
44 {
45 //......................................................................................................................
46 
47 	/** === begin UNO using === **/
48 	using ::com::sun::star::uno::Reference;
49 	using ::com::sun::star::uno::XInterface;
50 	using ::com::sun::star::uno::UNO_QUERY;
51 	using ::com::sun::star::uno::UNO_QUERY_THROW;
52 	using ::com::sun::star::uno::UNO_SET_THROW;
53 	using ::com::sun::star::uno::Exception;
54 	using ::com::sun::star::uno::RuntimeException;
55 	using ::com::sun::star::uno::Any;
56 	using ::com::sun::star::uno::makeAny;
57 	using ::com::sun::star::uno::Sequence;
58 	using ::com::sun::star::uno::Type;
59     using ::com::sun::star::embed::XStorage;
60     using ::com::sun::star::xml::sax::XDocumentHandler;
61     using ::com::sun::star::xml::sax::XAttributeList;
62     using ::com::sun::star::io::XStream;
63     using ::com::sun::star::io::XOutputStream;
64     using ::com::sun::star::io::XActiveDataSource;
65     using ::com::sun::star::xml::sax::XParser;
66     using ::com::sun::star::xml::sax::InputSource;
67 	/** === end UNO using === **/
68 
69 	//==================================================================================================================
70 	//= StorageXMLOutputStream_Data
71 	//==================================================================================================================
72     struct StorageXMLOutputStream_Data
73     {
74         Reference< XDocumentHandler >           xHandler;
75         ::std::stack< ::rtl::OUString >         aElements;
76         ::rtl::Reference< SvXMLAttributeList >  xAttributes;
77     };
78 
79 	//==================================================================================================================
80 	//= StorageXMLOutputStream
81 	//==================================================================================================================
82 	//------------------------------------------------------------------------------------------------------------------
StorageXMLOutputStream(const::comphelper::ComponentContext & i_rContext,const Reference<XStorage> & i_rParentStorage,const::rtl::OUString & i_rStreamName)83     StorageXMLOutputStream::StorageXMLOutputStream( const ::comphelper::ComponentContext& i_rContext,
84                                                     const Reference< XStorage >& i_rParentStorage,
85                                                     const ::rtl::OUString& i_rStreamName )
86         :StorageOutputStream( i_rContext, i_rParentStorage, i_rStreamName )
87         ,m_pData( new StorageXMLOutputStream_Data )
88     {
89         const Reference< XActiveDataSource > xSaxWriter( i_rContext.createComponent( "com.sun.star.xml.sax.Writer" ), UNO_QUERY_THROW );
90         xSaxWriter->setOutputStream( getOutputStream() );
91 
92         m_pData->xHandler.set( xSaxWriter, UNO_QUERY_THROW );
93         m_pData->xHandler->startDocument();
94 
95         m_pData->xAttributes = new SvXMLAttributeList;
96     }
97 
98 	//------------------------------------------------------------------------------------------------------------------
~StorageXMLOutputStream()99     StorageXMLOutputStream::~StorageXMLOutputStream()
100     {
101     }
102 
103     //------------------------------------------------------------------------------------------------------------------
close()104     void StorageXMLOutputStream::close()
105     {
106         ENSURE_OR_RETURN_VOID( m_pData->xHandler.is(), "illegal document handler" );
107         m_pData->xHandler->endDocument();
108         // do not call the base class, it would call closeOutput on the output stream, which is already done by
109         // endDocument
110     }
111 
112 	//------------------------------------------------------------------------------------------------------------------
addAttribute(const::rtl::OUString & i_rName,const::rtl::OUString & i_rValue) const113     void StorageXMLOutputStream::addAttribute( const ::rtl::OUString& i_rName, const ::rtl::OUString& i_rValue ) const
114     {
115         m_pData->xAttributes->AddAttribute( i_rName, i_rValue );
116     }
117 
118 	//------------------------------------------------------------------------------------------------------------------
startElement(const::rtl::OUString & i_rElementName) const119     void StorageXMLOutputStream::startElement( const ::rtl::OUString& i_rElementName ) const
120     {
121         ENSURE_OR_RETURN_VOID( m_pData->xHandler.is(), "no document handler" );
122 
123         m_pData->xHandler->startElement( i_rElementName, m_pData->xAttributes.get() );
124         m_pData->xAttributes = new SvXMLAttributeList;
125         m_pData->aElements.push( i_rElementName );
126     }
127 
128 	//------------------------------------------------------------------------------------------------------------------
endElement() const129     void StorageXMLOutputStream::endElement() const
130     {
131         ENSURE_OR_RETURN_VOID( m_pData->xHandler.is(), "no document handler" );
132         ENSURE_OR_RETURN_VOID( !m_pData->aElements.empty(), "no element on the stack" );
133 
134         const ::rtl::OUString sElementName( m_pData->aElements.top() );
135         m_pData->xHandler->endElement( sElementName );
136         m_pData->aElements.pop();
137     }
138 
139 	//------------------------------------------------------------------------------------------------------------------
ignorableWhitespace(const::rtl::OUString & i_rWhitespace) const140     void StorageXMLOutputStream::ignorableWhitespace( const ::rtl::OUString& i_rWhitespace ) const
141     {
142         ENSURE_OR_RETURN_VOID( m_pData->xHandler.is(), "no document handler" );
143 
144         m_pData->xHandler->ignorableWhitespace( i_rWhitespace );
145     }
146 
147 	//------------------------------------------------------------------------------------------------------------------
characters(const::rtl::OUString & i_rCharacters) const148     void StorageXMLOutputStream::characters( const ::rtl::OUString& i_rCharacters ) const
149     {
150         ENSURE_OR_RETURN_VOID( m_pData->xHandler.is(), "no document handler" );
151 
152         m_pData->xHandler->characters( i_rCharacters );
153     }
154 
155 	//==================================================================================================================
156 	//= StorageXMLInputStream_Data
157 	//==================================================================================================================
158     struct StorageXMLInputStream_Data
159     {
160         Reference< XParser >    xParser;
161     };
162 
163 	//==================================================================================================================
164 	//= StorageXMLInputStream
165 	//==================================================================================================================
166 	//------------------------------------------------------------------------------------------------------------------
StorageXMLInputStream(const::comphelper::ComponentContext & i_rContext,const Reference<XStorage> & i_rParentStorage,const::rtl::OUString & i_rStreamName)167     StorageXMLInputStream::StorageXMLInputStream( const ::comphelper::ComponentContext& i_rContext,
168                                                   const Reference< XStorage >& i_rParentStorage,
169                                                   const ::rtl::OUString& i_rStreamName )
170         :StorageInputStream( i_rContext, i_rParentStorage, i_rStreamName )
171         ,m_pData( new StorageXMLInputStream_Data )
172     {
173         m_pData->xParser.set( i_rContext.createComponent( "com.sun.star.xml.sax.Parser" ), UNO_QUERY_THROW );
174     }
175 
176 	//------------------------------------------------------------------------------------------------------------------
import(const Reference<XDocumentHandler> & i_rHandler)177     void StorageXMLInputStream::import( const Reference< XDocumentHandler >& i_rHandler )
178     {
179         ENSURE_OR_THROW( i_rHandler.is(), "illegal document handler (NULL)" );
180 
181         InputSource aInputSource;
182         aInputSource.aInputStream = getInputStream();
183 
184         m_pData->xParser->setDocumentHandler( i_rHandler );
185         m_pData->xParser->parseStream( aInputSource );
186     }
187 
188 	//------------------------------------------------------------------------------------------------------------------
~StorageXMLInputStream()189     StorageXMLInputStream::~StorageXMLInputStream()
190     {
191     }
192 
193 //......................................................................................................................
194 } // namespace dbaccess
195 //......................................................................................................................
196