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 <com/sun/star/xml/sax/XParser.hpp>
25 
26 #include <com/sun/star/xml/sax/SAXException.hpp>
27 #include <doctok/resourceids.hxx>
28 #include <ooxml/resourceids.hxx>
29 #include "OOXMLDocumentImpl.hxx"
30 #include "OOXMLBinaryObjectReference.hxx"
31 #include "OOXMLFastDocumentHandler.hxx"
32 #include "OOXMLPropertySetImpl.hxx"
33 #include "ooxmlLoggers.hxx"
34 
35 #include <iostream>
36 
37 using ::com::sun::star::xml::sax::SAXException;
38 namespace writerfilter {
39 namespace ooxml
40 {
41 
42 #ifdef DEBUG
43 TagLogger::Pointer_t debug_logger(TagLogger::getInstance("DEBUG"));
44 #endif
45 
46 using namespace ::std;
47 
OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream)48 OOXMLDocumentImpl::OOXMLDocumentImpl(
49     OOXMLStream::Pointer_t pStream )
50     : mpStream(pStream)
51     , mnIDForXNoteStream( -1 )
52     , mxModel()
53     , mxDrawPage()
54     , mbIsSubstream( false )
55 {
56 }
57 
OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream,uno::Reference<frame::XModel> xModel,uno::Reference<drawing::XDrawPage> xDrawPage,const bool bIsSubstream)58 OOXMLDocumentImpl::OOXMLDocumentImpl(
59     OOXMLStream::Pointer_t pStream,
60     uno::Reference<frame::XModel> xModel,
61     uno::Reference<drawing::XDrawPage> xDrawPage,
62     const bool bIsSubstream )
63     : mpStream(pStream)
64     , mnIDForXNoteStream( -1 )
65     , mxModel( xModel )
66     , mxDrawPage( xDrawPage )
67     , mbIsSubstream( bIsSubstream )
68 {
69 }
70 
OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream,const sal_Int32 nIDForXNoteStream)71 OOXMLDocumentImpl::OOXMLDocumentImpl(
72     OOXMLStream::Pointer_t pStream,
73     const sal_Int32 nIDForXNoteStream )
74     : mpStream(pStream)
75     , mnIDForXNoteStream( nIDForXNoteStream )
76     , mxModel()
77     , mxDrawPage()
78     , mbIsSubstream( false )
79 {
80 }
81 
~OOXMLDocumentImpl()82 OOXMLDocumentImpl::~OOXMLDocumentImpl()
83 {
84 }
85 
resolveFastSubStream(Stream & rStreamHandler,OOXMLStream::StreamType_t nType)86 void OOXMLDocumentImpl::resolveFastSubStream(Stream & rStreamHandler,
87                                              OOXMLStream::StreamType_t nType)
88 {
89     OOXMLStream::Pointer_t pStream
90         (OOXMLDocumentFactory::createStream(mpStream, nType));
91 
92     uno::Reference< xml::sax::XFastParser > xParser
93         (mpStream->getFastParser());
94 
95     if (xParser.is())
96     {
97         uno::Reference<uno::XComponentContext> xContext(mpStream->getContext());
98         OOXMLFastDocumentHandler * pDocHandler =
99             new OOXMLFastDocumentHandler( xContext, &rStreamHandler, this );
100 
101         uno::Reference < xml::sax::XFastDocumentHandler > xDocumentHandler
102             (pDocHandler);
103         uno::Reference < xml::sax::XFastTokenHandler > xTokenHandler
104             (mpStream->getFastTokenHandler(xContext));
105 
106         xParser->setFastDocumentHandler(xDocumentHandler);
107         xParser->setTokenHandler(xTokenHandler);
108 
109         uno::Reference<io::XInputStream> xInputStream =
110             pStream->getDocumentStream();
111 
112         if (xInputStream.is())
113         {
114             struct xml::sax::InputSource oInputSource;
115             oInputSource.aInputStream = xInputStream;
116             xParser->parseStream(oInputSource);
117 
118             xInputStream->closeInput();
119         }
120     }
121 }
122 
resolveFastSubStreamWithId(Stream & rStream,writerfilter::Reference<Stream>::Pointer_t pStream,sal_uInt32 nId)123 void OOXMLDocumentImpl::resolveFastSubStreamWithId(Stream & rStream,
124                                       writerfilter::Reference<Stream>::Pointer_t pStream,
125 				      sal_uInt32 nId)
126 {
127     rStream.substream(nId, pStream);
128 }
129 
setIDForXNoteStream(const sal_Int32 nID)130 void OOXMLDocumentImpl::setIDForXNoteStream( const sal_Int32 nID )
131 {
132     mnIDForXNoteStream = nID;
133 }
134 
getIDForXNoteStream() const135 sal_Int32 OOXMLDocumentImpl::getIDForXNoteStream() const
136 {
137     return mnIDForXNoteStream;
138 }
139 
140 
getTarget() const141 const ::rtl::OUString & OOXMLDocumentImpl::getTarget() const
142 {
143     return mpStream->getTarget();
144 }
145 
146 writerfilter::Reference<Stream>::Pointer_t
getSubStream(const rtl::OUString & rId)147 OOXMLDocumentImpl::getSubStream(const rtl::OUString & rId)
148 {
149     OOXMLStream::Pointer_t pStream
150         (OOXMLDocumentFactory::createStream(mpStream, rId));
151 
152     writerfilter::Reference<Stream>::Pointer_t pRet(
153         new OOXMLDocumentImpl(
154             pStream,
155             mxModel,
156             mxDrawPage,
157             true ) );
158 
159     return pRet;
160 }
161 
getXNoteStream(OOXMLStream::StreamType_t nType,const sal_Int32 nIDForXNoteStream)162 writerfilter::Reference<Stream>::Pointer_t OOXMLDocumentImpl::getXNoteStream(
163     OOXMLStream::StreamType_t nType,
164     const sal_Int32 nIDForXNoteStream )
165 {
166 #ifdef DEBUG_ELEMENT
167     debug_logger->startElement("getXNoteStream");
168     debug_logger->attribute("id", rId);
169     debug_logger->endElement("getXNoteStream");
170 #endif
171 
172     OOXMLStream::Pointer_t pStream =
173         (OOXMLDocumentFactory::createStream(mpStream, nType));
174     OOXMLDocumentImpl * pDocument =
175         new OOXMLDocumentImpl(
176             pStream,
177             nIDForXNoteStream );
178 
179     return writerfilter::Reference<Stream>::Pointer_t(pDocument);
180 }
181 
resolveFootnote(Stream & rStream,const Id & rType,const sal_Int32 nIDForXNoteStream)182 void OOXMLDocumentImpl::resolveFootnote(
183     Stream & rStream,
184     const Id & rType,
185     const sal_Int32 nIDForXNoteStream )
186 {
187     writerfilter::Reference<Stream>::Pointer_t pStream =
188         getXNoteStream( OOXMLStream::FOOTNOTES, nIDForXNoteStream );
189 
190     Id nId;
191     switch (rType)
192     {
193     case NS_ooxml::LN_Value_wordprocessingml_ST_FtnEdn_separator:
194     case NS_ooxml::LN_Value_wordprocessingml_ST_FtnEdn_continuationSeparator:
195         nId = rType;
196         break;
197     default:
198         nId = NS_rtf::LN_footnote;
199         break;
200     }
201 
202     resolveFastSubStreamWithId( rStream, pStream, nId );
203 }
204 
resolveEndnote(Stream & rStream,const Id & rType,const sal_Int32 nIDForXNoteStream)205 void OOXMLDocumentImpl::resolveEndnote(
206     Stream & rStream,
207     const Id & rType,
208     const sal_Int32 nIDForXNoteStream )
209 {
210     writerfilter::Reference<Stream>::Pointer_t pStream =
211         getXNoteStream( OOXMLStream::ENDNOTES, nIDForXNoteStream );
212 
213     Id nId;
214     switch (rType)
215     {
216     case NS_ooxml::LN_Value_wordprocessingml_ST_FtnEdn_separator:
217     case NS_ooxml::LN_Value_wordprocessingml_ST_FtnEdn_continuationSeparator:
218         nId = rType;
219         break;
220     default:
221         nId = NS_rtf::LN_endnote;
222         break;
223     }
224 
225     resolveFastSubStreamWithId( rStream, pStream, nId );
226 }
227 
resolveComment(Stream & rStream,const sal_Int32 nIDForXNoteStream)228 void OOXMLDocumentImpl::resolveComment(
229     Stream & rStream,
230     const sal_Int32 nIDForXNoteStream )
231 {
232     writerfilter::Reference<Stream>::Pointer_t pStream =
233         getXNoteStream(OOXMLStream::COMMENTS, nIDForXNoteStream );
234 
235     resolveFastSubStreamWithId( rStream, pStream, NS_rtf::LN_annotation );
236 }
237 
getPicturePropSet(const::rtl::OUString & rId)238 OOXMLPropertySet * OOXMLDocumentImpl::getPicturePropSet
239 (const ::rtl::OUString & rId)
240 {
241     OOXMLStream::Pointer_t pStream
242         (OOXMLDocumentFactory::createStream(mpStream, rId));
243 
244     writerfilter::Reference<BinaryObj>::Pointer_t pPicture
245         (new OOXMLBinaryObjectReference(pStream));
246 
247     OOXMLValue::Pointer_t pPayloadValue(new OOXMLBinaryValue(pPicture));
248 
249     OOXMLProperty::Pointer_t pPayloadProperty
250         (new OOXMLPropertyImpl(NS_rtf::LN_payload, pPayloadValue,
251                                OOXMLPropertyImpl::ATTRIBUTE));
252 
253     OOXMLPropertySet::Pointer_t pBlipSet(new OOXMLPropertySetImpl());
254 
255     pBlipSet->add(pPayloadProperty);
256 
257     OOXMLValue::Pointer_t pBlipValue(new OOXMLPropertySetValue(pBlipSet));
258 
259     OOXMLProperty::Pointer_t pBlipProperty
260         (new OOXMLPropertyImpl(NS_rtf::LN_blip, pBlipValue,
261                                OOXMLPropertyImpl::ATTRIBUTE));
262 
263     OOXMLPropertySet * pProps = new OOXMLPropertySetImpl();
264 
265     pProps->add(pBlipProperty);
266 
267     return pProps;
268 }
269 
resolvePicture(Stream & rStream,const rtl::OUString & rId)270 void OOXMLDocumentImpl::resolvePicture(Stream & rStream,
271                                        const rtl::OUString & rId)
272 {
273     OOXMLPropertySet * pProps = getPicturePropSet(rId);
274 
275     rStream.props(writerfilter::Reference<Properties>::Pointer_t(pProps));
276 }
277 
getTargetForId(const::rtl::OUString & rId)278 ::rtl::OUString OOXMLDocumentImpl::getTargetForId(const ::rtl::OUString & rId)
279 {
280     return mpStream->getTargetForId(rId);
281 }
282 
resolveHeader(Stream & rStream,const sal_Int32 type,const rtl::OUString & rId)283 void OOXMLDocumentImpl::resolveHeader(Stream & rStream,
284                                       const sal_Int32 type,
285                                       const rtl::OUString & rId)
286 {
287      writerfilter::Reference<Stream>::Pointer_t pStream =
288          getSubStream(rId);
289      switch (type)
290      {
291      case NS_ooxml::LN_Value_ST_HrdFtr_even:
292          resolveFastSubStreamWithId(rStream, pStream, NS_rtf::LN_headerl);
293         break;
294      case NS_ooxml::LN_Value_ST_HrdFtr_default: // here we assume that default is right, but not necessarily true :-(
295          resolveFastSubStreamWithId(rStream, pStream, NS_rtf::LN_headerr);
296          break;
297      case NS_ooxml::LN_Value_ST_HrdFtr_first:
298          resolveFastSubStreamWithId(rStream, pStream, NS_rtf::LN_headerf);
299          break;
300      default:
301          break;
302      }
303 }
304 
resolveFooter(Stream & rStream,const sal_Int32 type,const rtl::OUString & rId)305 void OOXMLDocumentImpl::resolveFooter(Stream & rStream,
306                                       const sal_Int32 type,
307                                       const rtl::OUString & rId)
308 {
309      writerfilter::Reference<Stream>::Pointer_t pStream =
310          getSubStream(rId);
311 
312      switch (type)
313      {
314      case NS_ooxml::LN_Value_ST_HrdFtr_even:
315          resolveFastSubStreamWithId(rStream, pStream, NS_rtf::LN_footerl);
316          break;
317      case NS_ooxml::LN_Value_ST_HrdFtr_default: // here we assume that default is right, but not necessarily true :-(
318          resolveFastSubStreamWithId(rStream, pStream, NS_rtf::LN_footerr);
319          break;
320      case NS_ooxml::LN_Value_ST_HrdFtr_first:
321          resolveFastSubStreamWithId(rStream, pStream, NS_rtf::LN_footerf);
322          break;
323      default:
324          break;
325      }
326 }
327 
resolve(Stream & rStream)328 void OOXMLDocumentImpl::resolve(Stream & rStream)
329 {
330 #ifdef DEBUG_RESOLVE
331     debug_logger->startElement("OOXMLDocumentImpl.resolve");
332 #endif
333 
334     uno::Reference< xml::sax::XFastParser > xParser
335         (mpStream->getFastParser());
336 
337     if (xParser.is())
338     {
339         uno::Reference<uno::XComponentContext> xContext(mpStream->getContext());
340 
341         OOXMLFastDocumentHandler * pDocHandler =
342             new OOXMLFastDocumentHandler( xContext, &rStream, this );
343         pDocHandler->setIsSubstream( mbIsSubstream );
344         uno::Reference < xml::sax::XFastDocumentHandler > xDocumentHandler
345             (pDocHandler);
346         uno::Reference < xml::sax::XFastTokenHandler > xTokenHandler
347             (mpStream->getFastTokenHandler(xContext));
348 
349         resolveFastSubStream(rStream, OOXMLStream::SETTINGS);
350         resolveFastSubStream(rStream, OOXMLStream::THEME);
351         resolveFastSubStream(rStream, OOXMLStream::FONTTABLE);
352         resolveFastSubStream(rStream, OOXMLStream::STYLES);
353         resolveFastSubStream(rStream, OOXMLStream::NUMBERING);
354 
355         xParser->setFastDocumentHandler( xDocumentHandler );
356         xParser->setTokenHandler( xTokenHandler );
357 
358         xml::sax::InputSource aParserInput;
359         aParserInput.aInputStream = mpStream->getDocumentStream();
360         try
361         {
362             xParser->parseStream(aParserInput);
363         }
364         catch (...) {
365 #ifdef DEBUG_ELEMENT
366             debug_logger->element("exception");
367 #endif
368         }
369     }
370 
371 #ifdef DEBUG_RESOLVE
372     debug_logger->endElement("OOXMLDocumentImpl.resolve");
373 #endif
374 }
375 
getInputStreamForId(const::rtl::OUString & rId)376 uno::Reference<io::XInputStream> OOXMLDocumentImpl::getInputStreamForId(const ::rtl::OUString & rId)
377 {
378     OOXMLStream::Pointer_t pStream(OOXMLDocumentFactory::createStream(mpStream, rId));
379 
380     return pStream->getDocumentStream();
381 }
382 
getType() const383 string OOXMLDocumentImpl::getType() const
384 {
385     return "OOXMLDocumentImpl";
386 }
387 
setModel(uno::Reference<frame::XModel> xModel)388 void OOXMLDocumentImpl::setModel(uno::Reference<frame::XModel> xModel)
389 {
390     mxModel.set(xModel);
391 }
392 
getModel()393 uno::Reference<frame::XModel> OOXMLDocumentImpl::getModel()
394 {
395     return mxModel;
396 }
397 
setDrawPage(uno::Reference<drawing::XDrawPage> xDrawPage)398 void OOXMLDocumentImpl::setDrawPage(uno::Reference<drawing::XDrawPage> xDrawPage)
399 {
400     mxDrawPage.set(xDrawPage);
401 }
402 
getDrawPage()403 uno::Reference<drawing::XDrawPage> OOXMLDocumentImpl::getDrawPage()
404 {
405     return mxDrawPage;
406 }
407 
getInputStream()408 uno::Reference<io::XInputStream> OOXMLDocumentImpl::getInputStream()
409 {
410     return mpStream->getDocumentStream();
411 }
412 
getStorageStream()413 uno::Reference<io::XInputStream> OOXMLDocumentImpl::getStorageStream()
414 {
415     return mpStream->getStorageStream();
416 }
417 
createDocument(OOXMLStream::Pointer_t pStream)418 OOXMLDocument * OOXMLDocumentFactory::createDocument(
419     OOXMLStream::Pointer_t pStream )
420 {
421     return new OOXMLDocumentImpl(pStream);
422 }
423 
424 }}
425