LCOV - code coverage report
Current view: top level - oox/source/core - xmlfilterbase.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 200 230 87.0 %
Date: 2012-08-25 Functions: 34 35 97.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 253 570 44.4 %

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

Generated by: LCOV version 1.10