Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <comphelper/sequenceashashmap.hxx>
21 :
22 : #include <com/sun/star/xml/sax/XParser.hpp>
23 :
24 : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
25 : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
26 : #include <com/sun/star/xml/sax/SAXException.hpp>
27 : #include <com/sun/star/xml/dom/DocumentBuilder.hpp>
28 : #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
29 : #include <ooxml/resourceids.hxx>
30 : #include "OOXMLStreamImpl.hxx"
31 : #include "OOXMLDocumentImpl.hxx"
32 : #include "OOXMLBinaryObjectReference.hxx"
33 : #include "OOXMLFastDocumentHandler.hxx"
34 : #include "OOXMLPropertySetImpl.hxx"
35 :
36 : #include <tools/resmgr.hxx>
37 : #include <vcl/svapp.hxx>
38 : #include <vcl/settings.hxx>
39 : #include <svx/dialogs.hrc>
40 :
41 : #include <iostream>
42 :
43 : // this extern variable is declared in OOXMLStreamImpl.hxx
44 24 : OUString customTarget;
45 24 : OUString embeddingsTarget;
46 : using namespace ::com::sun::star;
47 : namespace writerfilter {
48 : namespace ooxml
49 : {
50 :
51 2910 : OOXMLDocumentImpl::OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream, const uno::Reference<task::XStatusIndicator>& xStatusIndicator, bool bSkipImages)
52 : : mpStream(pStream)
53 : , mxStatusIndicator(xStatusIndicator)
54 : , mnXNoteId(0)
55 : , mXNoteType(0)
56 : , mxThemeDom(nullptr)
57 : , mbIsSubstream(false)
58 : , mbSkipImages(bSkipImages)
59 : , mnPercentSize(0)
60 : , mnProgressLastPos(0)
61 : , mnProgressCurrentPos(0)
62 2910 : , mnProgressEndPos(0)
63 : {
64 2910 : }
65 :
66 5820 : OOXMLDocumentImpl::~OOXMLDocumentImpl()
67 : {
68 5820 : }
69 :
70 16433 : void OOXMLDocumentImpl::resolveFastSubStream(Stream & rStreamHandler,
71 : OOXMLStream::StreamType_t nType)
72 : {
73 16433 : OOXMLStream::Pointer_t pStream;
74 : try
75 : {
76 16433 : pStream = OOXMLDocumentFactory::createStream(mpStream, nType);
77 : }
78 0 : catch (uno::Exception const& e)
79 : {
80 : SAL_INFO("writerfilter", "resolveFastSubStream: exception while "
81 : "resolving stream " << nType << " : " << e.Message);
82 16433 : return;
83 : }
84 32866 : OOXMLStream::Pointer_t savedStream = mpStream;
85 16433 : mpStream = pStream;
86 :
87 : uno::Reference< xml::sax::XFastParser > xParser
88 32866 : (mpStream->getFastParser());
89 :
90 16433 : if (xParser.is())
91 : {
92 16433 : uno::Reference<uno::XComponentContext> xContext(mpStream->getContext());
93 : OOXMLFastDocumentHandler * pDocHandler =
94 : new OOXMLFastDocumentHandler(
95 16433 : xContext, &rStreamHandler, this, mnXNoteId );
96 :
97 : uno::Reference < xml::sax::XFastDocumentHandler > xDocumentHandler
98 32866 : (pDocHandler);
99 32866 : uno::Reference < xml::sax::XFastTokenHandler > xTokenHandler(mpStream->getFastTokenHandler());
100 :
101 16433 : xParser->setFastDocumentHandler(xDocumentHandler);
102 16433 : xParser->setTokenHandler(xTokenHandler);
103 :
104 : uno::Reference<io::XInputStream> xInputStream =
105 32866 : pStream->getDocumentStream();
106 :
107 16433 : if (xInputStream.is())
108 : {
109 8117 : struct xml::sax::InputSource oInputSource;
110 8117 : oInputSource.aInputStream = xInputStream;
111 8117 : xParser->parseStream(oInputSource);
112 :
113 8117 : xInputStream->closeInput();
114 16433 : }
115 : }
116 :
117 32866 : mpStream = savedStream;
118 : }
119 :
120 1386 : void OOXMLDocumentImpl::resolveFastSubStreamWithId(Stream & rStream,
121 : writerfilter::Reference<Stream>::Pointer_t pStream,
122 : sal_uInt32 nId)
123 : {
124 1386 : rStream.substream(nId, pStream);
125 1386 : }
126 :
127 7706 : uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::importSubStream(OOXMLStream::StreamType_t nType)
128 : {
129 7706 : uno::Reference<xml::dom::XDocument> xRet;
130 :
131 15412 : OOXMLStream::Pointer_t pStream;
132 : try
133 : {
134 7706 : pStream = OOXMLDocumentFactory::createStream(mpStream, nType);
135 : }
136 0 : catch (uno::Exception const& e)
137 : {
138 : SAL_INFO("writerfilter", "importSubStream: exception while "
139 : "importing stream " << nType << " : " << e.Message);
140 0 : return xRet;
141 : }
142 :
143 : uno::Reference<io::XInputStream> xInputStream =
144 15412 : pStream->getDocumentStream();
145 :
146 7706 : if (xInputStream.is())
147 : {
148 : try
149 : {
150 3336 : uno::Reference<uno::XComponentContext> xContext(mpStream->getContext());
151 6672 : uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(xContext));
152 6672 : xRet = xDomBuilder->parse(xInputStream);
153 : }
154 0 : catch (uno::Exception const& e)
155 : {
156 : SAL_INFO("writerfilter", "importSubStream: exception while "
157 : "parsing stream " << nType << " : " << e.Message);
158 0 : return xRet;
159 : }
160 : }
161 :
162 7706 : if(OOXMLStream::CUSTOMXML == nType)
163 : {
164 497 : importSubStreamRelations(pStream, OOXMLStream::CUSTOMXMLPROPS);
165 : }
166 7706 : if(OOXMLStream::ACTIVEX == nType)
167 : {
168 1389 : importSubStreamRelations(pStream, OOXMLStream::ACTIVEXBIN);
169 : }
170 7706 : if(OOXMLStream::CHARTS == nType)
171 : {
172 0 : importSubStreamRelations(pStream, OOXMLStream::EMBEDDINGS);
173 : }
174 :
175 7706 : return xRet;
176 : }
177 :
178 :
179 2070 : void OOXMLDocumentImpl::importSubStreamRelations(OOXMLStream::Pointer_t pStream, OOXMLStream::StreamType_t nType)
180 : {
181 2070 : uno::Reference<xml::dom::XDocument> xRelation;
182 4131 : OOXMLStream::Pointer_t cStream;
183 : try
184 : {
185 2079 : cStream = OOXMLDocumentFactory::createStream(pStream, nType);
186 : }
187 18 : catch (uno::Exception const& e)
188 : {
189 : SAL_WARN("writerfilter", "importSubStreamRelations: exception while "
190 : "importing stream " << nType << " : " << e.Message);
191 2079 : return;
192 : }
193 :
194 : uno::Reference<io::XInputStream> xcpInputStream =
195 4122 : cStream->getDocumentStream();
196 :
197 2061 : if (xcpInputStream.is())
198 : {
199 : // imporing itemprops files for item.xml from customXml.
200 2058 : if(OOXMLStream::CUSTOMXMLPROPS == nType)
201 : {
202 : try
203 : {
204 497 : uno::Reference<uno::XComponentContext> xcpContext(pStream->getContext());
205 994 : uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(xcpContext));
206 994 : xRelation = xDomBuilder->parse(xcpInputStream);
207 : }
208 0 : catch (uno::Exception const& e)
209 : {
210 : SAL_WARN("writerfilter", "importSubStream: exception while "
211 : "parsing stream " << nType << " : " << e.Message);
212 0 : mxCustomXmlProsDom = xRelation;
213 : }
214 :
215 497 : if(xRelation.is())
216 : {
217 497 : mxCustomXmlProsDom = xRelation;
218 : }
219 : }
220 1561 : else if(OOXMLStream::ACTIVEXBIN == nType)
221 : {
222 : // imporing activex.bin files for activex.xml from activeX folder.
223 1389 : mxActiveXBin = xcpInputStream;
224 : }
225 172 : else if(OOXMLStream::EMBEDDINGS == nType)
226 : {
227 : // imporing activex.bin files for activex.xml from activeX folder.
228 80 : mxEmbeddings = xcpInputStream;
229 : }
230 92 : else if(OOXMLStream::CHARTS == nType)
231 : {
232 92 : importSubStreamRelations(cStream, OOXMLStream::EMBEDDINGS);
233 : }
234 2061 : }
235 :
236 :
237 : }
238 :
239 10648 : void OOXMLDocumentImpl::setXNoteId(const sal_Int32 nId)
240 : {
241 10648 : mnXNoteId = nId;
242 10648 : }
243 :
244 502 : sal_Int32 OOXMLDocumentImpl::getXNoteId() const
245 : {
246 502 : return mnXNoteId;
247 : }
248 :
249 74 : void OOXMLDocumentImpl::setXNoteType(const Id & nId)
250 : {
251 74 : mXNoteType = nId;
252 74 : }
253 :
254 0 : const Id & OOXMLDocumentImpl::getXNoteType() const
255 : {
256 0 : return mXNoteType;
257 : }
258 :
259 1702 : const OUString & OOXMLDocumentImpl::getTarget() const
260 : {
261 1702 : return mpStream->getTarget();
262 : }
263 :
264 : writerfilter::Reference<Stream>::Pointer_t
265 1312 : OOXMLDocumentImpl::getSubStream(const OUString & rId)
266 : {
267 : OOXMLStream::Pointer_t pStream
268 1312 : (OOXMLDocumentFactory::createStream(mpStream, rId));
269 :
270 : OOXMLDocumentImpl * pTemp;
271 : // Do not pass status indicator to sub-streams: they are typically marginal in size, so we just track the main document for now.
272 1312 : writerfilter::Reference<Stream>::Pointer_t pRet( pTemp = new OOXMLDocumentImpl(pStream, uno::Reference<task::XStatusIndicator>(), mbSkipImages ));
273 1312 : pTemp->setModel(mxModel);
274 1312 : pTemp->setDrawPage(mxDrawPage);
275 1312 : pTemp->setIsSubstream( true );
276 1312 : return pRet;
277 : }
278 :
279 : writerfilter::Reference<Stream>::Pointer_t
280 74 : OOXMLDocumentImpl::getXNoteStream(OOXMLStream::StreamType_t nType, const Id & rType,
281 : const sal_Int32 nId)
282 : {
283 : OOXMLStream::Pointer_t pStream =
284 74 : (OOXMLDocumentFactory::createStream(mpStream, nType));
285 : // See above, no status indicator for the note stream, either.
286 74 : OOXMLDocumentImpl * pDocument = new OOXMLDocumentImpl(pStream, uno::Reference<task::XStatusIndicator>(), mbSkipImages);
287 74 : pDocument->setXNoteId(nId);
288 74 : pDocument->setXNoteType(rType);
289 :
290 74 : return writerfilter::Reference<Stream>::Pointer_t(pDocument);
291 : }
292 :
293 35 : void OOXMLDocumentImpl::resolveFootnote(Stream & rStream,
294 : const Id & rType,
295 : const sal_Int32 nNoteId)
296 : {
297 : writerfilter::Reference<Stream>::Pointer_t pStream =
298 35 : getXNoteStream(OOXMLStream::FOOTNOTES, rType, nNoteId);
299 :
300 : Id nId;
301 35 : switch (rType)
302 : {
303 : case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator:
304 : case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator:
305 0 : nId = rType;
306 0 : break;
307 : default:
308 35 : nId = NS_ooxml::LN_footnote;
309 35 : break;
310 : }
311 :
312 35 : resolveFastSubStreamWithId(rStream, pStream, nId);
313 35 : }
314 :
315 9 : void OOXMLDocumentImpl::resolveEndnote(Stream & rStream,
316 : const Id & rType,
317 : const sal_Int32 nNoteId)
318 : {
319 : writerfilter::Reference<Stream>::Pointer_t pStream =
320 9 : getXNoteStream(OOXMLStream::ENDNOTES, rType, nNoteId);
321 :
322 : Id nId;
323 9 : switch (rType)
324 : {
325 : case NS_ooxml::LN_Value_doc_ST_FtnEdn_separator:
326 : case NS_ooxml::LN_Value_doc_ST_FtnEdn_continuationSeparator:
327 0 : nId = rType;
328 0 : break;
329 : default:
330 9 : nId = NS_ooxml::LN_endnote;
331 9 : break;
332 : }
333 :
334 9 : resolveFastSubStreamWithId(rStream, pStream, nId);
335 9 : }
336 :
337 30 : void OOXMLDocumentImpl::resolveComment(Stream & rStream,
338 : const sal_Int32 nId)
339 : {
340 : writerfilter::Reference<Stream>::Pointer_t pStream =
341 30 : getXNoteStream(OOXMLStream::COMMENTS, 0, nId);
342 :
343 30 : resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_annotation);
344 30 : }
345 :
346 0 : OOXMLPropertySet * OOXMLDocumentImpl::getPicturePropSet
347 : (const OUString & rId)
348 : {
349 : OOXMLStream::Pointer_t pStream
350 0 : (OOXMLDocumentFactory::createStream(mpStream, rId));
351 :
352 : writerfilter::Reference<BinaryObj>::Pointer_t pPicture
353 0 : (new OOXMLBinaryObjectReference(pStream));
354 :
355 0 : OOXMLValue::Pointer_t pPayloadValue(new OOXMLBinaryValue(pPicture));
356 :
357 : OOXMLProperty::Pointer_t pPayloadProperty
358 : (new OOXMLPropertyImpl(NS_ooxml::LN_payload, pPayloadValue,
359 0 : OOXMLPropertyImpl::ATTRIBUTE));
360 :
361 0 : OOXMLPropertySet::Pointer_t pBlipSet(new OOXMLPropertySetImpl());
362 :
363 0 : pBlipSet->add(pPayloadProperty);
364 :
365 0 : OOXMLValue::Pointer_t pBlipValue(new OOXMLPropertySetValue(pBlipSet));
366 :
367 : OOXMLProperty::Pointer_t pBlipProperty
368 : (new OOXMLPropertyImpl(NS_ooxml::LN_blip, pBlipValue,
369 0 : OOXMLPropertyImpl::ATTRIBUTE));
370 :
371 0 : OOXMLPropertySet * pProps = new OOXMLPropertySetImpl();
372 :
373 0 : pProps->add(pBlipProperty);
374 :
375 0 : return pProps;
376 : }
377 :
378 0 : void OOXMLDocumentImpl::resolvePicture(Stream & rStream,
379 : const OUString & rId)
380 : {
381 0 : OOXMLPropertySet * pProps = getPicturePropSet(rId);
382 :
383 0 : rStream.props(writerfilter::Reference<Properties>::Pointer_t(pProps));
384 0 : }
385 :
386 343 : OUString OOXMLDocumentImpl::getTargetForId(const OUString & rId)
387 : {
388 343 : return mpStream->getTargetForId(rId);
389 : }
390 :
391 644 : void OOXMLDocumentImpl::resolveHeader(Stream & rStream,
392 : const sal_Int32 type,
393 : const OUString & rId)
394 : {
395 : writerfilter::Reference<Stream>::Pointer_t pStream =
396 644 : getSubStream(rId);
397 644 : switch (type)
398 : {
399 : case NS_ooxml::LN_Value_ST_HdrFtr_even:
400 157 : resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_headerl);
401 157 : break;
402 : case NS_ooxml::LN_Value_ST_HdrFtr_default: // here we assume that default is right, but not necessarily true :-(
403 317 : resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_headerr);
404 317 : break;
405 : case NS_ooxml::LN_Value_ST_HdrFtr_first:
406 170 : resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_headerf);
407 170 : break;
408 : default:
409 0 : break;
410 644 : }
411 644 : }
412 :
413 668 : void OOXMLDocumentImpl::resolveFooter(Stream & rStream,
414 : const sal_Int32 type,
415 : const OUString & rId)
416 : {
417 : writerfilter::Reference<Stream>::Pointer_t pStream =
418 668 : getSubStream(rId);
419 :
420 668 : switch (type)
421 : {
422 : case NS_ooxml::LN_Value_ST_HdrFtr_even:
423 157 : resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_footerl);
424 157 : break;
425 : case NS_ooxml::LN_Value_ST_HdrFtr_default: // here we assume that default is right, but not necessarily true :-(
426 358 : resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_footerr);
427 358 : break;
428 : case NS_ooxml::LN_Value_ST_HdrFtr_first:
429 153 : resolveFastSubStreamWithId(rStream, pStream, NS_ooxml::LN_footerf);
430 153 : break;
431 : default:
432 0 : break;
433 668 : }
434 668 : }
435 :
436 2910 : void OOXMLDocumentImpl::resolve(Stream & rStream)
437 : {
438 : uno::Reference< xml::sax::XFastParser > xParser
439 2910 : (mpStream->getFastParser());
440 :
441 2910 : if (mxModel.is())
442 : {
443 2836 : uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(mxModel, uno::UNO_QUERY);
444 5672 : uno::Reference<document::XDocumentProperties> xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties();
445 5672 : comphelper::SequenceAsHashMap aMap(xDocumentProperties->getDocumentStatistics());
446 2836 : if (aMap.find("ParagraphCount") != aMap.end())
447 : {
448 : sal_Int32 nValue;
449 2714 : if (aMap["ParagraphCount"] >>= nValue)
450 : {
451 2714 : if (mxStatusIndicator.is())
452 : {
453 : // We want to care about the progress if we know the estimated paragraph count and we have given a status indicator as well.
454 : // Set the end position only here, so later it's enough to check if that is non-zero in incrementProgress().
455 1389 : mnProgressEndPos = nValue;
456 1389 : static ResMgr* pResMgr = ResMgr::CreateResMgr("svx", Application::GetSettings().GetUILanguageTag());
457 1389 : OUString aDocLoad(ResId(RID_SVXSTR_DOC_LOAD, *pResMgr).toString());
458 1389 : mxStatusIndicator->start(aDocLoad, mnProgressEndPos);
459 1389 : mnPercentSize = mnProgressEndPos / 100;
460 : }
461 : }
462 2836 : }
463 : }
464 :
465 2910 : if (xParser.is())
466 : {
467 2910 : uno::Reference<uno::XComponentContext> xContext(mpStream->getContext());
468 :
469 : OOXMLFastDocumentHandler * pDocHandler =
470 : new OOXMLFastDocumentHandler(
471 2910 : xContext, &rStream, this, mnXNoteId );
472 2910 : pDocHandler->setIsSubstream( mbIsSubstream );
473 : uno::Reference < xml::sax::XFastDocumentHandler > xDocumentHandler
474 5820 : (pDocHandler);
475 5820 : uno::Reference < xml::sax::XFastTokenHandler > xTokenHandler(mpStream->getFastTokenHandler());
476 :
477 2910 : resolveFastSubStream(rStream, OOXMLStream::SETTINGS);
478 2910 : mxThemeDom = importSubStream(OOXMLStream::THEME);
479 2910 : resolveFastSubStream(rStream, OOXMLStream::THEME);
480 2910 : mxGlossaryDocDom = importSubStream(OOXMLStream::GLOSSARY);
481 2910 : if (mxGlossaryDocDom.is())
482 70 : resolveGlossaryStream(rStream);
483 :
484 2911 : resolveEmbeddingsStream(mpStream);
485 :
486 : // Custom xml's are handled as part of grab bag.
487 2909 : resolveCustomXmlStream(rStream);
488 :
489 2909 : resolveActiveXStream(rStream);
490 :
491 2909 : resolveFastSubStream(rStream, OOXMLStream::FONTTABLE);
492 2909 : resolveFastSubStream(rStream, OOXMLStream::STYLES);
493 2909 : resolveFastSubStream(rStream, OOXMLStream::NUMBERING);
494 :
495 2909 : xParser->setFastDocumentHandler( xDocumentHandler );
496 2909 : xParser->setTokenHandler( xTokenHandler );
497 :
498 5818 : xml::sax::InputSource aParserInput;
499 2909 : aParserInput.sSystemId = mpStream->getTarget();
500 2909 : aParserInput.aInputStream = mpStream->getDocumentStream();
501 : try
502 : {
503 2909 : xParser->parseStream(aParserInput);
504 : }
505 2 : catch (xml::sax::SAXException const&)
506 : {
507 : // don't swallow these - handlers may not have been executed,
508 : // and the domain mapper is likely in an inconsistent state
509 1 : throw;
510 : }
511 0 : catch (uno::RuntimeException const&)
512 : {
513 0 : throw;
514 : }
515 : // note: cannot throw anything other than SAXException out of here?
516 0 : catch (uno::Exception const& e)
517 : {
518 : SAL_WARN("writerfilter.ooxml",
519 : "OOXMLDocumentImpl::resolve(): exception: " << e.Message);
520 : throw lang::WrappedTargetRuntimeException("", nullptr,
521 0 : uno::makeAny(e));
522 : }
523 0 : catch (...)
524 : {
525 : SAL_WARN("writerfilter.ooxml",
526 : "OOXMLDocumentImpl::resolve(): non-UNO exception");
527 2910 : }
528 : }
529 :
530 2908 : if (mxStatusIndicator.is())
531 1496 : mxStatusIndicator->end();
532 2908 : }
533 :
534 27730 : void OOXMLDocumentImpl::incrementProgress()
535 : {
536 27730 : mnProgressCurrentPos++;
537 : // 1) If we know the end
538 : // 2) We progressed enough that updating makes sense
539 : // 3) We did not reach the end yet (possible in case the doc stat is misleading)
540 27730 : if (mnProgressEndPos && mnProgressCurrentPos > (mnProgressLastPos + mnPercentSize) && mnProgressLastPos < mnProgressEndPos)
541 : {
542 3147 : mnProgressLastPos = mnProgressCurrentPos;
543 3147 : mxStatusIndicator->setValue(mnProgressLastPos);
544 : }
545 27730 : }
546 :
547 2909 : void OOXMLDocumentImpl::resolveCustomXmlStream(Stream & rStream)
548 : {
549 : // Resolving all item[n].xml files from CustomXml folder.
550 2909 : uno::Reference<embed::XRelationshipAccess> xRelationshipAccess;
551 2909 : xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*mpStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW);
552 2909 : if (xRelationshipAccess.is())
553 : {
554 : static const char sCustomType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
555 : static const char sCustomTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/customXml";
556 2909 : OUString sTarget("Target");
557 2909 : bool bFound = false;
558 2909 : sal_Int32 counter = 0;
559 5818 : uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs = xRelationshipAccess->getAllRelationships();
560 5818 : uno::Sequence<uno::Reference<xml::dom::XDocument> > xCustomXmlDomListTemp(aSeqs.getLength());
561 5818 : uno::Sequence<uno::Reference<xml::dom::XDocument> > xCustomXmlDomPropsListTemp(aSeqs.getLength());
562 17062 : for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
563 : {
564 14153 : uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
565 57437 : for (sal_Int32 i = 0; i < aSeq.getLength(); i++)
566 : {
567 43284 : beans::StringPair aPair = aSeq[i];
568 : // Need to resolve only customxml files from document relationships.
569 : // Skipping other files.
570 86071 : if (aPair.Second == sCustomType ||
571 42787 : aPair.Second == sCustomTypeStrict)
572 497 : bFound = true;
573 42787 : else if(aPair.First == sTarget && bFound)
574 : {
575 : // Adding value to extern variable customTarget. It will be used in ooxmlstreamimpl
576 : // to ensure customxml target is visited in lcl_getTarget.
577 497 : customTarget = aPair.Second;
578 : }
579 43284 : }
580 14153 : if(bFound)
581 : {
582 497 : uno::Reference<xml::dom::XDocument> customXmlTemp = importSubStream(OOXMLStream::CUSTOMXML);
583 : // This will add all item[n].xml with its relationship file i.e itemprops.xml to
584 : // grabbag list.
585 497 : if(mxCustomXmlProsDom.is() && customXmlTemp.is())
586 : {
587 497 : xCustomXmlDomListTemp[counter] = customXmlTemp;
588 497 : xCustomXmlDomPropsListTemp[counter] = mxCustomXmlProsDom;
589 497 : counter++;
590 497 : resolveFastSubStream(rStream, OOXMLStream::CUSTOMXML);
591 : }
592 497 : bFound = false;
593 : }
594 14153 : }
595 :
596 2909 : xCustomXmlDomListTemp.realloc(counter);
597 2909 : xCustomXmlDomPropsListTemp.realloc(counter);
598 2909 : mxCustomXmlDomList = xCustomXmlDomListTemp;
599 5818 : mxCustomXmlDomPropsList = xCustomXmlDomPropsListTemp;
600 2909 : }
601 2909 : }
602 :
603 70 : void OOXMLDocumentImpl::resolveGlossaryStream(Stream & /*rStream*/)
604 : {
605 : static const char sSettingsType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings";
606 : static const char sStylesType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
607 : static const char sFonttableType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable";
608 : static const char sWebSettings[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings";
609 : static const char sSettingsTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/settings";
610 : static const char sStylesTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/styles";
611 : static const char sFonttableTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/fontTable";
612 : static const char sWebSettingsStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/webSettings";
613 :
614 70 : OOXMLStream::Pointer_t pStream;
615 : try
616 : {
617 70 : pStream = OOXMLDocumentFactory::createStream(mpStream, OOXMLStream::GLOSSARY);
618 : }
619 0 : catch (uno::Exception const& e)
620 : {
621 : SAL_INFO("writerfilter", "resolveGlossaryStream: exception while "
622 : "createStream for glossary" << OOXMLStream::GLOSSARY << " : " << e.Message);
623 0 : return;
624 : }
625 140 : uno::Reference<embed::XRelationshipAccess> xRelationshipAccess;
626 70 : xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*pStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW);
627 70 : if (xRelationshipAccess.is())
628 : {
629 :
630 70 : uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs = xRelationshipAccess->getAllRelationships();
631 140 : uno::Sequence<uno::Sequence< uno::Any> > xGlossaryDomListTemp(aSeqs.getLength());
632 70 : sal_Int32 counter = 0;
633 388 : for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
634 : {
635 318 : OOXMLStream::Pointer_t gStream;
636 636 : uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
637 : //Follows following aSeq[0] is Id, aSeq[1] is Type, aSeq[2] is Target
638 636 : OUString gId(aSeq[0].Second);
639 636 : OUString gType(aSeq[1].Second);
640 636 : OUString gTarget(aSeq[2].Second);
641 636 : OUString contentType;
642 :
643 318 : OOXMLStream::StreamType_t nType(OOXMLStream::UNKNOWN);
644 318 : bool bFound = true;
645 566 : if(gType == sSettingsType ||
646 248 : gType == sSettingsTypeStrict)
647 : {
648 70 : nType = OOXMLStream::SETTINGS;
649 70 : contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml";
650 : }
651 426 : else if(gType == sStylesType ||
652 178 : gType == sStylesTypeStrict)
653 : {
654 70 : nType = OOXMLStream::STYLES;
655 70 : contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml";
656 : }
657 286 : else if(gType == sWebSettings ||
658 108 : gType == sWebSettingsStrict)
659 : {
660 70 : nType = OOXMLStream::WEBSETTINGS;
661 70 : contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml";
662 : }
663 146 : else if(gType == sFonttableType ||
664 38 : gType == sFonttableTypeStrict)
665 : {
666 70 : nType = OOXMLStream::FONTTABLE;
667 70 : contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml";
668 : }
669 : else
670 : {
671 38 : bFound = false;
672 : //"Unhandled content-type while grab bagging Glossary Folder");
673 : }
674 :
675 318 : if (bFound)
676 : {
677 280 : uno::Reference<xml::dom::XDocument> xDom;
678 : try
679 : {
680 280 : gStream = OOXMLDocumentFactory::createStream(pStream, nType);
681 280 : uno::Reference<io::XInputStream> xInputStream = gStream->getDocumentStream();
682 560 : uno::Reference<uno::XComponentContext> xContext(pStream->getContext());
683 560 : uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(xContext));
684 560 : xDom = xDomBuilder->parse(xInputStream);
685 : }
686 0 : catch (uno::Exception const& e)
687 : {
688 : SAL_INFO("writerfilter", "importSubStream: exception while "
689 : "parsing stream of Type" << nType << " : " << e.Message);
690 0 : return;
691 : }
692 :
693 280 : if (xDom.is())
694 : {
695 280 : uno::Sequence< uno::Any > glossaryTuple (5);
696 280 : glossaryTuple[0] = uno::makeAny(xDom);
697 280 : glossaryTuple[1] = uno::makeAny(gId);
698 280 : glossaryTuple[2] = uno::makeAny(gType);
699 280 : glossaryTuple[3] = uno::makeAny(gTarget);
700 280 : glossaryTuple[4] = uno::makeAny(contentType);
701 280 : xGlossaryDomListTemp[counter] = glossaryTuple;
702 280 : counter++;
703 280 : }
704 : }
705 318 : }
706 70 : xGlossaryDomListTemp.realloc(counter);
707 140 : mxGlossaryDomList = xGlossaryDomListTemp;
708 70 : }
709 : }
710 :
711 4239 : void OOXMLDocumentImpl::resolveEmbeddingsStream(OOXMLStream::Pointer_t pStream)
712 : {
713 4239 : uno::Reference<embed::XRelationshipAccess> xRelationshipAccess;
714 4239 : xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*pStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW);
715 4239 : if (xRelationshipAccess.is())
716 : {
717 4239 : OUString sChartType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart");
718 8478 : OUString sChartTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/chart");
719 8478 : OUString sFootersType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer");
720 8478 : OUString sFootersTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/footer");
721 8478 : OUString sHeaderType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header");
722 8478 : OUString sHeaderTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/header");
723 :
724 8478 : OUString sTarget("Target");
725 4239 : bool bFound = false;
726 4239 : bool bHeaderFooterFound = false;
727 4239 : OOXMLStream::StreamType_t streamType = OOXMLStream::UNKNOWN;
728 8478 : uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs = xRelationshipAccess->getAllRelationships();
729 18527 : for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
730 : {
731 14289 : uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
732 58002 : for (sal_Int32 i = 0; i < aSeq.getLength(); i++)
733 : {
734 43713 : beans::StringPair aPair = aSeq[i];
735 87335 : if (aPair.Second == sChartType ||
736 43622 : aPair.Second == sChartTypeStrict)
737 : {
738 92 : bFound = true;
739 : }
740 86561 : else if(aPair.Second == sFootersType ||
741 42940 : aPair.Second == sFootersTypeStrict)
742 : {
743 681 : bHeaderFooterFound = true;
744 681 : streamType = OOXMLStream::FOOTER;
745 : }
746 85232 : else if(aPair.Second == sHeaderType ||
747 42292 : aPair.Second == sHeaderTypeStrict)
748 : {
749 649 : bHeaderFooterFound = true;
750 649 : streamType = OOXMLStream::HEADER;
751 : }
752 42291 : else if(aPair.First == sTarget && ( bFound || bHeaderFooterFound ))
753 : {
754 : // Adding value to extern variable customTarget. It will be used in ooxmlstreamimpl
755 : // to ensure chart.xml target is visited in lcl_getTarget.
756 1422 : customTarget = aPair.Second;
757 : }
758 43713 : }
759 14289 : if(( bFound || bHeaderFooterFound))
760 : {
761 1422 : if(bFound)
762 : {
763 92 : importSubStreamRelations(pStream, OOXMLStream::CHARTS);
764 : }
765 1422 : if(bHeaderFooterFound)
766 : {
767 1331 : OOXMLStream::Pointer_t Stream = OOXMLDocumentFactory::createStream(pStream, streamType);
768 1329 : if(Stream)
769 1329 : resolveEmbeddingsStream(Stream);
770 : }
771 :
772 1421 : beans::PropertyValue embeddingsTemp;
773 : // This will add all .xlsx and .bin to grabbag list.
774 1421 : if(bFound)
775 : {
776 92 : if(mxEmbeddings.is())
777 : {
778 80 : embeddingsTemp.Name = embeddingsTarget;
779 80 : embeddingsTemp.Value = uno::makeAny(mxEmbeddings);
780 80 : mxEmbeddingsListTemp.push_back(embeddingsTemp);
781 80 : mxEmbeddings.clear();
782 : }
783 : }
784 1421 : bFound = false;
785 1421 : bHeaderFooterFound = false;
786 : }
787 18528 : }
788 : }
789 4238 : if(0 != mxEmbeddingsListTemp.size())
790 : {
791 85 : mxEmbeddingsList.realloc(mxEmbeddingsListTemp.size());
792 181 : for (size_t i = 0; i < mxEmbeddingsListTemp.size(); i++)
793 : {
794 96 : mxEmbeddingsList[i] = mxEmbeddingsListTemp[i];
795 : }
796 4239 : }
797 4238 : }
798 :
799 2909 : void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream)
800 : {
801 : // Resolving all ActiveX[n].xml files from ActiveX folder.
802 2909 : uno::Reference<embed::XRelationshipAccess> xRelationshipAccess;
803 2909 : xRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*mpStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW);
804 2909 : if (xRelationshipAccess.is())
805 : {
806 : static const char sCustomType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/control";
807 : static const char sCustomTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/control";
808 2909 : OUString sTarget("Target");
809 2909 : bool bFound = false;
810 2909 : sal_Int32 counter = 0;
811 5818 : uno::Sequence< uno::Sequence< beans::StringPair > > aSeqs = xRelationshipAccess->getAllRelationships();
812 5818 : uno::Sequence<uno::Reference<xml::dom::XDocument> > xActiveXDomListTemp(aSeqs.getLength());
813 5818 : uno::Sequence<uno::Reference<io::XInputStream> > xActiveXBinListTemp(aSeqs.getLength());
814 17062 : for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
815 : {
816 14153 : uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
817 57437 : for (sal_Int32 i = 0; i < aSeq.getLength(); i++)
818 : {
819 43284 : beans::StringPair aPair = aSeq[i];
820 : // Need to resolve only ActiveX files from document relationships.
821 : // Skipping other files.
822 85179 : if (aPair.Second == sCustomType ||
823 41895 : aPair.Second == sCustomTypeStrict)
824 1389 : bFound = true;
825 41895 : else if(aPair.First == sTarget && bFound)
826 : {
827 : // Adding value to extern variable customTarget. It will be used in ooxmlstreamimpl
828 : // to ensure ActiveX.xml target is visited in lcl_getTarget.
829 1389 : customTarget = aPair.Second;
830 : }
831 43284 : }
832 14153 : if(bFound)
833 : {
834 1389 : uno::Reference<xml::dom::XDocument> activeXTemp = importSubStream(OOXMLStream::ACTIVEX);
835 : // This will add all ActiveX[n].xml to grabbag list.
836 1389 : if(activeXTemp.is())
837 : {
838 1389 : xActiveXDomListTemp[counter] = activeXTemp;
839 1389 : if(mxActiveXBin.is())
840 : {
841 1389 : xActiveXBinListTemp[counter] = mxActiveXBin;
842 : }
843 1389 : counter++;
844 1389 : resolveFastSubStream(rStream, OOXMLStream::ACTIVEX);
845 : }
846 1389 : bFound = false;
847 : }
848 14153 : }
849 2909 : xActiveXDomListTemp.realloc(counter);
850 2909 : xActiveXBinListTemp.realloc(counter);
851 2909 : mxActiveXDomList = xActiveXDomListTemp;
852 5818 : mxActiveXBinList = xActiveXBinListTemp;
853 2909 : }
854 2909 : }
855 :
856 1522 : uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::getGlossaryDocDom( )
857 : {
858 1522 : return mxGlossaryDocDom;
859 : }
860 :
861 1522 : uno::Sequence<uno::Sequence< uno::Any> > OOXMLDocumentImpl::getGlossaryDomList()
862 : {
863 1522 : return mxGlossaryDomList;
864 : }
865 :
866 54 : uno::Reference<io::XInputStream> OOXMLDocumentImpl::getInputStreamForId(const OUString & rId)
867 : {
868 54 : OOXMLStream::Pointer_t pStream(OOXMLDocumentFactory::createStream(mpStream, rId));
869 :
870 54 : return pStream->getDocumentStream();
871 : }
872 :
873 2836 : void OOXMLDocumentImpl::setModel(uno::Reference<frame::XModel> xModel)
874 : {
875 2836 : mxModel.set(xModel);
876 2836 : }
877 :
878 3404 : uno::Reference<frame::XModel> OOXMLDocumentImpl::getModel()
879 : {
880 3404 : return mxModel;
881 : }
882 :
883 2836 : void OOXMLDocumentImpl::setDrawPage(uno::Reference<drawing::XDrawPage> xDrawPage)
884 : {
885 2836 : mxDrawPage.set(xDrawPage);
886 2836 : }
887 :
888 1702 : uno::Reference<drawing::XDrawPage> OOXMLDocumentImpl::getDrawPage()
889 : {
890 1702 : return mxDrawPage;
891 : }
892 :
893 0 : uno::Reference<io::XInputStream> OOXMLDocumentImpl::getInputStream()
894 : {
895 0 : return mpStream->getDocumentStream();
896 : }
897 :
898 1702 : uno::Reference<io::XInputStream> OOXMLDocumentImpl::getStorageStream()
899 : {
900 1702 : return mpStream->getStorageStream();
901 : }
902 :
903 799 : void OOXMLDocumentImpl::setShapeContext( uno::Reference<xml::sax::XFastShapeContextHandler> xContext )
904 : {
905 799 : mxShapeContext = xContext;
906 799 : }
907 :
908 1702 : uno::Reference<xml::sax::XFastShapeContextHandler> OOXMLDocumentImpl::getShapeContext( )
909 : {
910 1702 : return mxShapeContext;
911 : }
912 :
913 0 : void OOXMLDocumentImpl::setThemeDom( uno::Reference<xml::dom::XDocument> xThemeDom )
914 : {
915 0 : mxThemeDom = xThemeDom;
916 0 : }
917 :
918 1522 : uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::getThemeDom( )
919 : {
920 1522 : return mxThemeDom;
921 : }
922 :
923 1522 : uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getCustomXmlDomList( )
924 : {
925 1522 : return mxCustomXmlDomList;
926 : }
927 :
928 1522 : uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getCustomXmlDomPropsList( )
929 : {
930 1522 : return mxCustomXmlDomPropsList;
931 : }
932 :
933 1522 : uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getActiveXDomList( )
934 : {
935 1522 : return mxActiveXDomList;
936 : }
937 :
938 1522 : uno::Sequence<uno::Reference<io::XInputStream> > OOXMLDocumentImpl::getActiveXBinList( )
939 : {
940 1522 : return mxActiveXBinList;
941 : }
942 :
943 1522 : uno::Sequence<beans::PropertyValue > OOXMLDocumentImpl::getEmbeddingsList( )
944 : {
945 1522 : return mxEmbeddingsList;
946 : }
947 :
948 : OOXMLDocument *
949 1524 : OOXMLDocumentFactory::createDocument
950 : (OOXMLStream::Pointer_t pStream, const uno::Reference<task::XStatusIndicator>& xStatusIndicator, bool mbSkipImages)
951 : {
952 1524 : return new OOXMLDocumentImpl(pStream, xStatusIndicator, mbSkipImages);
953 : }
954 :
955 72 : }}
956 :
957 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|