/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #ifndef _DOCSH_HXX #include #endif #include #include #include #include #include #include #include #define STREAM_STGREAD ( STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE ) #define STREAM_STGWRITE ( STREAM_READ | STREAM_WRITE | STREAM_SHARE_DENYWRITE ) sal_Char __FAR_DATA XMLN_BLOCKLIST[] = "BlockList.xml"; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::container; using ::rtl::OUString; using ::xmloff::token::XML_BLOCK_LIST; using ::xmloff::token::XML_UNFORMATTED_TEXT; using ::xmloff::token::GetXMLToken; sal_uLong SwXMLTextBlocks::GetDoc( sal_uInt16 nIdx ) { String aFolderName ( GetPackageName ( nIdx ) ); if (!IsOnlyTextBlock ( nIdx ) ) { try { xRoot = xBlkRoot->openStorageElement( aFolderName, embed::ElementModes::READ ); xMedium = new SfxMedium(xRoot, GetBaseURL(), S2U("writer8")); SwReader aReader(*xMedium,aFolderName, pDoc ); ReadXML->SetBlockMode( sal_True ); aReader.Read( *ReadXML ); ReadXML->SetBlockMode( sal_False ); // Ole objects fails to display when inserted into document // because the ObjectReplacement folder ( and contents are missing ) rtl::OUString sObjReplacements( RTL_CONSTASCII_USTRINGPARAM( "ObjectReplacements" ) ); if ( xRoot->hasByName( sObjReplacements ) ) { uno::Reference< document::XStorageBasedDocument > xDocStor( pDoc->GetDocShell()->GetModel(), uno::UNO_QUERY_THROW ); uno::Reference< embed::XStorage > xStr( xDocStor->getDocumentStorage() ); if ( xStr.is() ) { xRoot->copyElementTo( sObjReplacements, xStr, sObjReplacements ); uno::Reference< embed::XTransactedObject > xTrans( xStr, uno::UNO_QUERY ); if ( xTrans.is() ) xTrans->commit(); } } } catch( uno::Exception& ) { } xRoot = 0; } else { String aStreamName = aFolderName + (OUString) String::CreateFromAscii(".xml"); try { xRoot = xBlkRoot->openStorageElement( aFolderName, embed::ElementModes::READ ); uno::Reference < io::XStream > xStream = xRoot->openStreamElement( aStreamName, embed::ElementModes::READ ); uno::Reference< lang::XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory(); ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" ); if( !xServiceFactory.is() ) { // Throw an exception ? } xml::sax::InputSource aParserInput; aParserInput.sSystemId = aNames [ nIdx ] ->aPackageName; aParserInput.aInputStream = xStream->getInputStream(); // get parser uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance( OUString::createFromAscii("com.sun.star.xml.sax.Parser") ); ASSERT( xXMLParser.is(), "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" ); if( !xXMLParser.is() ) { // Maybe throw an exception? } // get filter // #110680# // uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLTextBlockImport( *this, aCur, sal_True ); uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLTextBlockImport( xServiceFactory, *this, aCur, sal_True ); // connect parser and filter uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY ); xParser->setDocumentHandler( xFilter ); // parse try { xParser->parseStream( aParserInput ); } catch( xml::sax::SAXParseException& ) { // re throw ? } catch( xml::sax::SAXException& ) { // re throw ? } catch( io::IOException& ) { // re throw ? } bInfoChanged = sal_False; MakeBlockText(aCur); } catch( uno::Exception& ) { } xRoot = 0; } return 0; } // event description for autotext events; this constant should really be // taken from unocore/unoevents.cxx or ui/unotxt.cxx const struct SvEventDescription aAutotextEvents[] = { { SW_EVENT_START_INS_GLOSSARY, "OnInsertStart" }, { SW_EVENT_END_INS_GLOSSARY, "OnInsertDone" }, { 0, NULL } }; sal_uLong SwXMLTextBlocks::GetMacroTable( sal_uInt16 nIdx, SvxMacroTableDtor& rMacroTbl, sal_Bool bFileAlreadyOpen ) { // set current auto text aShort = aNames[ nIdx ]->aShort; aLong = aNames[ nIdx ]->aLong; aPackageName = aNames[ nIdx ]->aPackageName; sal_uLong nRet = 0; // open stream in proper sub-storage if( !bFileAlreadyOpen ) { CloseFile(); nRet = OpenFile ( sal_True ); } if ( 0 == nRet ) { try { xRoot = xBlkRoot->openStorageElement( aPackageName, embed::ElementModes::READ ); long nTmp = SOT_FORMATSTR_ID_STARWRITER_60; sal_Bool bOasis = ( SotStorage::GetVersion( xRoot ) > nTmp ); OUString sStreamName = OUString::createFromAscii("atevent.xml"); uno::Reference < io::XStream > xDocStream = xRoot->openStreamElement( sStreamName, embed::ElementModes::READ ); DBG_ASSERT(xDocStream.is(), "Can't create stream"); if ( xDocStream.is() ) { uno::Reference xInputStream = xDocStream->getInputStream(); // prepare ParserInputSrouce xml::sax::InputSource aParserInput; aParserInput.sSystemId = aName; aParserInput.aInputStream = xInputStream; // get service factory uno::Reference< lang::XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory(); if ( xServiceFactory.is() ) { // get parser OUString sParserService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" ) ); uno::Reference< xml::sax::XParser > xParser( xServiceFactory->createInstance(sParserService), UNO_QUERY ); DBG_ASSERT( xParser.is(), "Can't create parser" ); if( xParser.is() ) { // create descriptor and reference to it. Either // both or neither must be kept because of the // reference counting! SvMacroTableEventDescriptor* pDescriptor = new SvMacroTableEventDescriptor(aAutotextEvents); uno::Reference xReplace = pDescriptor; Sequence aFilterArguments( 1 ); aFilterArguments[0] <<= xReplace; // get filter OUString sFilterComponent( OUString::createFromAscii( bOasis ? "com.sun.star.comp.Writer.XMLOasisAutotextEventsImporter" : "com.sun.star.comp.Writer.XMLAutotextEventsImporter")); uno::Reference< xml::sax::XDocumentHandler > xFilter( xServiceFactory->createInstanceWithArguments( sFilterComponent, aFilterArguments), UNO_QUERY ); DBG_ASSERT( xFilter.is(), "can't instantiate atevents filter"); if ( xFilter.is() ) { // connect parser and filter xParser->setDocumentHandler( xFilter ); // connect model and filter uno::Reference xImporter( xFilter, UNO_QUERY ); // we don't need a model // xImporter->setTargetDocument( xModelComponent ); // parse the stream try { xParser->parseStream( aParserInput ); } catch( xml::sax::SAXParseException& ) { // workaround for #83452#: SetSize doesn't work // nRet = ERR_SWG_READ_ERROR; } catch( xml::sax::SAXException& ) { nRet = ERR_SWG_READ_ERROR; } catch( io::IOException& ) { nRet = ERR_SWG_READ_ERROR; } // and finally, copy macro into table if (0 == nRet) pDescriptor->copyMacrosIntoTable(rMacroTbl); } else nRet = ERR_SWG_READ_ERROR; } else nRet = ERR_SWG_READ_ERROR; } else nRet = ERR_SWG_READ_ERROR; } else nRet = ERR_SWG_READ_ERROR; } catch( uno::Exception& ) { nRet = ERR_SWG_READ_ERROR; } } else nRet = ERR_SWG_READ_ERROR; // success! return nRet; } sal_uLong SwXMLTextBlocks::GetBlockText( const String& rShort, String& rText ) { sal_uLong n = 0; sal_Bool bTextOnly = sal_True; String aFolderName; GeneratePackageName ( rShort, aFolderName ); String aStreamName = aFolderName + (OUString) String::CreateFromAscii(".xml"); rText.Erase(); try { xRoot = xBlkRoot->openStorageElement( aFolderName, embed::ElementModes::READ ); uno::Reference < container::XNameAccess > xAccess( xRoot, uno::UNO_QUERY ); if ( !xAccess->hasByName( aStreamName ) || !xRoot->isStreamElement( aStreamName ) ) { bTextOnly = sal_False; aStreamName = String::CreateFromAscii("content.xml"); } uno::Reference < io::XStream > xContents = xRoot->openStreamElement( aStreamName, embed::ElementModes::READ ); uno::Reference< lang::XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory(); ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" ); if( !xServiceFactory.is() ) { // Throw an exception ? } xml::sax::InputSource aParserInput; aParserInput.sSystemId = aName; aParserInput.aInputStream = xContents->getInputStream(); // get parser uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance( OUString::createFromAscii("com.sun.star.xml.sax.Parser") ); ASSERT( xXMLParser.is(), "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" ); if( !xXMLParser.is() ) { // Maybe throw an exception? } // get filter // #110680# // uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLTextBlockImport( *this, rText, bTextOnly ); uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLTextBlockImport( xServiceFactory, *this, rText, bTextOnly ); // connect parser and filter uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY ); xParser->setDocumentHandler( xFilter ); // parse try { xParser->parseStream( aParserInput ); } catch( xml::sax::SAXParseException& ) { // re throw ? } catch( xml::sax::SAXException& ) { // re throw ? } catch( io::IOException& ) { // re throw ? } xRoot = 0; } catch ( uno::Exception& ) { ASSERT( sal_False, "Tried to open non-existent folder or stream!"); } return n; } sal_uLong SwXMLTextBlocks::PutBlockText( const String& rShort, const String& , const String& rText, const String& rPackageName ) { GetIndex ( rShort ); /* if (xBlkRoot->IsContained ( rPackageName ) ) { xBlkRoot->Remove ( rPackageName ); xBlkRoot->Commit ( ); } */ String aFolderName( rPackageName ); String aStreamName = aFolderName + (OUString) String::CreateFromAscii(".xml"); uno::Reference< lang::XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory(); ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" ); if( !xServiceFactory.is() ) { // Throw an exception ? } uno::Reference < XInterface > xWriter (xServiceFactory->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer")))); DBG_ASSERT(xWriter.is(),"com.sun.star.xml.sax.Writer service missing"); sal_uLong nRes = 0; try { xRoot = xBlkRoot->openStorageElement( aFolderName, embed::ElementModes::WRITE ); uno::Reference < io::XStream > xDocStream = xRoot->openStreamElement( aStreamName, embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ); uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY ); String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) ); OUString aMime ( RTL_CONSTASCII_USTRINGPARAM ( "text/xml") ); Any aAny; aAny <<= aMime; xSet->setPropertyValue( aPropName, aAny ); uno::Reference < io::XOutputStream > xOut = xDocStream->getOutputStream(); uno::Reference xSrc(xWriter, uno::UNO_QUERY); xSrc->setOutputStream(xOut); uno::Reference xHandler(xWriter, uno::UNO_QUERY); // #110680# // SwXMLTextBlockExport aExp(*this, GetXMLToken ( XML_UNFORMATTED_TEXT ), xHandler); SwXMLTextBlockExport aExp( xServiceFactory, *this, GetXMLToken ( XML_UNFORMATTED_TEXT ), xHandler); aExp.exportDoc( rText ); uno::Reference < embed::XTransactedObject > xTrans( xRoot, uno::UNO_QUERY ); if ( xTrans.is() ) xTrans->commit(); if (! (nFlags & SWXML_NOROOTCOMMIT) ) { uno::Reference < embed::XTransactedObject > xTmpTrans( xBlkRoot, uno::UNO_QUERY ); if ( xTmpTrans.is() ) xTmpTrans->commit(); } } catch ( uno::Exception& ) { nRes = ERR_SWG_WRITE_ERROR; } xRoot = 0; //TODO/LATER: error handling /* sal_uLong nErr = xBlkRoot->GetError(); sal_uLong nRes = 0; if( nErr == SVSTREAM_DISK_FULL ) nRes = ERR_W4W_WRITE_FULL; else if( nErr != SVSTREAM_OK ) nRes = ERR_SWG_WRITE_ERROR; */ if( !nRes ) // damit ueber GetText & nCur aufs Doc zugegriffen MakeBlockText( rText ); return nRes; } void SwXMLTextBlocks::ReadInfo( void ) { try { const OUString sDocName( RTL_CONSTASCII_USTRINGPARAM( XMLN_BLOCKLIST ) ); uno::Reference < container::XNameAccess > xAccess( xBlkRoot, uno::UNO_QUERY ); if ( xAccess.is() && xAccess->hasByName( sDocName ) && xBlkRoot->isStreamElement( sDocName ) ) { uno::Reference< lang::XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory(); ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" ); if( !xServiceFactory.is() ) { // Throw an exception ? } xml::sax::InputSource aParserInput; aParserInput.sSystemId = sDocName; uno::Reference < io::XStream > xDocStream = xBlkRoot->openStreamElement( sDocName, embed::ElementModes::READ ); aParserInput.aInputStream = xDocStream->getInputStream(); // get parser uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance( OUString::createFromAscii("com.sun.star.xml.sax.Parser") ); ASSERT( xXMLParser.is(), "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" ); if( !xXMLParser.is() ) { // Maybe throw an exception? } // get filter // #110680# // uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLBlockListImport( *this ); uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLBlockListImport( xServiceFactory, *this ); // connect parser and filter uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY ); xParser->setDocumentHandler( xFilter ); // parse try { xParser->parseStream( aParserInput ); } catch( xml::sax::SAXParseException& ) { // re throw ? } catch( xml::sax::SAXException& ) { // re throw ? } catch( io::IOException& ) { // re throw ? } } } catch ( uno::Exception& ) { } } void SwXMLTextBlocks::WriteInfo( void ) { if ( xBlkRoot.is() || 0 == OpenFile ( sal_False ) ) { uno::Reference< lang::XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory(); DBG_ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" ); if( !xServiceFactory.is() ) { // Throw an exception ? } uno::Reference < XInterface > xWriter (xServiceFactory->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer")))); DBG_ASSERT(xWriter.is(),"com.sun.star.xml.sax.Writer service missing"); OUString sDocName( RTL_CONSTASCII_USTRINGPARAM( XMLN_BLOCKLIST ) ); /* if ( xBlkRoot->IsContained( sDocName) ) { xBlkRoot->Remove ( sDocName ); xBlkRoot->Commit(); } */ try { uno::Reference < io::XStream > xDocStream = xBlkRoot->openStreamElement( sDocName, embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ); uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY ); String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) ); OUString aMime ( RTL_CONSTASCII_USTRINGPARAM ( "text/xml") ); Any aAny; aAny <<= aMime; xSet->setPropertyValue( aPropName, aAny ); uno::Reference < io::XOutputStream > xOut = xDocStream->getOutputStream(); uno::Reference xSrc(xWriter, uno::UNO_QUERY); xSrc->setOutputStream(xOut); uno::Reference xHandler(xWriter, uno::UNO_QUERY); // #110680# // SwXMLBlockListExport aExp(*this, OUString::createFromAscii(XMLN_BLOCKLIST), xHandler); SwXMLBlockListExport aExp( xServiceFactory, *this, OUString::createFromAscii(XMLN_BLOCKLIST), xHandler); aExp.exportDoc( XML_BLOCK_LIST ); uno::Reference < embed::XTransactedObject > xTrans( xBlkRoot, uno::UNO_QUERY ); if ( xTrans.is() ) xTrans->commit(); } catch ( uno::Exception& ) { } bInfoChanged = sal_False; return; } } sal_uLong SwXMLTextBlocks::SetMacroTable( sal_uInt16 nIdx, const SvxMacroTableDtor& rMacroTbl, sal_Bool bFileAlreadyOpen ) { // set current autotext aShort = aNames[ nIdx ]->aShort; aLong = aNames[ nIdx ]->aLong; aPackageName = aNames[ nIdx ]->aPackageName; // start XML autotext event export sal_uLong nRes = 0; uno::Reference< lang::XMultiServiceFactory > xServiceFactory = comphelper::getProcessServiceFactory(); ASSERT( xServiceFactory.is(), "XML autotext event write:: got no service manager" ); if( !xServiceFactory.is() ) return ERR_SWG_WRITE_ERROR; // Get model uno::Reference< lang::XComponent > xModelComp( pDoc->GetDocShell()->GetModel(), UNO_QUERY ); ASSERT( xModelComp.is(), "XMLWriter::Write: got no model" ); if( !xModelComp.is() ) return ERR_SWG_WRITE_ERROR; // open stream in proper sub-storage if( !bFileAlreadyOpen ) { CloseFile(); // close (it may be open in read-only-mode) nRes = OpenFile ( sal_False ); } if ( 0 == nRes ) { try { xRoot = xBlkRoot->openStorageElement( aPackageName, embed::ElementModes::WRITE ); OUString sStreamName( RTL_CONSTASCII_USTRINGPARAM("atevent.xml") ); long nTmp = SOT_FORMATSTR_ID_STARWRITER_60; sal_Bool bOasis = ( SotStorage::GetVersion( xRoot ) > nTmp ); uno::Reference < io::XStream > xDocStream = xRoot->openStreamElement( sStreamName, embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ); uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY ); String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) ); OUString aMime ( RTL_CONSTASCII_USTRINGPARAM ( "text/xml") ); Any aAny; aAny <<= aMime; xSet->setPropertyValue( aPropName, aAny ); uno::Reference < io::XOutputStream > xOutputStream = xDocStream->getOutputStream(); // get XML writer uno::Reference< io::XActiveDataSource > xSaxWriter( xServiceFactory->createInstance( OUString::createFromAscii("com.sun.star.xml.sax.Writer") ), UNO_QUERY ); ASSERT( xSaxWriter.is(), "can't instantiate XML writer" ); if( xSaxWriter.is() ) { // connect XML writer to output stream xSaxWriter->setOutputStream( xOutputStream ); uno::Reference xDocHandler( xSaxWriter, UNO_QUERY); // construct events object uno::Reference xEvents = new SvMacroTableEventDescriptor(rMacroTbl,aAutotextEvents); // prepare arguments (prepend doc handler to given arguments) Sequence aParams(2); aParams[0] <<= xDocHandler; aParams[1] <<= xEvents; // get filter component uno::Reference< document::XExporter > xExporter( xServiceFactory->createInstanceWithArguments( OUString::createFromAscii( bOasis ? "com.sun.star.comp.Writer.XMLOasisAutotextEventsExporter" : "com.sun.star.comp.Writer.XMLAutotextEventsExporter"), aParams), UNO_QUERY); ASSERT( xExporter.is(), "can't instantiate export filter component" ); if( xExporter.is() ) { // connect model and filter xExporter->setSourceDocument( xModelComp ); // filter! Sequence aFilterProps( 0 ); uno::Reference < document::XFilter > xFilter( xExporter, UNO_QUERY ); xFilter->filter( aFilterProps ); } else nRes = ERR_SWG_WRITE_ERROR; } else nRes = ERR_SWG_WRITE_ERROR; // finally, commit stream, sub-storage and storage uno::Reference < embed::XTransactedObject > xTmpTrans( xRoot, uno::UNO_QUERY ); if ( xTmpTrans.is() ) xTmpTrans->commit(); if ( !bFileAlreadyOpen ) { uno::Reference < embed::XTransactedObject > xTrans( xBlkRoot, uno::UNO_QUERY ); if ( xTrans.is() ) xTrans->commit(); } xRoot = 0; } catch ( uno::Exception& ) { nRes = ERR_SWG_WRITE_ERROR; } if( !bFileAlreadyOpen ) CloseFile(); } else nRes = ERR_SWG_WRITE_ERROR; return nRes; }