xref: /AOO41X/main/filter/source/xsltfilter/uof2splithandler.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
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  // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_filter.hxx"
24 
25 //This file is about the conversion of the UOF v2.0 and ODF document format
26 #include <com/sun/star/io/XActiveDataSource.hpp>
27 #include <com/sun/star/uno/Exception.hpp>
28 #include <com/sun/star/embed/ElementModes.hpp>
29 #include <comphelper/storagehelper.hxx>
30 #include <comphelper/attributelist.hxx>
31 #include <xmloff/attrlist.hxx>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/uno/Any.hxx>
34 
35 
36 #include "uof2splithandler.hxx"
37 
38 using namespace XSLT;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::io;
41 using namespace ::com::sun::star::xml::sax;
42 using namespace ::com::sun::star::embed;
43 using namespace ::com::sun::star::beans;
44 using namespace ::rtl;
45 
46 
47 
UOF2SplitHandler(::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rMultiFactory,::com::sun::star::uno::Reference<::com::sun::star::io::XStream> & rStream)48 UOF2SplitHandler::UOF2SplitHandler(
49         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rMultiFactory,
50         ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rStream )
51 : m_rStream( rStream )
52 , m_rMultiFactory( rMultiFactory )
53 , m_bIsStart( sal_False )
54 {
55     _Init();
56 }
57 
_Init()58 void UOF2SplitHandler::_Init()
59 {
60     if ( m_rMultiFactory.is() && m_rStream.is() )
61     {
62         try {
63             m_pStore = new UOF2Storage( m_rMultiFactory, m_rStream );
64             if ( m_pStore != NULL )
65                 m_pMainStore = m_pStore->getMainStorageRef();
66 
67             m_xHandler = Reference< XExtendedDocumentHandler >( m_rMultiFactory->createInstance(
68                 OUString::createFromAscii("com.sun.star.xml.sax.Writer")), UNO_QUERY );
69             Reference< XActiveDataSource > xSource( m_xHandler, UNO_QUERY );
70             xSource->setOutputStream( m_rStream->getOutputStream() );
71         }
72         catch( Exception& e)
73         {
74             OSL_ENSURE(0, ::rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
75         }
76     }
77 }
78 
~UOF2SplitHandler()79 UOF2SplitHandler::~UOF2SplitHandler()
80 {
81     delete m_pStore;
82 }
83 
startDocument()84 void UOF2SplitHandler::startDocument() throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
85 {
86     m_xHandler->startDocument();
87 }
88 
endDocument()89 void UOF2SplitHandler::endDocument() throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
90 {
91     m_xHandler->endDocument();
92 }
93 
startElement(const::rtl::OUString & qName,const::com::sun::star::uno::Reference<::com::sun::star::xml::sax::XAttributeList> & AttrList)94 void UOF2SplitHandler::startElement(const ::rtl::OUString& qName, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& AttrList )
95         throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
96 {
97     if ( qName.equalsAscii("pzip:entry") )
98     {
99         namespaceMap( AttrList );
100     }
101     else if ( qName.equalsAscii("pzip:target") )
102     {
103         aOutFileName = AttrList->getValueByName(::rtl::OUString::createFromAscii("pzip:path"));
104         m_bIsStart = sal_True;
105         Write( aOutFileName , m_bIsStart );
106     }
107     else
108     {
109         if ( m_bIsStart )  // start a sub file
110         {
111             // insert namespace declaration for the root element in each sub file
112             ::comphelper::AttributeList * aTmpAtt = new ::comphelper::AttributeList();
113             if ( aTmpAtt != NULL )
114             {
115                 typedef ::std::map< OUString, NamespaceValue >::iterator NSItr;
116                 for( NSItr it = aNamespaceMap.begin(); it != aNamespaceMap.end(); it++ )
117                 {
118                     aTmpAtt->AddAttribute( it->first, it->second.aType, it->second.aValue );
119                 }
120                 aTmpAtt->AppendAttributeList( AttrList );
121                 m_bIsStart = sal_False;
122                 const Reference< XAttributeList > xnewAttr( aTmpAtt );
123                 m_xHandler->startElement( qName, xnewAttr );
124             }
125         }
126         else
127             m_xHandler->startElement( qName, AttrList );
128     }
129 }
130 
endElement(const::rtl::OUString & qName)131 void UOF2SplitHandler::endElement(const ::rtl::OUString& qName )
132         throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
133 {
134     if ( qName.equalsAscii("pzip:entry") )
135     {
136         m_pMainStore->commit();
137     }
138     else if ( qName.equalsAscii("pzip:target" ) )
139     {
140         Write( aOutFileName, sal_False );
141     }
142     else
143     {
144         m_xHandler->endElement( qName );
145     }
146 }
147 
characters(const::rtl::OUString & rStr)148 void UOF2SplitHandler::characters(const ::rtl::OUString& rStr )
149         throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
150 {
151     m_xHandler->characters( rStr );
152 }
153 
ignorableWhitespace(const::rtl::OUString & str)154 void UOF2SplitHandler::ignorableWhitespace(const ::rtl::OUString& str)
155         throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
156 {
157     m_xHandler->ignorableWhitespace( str );
158 }
159 
processingInstruction(const::rtl::OUString &,const::rtl::OUString &)160 void UOF2SplitHandler::processingInstruction(const ::rtl::OUString& /*str*/, const ::rtl::OUString& /*str2*/)
161         throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
162 {
163 }
164 
setDocumentLocator(const::com::sun::star::uno::Reference<::com::sun::star::xml::sax::XLocator> &)165 void UOF2SplitHandler::setDocumentLocator(const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >&/* doclocator*/)
166         throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
167 {
168 }
169 
170 /* ----
171     create substream and write sub file when starting a <pzip:target> element
172     close substream when ending a <pzip:target> element
173 ---- */
Write(OUString & rFileName,sal_Bool bStart)174 void UOF2SplitHandler::Write( OUString & rFileName , sal_Bool bStart ) throw( RuntimeException )
175 {
176     if ( bStart )
177     {
178         try {
179             OUString sPath;
180             sal_Int32 nIndex = rFileName.lastIndexOf( sal_Unicode('/') );
181             if ( nIndex != -1 )
182             {
183                 OUString aTmp = rFileName;
184                 sPath = aTmp.copy(0, nIndex);
185                 rFileName = aTmp.copy( nIndex+1 );
186                 m_pCurStore = m_pMainStore->openSubStorage( sPath, sal_True );
187 
188                 m_xOutputStream = m_pCurStore->openOutputStream( rFileName );
189             }
190             else
191                 m_xOutputStream = m_pMainStore->openOutputStream( rFileName );
192 
193             if ( !m_xHandler.is() )
194             {
195                 m_xHandler = Reference< XExtendedDocumentHandler >( m_rMultiFactory->createInstance(
196                     OUString::createFromAscii("com.sun.star.xml.sax.Writer")), UNO_QUERY );
197             }
198             Reference< XActiveDataSource > xSource( m_xHandler, UNO_QUERY );
199             xSource->setOutputStream( m_xOutputStream );
200 
201             if ( m_xHandler.is() )
202                 m_xHandler->startDocument();
203             else
204             {
205                 SAXException except;
206                 except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "startElement called before startDocument" ));
207                 throw except;
208             }
209         }
210         catch( ::com::sun::star::uno::Exception& e )
211         {
212             OSL_ENSURE(0, ::rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
213         }
214     }
215     else
216     {
217         if ( m_xHandler.is() )
218             m_xHandler->endDocument();
219     }
220 }
221 
222 /* -----
223     collect namesapce declaration of the <pzip:entry> element
224 ---- */
namespaceMap(const::com::sun::star::uno::Reference<::com::sun::star::xml::sax::XAttributeList> & AttrList)225 void UOF2SplitHandler::namespaceMap( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& AttrList )
226 {
227     sal_Int16 aAttrCount = AttrList->getLength();
228     for ( sal_Int16 i = 0; i< aAttrCount; i++ )
229     {
230         OUString aName = AttrList->getNameByIndex( i );
231         sal_Int32 nToken = aName.indexOf( sal_Unicode(':') );
232         OUString aPrefix = aName.copy( 0, nToken );
233         if ( aPrefix.equalsAscii("xmlns") )
234         {
235             if ( aNamespaceMap.find( aName ) == aNamespaceMap.end() )
236             {
237                 OUString sType = AttrList->getTypeByIndex( i );
238                 OUString sValue = AttrList->getValueByIndex( i );
239                 aNamespaceMap.insert( ::std::map< OUString, NamespaceValue >::value_type(aName , NamespaceValue( sType , sValue )) );
240             }
241         }
242     }
243 }
244