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