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