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