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