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