LCOV - code coverage report
Current view: top level - libreoffice/oox/source/core - xmlfilterbase.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 191 221 86.4 %
Date: 2012-12-17 Functions: 33 34 97.1 %
Legend: Lines: hit not hit

          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 "oox/core/xmlfilterbase.hxx"
      21             : 
      22             : #include <cstdio>
      23             : #include <com/sun/star/container/XNameContainer.hpp>
      24             : #include <com/sun/star/embed/XRelationshipAccess.hpp>
      25             : #include <com/sun/star/xml/sax/InputSource.hpp>
      26             : #include <com/sun/star/xml/sax/XFastParser.hpp>
      27             : #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
      28             : #include <com/sun/star/document/XDocumentProperties.hpp>
      29             : #include <comphelper/mediadescriptor.hxx>
      30             : #include <sax/fshelper.hxx>
      31             : #include <rtl/strbuf.hxx>
      32             : #include <rtl/ustrbuf.hxx>
      33             : #include <rtl/instance.hxx>
      34             : #include "oox/core/fastparser.hxx"
      35             : #include "oox/core/filterdetect.hxx"
      36             : #include "oox/core/fragmenthandler.hxx"
      37             : #include "oox/core/recordparser.hxx"
      38             : #include "oox/core/relationshandler.hxx"
      39             : #include "oox/helper/containerhelper.hxx"
      40             : #include "oox/helper/propertyset.hxx"
      41             : #include "oox/helper/zipstorage.hxx"
      42             : #include "oox/token/properties.hxx"
      43             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      44             : #include <com/sun/star/document/XOOXMLDocumentPropertiesImporter.hpp>
      45             : #include <com/sun/star/xml/dom/XDocument.hpp>
      46             : #include <com/sun/star/xml/dom/DocumentBuilder.hpp>
      47             : #include <comphelper/processfactory.hxx>
      48             : #include <comphelper/mediadescriptor.hxx>
      49             : #include <oox/core/filterdetect.hxx>
      50             : #include <comphelper/storagehelper.hxx>
      51             : using ::com::sun::star::uno::XComponentContext;
      52             : using ::com::sun::star::document::XOOXMLDocumentPropertiesImporter;
      53             : using ::com::sun::star::document::XDocumentPropertiesSupplier;
      54             : using ::com::sun::star::xml::dom::DocumentBuilder;
      55             : using ::com::sun::star::xml::dom::XDocument;
      56             : using ::com::sun::star::xml::dom::XDocumentBuilder;
      57             : using ::com::sun::star::xml::sax::XFastSAXSerializable;
      58             : using ::com::sun::star::lang::XComponent;
      59             : 
      60             : namespace oox {
      61             : namespace core {
      62             : 
      63             : // ============================================================================
      64             : 
      65             : using namespace ::com::sun::star;
      66             : using namespace ::com::sun::star::beans;
      67             : using namespace ::com::sun::star::container;
      68             : using namespace ::com::sun::star::document;
      69             : using namespace ::com::sun::star::embed;
      70             : using namespace ::com::sun::star::io;
      71             : using namespace ::com::sun::star::lang;
      72             : using namespace ::com::sun::star::uno;
      73             : using namespace ::com::sun::star::xml::sax;
      74             : 
      75             : using ::comphelper::MediaDescriptor;
      76             : using ::rtl::OStringBuffer;
      77             : using ::rtl::OUString;
      78             : using ::rtl::OUStringBuffer;
      79             : using ::sax_fastparser::FSHelperPtr;
      80             : using ::sax_fastparser::FastSerializerHelper;
      81             : 
      82             : 
      83             : 
      84             : 
      85             : 
      86             : // ============================================================================
      87             : 
      88             : namespace {
      89             : 
      90         418 : bool lclHasSuffix( const OUString& rFragmentPath, const OUString& rSuffix )
      91             : {
      92         418 :     sal_Int32 nSuffixPos = rFragmentPath.getLength() - rSuffix.getLength();
      93         418 :     return (nSuffixPos >= 0) && rFragmentPath.match( rSuffix, nSuffixPos );
      94             : }
      95             : 
      96             : } // namespace
      97             : 
      98             : // ============================================================================
      99             : 
     100         122 : struct XmlFilterBaseImpl
     101             : {
     102             :     typedef RefMap< OUString, Relations > RelationsMap;
     103             : 
     104             :     FastParser                     maFastParser;
     105             :     const OUString                 maBinSuffix;
     106             :     const OUString                 maVmlSuffix;
     107             :     RelationsMap                   maRelationsMap;
     108             :     TextFieldStack                 maTextFieldStack;
     109             : 
     110             :     explicit            XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException );
     111             : };
     112             : 
     113             : // ----------------------------------------------------------------------------
     114             : 
     115             : namespace
     116             : {
     117             :     struct NamespaceIds: public rtl::StaticWithInit<
     118             :         Sequence< beans::Pair< OUString, sal_Int32 > >,
     119             :         NamespaceIds>
     120             :     {
     121          14 :         Sequence< beans::Pair< OUString, sal_Int32 > > operator()()
     122             :         {
     123             :             static const char* const namespaceURIs[] = {
     124             :                 "http://www.w3.org/XML/1998/namespace",
     125             :                 "http://schemas.openxmlformats.org/package/2006/relationships",
     126             :                 "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
     127             :                 "http://schemas.openxmlformats.org/drawingml/2006/main",
     128             :                 "http://schemas.openxmlformats.org/drawingml/2006/diagram",
     129             :                 "http://schemas.openxmlformats.org/drawingml/2006/chart",
     130             :                 "http://schemas.openxmlformats.org/drawingml/2006/chartDrawing",
     131             :                 "urn:schemas-microsoft-com:vml",
     132             :                 "urn:schemas-microsoft-com:office:office",
     133             :                 "urn:schemas-microsoft-com:office:word",
     134             :                 "urn:schemas-microsoft-com:office:excel",
     135             :                 "urn:schemas-microsoft-com:office:powerpoint",
     136             :                 "http://schemas.microsoft.com/office/2006/activeX",
     137             :                 "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
     138             :                 "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
     139             :                 "http://schemas.microsoft.com/office/excel/2006/main",
     140             :                 "http://schemas.openxmlformats.org/presentationml/2006/main",
     141             :                 "http://schemas.openxmlformats.org/markup-compatibility/2006",
     142             :                 "http://schemas.openxmlformats.org/spreadsheetml/2006/main/v2",
     143             :                 "http://schemas.microsoft.com/office/drawing/2008/diagram",
     144             :                 "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
     145             :             };
     146             : 
     147             :             static const sal_Int32 namespaceIds[] = {
     148             :                 NMSP_xml,
     149             :                 NMSP_packageRel,
     150             :                 NMSP_officeRel,
     151             :                 NMSP_dml,
     152             :                 NMSP_dmlDiagram,
     153             :                 NMSP_dmlChart,
     154             :                 NMSP_dmlChartDr,
     155             :                 NMSP_dmlSpreadDr,
     156             :                 NMSP_vml,
     157             :                 NMSP_vmlOffice,
     158             :                 NMSP_vmlWord,
     159             :                 NMSP_vmlExcel,
     160             :                 NMSP_vmlPowerpoint,
     161             :                 NMSP_xls,
     162             :                 NMSP_ppt,
     163             :                 NMSP_ax,
     164             :                 NMSP_xm,
     165             :                 NMSP_mce,
     166             :                 NMSP_mceTest,
     167             :                 NMSP_dsp,
     168             :                 NMSP_xlsExtLst
     169             :             };
     170             : 
     171          14 :             Sequence< beans::Pair< OUString, sal_Int32 > > aRet(STATIC_ARRAY_SIZE(namespaceIds));
     172         308 :             for( sal_Int32 i=0; i<aRet.getLength(); ++i )
     173         294 :                 aRet[i] = make_Pair(
     174         294 :                     OUString::createFromAscii(namespaceURIs[i]),
     175         882 :                     namespaceIds[i]);
     176          14 :             return aRet;
     177             :         }
     178             :     };
     179             : }
     180             : 
     181             : // ----------------------------------------------------------------------------
     182             : 
     183         122 : XmlFilterBaseImpl::XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
     184             :     maFastParser( rxContext ),
     185             :     maBinSuffix( CREATE_OUSTRING( ".bin" ) ),
     186         122 :     maVmlSuffix( CREATE_OUSTRING( ".vml" ) )
     187             : {
     188             :     // register XML namespaces
     189             :     const Sequence< beans::Pair< OUString, sal_Int32 > > ids=
     190         122 :         NamespaceIds::get();
     191        2684 :     for( sal_Int32 i=0; i<ids.getLength(); ++i )
     192        2684 :         maFastParser.registerNamespace( ids[i].Second );
     193         122 : }
     194             : 
     195         122 : XmlFilterBase::XmlFilterBase( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
     196             :     FilterBase( rxContext ),
     197         122 :     mxImpl( new XmlFilterBaseImpl( rxContext ) ),
     198             :     mnRelId( 1 ),
     199         244 :     mnMaxDocId( 0 )
     200             : {
     201         122 : }
     202             : 
     203         122 : XmlFilterBase::~XmlFilterBase()
     204             : {
     205         122 : }
     206             : 
     207             : // ----------------------------------------------------------------------------
     208             : 
     209          22 : void XmlFilterBase::importDocumentProperties()
     210             : {
     211          22 :     Reference< XMultiServiceFactory > xFactory( getServiceFactory(), UNO_QUERY );
     212          22 :     MediaDescriptor aMediaDesc( getMediaDescriptor() );
     213          22 :     Reference< XInputStream > xInputStream;
     214          22 :     Reference< XComponentContext > xContext = comphelper::getComponentContext(getServiceFactory());
     215          22 :     ::oox::core::FilterDetect aDetector( xContext );
     216          22 :     xInputStream = aDetector.extractUnencryptedPackage( aMediaDesc );
     217          22 :     Reference< XComponent > xModel( getModel(), UNO_QUERY );
     218             :     Reference< XStorage > xDocumentStorage (
     219          22 :             ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( OFOPXML_STORAGE_FORMAT_STRING, xInputStream ) );
     220          44 :     Reference< XInterface > xTemp = xContext->getServiceManager()->createInstanceWithContext(
     221             :             "com.sun.star.document.OOXMLDocumentPropertiesImporter",
     222          22 :             xContext);
     223          22 :     Reference< XOOXMLDocumentPropertiesImporter > xImporter( xTemp, UNO_QUERY );
     224          22 :     Reference< XDocumentPropertiesSupplier > xPropSupplier( xModel, UNO_QUERY);
     225          22 :     xImporter->importProperties( xDocumentStorage, xPropSupplier->getDocumentProperties() );
     226          22 : }
     227             : 
     228          30 : OUString XmlFilterBase::getFragmentPathFromFirstType( const OUString& rType )
     229             : {
     230             :     // importRelations() caches the relations map for subsequence calls
     231          30 :     return importRelations( OUString() )->getFragmentPathFromFirstType( rType );
     232             : }
     233             : 
     234         418 : bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& rxHandler )
     235             : {
     236             :     OSL_ENSURE( rxHandler.is(), "XmlFilterBase::importFragment - missing fragment handler" );
     237         418 :     if( !rxHandler.is() )
     238           0 :         return false;
     239             : 
     240             :     // fragment handler must contain path to fragment stream
     241         418 :     OUString aFragmentPath = rxHandler->getFragmentPath();
     242             :     OSL_ENSURE( !aFragmentPath.isEmpty(), "XmlFilterBase::importFragment - missing fragment path" );
     243         418 :     if( aFragmentPath.isEmpty() )
     244           0 :         return false;
     245             : 
     246             :     // try to import binary streams (fragment extension must be '.bin')
     247         418 :     if( lclHasSuffix( aFragmentPath, mxImpl->maBinSuffix ) )
     248             :     {
     249             :         try
     250             :         {
     251             :             // try to open the fragment stream (this may fail - do not assert)
     252           0 :             Reference< XInputStream > xInStrm( openInputStream( aFragmentPath ), UNO_SET_THROW );
     253             : 
     254             :             // create the record parser
     255           0 :             RecordParser aParser;
     256           0 :             aParser.setFragmentHandler( rxHandler );
     257             : 
     258             :             // create the input source and parse the stream
     259           0 :             RecordInputSource aSource;
     260           0 :             aSource.mxInStream.reset( new BinaryXInputStream( xInStrm, true ) );
     261           0 :             aSource.maSystemId = aFragmentPath;
     262           0 :             aParser.parseStream( aSource );
     263           0 :             return true;
     264             :         }
     265           0 :         catch( Exception& )
     266             :         {
     267             :         }
     268           0 :         return false;
     269             :     }
     270             : 
     271             :     // get the XFastDocumentHandler interface from the fragment handler
     272         418 :     Reference< XFastDocumentHandler > xDocHandler( rxHandler.get() );
     273         418 :     if( !xDocHandler.is() )
     274           0 :         return false;
     275             : 
     276             :     // try to import XML stream
     277             :     try
     278             :     {
     279             :         /*  Try to open the fragment stream (may fail, do not throw/assert).
     280             :             Using the virtual function openFragmentStream() allows a document
     281             :             handler to create specialized input streams, e.g. VML streams that
     282             :             have to preprocess the raw input data. */
     283         418 :         Reference< XInputStream > xInStrm = rxHandler->openFragmentStream();
     284             : 
     285             :         // own try/catch block for showing parser failure assertion with fragment path
     286         418 :         if( xInStrm.is() ) try
     287             :         {
     288         302 :             mxImpl->maFastParser.setDocumentHandler( xDocHandler );
     289         302 :             mxImpl->maFastParser.parseStream( xInStrm, aFragmentPath );
     290         302 :             return true;
     291             :         }
     292           0 :         catch( Exception& )
     293             :         {
     294             :             OSL_FAIL( OStringBuffer( "XmlFilterBase::importFragment - XML parser failed in fragment '" ).
     295             :                 append( OUStringToOString( aFragmentPath, RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() );
     296         418 :         }
     297             :     }
     298           0 :     catch( Exception& )
     299             :     {
     300             :     }
     301         116 :     return false;
     302             : }
     303             : 
     304          12 : OUString XmlFilterBase::getNamespaceURL( const OUString& rPrefix )
     305             : {
     306          12 :     return mxImpl->maFastParser.getNamespaceURL( rPrefix );
     307             : }
     308             : 
     309          12 : sal_Int32 XmlFilterBase::getNamespaceId( const OUString& rUrl )
     310             : {
     311          12 :      return mxImpl->maFastParser.getNamespaceId( rUrl );
     312             : }
     313             : 
     314          12 : Reference<XDocument> XmlFilterBase::importFragment( const OUString& aFragmentPath )
     315             : {
     316          12 :     Reference<XDocument> xRet;
     317             : 
     318             :     // path to fragment stream valid?
     319             :     OSL_ENSURE( !aFragmentPath.isEmpty(), "XmlFilterBase::importFragment - empty fragment path" );
     320          12 :     if( aFragmentPath.isEmpty() )
     321             :         return xRet;
     322             : 
     323             :     // try to open the fragment stream (this may fail - do not assert)
     324          12 :     Reference< XInputStream > xInStrm = openInputStream( aFragmentPath );
     325          12 :     if( !xInStrm.is() )
     326             :         return xRet;
     327             : 
     328             :     // binary streams (fragment extension is '.bin') currently not supported
     329          12 :     sal_Int32 nBinSuffixPos = aFragmentPath.getLength() - mxImpl->maBinSuffix.getLength();
     330          12 :     if( (nBinSuffixPos >= 0) && aFragmentPath.match( mxImpl->maBinSuffix, nBinSuffixPos ) )
     331             :         return xRet;
     332             : 
     333             :     // try to import XML stream
     334             :     try
     335             :     {
     336             :         // create the dom parser
     337             :         Reference< XComponentContext > xContext =
     338          12 :             comphelper::getComponentContext(getServiceFactory());
     339          12 :         Reference<XDocumentBuilder> xDomBuilder( DocumentBuilder::create(xContext) );
     340             : 
     341             :         // create DOM from fragment
     342          12 :         xRet = xDomBuilder->parse(xInStrm);
     343             :     }
     344           0 :     catch( Exception& )
     345             :     {
     346             :     }
     347             : 
     348          12 :     return xRet;
     349             : }
     350             : 
     351          12 : bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& rxHandler,
     352             :                                     const Reference< XFastSAXSerializable >& rxSerializer )
     353             : {
     354          12 :     Reference< XFastDocumentHandler > xDocHandler( rxHandler.get() );
     355          12 :     if( !xDocHandler.is() )
     356           0 :         return false;
     357             : 
     358             :     // try to import XML stream
     359             :     try
     360             :     {
     361          12 :         rxSerializer->fastSerialize( xDocHandler,
     362          12 :                                      mxImpl->maFastParser.getTokenHandler(),
     363             :                                      Sequence< StringPair >(),
     364          24 :                                      NamespaceIds::get() );
     365          12 :         return true;
     366             :     }
     367           0 :     catch( Exception& )
     368             :     {}
     369             : 
     370           0 :     return false;
     371             : }
     372             : 
     373         288 : RelationsRef XmlFilterBase::importRelations( const OUString& rFragmentPath )
     374             : {
     375             :     // try to find cached relations
     376         288 :     RelationsRef& rxRelations = mxImpl->maRelationsMap[ rFragmentPath ];
     377         288 :     if( !rxRelations )
     378             :     {
     379             :         // import and cache relations
     380         250 :         rxRelations.reset( new Relations( rFragmentPath ) );
     381         250 :         importFragment( new RelationsFragment( *this, rxRelations ) );
     382             :     }
     383         288 :     return rxRelations;
     384             : }
     385             : 
     386         304 : Reference< XOutputStream > XmlFilterBase::openFragmentStream( const OUString& rStreamName, const OUString& rMediaType )
     387             : {
     388         304 :     Reference< XOutputStream > xOutputStream = openOutputStream( rStreamName );
     389         304 :     PropertySet aPropSet( xOutputStream );
     390         304 :     aPropSet.setProperty( PROP_MediaType, rMediaType );
     391         304 :     return xOutputStream;
     392             : }
     393             : 
     394         302 : FSHelperPtr XmlFilterBase::openFragmentStreamWithSerializer( const OUString& rStreamName, const OUString& rMediaType )
     395             : {
     396         302 :     bool bWriteHeader = true;
     397         302 :     if( rMediaType.indexOfAsciiL( "vml", 3 ) >= 0 &&
     398           0 :         rMediaType.indexOfAsciiL( "+xml", 4 ) < 0 )
     399           0 :         bWriteHeader = false;
     400         302 :     return FSHelperPtr( new FastSerializerHelper( openFragmentStream( rStreamName, rMediaType ), bWriteHeader ) );
     401             : }
     402             : 
     403           8 : TextFieldStack& XmlFilterBase::getTextFieldStack() const
     404             : {
     405           8 :     return mxImpl->maTextFieldStack;
     406             : }
     407             : 
     408             : namespace {
     409             : 
     410         306 : OUString lclAddRelation( const Reference< XRelationshipAccess > xRelations, sal_Int32 nId, const OUString& rType, const OUString& rTarget, bool bExternal )
     411             : {
     412         306 :     OUString sId = OUStringBuffer().appendAscii( "rId" ).append( nId ).makeStringAndClear();
     413             : 
     414         306 :     Sequence< StringPair > aEntry( bExternal ? 3 : 2 );
     415         306 :     aEntry[0].First = CREATE_OUSTRING( "Type" );
     416         306 :     aEntry[0].Second = rType;
     417         306 :     aEntry[1].First = CREATE_OUSTRING( "Target" );
     418         306 :     aEntry[1].Second = rTarget;
     419         306 :     if( bExternal )
     420             :     {
     421           2 :         aEntry[2].First = CREATE_OUSTRING( "TargetMode" );
     422           2 :         aEntry[2].Second = CREATE_OUSTRING( "External" );
     423             :     }
     424         306 :     xRelations->insertRelationshipByID( sId, aEntry, sal_True );
     425             : 
     426         306 :     return sId;
     427             : }
     428             : 
     429             : } // namespace
     430             : 
     431         150 : OUString XmlFilterBase::addRelation( const OUString& rType, const OUString& rTarget, bool bExternal )
     432             : {
     433         150 :     Reference< XRelationshipAccess > xRelations( getStorage()->getXStorage(), UNO_QUERY );
     434         150 :     if( xRelations.is() )
     435         150 :         return lclAddRelation( xRelations, mnRelId ++, rType, rTarget, bExternal );
     436             : 
     437           0 :     return OUString();
     438             : }
     439             : 
     440         156 : OUString XmlFilterBase::addRelation( const Reference< XOutputStream > xOutputStream, const OUString& rType, const OUString& rTarget, bool bExternal )
     441             : {
     442         156 :     sal_Int32 nId = 0;
     443             : 
     444         156 :     PropertySet aPropSet( xOutputStream );
     445         156 :     if( aPropSet.is() )
     446         156 :         aPropSet.getProperty( nId, PROP_RelId );
     447             :     else
     448           0 :         nId = mnRelId++;
     449             : 
     450         156 :     Reference< XRelationshipAccess > xRelations( xOutputStream, UNO_QUERY );
     451         156 :     if( xRelations.is() )
     452         156 :         return lclAddRelation( xRelations, nId, rType, rTarget, bExternal );
     453             : 
     454           0 :     return OUString();
     455             : }
     456             : 
     457             : static void
     458         400 : writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const OUString& sValue )
     459             : {
     460         400 :     if( sValue.isEmpty() )
     461         738 :         return;
     462          62 :     pDoc->startElement( nXmlElement, FSEND );
     463          62 :     pDoc->write( sValue );
     464          62 :     pDoc->endElement( nXmlElement );
     465             : }
     466             : 
     467             : static void
     468         100 : writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const sal_Int32 nValue )
     469             : {
     470         100 :     pDoc->startElement( nXmlElement, FSEND );
     471         100 :     pDoc->write( OUString::valueOf( nValue ) );
     472         100 :     pDoc->endElement( nXmlElement );
     473         100 : }
     474             : 
     475             : static void
     476         150 : writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const util::DateTime& rTime )
     477             : {
     478         150 :     if( rTime.Year == 0 )
     479         150 :         return;
     480             : 
     481          68 :     if ( ( nXmlElement >> 16 ) != XML_dcterms )
     482           0 :         pDoc->startElement( nXmlElement, FSEND );
     483             :     else
     484             :         pDoc->startElement( nXmlElement,
     485             :                 FSNS( XML_xsi, XML_type ), "dcterms:W3CDTF",
     486          68 :                 FSEND );
     487             : 
     488             :     char pStr[200];
     489             :     snprintf( pStr, sizeof( pStr ), "%d-%02d-%02dT%02d:%02d:%02d.%02dZ",
     490             :             rTime.Year, rTime.Month, rTime.Day,
     491             :             rTime.Hours, rTime.Minutes, rTime.Seconds,
     492          68 :             rTime.HundredthSeconds );
     493             : 
     494          68 :     pDoc->write( pStr );
     495             : 
     496          68 :     pDoc->endElement( nXmlElement );
     497             : }
     498             : 
     499             : static void
     500          50 : writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, Sequence< rtl::OUString > aItems )
     501             : {
     502          50 :     if( aItems.getLength() == 0 )
     503          50 :         return;
     504             : 
     505           0 :     OUStringBuffer sRep;
     506           0 :     sRep.append( aItems[ 0 ] );
     507             : 
     508           0 :     for( sal_Int32 i = 1, end = aItems.getLength(); i < end; ++i )
     509             :     {
     510           0 :         sRep.appendAscii( " " ).append( aItems[ i ] );
     511             :     }
     512             : 
     513           0 :     writeElement( pDoc, nXmlElement, sRep.makeStringAndClear() );
     514             : }
     515             : 
     516             : static void
     517          50 : writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const Locale& rLocale )
     518             : {
     519             :     // TODO: what to do with .Country and .Variant
     520          50 :     writeElement( pDoc, nXmlElement, rLocale.Language );
     521          50 : }
     522             : 
     523             : static void
     524          50 : writeCoreProperties( XmlFilterBase& rSelf, Reference< XDocumentProperties > xProperties )
     525             : {
     526          50 :     OUString sValue;
     527          50 :     if( rSelf.getVersion() == oox::core::ISOIEC_29500_2008  )
     528          48 :         sValue = CREATE_OUSTRING( "http://schemas.openxmlformats.org/officedocument/2006/relationships/metadata/core-properties" );
     529             :     else
     530           2 :         sValue = CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" );
     531             : 
     532          50 :     rSelf.addRelation( sValue, CREATE_OUSTRING( "docProps/core.xml" ) );
     533             :     FSHelperPtr pCoreProps = rSelf.openFragmentStreamWithSerializer(
     534             :             CREATE_OUSTRING( "docProps/core.xml" ),
     535          50 :             CREATE_OUSTRING( "application/vnd.openxmlformats-package.core-properties+xml" ) );
     536             :     pCoreProps->startElementNS( XML_cp, XML_coreProperties,
     537             :             FSNS( XML_xmlns, XML_cp ),          "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
     538             :             FSNS( XML_xmlns, XML_dc ),          "http://purl.org/dc/elements/1.1/",
     539             :             FSNS( XML_xmlns, XML_dcterms ),     "http://purl.org/dc/terms/",
     540             :             FSNS( XML_xmlns, XML_dcmitype ),    "http://purl.org/dc/dcmitype/",
     541             :             FSNS( XML_xmlns, XML_xsi ),         "http://www.w3.org/2001/XMLSchema-instance",
     542          50 :             FSEND );
     543             : 
     544             : #if OOXTODO
     545             :     writeElement( pCoreProps, FSNS( XML_cp, XML_category ),         "category" );
     546             :     writeElement( pCoreProps, FSNS( XML_cp, XML_contentStatus ),    "status" );
     547             :     writeElement( pCoreProps, FSNS( XML_cp, XML_contentType ),      "contentType" );
     548             : #endif  /* def OOXTODO */
     549          50 :     writeElement( pCoreProps, FSNS( XML_dcterms, XML_created ),     xProperties->getCreationDate() );
     550          50 :     writeElement( pCoreProps, FSNS( XML_dc, XML_creator ),          xProperties->getAuthor() );
     551          50 :     writeElement( pCoreProps, FSNS( XML_dc, XML_description ),      xProperties->getDescription() );
     552             : #if OOXTODO
     553             :     writeElement( pCoreProps, FSNS( XML_dc, XML_identifier ),       "ident" );
     554             : #endif  /* def OOXTODO */
     555          50 :     writeElement( pCoreProps, FSNS( XML_cp, XML_keywords ),         xProperties->getKeywords() );
     556          50 :     writeElement( pCoreProps, FSNS( XML_dc, XML_language ),         xProperties->getLanguage() );
     557          50 :     writeElement( pCoreProps, FSNS( XML_cp, XML_lastModifiedBy ),   xProperties->getModifiedBy() );
     558          50 :     writeElement( pCoreProps, FSNS( XML_cp, XML_lastPrinted ),      xProperties->getPrintDate() );
     559          50 :     writeElement( pCoreProps, FSNS( XML_dcterms, XML_modified ),    xProperties->getModificationDate() );
     560          50 :     writeElement( pCoreProps, FSNS( XML_cp, XML_revision ),         xProperties->getEditingCycles() );
     561          50 :     writeElement( pCoreProps, FSNS( XML_dc, XML_subject ),          xProperties->getSubject() );
     562          50 :     writeElement( pCoreProps, FSNS( XML_dc, XML_title ),            xProperties->getTitle() );
     563             : #if OOXTODO
     564             :     writeElement( pCoreProps, FSNS( XML_cp, XML_version ),          "version" );
     565             : #endif  /* def OOXTODO */
     566             : 
     567          50 :     pCoreProps->endElementNS( XML_cp, XML_coreProperties );
     568          50 : }
     569             : 
     570             : static void
     571          50 : writeAppProperties( XmlFilterBase& rSelf, Reference< XDocumentProperties > xProperties )
     572             : {
     573             :     rSelf.addRelation(
     574             :             CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" ),
     575          50 :             CREATE_OUSTRING( "docProps/app.xml" ) );
     576             :     FSHelperPtr pAppProps = rSelf.openFragmentStreamWithSerializer(
     577             :             CREATE_OUSTRING( "docProps/app.xml" ),
     578          50 :             CREATE_OUSTRING( "application/vnd.openxmlformats-officedocument.extended-properties+xml" ) );
     579             :     pAppProps->startElement( XML_Properties,
     580             :             XML_xmlns,                  "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",
     581             :             FSNS( XML_xmlns, XML_vt ),  "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes",
     582          50 :             FSEND );
     583             : 
     584          50 :     writeElement( pAppProps, XML_Template,              xProperties->getTemplateName() );
     585             : #if OOXTODO
     586             :     writeElement( pAppProps, XML_Manager,               "manager" );
     587             :     writeElement( pAppProps, XML_Company,               "company" );
     588             :     writeElement( pAppProps, XML_Pages,                 "pages" );
     589             :     writeElement( pAppProps, XML_Words,                 "words" );
     590             :     writeElement( pAppProps, XML_Characters,            "characters" );
     591             :     writeElement( pAppProps, XML_PresentationFormat,    "presentation format" );
     592             :     writeElement( pAppProps, XML_Lines,                 "lines" );
     593             :     writeElement( pAppProps, XML_Paragraphs,            "paragraphs" );
     594             :     writeElement( pAppProps, XML_Slides,                "slides" );
     595             :     writeElement( pAppProps, XML_Notes,                 "notes" );
     596             : #endif  /* def OOXTODO */
     597          50 :     writeElement( pAppProps, XML_TotalTime,             xProperties->getEditingDuration() );
     598             : #if OOXTODO
     599             :     writeElement( pAppProps, XML_HiddenSlides,          "hidden slides" );
     600             :     writeElement( pAppProps, XML_MMClips,               "mm clips" );
     601             :     writeElement( pAppProps, XML_ScaleCrop,             "scale crop" );
     602             :     writeElement( pAppProps, XML_HeadingPairs,          "heading pairs" );
     603             :     writeElement( pAppProps, XML_TitlesOfParts,         "titles of parts" );
     604             :     writeElement( pAppProps, XML_LinksUpToDate,         "links up-to-date" );
     605             :     writeElement( pAppProps, XML_CharactersWithSpaces,  "characters with spaces" );
     606             :     writeElement( pAppProps, XML_SharedDoc,             "shared doc" );
     607             :     writeElement( pAppProps, XML_HyperlinkBase,         "hyperlink base" );
     608             :     writeElement( pAppProps, XML_HLinks,                "hlinks" );
     609             :     writeElement( pAppProps, XML_HyperlinksChanged,     "hyperlinks changed" );
     610             :     writeElement( pAppProps, XML_DigSig,                "digital signature" );
     611             : #endif  /* def OOXTODO */
     612          50 :     writeElement( pAppProps, XML_Application,           xProperties->getGenerator() );
     613             : #if OOXTODO
     614             :     writeElement( pAppProps, XML_AppVersion,            "app version" );
     615             :     writeElement( pAppProps, XML_DocSecurity,           "doc security" );
     616             : #endif  /* def OOXTODO */
     617          50 :     pAppProps->endElement( XML_Properties );
     618          50 : }
     619             : 
     620          50 : XmlFilterBase& XmlFilterBase::exportDocumentProperties( Reference< XDocumentProperties > xProperties )
     621             : {
     622          50 :     if( xProperties.is() )
     623             :     {
     624          50 :         writeCoreProperties( *this, xProperties );
     625          50 :         writeAppProperties( *this, xProperties );
     626          50 :         Sequence< ::com::sun::star::beans::NamedValue > aStats = xProperties->getDocumentStatistics();
     627             :         OSL_TRACE( "# Document Statistics:" );
     628         146 :         for( sal_Int32 i = 0, end = aStats.getLength(); i < end; ++i )
     629             :         {
     630          96 :             ::com::sun::star::uno::Any aValue = aStats[ i ].Value;
     631          96 :             OUString sValue;
     632          96 :             bool bHaveString = aValue >>= sValue;
     633             :             OSL_TRACE ("#\t%s=%s [%s]\n",
     634             :                     OUStringToOString( aStats[ i ].Name, RTL_TEXTENCODING_UTF8 ).getStr(),
     635             :                     bHaveString
     636             :                         ? OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr()
     637             :                         : "<unconvertable>",
     638             :                     OUStringToOString( aValue.getValueTypeName(), RTL_TEXTENCODING_UTF8 ).getStr());
     639         146 :         }
     640             :     }
     641          50 :     return *this;
     642             : }
     643             : 
     644             : // protected ------------------------------------------------------------------
     645             : 
     646         102 : Reference< XInputStream > XmlFilterBase::implGetInputStream( MediaDescriptor& rMediaDesc ) const
     647             : {
     648             :     /*  Get the input stream directly from the media descriptor, or decrypt the
     649             :         package again. The latter is needed e.g. when the document is reloaded.
     650             :         All this is implemented in the detector service. */
     651         102 :     FilterDetect aDetector( getComponentContext() );
     652         102 :     return aDetector.extractUnencryptedPackage( rMediaDesc );
     653             : }
     654             : 
     655             : // private --------------------------------------------------------------------
     656             : 
     657         102 : StorageRef XmlFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const
     658             : {
     659         102 :     return StorageRef( new ZipStorage( getComponentContext(), rxInStream ) );
     660             : }
     661             : 
     662          52 : StorageRef XmlFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const
     663             : {
     664          52 :     return StorageRef( new ZipStorage( getComponentContext(), rxOutStream ) );
     665             : }
     666             : 
     667             : // ============================================================================
     668             : 
     669             : } // namespace core
     670         174 : } // namespace oox
     671             : 
     672             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10