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