LCOV - code coverage report
Current view: top level - sfx2/source/doc - SfxDocumentMetaData.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 892 1020 87.5 %
Date: 2012-08-25 Functions: 92 111 82.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 870 1858 46.8 %

           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                 :            : 
      21                 :            : #include "sal/config.h"
      22                 :            : #include "cppuhelper/factory.hxx"
      23                 :            : #include "cppuhelper/implementationentry.hxx"
      24                 :            : #include "cppuhelper/compbase6.hxx"
      25                 :            : #include "com/sun/star/lang/XServiceInfo.hpp"
      26                 :            : #include "com/sun/star/document/XDocumentProperties.hpp"
      27                 :            : #include "com/sun/star/lang/XInitialization.hpp"
      28                 :            : #include "com/sun/star/util/XCloneable.hpp"
      29                 :            : #include "com/sun/star/util/XModifiable.hpp"
      30                 :            : #include "com/sun/star/xml/sax/XSAXSerializable.hpp"
      31                 :            : 
      32                 :            : #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
      33                 :            : #include "com/sun/star/lang/EventObject.hpp"
      34                 :            : #include "com/sun/star/beans/XPropertySet.hpp"
      35                 :            : #include "com/sun/star/beans/XPropertySetInfo.hpp"
      36                 :            : #include "com/sun/star/beans/PropertyAttribute.hpp"
      37                 :            : #include "com/sun/star/task/ErrorCodeIOException.hpp"
      38                 :            : #include "com/sun/star/embed/XStorage.hpp"
      39                 :            : #include "com/sun/star/embed/XTransactedObject.hpp"
      40                 :            : #include "com/sun/star/embed/ElementModes.hpp"
      41                 :            : #include "com/sun/star/io/XActiveDataControl.hpp"
      42                 :            : #include "com/sun/star/io/XActiveDataSource.hpp"
      43                 :            : #include "com/sun/star/io/XStream.hpp"
      44                 :            : #include "com/sun/star/document/XImporter.hpp"
      45                 :            : #include "com/sun/star/document/XExporter.hpp"
      46                 :            : #include "com/sun/star/document/XFilter.hpp"
      47                 :            : #include "com/sun/star/xml/sax/XParser.hpp"
      48                 :            : #include "com/sun/star/xml/dom/XDocument.hpp"
      49                 :            : #include "com/sun/star/xml/dom/XElement.hpp"
      50                 :            : #include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
      51                 :            : #include "com/sun/star/xml/dom/XSAXDocumentBuilder.hpp"
      52                 :            : #include "com/sun/star/xml/dom/NodeType.hpp"
      53                 :            : #include "com/sun/star/xml/xpath/XXPathAPI.hpp"
      54                 :            : #include "com/sun/star/util/Date.hpp"
      55                 :            : #include "com/sun/star/util/Time.hpp"
      56                 :            : #include "com/sun/star/util/Duration.hpp"
      57                 :            : 
      58                 :            : #include "SfxDocumentMetaData.hxx"
      59                 :            : #include "rtl/ustrbuf.hxx"
      60                 :            : #include "tools/debug.hxx"
      61                 :            : #include "tools/datetime.hxx"
      62                 :            : #include "osl/mutex.hxx"
      63                 :            : #include "cppuhelper/basemutex.hxx"
      64                 :            : #include "cppuhelper/interfacecontainer.hxx"
      65                 :            : #include "comphelper/storagehelper.hxx"
      66                 :            : #include "comphelper/mediadescriptor.hxx"
      67                 :            : #include "comphelper/sequenceasvector.hxx"
      68                 :            : #include "comphelper/stlunosequence.hxx"
      69                 :            : #include "sot/storage.hxx"
      70                 :            : #include "sfx2/docfile.hxx"
      71                 :            : #include "sax/tools/converter.hxx"
      72                 :            : 
      73                 :            : #include <utility>
      74                 :            : #include <vector>
      75                 :            : #include <map>
      76                 :            : #include <cstring>
      77                 :            : #include <limits>
      78                 :            : 
      79                 :            : 
      80                 :            : #include <cppuhelper/implbase1.hxx>
      81                 :            : #include <com/sun/star/document/XCompatWriterDocProperties.hpp>
      82                 :            : 
      83                 :            : /**
      84                 :            :  * This file contains the implementation of the service
      85                 :            :  * com.sun.star.document.DocumentProperties.
      86                 :            :  * This service enables access to the meta-data stored in documents.
      87                 :            :  * Currently, this service only handles documents in ODF format.
      88                 :            :  *
      89                 :            :  * The implementation uses an XML DOM to store the properties.
      90                 :            :  * This approach was taken because it allows for preserving arbitrary XML data
      91                 :            :  * in loaded documents, which will be stored unmodified when saving the
      92                 :            :  * document again.
      93                 :            :  *
      94                 :            :  * Upon access, some properties are directly read from and updated in the DOM.
      95                 :            :  * Exception: it seems impossible to get notified upon addition of a property
      96                 :            :  * to a com.sun.star.beans.PropertyBag, which is used for storing user-defined
      97                 :            :  * properties; because of this, user-defined properties are updated in the
      98                 :            :  * XML DOM only when storing the document.
      99                 :            :  * Exception 2: when setting certain properties which correspond to attributes
     100                 :            :  * in the XML DOM, we want to remove the corresponding XML element. Detecting
     101                 :            :  * this condition can get messy, so we store all such properties as members,
     102                 :            :  * and update the DOM tree only when storing the document (in
     103                 :            :  * <method>updateUserDefinedAndAttributes</method>).
     104                 :            :  *
     105                 :            :  * @author mst
     106                 :            :  */
     107                 :            : 
     108                 :            : /// anonymous implementation namespace
     109                 :            : namespace {
     110                 :            : 
     111                 :            : namespace css = ::com::sun::star;
     112                 :            : 
     113                 :            : 
     114                 :            : /// a list of attribute-lists, where attribute means name and content
     115                 :            : typedef std::vector<std::vector<std::pair<const char*, ::rtl::OUString> > >
     116                 :            :         AttrVector;
     117                 :            : 
     118                 :            : typedef ::cppu::WeakComponentImplHelper6<
     119                 :            :             css::lang::XServiceInfo,
     120                 :            :             css::document::XDocumentProperties,
     121                 :            :             css::lang::XInitialization,
     122                 :            :             css::util::XCloneable,
     123                 :            :             css::util::XModifiable,
     124                 :            :             css::xml::sax::XSAXSerializable>
     125                 :            :     SfxDocumentMetaData_Base;
     126                 :            : 
     127                 :            : class SfxDocumentMetaData:
     128                 :            :     private ::cppu::BaseMutex,
     129                 :            :     public SfxDocumentMetaData_Base
     130                 :            : {
     131                 :            : public:
     132                 :            :     explicit SfxDocumentMetaData(
     133                 :            :         css::uno::Reference< css::uno::XComponentContext > const & context);
     134                 :            : 
     135                 :            :     // ::com::sun::star::lang::XServiceInfo:
     136                 :            :     virtual ::rtl::OUString SAL_CALL getImplementationName()
     137                 :            :         throw (css::uno::RuntimeException);
     138                 :            :     virtual ::sal_Bool SAL_CALL supportsService(
     139                 :            :         const ::rtl::OUString & ServiceName) throw (css::uno::RuntimeException);
     140                 :            :     virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL
     141                 :            :         getSupportedServiceNames() throw (css::uno::RuntimeException);
     142                 :            : 
     143                 :            :     // ::com::sun::star::lang::XComponent:
     144                 :            :     virtual void SAL_CALL dispose() throw (css::uno::RuntimeException);
     145                 :            : 
     146                 :            :     // ::com::sun::star::document::XDocumentProperties:
     147                 :            :     virtual ::rtl::OUString SAL_CALL getAuthor()
     148                 :            :         throw (css::uno::RuntimeException);
     149                 :            :     virtual void SAL_CALL setAuthor(const ::rtl::OUString & the_value)
     150                 :            :         throw (css::uno::RuntimeException);
     151                 :            :     virtual ::rtl::OUString SAL_CALL getGenerator()
     152                 :            :         throw (css::uno::RuntimeException);
     153                 :            :     virtual void SAL_CALL setGenerator(const ::rtl::OUString & the_value)
     154                 :            :         throw (css::uno::RuntimeException);
     155                 :            :     virtual css::util::DateTime SAL_CALL getCreationDate()
     156                 :            :         throw (css::uno::RuntimeException);
     157                 :            :     virtual void SAL_CALL setCreationDate(const css::util::DateTime & the_value)
     158                 :            :         throw (css::uno::RuntimeException);
     159                 :            :     virtual ::rtl::OUString SAL_CALL getTitle()
     160                 :            :         throw (css::uno::RuntimeException);
     161                 :            :     virtual void SAL_CALL setTitle(const ::rtl::OUString & the_value)
     162                 :            :         throw (css::uno::RuntimeException);
     163                 :            :     virtual ::rtl::OUString SAL_CALL getSubject()
     164                 :            :         throw (css::uno::RuntimeException);
     165                 :            :     virtual void SAL_CALL setSubject(const ::rtl::OUString & the_value)
     166                 :            :         throw (css::uno::RuntimeException);
     167                 :            :     virtual ::rtl::OUString SAL_CALL getDescription()
     168                 :            :         throw (css::uno::RuntimeException);
     169                 :            :     virtual void SAL_CALL setDescription(const ::rtl::OUString & the_value)
     170                 :            :         throw (css::uno::RuntimeException);
     171                 :            :     virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getKeywords()
     172                 :            :         throw (css::uno::RuntimeException);
     173                 :            :     virtual void SAL_CALL setKeywords(
     174                 :            :         const css::uno::Sequence< ::rtl::OUString > & the_value)
     175                 :            :         throw (css::uno::RuntimeException);
     176                 :            :     virtual css::lang::Locale SAL_CALL getLanguage()
     177                 :            :         throw (css::uno::RuntimeException);
     178                 :            :     virtual void SAL_CALL setLanguage(const css::lang::Locale & the_value)
     179                 :            :         throw (css::uno::RuntimeException);
     180                 :            :     virtual ::rtl::OUString SAL_CALL getModifiedBy()
     181                 :            :         throw (css::uno::RuntimeException);
     182                 :            :     virtual void SAL_CALL setModifiedBy(const ::rtl::OUString & the_value)
     183                 :            :         throw (css::uno::RuntimeException);
     184                 :            :     virtual css::util::DateTime SAL_CALL getModificationDate()
     185                 :            :         throw (css::uno::RuntimeException);
     186                 :            :     virtual void SAL_CALL setModificationDate(
     187                 :            :             const css::util::DateTime & the_value)
     188                 :            :         throw (css::uno::RuntimeException);
     189                 :            :     virtual ::rtl::OUString SAL_CALL getPrintedBy()
     190                 :            :         throw (css::uno::RuntimeException);
     191                 :            :     virtual void SAL_CALL setPrintedBy(const ::rtl::OUString & the_value)
     192                 :            :         throw (css::uno::RuntimeException);
     193                 :            :     virtual css::util::DateTime SAL_CALL getPrintDate()
     194                 :            :         throw (css::uno::RuntimeException);
     195                 :            :     virtual void SAL_CALL setPrintDate(const css::util::DateTime & the_value)
     196                 :            :         throw (css::uno::RuntimeException);
     197                 :            :     virtual ::rtl::OUString SAL_CALL getTemplateName()
     198                 :            :         throw (css::uno::RuntimeException);
     199                 :            :     virtual void SAL_CALL setTemplateName(const ::rtl::OUString & the_value)
     200                 :            :         throw (css::uno::RuntimeException);
     201                 :            :     virtual ::rtl::OUString SAL_CALL getTemplateURL()
     202                 :            :         throw (css::uno::RuntimeException);
     203                 :            :     virtual void SAL_CALL setTemplateURL(const ::rtl::OUString & the_value)
     204                 :            :         throw (css::uno::RuntimeException);
     205                 :            :     virtual css::util::DateTime SAL_CALL getTemplateDate()
     206                 :            :         throw (css::uno::RuntimeException);
     207                 :            :     virtual void SAL_CALL setTemplateDate(const css::util::DateTime & the_value)
     208                 :            :         throw (css::uno::RuntimeException);
     209                 :            :     virtual ::rtl::OUString SAL_CALL getAutoloadURL()
     210                 :            :         throw (css::uno::RuntimeException);
     211                 :            :     virtual void SAL_CALL setAutoloadURL(const ::rtl::OUString & the_value)
     212                 :            :         throw (css::uno::RuntimeException);
     213                 :            :     virtual ::sal_Int32 SAL_CALL getAutoloadSecs()
     214                 :            :         throw (css::uno::RuntimeException);
     215                 :            :     virtual void SAL_CALL setAutoloadSecs(::sal_Int32 the_value)
     216                 :            :         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
     217                 :            :     virtual ::rtl::OUString SAL_CALL getDefaultTarget()
     218                 :            :         throw (css::uno::RuntimeException);
     219                 :            :     virtual void SAL_CALL setDefaultTarget(const ::rtl::OUString & the_value)
     220                 :            :         throw (css::uno::RuntimeException);
     221                 :            :     virtual css::uno::Sequence< css::beans::NamedValue > SAL_CALL
     222                 :            :         getDocumentStatistics() throw (css::uno::RuntimeException);
     223                 :            :     virtual void SAL_CALL setDocumentStatistics(
     224                 :            :         const css::uno::Sequence< css::beans::NamedValue > & the_value)
     225                 :            :         throw (css::uno::RuntimeException);
     226                 :            :     virtual ::sal_Int16 SAL_CALL getEditingCycles()
     227                 :            :         throw (css::uno::RuntimeException);
     228                 :            :     virtual void SAL_CALL setEditingCycles(::sal_Int16 the_value)
     229                 :            :         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
     230                 :            :     virtual ::sal_Int32 SAL_CALL getEditingDuration()
     231                 :            :         throw (css::uno::RuntimeException);
     232                 :            :     virtual void SAL_CALL setEditingDuration(::sal_Int32 the_value)
     233                 :            :         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
     234                 :            :     virtual void SAL_CALL resetUserData(const ::rtl::OUString & the_value)
     235                 :            :         throw (css::uno::RuntimeException);
     236                 :            :     virtual css::uno::Reference< css::beans::XPropertyContainer > SAL_CALL
     237                 :            :         getUserDefinedProperties() throw (css::uno::RuntimeException);
     238                 :            :     virtual void SAL_CALL loadFromStorage(
     239                 :            :         const css::uno::Reference< css::embed::XStorage > & Storage,
     240                 :            :         const css::uno::Sequence< css::beans::PropertyValue > & Medium)
     241                 :            :         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException,
     242                 :            :                css::io::WrongFormatException,
     243                 :            :                css::lang::WrappedTargetException, css::io::IOException);
     244                 :            :     virtual void SAL_CALL loadFromMedium(const ::rtl::OUString & URL,
     245                 :            :         const css::uno::Sequence< css::beans::PropertyValue > & Medium)
     246                 :            :         throw (css::uno::RuntimeException,
     247                 :            :                css::io::WrongFormatException,
     248                 :            :                css::lang::WrappedTargetException, css::io::IOException);
     249                 :            :     virtual void SAL_CALL storeToStorage(
     250                 :            :         const css::uno::Reference< css::embed::XStorage > & Storage,
     251                 :            :         const css::uno::Sequence< css::beans::PropertyValue > & Medium)
     252                 :            :         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException,
     253                 :            :                css::lang::WrappedTargetException, css::io::IOException);
     254                 :            :     virtual void SAL_CALL storeToMedium(const ::rtl::OUString & URL,
     255                 :            :         const css::uno::Sequence< css::beans::PropertyValue > & Medium)
     256                 :            :         throw (css::uno::RuntimeException,
     257                 :            :                css::lang::WrappedTargetException, css::io::IOException);
     258                 :            : 
     259                 :            :     // ::com::sun::star::lang::XInitialization:
     260                 :            :     virtual void SAL_CALL initialize(
     261                 :            :         const css::uno::Sequence< css::uno::Any > & aArguments)
     262                 :            :         throw (css::uno::RuntimeException, css::uno::Exception);
     263                 :            : 
     264                 :            :     // ::com::sun::star::util::XCloneable:
     265                 :            :     virtual css::uno::Reference<css::util::XCloneable> SAL_CALL createClone()
     266                 :            :         throw (css::uno::RuntimeException);
     267                 :            : 
     268                 :            :     // ::com::sun::star::util::XModifiable:
     269                 :            :     virtual ::sal_Bool SAL_CALL isModified(  )
     270                 :            :         throw (css::uno::RuntimeException);
     271                 :            :     virtual void SAL_CALL setModified( ::sal_Bool bModified )
     272                 :            :         throw (css::beans::PropertyVetoException, css::uno::RuntimeException);
     273                 :            : 
     274                 :            :     // ::com::sun::star::util::XModifyBroadcaster:
     275                 :            :     virtual void SAL_CALL addModifyListener(
     276                 :            :         const css::uno::Reference< css::util::XModifyListener > & xListener)
     277                 :            :         throw (css::uno::RuntimeException);
     278                 :            :     virtual void SAL_CALL removeModifyListener(
     279                 :            :         const css::uno::Reference< css::util::XModifyListener > & xListener)
     280                 :            :         throw (css::uno::RuntimeException);
     281                 :            : 
     282                 :            :     // ::com::sun::star::xml::sax::XSAXSerializable
     283                 :            :     virtual void SAL_CALL serialize(
     284                 :            :         const css::uno::Reference<css::xml::sax::XDocumentHandler>& i_xHandler,
     285                 :            :         const css::uno::Sequence< css::beans::StringPair >& i_rNamespaces)
     286                 :            :         throw (css::uno::RuntimeException, css::xml::sax::SAXException);
     287                 :            : 
     288                 :            : protected:
     289                 :            :     SfxDocumentMetaData(SfxDocumentMetaData &); // not defined
     290                 :            :     SfxDocumentMetaData& operator =(SfxDocumentMetaData &); // not defined
     291                 :            : 
     292 [ +  - ][ +  - ]:       4940 :     virtual ~SfxDocumentMetaData() {}
                 [ -  + ]
     293         [ +  - ]:        159 :     virtual SfxDocumentMetaData* createMe( css::uno::Reference< css::uno::XComponentContext > const & context ) { return new SfxDocumentMetaData( context ); };
     294                 :            :     const css::uno::Reference< css::uno::XComponentContext > m_xContext;
     295                 :            : 
     296                 :            :     /// for notification
     297                 :            :     ::cppu::OInterfaceContainerHelper m_NotifyListeners;
     298                 :            :     /// flag: false means not initialized yet, or disposed
     299                 :            :     bool m_isInitialized;
     300                 :            :     /// flag
     301                 :            :     bool m_isModified;
     302                 :            :     /// meta-data DOM tree
     303                 :            :     css::uno::Reference< css::xml::dom::XDocument > m_xDoc;
     304                 :            :     /// meta-data super node in the meta-data DOM tree
     305                 :            :     css::uno::Reference< css::xml::dom::XNode> m_xParent;
     306                 :            :     /// standard meta data (single occurrence)
     307                 :            :     std::map< ::rtl::OUString, css::uno::Reference<css::xml::dom::XNode> >
     308                 :            :         m_meta;
     309                 :            :     /// standard meta data (multiple occurrences)
     310                 :            :     std::map< ::rtl::OUString,
     311                 :            :         std::vector<css::uno::Reference<css::xml::dom::XNode> > > m_metaList;
     312                 :            :     /// user-defined meta data (meta:user-defined) @ATTENTION may be null!
     313                 :            :     css::uno::Reference<css::beans::XPropertyContainer> m_xUserDefined;
     314                 :            :     // now for some meta-data attributes; these are not updated directly in the
     315                 :            :     // DOM because updates (detecting "empty" elements) would be quite messy
     316                 :            :     ::rtl::OUString m_TemplateName;
     317                 :            :     ::rtl::OUString m_TemplateURL;
     318                 :            :     css::util::DateTime m_TemplateDate;
     319                 :            :     ::rtl::OUString m_AutoloadURL;
     320                 :            :     sal_Int32 m_AutoloadSecs;
     321                 :            :     ::rtl::OUString m_DefaultTarget;
     322                 :            : 
     323                 :            :     /// check if we are initialized properly
     324                 :            :     void SAL_CALL checkInit() const;
     325                 :            :     /// initialize state from given DOM tree
     326                 :            :     void SAL_CALL init(css::uno::Reference<css::xml::dom::XDocument> i_xDom);
     327                 :            :     /// update element in DOM tree
     328                 :            :     void SAL_CALL updateElement(const char *i_name,
     329                 :            :         std::vector<std::pair<const char *, ::rtl::OUString> >* i_pAttrs = 0);
     330                 :            :     /// update user-defined meta data and attributes in DOM tree
     331                 :            :     void SAL_CALL updateUserDefinedAndAttributes();
     332                 :            :     /// create empty DOM tree (XDocument)
     333                 :            :     css::uno::Reference<css::xml::dom::XDocument> SAL_CALL createDOM() const;
     334                 :            :     /// extract base URL (necessary for converting relative links)
     335                 :            :     css::uno::Reference<css::beans::XPropertySet> SAL_CALL getURLProperties(
     336                 :            :         const css::uno::Sequence<css::beans::PropertyValue> & i_rMedium) const;
     337                 :            :     /// get text of standard meta data element
     338                 :            :     ::rtl::OUString SAL_CALL getMetaText(const char* i_name) const;
     339                 :            :     /// set text of standard meta data element iff not equal to existing text
     340                 :            :     bool SAL_CALL setMetaText(const char* i_name,
     341                 :            :         const ::rtl::OUString & i_rValue);
     342                 :            :     /// set text of standard meta data element iff not equal to existing text
     343                 :            :     void SAL_CALL setMetaTextAndNotify(const char* i_name,
     344                 :            :         const ::rtl::OUString & i_rValue);
     345                 :            :     /// get text of standard meta data element's attribute
     346                 :            :     ::rtl::OUString SAL_CALL getMetaAttr(const char* i_name,
     347                 :            :         const char* i_attr) const;
     348                 :            :     /// get text of a list of standard meta data elements (multiple occ.)
     349                 :            :     css::uno::Sequence< ::rtl::OUString > SAL_CALL getMetaList(
     350                 :            :         const char* i_name) const;
     351                 :            :     /// set text of a list of standard meta data elements (multiple occ.)
     352                 :            :     bool SAL_CALL setMetaList(const char* i_name,
     353                 :            :         const css::uno::Sequence< ::rtl::OUString > & i_rValue,
     354                 :            :         AttrVector const* = 0);
     355                 :            :     void createUserDefined();
     356                 :            : };
     357                 :            : 
     358                 :            : typedef ::cppu::ImplInheritanceHelper1< SfxDocumentMetaData, css::document::XCompatWriterDocProperties > CompatWriterDocPropsImpl_BASE;
     359                 :            : 
     360         [ #  # ]:          0 : class CompatWriterDocPropsImpl : public CompatWriterDocPropsImpl_BASE
     361                 :            : {
     362                 :            :     rtl::OUString msManager;
     363                 :            :     rtl::OUString msCategory;
     364                 :            :     rtl::OUString msCompany;
     365                 :            : protected:
     366         [ #  # ]:          0 :     virtual SfxDocumentMetaData* createMe( css::uno::Reference< css::uno::XComponentContext > const & context ) { return new CompatWriterDocPropsImpl( context ); };
     367                 :            : public:
     368                 :          0 :     CompatWriterDocPropsImpl( css::uno::Reference< css::uno::XComponentContext > const & context) : CompatWriterDocPropsImpl_BASE( context ) {}
     369                 :            : // XCompatWriterDocPropsImpl
     370                 :          0 :     virtual ::rtl::OUString SAL_CALL getManager() throw (::com::sun::star::uno::RuntimeException) { return msManager; }
     371                 :          0 :     virtual void SAL_CALL setManager( const ::rtl::OUString& _manager ) throw (::com::sun::star::uno::RuntimeException) { msManager = _manager; }
     372                 :          0 :     virtual ::rtl::OUString SAL_CALL getCategory() throw (::com::sun::star::uno::RuntimeException){ return msCategory; }
     373                 :          0 :     virtual void SAL_CALL setCategory( const ::rtl::OUString& _category ) throw (::com::sun::star::uno::RuntimeException){ msCategory = _category; }
     374                 :          0 :     virtual ::rtl::OUString SAL_CALL getCompany() throw (::com::sun::star::uno::RuntimeException){ return msCompany; }
     375                 :          0 :     virtual void SAL_CALL setCompany( const ::rtl::OUString& _company ) throw (::com::sun::star::uno::RuntimeException){ msCompany = _company; }
     376                 :            : 
     377                 :            : // XServiceInfo
     378                 :          0 :     virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException)
     379                 :            :     {
     380                 :          0 :         return comp_CompatWriterDocProps::_getImplementationName();
     381                 :            :     }
     382                 :            : 
     383                 :          0 :     virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException)
     384                 :            :     {
     385         [ #  # ]:          0 :         css::uno::Sequence< rtl::OUString > sServiceNames= getSupportedServiceNames();
     386                 :          0 :         sal_Int32 nLen = sServiceNames.getLength();
     387         [ #  # ]:          0 :         rtl::OUString* pIt = sServiceNames.getArray();
     388                 :          0 :         rtl::OUString* pEnd = ( pIt + nLen );
     389                 :          0 :         sal_Bool bRes = sal_False;
     390         [ #  # ]:          0 :         for ( ; pIt != pEnd; ++pIt )
     391                 :            :         {
     392         [ #  # ]:          0 :             if ( pIt->equals( ServiceName ) )
     393                 :            :             {
     394                 :          0 :                 bRes = sal_True;
     395                 :          0 :                 break;
     396                 :            :             }
     397                 :            :         }
     398         [ #  # ]:          0 :         return bRes;
     399                 :            :     }
     400                 :            : 
     401                 :          0 :     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw (::com::sun::star::uno::RuntimeException)
     402                 :            :     {
     403                 :          0 :         return comp_CompatWriterDocProps::_getSupportedServiceNames();
     404                 :            :     }
     405                 :            : };
     406                 :            : 
     407                 :         15 : bool operator== (const css::util::DateTime &i_rLeft,
     408                 :            :                  const css::util::DateTime &i_rRight)
     409                 :            : {
     410                 :            :     return i_rLeft.Year             == i_rRight.Year
     411                 :            :         && i_rLeft.Month            == i_rRight.Month
     412                 :            :         && i_rLeft.Day              == i_rRight.Day
     413                 :            :         && i_rLeft.Hours            == i_rRight.Hours
     414                 :            :         && i_rLeft.Minutes          == i_rRight.Minutes
     415                 :            :         && i_rLeft.Seconds          == i_rRight.Seconds
     416 [ +  + ][ +  - ]:         15 :         && i_rLeft.HundredthSeconds == i_rRight.HundredthSeconds;
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     417                 :            : }
     418                 :            : 
     419                 :            : // NB: keep these two arrays in sync!
     420                 :            : const char* s_stdStatAttrs[] = {
     421                 :            :     "meta:page-count",
     422                 :            :     "meta:table-count",
     423                 :            :     "meta:draw-count",
     424                 :            :     "meta:image-count",
     425                 :            :     "meta:object-count",
     426                 :            :     "meta:ole-object-count",
     427                 :            :     "meta:paragraph-count",
     428                 :            :     "meta:word-count",
     429                 :            :     "meta:character-count",
     430                 :            :     "meta:row-count",
     431                 :            :     "meta:frame-count",
     432                 :            :     "meta:sentence-count",
     433                 :            :     "meta:syllable-count",
     434                 :            :     "meta:non-whitespace-character-count",
     435                 :            :     "meta:cell-count",
     436                 :            :     0
     437                 :            : };
     438                 :            : 
     439                 :            : // NB: keep these two arrays in sync!
     440                 :            : const char* s_stdStats[] = {
     441                 :            :     "PageCount",
     442                 :            :     "TableCount",
     443                 :            :     "DrawCount",
     444                 :            :     "ImageCount",
     445                 :            :     "ObjectCount",
     446                 :            :     "OLEObjectCount",
     447                 :            :     "ParagraphCount",
     448                 :            :     "WordCount",
     449                 :            :     "CharacterCount",
     450                 :            :     "RowCount",
     451                 :            :     "FrameCount",
     452                 :            :     "SentenceCount",
     453                 :            :     "SyllableCount",
     454                 :            :     "NonWhitespaceCharacterCount",
     455                 :            :     "CellCount",
     456                 :            :     0
     457                 :            : };
     458                 :            : 
     459                 :            : const char* s_stdMeta[] = {
     460                 :            :     "meta:generator",           // string
     461                 :            :     "dc:title",                 // string
     462                 :            :     "dc:description",           // string
     463                 :            :     "dc:subject",               // string
     464                 :            :     "meta:initial-creator",     // string
     465                 :            :     "dc:creator",               // string
     466                 :            :     "meta:printed-by",          // string
     467                 :            :     "meta:creation-date",       // dateTime
     468                 :            :     "dc:date",                  // dateTime
     469                 :            :     "meta:print-date",          // dateTime
     470                 :            :     "meta:template",            // XLink
     471                 :            :     "meta:auto-reload",         // ...
     472                 :            :     "meta:hyperlink-behaviour", // ...
     473                 :            :     "dc:language",              // language
     474                 :            :     "meta:editing-cycles",      // nonNegativeInteger
     475                 :            :     "meta:editing-duration",    // duration
     476                 :            :     "meta:document-statistic",  // ... // note: statistic is singular, no s!
     477                 :            :     0
     478                 :            : };
     479                 :            : 
     480                 :            : const char* s_stdMetaList[] = {
     481                 :            :     "meta:keyword",             // string*
     482                 :            :     "meta:user-defined",        // ...*
     483                 :            :     0
     484                 :            : };
     485                 :            : 
     486                 :            : const char* s_nsXLink   = "http://www.w3.org/1999/xlink";
     487                 :            : const char* s_nsDC      = "http://purl.org/dc/elements/1.1/";
     488                 :            : const char* s_nsODF     = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
     489                 :            : const char* s_nsODFMeta = "urn:oasis:names:tc:opendocument:xmlns:meta:1.0";
     490                 :            : // const char* s_nsOOo     = "http://openoffice.org/2004/office"; // not used (yet?)
     491                 :            : 
     492                 :            : static const char s_meta    [] = "meta.xml";
     493                 :            : 
     494                 :          4 : bool isValidDate(const css::util::Date & i_rDate)
     495                 :            : {
     496                 :          4 :     return i_rDate.Month > 0;
     497                 :            : }
     498                 :            : 
     499                 :       2480 : bool isValidDateTime(const css::util::DateTime & i_rDateTime)
     500                 :            : {
     501                 :       2480 :     return i_rDateTime.Month > 0;
     502                 :            : }
     503                 :            : 
     504                 :            : std::pair< ::rtl::OUString, ::rtl::OUString > SAL_CALL
     505                 :      33155 : getQualifier(const char* i_name) {
     506                 :      33155 :     ::rtl::OUString nm = ::rtl::OUString::createFromAscii(i_name);
     507                 :      33155 :     sal_Int32 ix = nm.indexOf(static_cast<sal_Unicode> (':'));
     508         [ -  + ]:      33155 :     if (ix == -1) {
     509                 :          0 :         return std::make_pair(::rtl::OUString(), nm);
     510                 :            :     } else {
     511                 :      33155 :         return std::make_pair(nm.copy(0,ix), nm.copy(ix+1));
     512                 :      33155 :     }
     513                 :            : }
     514                 :            : 
     515                 :            : // get namespace for standard qualified names
     516                 :            : // NB: only call this with statically known strings!
     517                 :      25847 : ::rtl::OUString SAL_CALL getNameSpace(const char* i_qname) throw ()
     518                 :            : {
     519                 :            :     DBG_ASSERT(i_qname, "SfxDocumentMetaData: getNameSpace: argument is null");
     520                 :      25847 :     const char * ns = "";
     521                 :      25847 :     ::rtl::OUString n = getQualifier(i_qname).first;
     522         [ +  + ]:      25847 :     if ( n == "xlink" ) ns = s_nsXLink;
     523         [ +  + ]:      25847 :     if ( n == "dc" ) ns = s_nsDC;
     524         [ +  + ]:      25847 :     if ( n == "office" ) ns = s_nsODF;
     525         [ +  + ]:      25847 :     if ( n == "meta" ) ns = s_nsODFMeta;
     526                 :            :     DBG_ASSERT(*ns, "SfxDocumentMetaData: unknown namespace prefix");
     527                 :      25847 :     return ::rtl::OUString::createFromAscii(ns);
     528                 :            : }
     529                 :            : 
     530                 :            : bool SAL_CALL
     531                 :          6 : textToDateOrDateTime(css::util::Date & io_rd, css::util::DateTime & io_rdt,
     532                 :            :         bool & o_rIsDateTime, ::rtl::OUString i_text) throw ()
     533                 :            : {
     534         [ +  + ]:          6 :     if (::sax::Converter::convertDateOrDateTime(
     535                 :            :                 io_rd, io_rdt, o_rIsDateTime, i_text)) {
     536                 :          4 :         return true;
     537                 :            :     } else {
     538                 :            :         DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
     539                 :            :             OUStringToOString(i_text, RTL_TEXTENCODING_UTF8).getStr());
     540                 :          6 :         return false;
     541                 :            :     }
     542                 :            : }
     543                 :            : 
     544                 :            : // convert string to date/time
     545                 :            : bool SAL_CALL
     546                 :       3487 : textToDateTime(css::util::DateTime & io_rdt, ::rtl::OUString i_text) throw ()
     547                 :            : {
     548         [ +  + ]:       3487 :     if (::sax::Converter::convertDateTime(io_rdt, i_text)) {
     549                 :        167 :         return true;
     550                 :            :     } else {
     551                 :            :         DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
     552                 :            :             OUStringToOString(i_text, RTL_TEXTENCODING_UTF8).getStr());
     553                 :       3487 :         return false;
     554                 :            :     }
     555                 :            : }
     556                 :            : 
     557                 :            : // convert string to date/time with default return value
     558                 :            : css::util::DateTime SAL_CALL
     559                 :       3487 : textToDateTimeDefault(::rtl::OUString i_text) throw ()
     560                 :            : {
     561                 :       3487 :     css::util::DateTime dt;
     562                 :       3487 :     static_cast<void> (textToDateTime(dt, i_text));
     563                 :            :     // on conversion error: return default value (unchanged)
     564                 :       3487 :     return dt;
     565                 :            : }
     566                 :            : 
     567                 :            : // convert date to string
     568                 :            : ::rtl::OUString SAL_CALL
     569                 :          4 : dateToText(css::util::Date const& i_rd) throw ()
     570                 :            : {
     571         [ +  + ]:          4 :     if (isValidDate(i_rd)) {
     572                 :          2 :         ::rtl::OUStringBuffer buf;
     573         [ +  - ]:          2 :         ::sax::Converter::convertDate(buf, i_rd);
     574         [ +  - ]:          2 :         return buf.makeStringAndClear();
     575                 :            :     } else {
     576                 :          4 :         return ::rtl::OUString();
     577                 :            :     }
     578                 :            : }
     579                 :            : 
     580                 :            : 
     581                 :            : // convert date/time to string
     582                 :            : ::rtl::OUString SAL_CALL
     583                 :       2271 : dateTimeToText(css::util::DateTime const& i_rdt) throw ()
     584                 :            : {
     585         [ +  + ]:       2271 :     if (isValidDateTime(i_rdt)) {
     586                 :       1793 :         ::rtl::OUStringBuffer buf;
     587         [ +  - ]:       1793 :         ::sax::Converter::convertDateTime(buf, i_rdt, true);
     588         [ +  - ]:       1793 :         return buf.makeStringAndClear();
     589                 :            :     } else {
     590                 :       2271 :         return ::rtl::OUString();
     591                 :            :     }
     592                 :            : }
     593                 :            : 
     594                 :            : // convert string to duration
     595                 :            : bool
     596                 :       3074 : textToDuration(css::util::Duration& io_rDur, ::rtl::OUString const& i_rText)
     597                 :            : throw ()
     598                 :            : {
     599         [ +  + ]:       3074 :     if (::sax::Converter::convertDuration(io_rDur, i_rText)) {
     600                 :         75 :         return true;
     601                 :            :     } else {
     602                 :            :         DBG_WARNING1("SfxDocumentMetaData: invalid duration: %s",
     603                 :            :             OUStringToOString(i_rText, RTL_TEXTENCODING_UTF8).getStr());
     604                 :       3074 :         return false;
     605                 :            :     }
     606                 :            : }
     607                 :            : 
     608                 :       3070 : sal_Int32 textToDuration(::rtl::OUString const& i_rText) throw ()
     609                 :            : {
     610                 :       3070 :     css::util::Duration d;
     611         [ +  + ]:       3070 :     if (textToDuration(d, i_rText)) {
     612                 :            :         // #i107372#: approximate years/months
     613                 :         71 :         const sal_Int32 days( (d.Years * 365) + (d.Months * 30) + d.Days );
     614                 :            :         return  (days * (24*3600))
     615                 :         71 :                 + (d.Hours * 3600) + (d.Minutes * 60) + d.Seconds;
     616                 :            :     } else {
     617                 :       3070 :         return 0; // default
     618                 :            :     }
     619                 :            : }
     620                 :            : 
     621                 :            : // convert duration to string
     622                 :        354 : ::rtl::OUString durationToText(css::util::Duration const& i_rDur) throw ()
     623                 :            : {
     624                 :        354 :     ::rtl::OUStringBuffer buf;
     625         [ +  - ]:        354 :     ::sax::Converter::convertDuration(buf, i_rDur);
     626         [ +  - ]:        354 :     return buf.makeStringAndClear();
     627                 :            : }
     628                 :            : 
     629                 :            : // convert duration to string
     630                 :        350 : ::rtl::OUString SAL_CALL durationToText(sal_Int32 i_value) throw ()
     631                 :            : {
     632                 :        350 :     css::util::Duration ud;
     633                 :        350 :     ud.Days    = static_cast<sal_Int16>(i_value / (24 * 3600));
     634                 :        350 :     ud.Hours   = static_cast<sal_Int16>((i_value % (24 * 3600)) / 3600);
     635                 :        350 :     ud.Minutes = static_cast<sal_Int16>((i_value % 3600) / 60);
     636                 :        350 :     ud.Seconds = static_cast<sal_Int16>(i_value % 60);
     637                 :        350 :     ud.MilliSeconds = 0;
     638                 :        350 :     return durationToText(ud);
     639                 :            : }
     640                 :            : 
     641                 :            : // extract base URL (necessary for converting relative links)
     642                 :            : css::uno::Reference< css::beans::XPropertySet > SAL_CALL
     643                 :         34 : SfxDocumentMetaData::getURLProperties(
     644                 :            :     const css::uno::Sequence< css::beans::PropertyValue > & i_rMedium) const
     645                 :            : {
     646                 :            :     css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
     647 [ +  - ][ +  - ]:         34 :         m_xContext->getServiceManager());
     648                 :            :     css::uno::Reference< css::beans::XPropertyContainer> xPropArg(
     649         [ +  - ]:         34 :         xMsf->createInstanceWithContext(::rtl::OUString(
     650                 :         34 :                 "com.sun.star.beans.PropertyBag"), m_xContext),
     651 [ +  - ][ +  - ]:         34 :         css::uno::UNO_QUERY_THROW);
     652                 :            :     try {
     653                 :            :         ::rtl::OUString dburl =
     654                 :         34 :             ::rtl::OUString("DocumentBaseURL");
     655                 :            :         ::rtl::OUString hdn =
     656                 :         34 :             ::rtl::OUString("HierarchicalDocumentName");
     657         [ +  + ]:        120 :         for (sal_Int32 i = 0; i < i_rMedium.getLength(); ++i) {
     658         [ +  + ]:         86 :             if (i_rMedium[i].Name.equals(dburl)) {
     659         [ +  - ]:         20 :                 xPropArg->addProperty(
     660                 :            :                     ::rtl::OUString("BaseURI"),
     661                 :            :                     css::beans::PropertyAttribute::MAYBEVOID,
     662         [ +  - ]:         20 :                     i_rMedium[i].Value);
     663         [ -  + ]:         66 :             } else if (i_rMedium[i].Name.equals(hdn)) {
     664         [ #  # ]:          0 :                 xPropArg->addProperty(
     665                 :            :                     ::rtl::OUString("StreamRelPath"),
     666                 :            :                     css::beans::PropertyAttribute::MAYBEVOID,
     667         [ #  # ]:          0 :                     i_rMedium[i].Value);
     668                 :            :             }
     669                 :            :         }
     670         [ +  - ]:         34 :         xPropArg->addProperty(::rtl::OUString("StreamName"),
     671                 :            :                 css::beans::PropertyAttribute::MAYBEVOID,
     672 [ +  - ][ +  - ]:         34 :                 css::uno::makeAny(::rtl::OUString(s_meta)));
                 [ #  # ]
     673         [ #  # ]:          0 :     } catch (const css::uno::Exception &) {
     674                 :            :         // ignore
     675                 :            :     }
     676                 :            :     return css::uno::Reference< css::beans::XPropertySet>(xPropArg,
     677         [ +  - ]:         34 :                 css::uno::UNO_QUERY_THROW);
     678                 :            : }
     679                 :            : 
     680                 :            : // return the text of the (hopefully unique, i.e., normalize first!) text
     681                 :            : // node _below_ the given node
     682                 :            : ::rtl::OUString SAL_CALL
     683                 :       1273 : getNodeText(css::uno::Reference<css::xml::dom::XNode> i_xNode)
     684                 :            :         throw (css::uno::RuntimeException)
     685                 :            : {
     686         [ -  + ]:       1273 :     if (!i_xNode.is()) throw css::uno::RuntimeException(
     687                 :            :         ::rtl::OUString(
     688 [ #  # ][ #  # ]:          0 :                 "SfxDocumentMetaData::getNodeText: argument is null"), i_xNode);
     689 [ +  - ][ +  - ]:       2546 :     for (css::uno::Reference<css::xml::dom::XNode> c = i_xNode->getFirstChild();
           [ #  #  +  + ]
     690                 :       1273 :             c.is();
     691 [ #  # ][ #  # ]:          0 :             c = c->getNextSibling()) {
     692 [ +  - ][ +  - ]:       1182 :         if (c->getNodeType() == css::xml::dom::NodeType_TEXT_NODE) {
                 [ +  - ]
     693                 :            :             try {
     694 [ +  - ][ +  - ]:       1182 :                 return c->getNodeValue();
     695         [ #  # ]:          0 :             } catch (const css::xml::dom::DOMException &) { // too big?
     696                 :          0 :                 return ::rtl::OUString();
     697                 :            :             }
     698                 :            :         }
     699         [ +  + ]:       1273 :     }
     700                 :       1273 :     return ::rtl::OUString();
     701                 :            : }
     702                 :            : 
     703                 :            : ::rtl::OUString SAL_CALL
     704                 :       4934 : SfxDocumentMetaData::getMetaText(const char* i_name) const
     705                 :            : //        throw (css::uno::RuntimeException)
     706                 :            : {
     707         [ +  - ]:       4934 :     checkInit();
     708                 :            : 
     709                 :       4934 :     const ::rtl::OUString name( ::rtl::OUString::createFromAscii(i_name) );
     710                 :            :     DBG_ASSERT(m_meta.find(name) != m_meta.end(),
     711                 :            :         "SfxDocumentMetaData::getMetaText: not found");
     712         [ +  - ]:       4934 :     css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
     713 [ +  - ][ +  + ]:       4934 :     return (xNode.is()) ? getNodeText(xNode) : ::rtl::OUString();
         [ #  # ][ +  + ]
     714                 :            : }
     715                 :            : 
     716                 :            : bool SAL_CALL
     717                 :       6261 : SfxDocumentMetaData::setMetaText(const char* i_name,
     718                 :            :         const ::rtl::OUString & i_rValue)
     719                 :            :     // throw (css::uno::RuntimeException)
     720                 :            : {
     721         [ +  - ]:       6261 :     checkInit();
     722                 :            : 
     723                 :       6261 :     const ::rtl::OUString name( ::rtl::OUString::createFromAscii(i_name) );
     724                 :            :     DBG_ASSERT(m_meta.find(name) != m_meta.end(),
     725                 :            :         "SfxDocumentMetaData::setMetaText: not found");
     726         [ +  - ]:       6261 :     css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
     727                 :            : 
     728                 :            :     try {
     729         [ +  + ]:       6261 :         if (i_rValue.isEmpty()) {
     730         [ +  + ]:       1998 :             if (xNode.is()) { // delete
     731 [ +  - ][ +  - ]:         18 :                 m_xParent->removeChild(xNode);
     732                 :         18 :                 xNode.clear();
     733 [ +  - ][ +  - ]:         18 :                 m_meta[name] = xNode;
     734                 :         18 :                 return true;
     735                 :            :             } else {
     736                 :       1980 :                 return false;
     737                 :            :             }
     738                 :            :         } else {
     739         [ +  + ]:       4263 :             if (xNode.is()) { // update
     740   [ #  #  +  + ]:       1236 :                 for (css::uno::Reference<css::xml::dom::XNode> c =
     741 [ +  - ][ +  - ]:        618 :                             xNode->getFirstChild();
     742                 :        618 :                         c.is();
     743 [ #  # ][ #  # ]:          0 :                         c = c->getNextSibling()) {
     744 [ +  - ][ +  - ]:        616 :                     if (c->getNodeType() == css::xml::dom::NodeType_TEXT_NODE) {
                 [ +  - ]
     745 [ +  - ][ +  - ]:        616 :                         if (!c->getNodeValue().equals(i_rValue)) {
                 [ +  + ]
     746 [ +  - ][ +  - ]:        159 :                             c->setNodeValue(i_rValue);
     747                 :        159 :                             return true;
     748                 :            :                         } else {
     749                 :        457 :                             return false;
     750                 :            :                         }
     751                 :            :                     }
     752         [ +  + ]:        618 :                 }
     753                 :            :             } else { // insert
     754         [ +  - ]:       3645 :                 xNode.set(m_xDoc->createElementNS(getNameSpace(i_name), name),
     755 [ +  - ][ +  - ]:       3645 :                             css::uno::UNO_QUERY_THROW);
     756 [ +  - ][ +  - ]:       3645 :                 m_xParent->appendChild(xNode);
     757 [ +  - ][ +  - ]:       3645 :                 m_meta[name] = xNode;
     758                 :            :             }
     759                 :            :             css::uno::Reference<css::xml::dom::XNode> xTextNode(
     760 [ +  - ][ +  - ]:       3647 :                 m_xDoc->createTextNode(i_rValue), css::uno::UNO_QUERY_THROW);
                 [ +  - ]
     761 [ +  - ][ +  - ]:       3647 :             xNode->appendChild(xTextNode);
     762                 :       4263 :             return true;
     763                 :            :         }
     764         [ #  # ]:          0 :     } catch (const css::xml::dom::DOMException & e) {
     765         [ #  # ]:          0 :         css::uno::Any a(e);
     766                 :            :         throw css::lang::WrappedTargetRuntimeException(
     767                 :            :                 ::rtl::OUString(
     768                 :            :                         "SfxDocumentMetaData::setMetaText: DOM exception"),
     769   [ #  #  #  # ]:          0 :                 css::uno::Reference<css::uno::XInterface>(*this), a);
     770                 :       6261 :     }
     771                 :            : }
     772                 :            : 
     773                 :            : void SAL_CALL
     774                 :       6221 : SfxDocumentMetaData::setMetaTextAndNotify(const char* i_name,
     775                 :            :         const ::rtl::OUString & i_rValue)
     776                 :            :     // throw (css::uno::RuntimeException)
     777                 :            : {
     778         [ +  - ]:       6221 :     ::osl::ClearableMutexGuard g(m_aMutex);
     779 [ +  - ][ +  + ]:       6221 :     if (setMetaText(i_name, i_rValue)) {
     780         [ +  - ]:       3797 :         g.clear();
     781         [ +  - ]:       3797 :         setModified(true);
     782         [ +  - ]:       6221 :     }
     783                 :       6221 : }
     784                 :            : 
     785                 :            : ::rtl::OUString SAL_CALL
     786                 :      27048 : SfxDocumentMetaData::getMetaAttr(const char* i_name, const char* i_attr) const
     787                 :            : //        throw (css::uno::RuntimeException)
     788                 :            : {
     789                 :      27048 :     ::rtl::OUString name = ::rtl::OUString::createFromAscii(i_name);
     790                 :            :     DBG_ASSERT(m_meta.find(name) != m_meta.end(),
     791                 :            :         "SfxDocumentMetaData::getMetaAttr: not found");
     792         [ +  - ]:      27048 :     css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
     793         [ +  + ]:      27048 :     if (xNode.is()) {
     794                 :            :         css::uno::Reference<css::xml::dom::XElement> xElem(xNode,
     795         [ +  - ]:       7308 :             css::uno::UNO_QUERY_THROW);
     796         [ +  - ]:       7308 :         return xElem->getAttributeNS(getNameSpace(i_attr),
     797         [ +  - ]:       7308 :                     getQualifier(i_attr).second);
     798                 :            :     } else {
     799                 :      19740 :         return ::rtl::OUString();
     800                 :      27048 :     }
     801                 :            : }
     802                 :            : 
     803                 :            : css::uno::Sequence< ::rtl::OUString> SAL_CALL
     804                 :        161 : SfxDocumentMetaData::getMetaList(const char* i_name) const
     805                 :            : //        throw (css::uno::RuntimeException)
     806                 :            : {
     807         [ +  - ]:        161 :     checkInit();
     808                 :        161 :     ::rtl::OUString name = ::rtl::OUString::createFromAscii(i_name);
     809                 :            :     DBG_ASSERT(m_metaList.find(name) != m_metaList.end(),
     810                 :            :         "SfxDocumentMetaData::getMetaList: not found");
     811                 :            :     std::vector<css::uno::Reference<css::xml::dom::XNode> > const & vec =
     812         [ +  - ]:        161 :         m_metaList.find(name)->second;
     813         [ +  - ]:        161 :     css::uno::Sequence< ::rtl::OUString> ret(vec.size());
     814         [ +  + ]:        185 :     for (size_t i = 0; i < vec.size(); ++i) {
     815 [ +  - ][ +  - ]:         24 :         ret[i] = getNodeText(vec.at(i));
                 [ +  - ]
     816                 :            :     }
     817                 :        161 :     return ret;
     818                 :            : }
     819                 :            : 
     820                 :            : bool SAL_CALL
     821                 :        291 : SfxDocumentMetaData::setMetaList(const char* i_name,
     822                 :            :         const css::uno::Sequence< ::rtl::OUString> & i_rValue,
     823                 :            :         AttrVector const* i_pAttrs)
     824                 :            :     // throw (css::uno::RuntimeException)
     825                 :            : {
     826                 :        291 :     checkInit();
     827                 :            :     DBG_ASSERT((i_pAttrs == 0) ||
     828                 :            :                (static_cast<size_t>(i_rValue.getLength()) == i_pAttrs->size()),
     829                 :            :         "SfxDocumentMetaData::setMetaList: invalid args");
     830                 :            : 
     831                 :            :     try {
     832                 :        291 :         ::rtl::OUString name = ::rtl::OUString::createFromAscii(i_name);
     833                 :            :         DBG_ASSERT(m_metaList.find(name) != m_metaList.end(),
     834                 :            :             "SfxDocumentMetaData::setMetaList: not found");
     835                 :            :         std::vector<css::uno::Reference<css::xml::dom::XNode> > & vec =
     836         [ +  - ]:        291 :             m_metaList[name];
     837                 :            : 
     838                 :            :         // if nothing changed, do nothing
     839                 :            :         // alas, this does not check for permutations, or attributes...
     840         [ +  + ]:        291 :         if ((0 == i_pAttrs)) {
     841         [ +  + ]:         82 :             if (static_cast<size_t>(i_rValue.getLength()) == vec.size()) {
     842                 :         76 :                 bool isEqual(true);
     843         [ +  + ]:         78 :                 for (sal_Int32 i = 0; i < i_rValue.getLength(); ++i) {
     844         [ +  - ]:          2 :                     css::uno::Reference<css::xml::dom::XNode> xNode(vec.at(i));
     845         [ +  - ]:          2 :                     if (xNode.is()) {
     846         [ +  - ]:          2 :                         ::rtl::OUString val = getNodeText(xNode);
     847         [ +  - ]:          2 :                         if (!val.equals(i_rValue[i])) {
     848                 :          2 :                             isEqual = false;
     849                 :            :                             break;
     850         [ -  + ]:          2 :                         }
     851                 :            :                     }
     852         [ -  + ]:          2 :                 }
     853         [ +  + ]:         76 :                 if (isEqual) return false;
     854                 :            :             }
     855                 :            :         }
     856                 :            : 
     857                 :            :         // remove old meta data nodes
     858                 :            :         {
     859                 :            :             std::vector<css::uno::Reference<css::xml::dom::XNode> >
     860                 :        217 :                 ::reverse_iterator it(vec.rbegin());
     861                 :            :             try {
     862 [ +  - ][ +  + ]:        295 :                 for ( ;it != vec.rend(); ++it)
                 [ +  - ]
     863                 :            :                 {
     864 [ +  - ][ +  - ]:         78 :                     m_xParent->removeChild(*it);
                 [ +  - ]
     865                 :            :                 }
     866                 :            :             }
     867                 :          0 :             catch (...)
     868                 :            :             {
     869                 :            :                 // Clean up already removed nodes
     870         [ #  # ]:          0 :                 vec.erase(it.base(), vec.end());
     871                 :          0 :                 throw;
     872                 :            :             }
     873                 :        217 :             vec.clear();
     874                 :            :         }
     875                 :            : 
     876                 :            :         // insert new meta data nodes into DOM tree
     877         [ +  + ]:        401 :         for (sal_Int32 i = 0; i < i_rValue.getLength(); ++i) {
     878                 :            :             css::uno::Reference<css::xml::dom::XElement> xElem(
     879         [ +  - ]:        184 :                 m_xDoc->createElementNS(getNameSpace(i_name), name),
     880 [ +  - ][ +  - ]:        184 :                 css::uno::UNO_QUERY_THROW);
     881                 :            :             css::uno::Reference<css::xml::dom::XNode> xNode(xElem,
     882         [ +  - ]:        184 :                 css::uno::UNO_QUERY_THROW);
     883                 :            :             css::uno::Reference<css::xml::dom::XNode> xTextNode(
     884 [ +  - ][ +  - ]:        184 :                 m_xDoc->createTextNode(i_rValue[i]), css::uno::UNO_QUERY_THROW);
                 [ +  - ]
     885                 :            :             // set attributes
     886         [ +  + ]:        184 :             if (i_pAttrs != 0) {
     887 [ +  + ][ +  - ]:        878 :                 for (std::vector<std::pair<const char*, ::rtl::OUString> >
     888                 :        166 :                                 ::const_iterator it = (*i_pAttrs)[i].begin();
     889                 :        439 :                         it != (*i_pAttrs)[i].end(); ++it) {
     890         [ +  - ]:        546 :                     xElem->setAttributeNS(getNameSpace(it->first),
     891                 :        273 :                         ::rtl::OUString::createFromAscii(it->first),
     892         [ +  - ]:        819 :                         it->second);
     893                 :            :                 }
     894                 :            :             }
     895 [ +  - ][ +  - ]:        184 :             xNode->appendChild(xTextNode);
     896 [ +  - ][ +  - ]:        184 :             m_xParent->appendChild(xNode);
     897         [ +  - ]:        184 :             vec.push_back(xNode);
     898                 :        184 :         }
     899                 :            : 
     900                 :        291 :         return true;
     901         [ #  # ]:          0 :     } catch (const css::xml::dom::DOMException & e) {
     902         [ #  # ]:          0 :         css::uno::Any a(e);
     903                 :            :         throw css::lang::WrappedTargetRuntimeException(
     904                 :            :                 ::rtl::OUString(
     905                 :            :                         "SfxDocumentMetaData::setMetaList: DOM exception"),
     906   [ #  #  #  # ]:          0 :                 css::uno::Reference<css::uno::XInterface>(*this), a);
     907                 :            :     }
     908                 :            : }
     909                 :            : 
     910                 :            : // convert property list to string list and attribute list
     911                 :            : std::pair<css::uno::Sequence< ::rtl::OUString>, AttrVector> SAL_CALL
     912                 :        209 : propsToStrings(css::uno::Reference<css::beans::XPropertySet> const & i_xPropSet)
     913                 :            : {
     914         [ +  - ]:        209 :     ::comphelper::SequenceAsVector< ::rtl::OUString > values;
     915         [ +  - ]:        209 :     AttrVector attrs;
     916                 :            : 
     917                 :            :     css::uno::Reference<css::beans::XPropertySetInfo> xSetInfo
     918 [ +  - ][ +  - ]:        209 :         = i_xPropSet->getPropertySetInfo();
     919 [ +  - ][ +  - ]:        209 :     css::uno::Sequence<css::beans::Property> props = xSetInfo->getProperties();
     920                 :            : 
     921         [ +  + ]:        375 :     for (sal_Int32 i = 0; i < props.getLength(); ++i) {
     922 [ +  - ][ -  + ]:        166 :         if (props[i].Attributes & css::beans::PropertyAttribute::TRANSIENT) {
     923                 :          0 :             continue;
     924                 :            :         }
     925         [ +  - ]:        166 :         const ::rtl::OUString name = props[i].Name;
     926                 :        166 :         css::uno::Any any;
     927                 :            :         try {
     928 [ +  - ][ +  - ]:        166 :             any = i_xPropSet->getPropertyValue(name);
     929         [ #  # ]:          0 :         } catch (const css::uno::Exception &) {
     930                 :            :             // ignore
     931                 :            :         }
     932                 :        166 :         const css::uno::Type & type = any.getValueType();
     933         [ +  - ]:        166 :         std::vector<std::pair<const char*, ::rtl::OUString> > as;
     934                 :            :         as.push_back(std::make_pair(static_cast<const char*>("meta:name"),
     935 [ +  - ][ +  - ]:        166 :                                         name));
     936                 :        166 :         const char* vt = "meta:value-type";
     937                 :            : 
     938                 :            :         // convert according to type
     939         [ +  + ]:        166 :         if (type == ::cppu::UnoType<bool>::get()) {
     940                 :         66 :             bool b = false;
     941                 :         66 :             any >>= b;
     942                 :         66 :             ::rtl::OUStringBuffer buf;
     943         [ +  - ]:         66 :             ::sax::Converter::convertBool(buf, b);
     944 [ +  - ][ +  - ]:         66 :             values.push_back(buf.makeStringAndClear());
     945                 :            :             as.push_back(std::make_pair(vt,
     946         [ +  - ]:         66 :                 ::rtl::OUString("boolean")));
     947         [ +  + ]:        100 :         } else if (type == ::cppu::UnoType< ::rtl::OUString>::get()) {
     948                 :         65 :             ::rtl::OUString s;
     949                 :         65 :             any >>= s;
     950         [ +  - ]:         65 :             values.push_back(s);
     951                 :            : // #i90847# OOo 2.x does stupid things if value-type="string";
     952                 :            : // fortunately string is default anyway, so we can just omit it
     953                 :            : // #i107502#: however, OOo 2.x only reads 4 user-defined without @value-type
     954                 :            : // => best backward compatibility: first 4 without @value-type, rest with
     955         [ +  + ]:         65 :             if (4 <= i)
     956                 :            :             {
     957                 :            :                 as.push_back(std::make_pair(vt,
     958         [ +  - ]:          6 :                     ::rtl::OUString("string")));
     959                 :         65 :             }
     960         [ +  + ]:         35 :         } else if (type == ::cppu::UnoType<css::util::DateTime>::get()) {
     961                 :          2 :             css::util::DateTime dt;
     962         [ +  - ]:          2 :             any >>= dt;
     963         [ +  - ]:          2 :             values.push_back(dateTimeToText(dt));
     964                 :            :             as.push_back(std::make_pair(vt,
     965         [ +  - ]:          2 :                 ::rtl::OUString("date")));
     966         [ +  + ]:         33 :         } else if (type == ::cppu::UnoType<css::util::Date>::get()) {
     967                 :          4 :             css::util::Date d;
     968         [ +  - ]:          4 :             any >>= d;
     969         [ +  - ]:          4 :             values.push_back(dateToText(d));
     970                 :            :             as.push_back(std::make_pair(vt,
     971         [ +  - ]:          4 :                 ::rtl::OUString("date")));
     972         [ +  + ]:         29 :         } else if (type == ::cppu::UnoType<css::util::Time>::get()) {
     973                 :            :             // #i97029#: replaced by Duration
     974                 :            :             // Time is supported for backward compatibility with OOo 3.x, x<=2
     975                 :          2 :             css::util::Time ut;
     976         [ +  - ]:          2 :             any >>= ut;
     977                 :          2 :             css::util::Duration ud;
     978                 :          2 :             ud.Hours   = ut.Hours;
     979                 :          2 :             ud.Minutes = ut.Minutes;
     980                 :          2 :             ud.Seconds = ut.Seconds;
     981                 :          2 :             ud.MilliSeconds = 10 * ut.HundredthSeconds;
     982         [ +  - ]:          2 :             values.push_back(durationToText(ud));
     983                 :            :             as.push_back(std::make_pair(vt,
     984         [ +  - ]:          2 :                 ::rtl::OUString("time")));
     985         [ +  + ]:         27 :         } else if (type == ::cppu::UnoType<css::util::Duration>::get()) {
     986                 :          2 :             css::util::Duration ud;
     987         [ +  - ]:          2 :             any >>= ud;
     988         [ +  - ]:          2 :             values.push_back(durationToText(ud));
     989                 :            :             as.push_back(std::make_pair(vt,
     990         [ +  - ]:          2 :                 ::rtl::OUString("time")));
     991         [ +  - ]:         25 :         } else if (::cppu::UnoType<double>::get().isAssignableFrom(type)) {
     992                 :            :             // support not just double, but anything that can be converted
     993                 :         25 :             double d = 0;
     994                 :         25 :             any >>= d;
     995                 :         25 :             ::rtl::OUStringBuffer buf;
     996         [ +  - ]:         25 :             ::sax::Converter::convertDouble(buf, d);
     997 [ +  - ][ +  - ]:         25 :             values.push_back(buf.makeStringAndClear());
     998                 :            :             as.push_back(std::make_pair(vt,
     999         [ +  - ]:         25 :                 ::rtl::OUString("float")));
    1000                 :            :         } else {
    1001                 :            :             DBG_WARNING1("SfxDocumentMetaData: unsupported property type: %s",
    1002                 :            :                 OUStringToOString(any.getValueTypeName(),
    1003                 :            :                     RTL_TEXTENCODING_UTF8).getStr());
    1004                 :          0 :             continue;
    1005                 :            :         }
    1006 [ +  - ][ -  + ]:        332 :         attrs.push_back(as);
    1007 [ -  + ][ +  - ]:        332 :     }
    1008                 :            : 
    1009 [ +  - ][ +  - ]:        209 :     return std::make_pair(values.getAsConstList(), attrs);
         [ +  - ][ +  - ]
                 [ #  # ]
    1010                 :            : }
    1011                 :            : 
    1012                 :            : // remove the given element from the DOM, and iff i_pAttrs != 0 insert new one
    1013                 :            : void SAL_CALL
    1014                 :       2444 : SfxDocumentMetaData::updateElement(const char *i_name,
    1015                 :            :         std::vector<std::pair<const char *, ::rtl::OUString> >* i_pAttrs)
    1016                 :            : {
    1017                 :       2444 :     ::rtl::OUString name = ::rtl::OUString::createFromAscii(i_name);
    1018                 :            :     try {
    1019                 :            :         // remove old element
    1020                 :            :         css::uno::Reference<css::xml::dom::XNode> xNode =
    1021         [ +  - ]:       2444 :             m_meta.find(name)->second;
    1022         [ +  + ]:       2444 :         if (xNode.is()) {
    1023 [ +  - ][ +  - ]:        980 :             m_xParent->removeChild(xNode);
    1024                 :        980 :             xNode.clear();
    1025                 :            :         }
    1026                 :            :         // add new element
    1027         [ +  + ]:       2444 :         if (0 != i_pAttrs) {
    1028                 :            :             css::uno::Reference<css::xml::dom::XElement> xElem(
    1029         [ +  - ]:       1841 :                 m_xDoc->createElementNS(getNameSpace(i_name), name),
    1030 [ +  - ][ +  - ]:       1841 :                     css::uno::UNO_QUERY_THROW);
    1031         [ +  - ]:       1841 :             xNode.set(xElem, css::uno::UNO_QUERY_THROW);
    1032                 :            :             // set attributes
    1033 [ +  - ][ +  + ]:      28874 :             for (std::vector<std::pair<const char *, ::rtl::OUString> >
    1034         [ +  - ]:       1841 :                     ::const_iterator it = i_pAttrs->begin();
    1035                 :      14437 :                     it != i_pAttrs->end(); ++it) {
    1036         [ +  - ]:      25192 :                 xElem->setAttributeNS(getNameSpace(it->first),
    1037         [ +  - ]:      25192 :                     ::rtl::OUString::createFromAscii(it->first), it->second);
    1038                 :            :             }
    1039 [ +  - ][ +  - ]:       1841 :             m_xParent->appendChild(xNode);
    1040                 :            :         }
    1041 [ +  - ][ +  - ]:       2444 :         m_meta[name] = xNode;
    1042         [ #  # ]:          0 :     } catch (const css::xml::dom::DOMException & e) {
    1043         [ #  # ]:          0 :         css::uno::Any a(e);
    1044                 :            :         throw css::lang::WrappedTargetRuntimeException(
    1045                 :            :                 ::rtl::OUString(
    1046                 :            :                     "SfxDocumentMetaData::updateElement: DOM exception"),
    1047   [ #  #  #  # ]:          0 :                 css::uno::Reference<css::uno::XInterface>(*this), a);
    1048                 :       2444 :     }
    1049                 :       2444 : }
    1050                 :            : 
    1051                 :            : // update user-defined meta data in DOM tree
    1052                 :        209 : void SAL_CALL SfxDocumentMetaData::updateUserDefinedAndAttributes()
    1053                 :            : {
    1054         [ +  - ]:        209 :     createUserDefined();
    1055                 :            :     const css::uno::Reference<css::beans::XPropertySet> xPSet(m_xUserDefined,
    1056         [ +  - ]:        209 :             css::uno::UNO_QUERY_THROW);
    1057                 :            :     const std::pair<css::uno::Sequence< ::rtl::OUString>, AttrVector>
    1058         [ +  - ]:        209 :         udStringsAttrs( propsToStrings(xPSet) );
    1059                 :            :     (void) setMetaList("meta:user-defined", udStringsAttrs.first,
    1060         [ +  - ]:        209 :             &udStringsAttrs.second);
    1061                 :            : 
    1062                 :            :     // update elements with attributes
    1063         [ +  - ]:        209 :     std::vector<std::pair<const char *, ::rtl::OUString> > attributes;
    1064         [ +  + ]:        398 :     if (!m_TemplateName.isEmpty() || !m_TemplateURL.isEmpty()
           [ +  -  -  + ]
                 [ +  + ]
    1065                 :        189 :             || isValidDateTime(m_TemplateDate)) {
    1066                 :            :         attributes.push_back(std::make_pair(
    1067                 :            :                 static_cast<const char*>("xlink:type"),
    1068         [ +  - ]:         20 :                 ::rtl::OUString("simple")));
    1069                 :            :         attributes.push_back(std::make_pair(
    1070                 :            :                 static_cast<const char*>("xlink:actuate"),
    1071         [ +  - ]:         20 :                 ::rtl::OUString("onRequest")));
    1072                 :            :         attributes.push_back(std::make_pair(
    1073         [ +  - ]:         20 :                 static_cast<const char*>("xlink:title"), m_TemplateName));
    1074                 :            :         attributes.push_back(std::make_pair(
    1075         [ +  - ]:         20 :                 static_cast<const char*>("xlink:href" ), m_TemplateURL ));
    1076         [ +  + ]:         20 :         if (isValidDateTime(m_TemplateDate)) {
    1077                 :            :             attributes.push_back(std::make_pair(
    1078                 :            :                 static_cast<const char*>("meta:date"  ),
    1079         [ +  - ]:          2 :                 dateTimeToText(m_TemplateDate)));
    1080                 :            :         }
    1081         [ +  - ]:         20 :         updateElement("meta:template", &attributes);
    1082                 :            :     } else {
    1083         [ +  - ]:        189 :         updateElement("meta:template");
    1084                 :            :     }
    1085                 :        209 :     attributes.clear();
    1086                 :            : 
    1087 [ -  + ][ +  + ]:        209 :     if (!m_AutoloadURL.isEmpty() || (0 != m_AutoloadSecs)) {
                 [ +  + ]
    1088                 :            :         attributes.push_back(std::make_pair(
    1089         [ +  - ]:          2 :                 static_cast<const char*>("xlink:href" ), m_AutoloadURL ));
    1090                 :            :         attributes.push_back(std::make_pair(
    1091                 :            :                 static_cast<const char*>("meta:delay" ),
    1092         [ +  - ]:          2 :                 durationToText(m_AutoloadSecs)));
    1093         [ +  - ]:          2 :         updateElement("meta:auto-reload", &attributes);
    1094                 :            :     } else {
    1095         [ +  - ]:        207 :         updateElement("meta:auto-reload");
    1096                 :            :     }
    1097                 :        209 :     attributes.clear();
    1098                 :            : 
    1099         [ +  + ]:        209 :     if (!m_DefaultTarget.isEmpty()) {
    1100                 :            :         attributes.push_back(std::make_pair(
    1101                 :            :                 static_cast<const char*>("office:target-frame-name"),
    1102         [ +  - ]:          2 :                 m_DefaultTarget));
    1103                 :            :         // xlink:show: _blank -> new, any other value -> replace
    1104         [ +  - ]:          2 :         const sal_Char* show = m_DefaultTarget == "_blank" ? "new" : "replace";
    1105                 :            :         attributes.push_back(std::make_pair(
    1106                 :            :                 static_cast<const char*>("xlink:show"),
    1107         [ +  - ]:          2 :                 ::rtl::OUString::createFromAscii(show)));
    1108         [ +  - ]:          2 :         updateElement("meta:hyperlink-behaviour", &attributes);
    1109                 :            :     } else {
    1110         [ +  - ]:        207 :         updateElement("meta:hyperlink-behaviour");
    1111                 :            :     }
    1112         [ +  - ]:        209 :     attributes.clear();
    1113                 :        209 : }
    1114                 :            : 
    1115                 :            : // create empty DOM tree (XDocument)
    1116                 :            : css::uno::Reference<css::xml::dom::XDocument> SAL_CALL
    1117                 :       2793 : SfxDocumentMetaData::createDOM() const // throw (css::uno::RuntimeException)
    1118                 :            : {
    1119                 :            :     css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
    1120 [ +  - ][ +  - ]:       2793 :         m_xContext->getServiceManager());
    1121                 :            :     css::uno::Reference<css::xml::dom::XDocumentBuilder> xBuilder(
    1122         [ +  - ]:       2793 :         xMsf->createInstanceWithContext(::rtl::OUString(
    1123                 :       2793 :                 "com.sun.star.xml.dom.DocumentBuilder"), m_xContext),
    1124 [ +  - ][ +  - ]:       2793 :         css::uno::UNO_QUERY_THROW );
    1125         [ -  + ]:       2793 :     if (!xBuilder.is()) throw css::uno::RuntimeException(
    1126                 :            :         ::rtl::OUString("SfxDocumentMetaData::createDOM: "
    1127                 :            :                 "cannot create DocumentBuilder service"),
    1128 [ #  # ][ #  # ]:          0 :                 *const_cast<SfxDocumentMetaData*>(this));
    1129                 :            :     css::uno::Reference<css::xml::dom::XDocument> xDoc =
    1130 [ +  - ][ +  - ]:       2793 :                 xBuilder->newDocument();
    1131         [ -  + ]:       2793 :     if (!xDoc.is()) throw css::uno::RuntimeException(
    1132                 :            :         ::rtl::OUString("SfxDocumentMetaData::createDOM: "
    1133                 :            :                 "cannot create new document"),
    1134 [ #  # ][ #  # ]:          0 :                 *const_cast<SfxDocumentMetaData*>(this));
    1135                 :       2793 :     return xDoc;
    1136                 :            : }
    1137                 :            : 
    1138                 :            : void SAL_CALL
    1139                 :      33287 : SfxDocumentMetaData::checkInit() const // throw (css::uno::RuntimeException)
    1140                 :            : {
    1141         [ -  + ]:      33287 :     if (!m_isInitialized) {
    1142                 :            :         throw css::uno::RuntimeException(::rtl::OUString(
    1143                 :            :                 "SfxDocumentMetaData::checkInit: not initialized"),
    1144 [ #  # ][ #  # ]:          0 :                 *const_cast<SfxDocumentMetaData*>(this));
    1145                 :            :     }
    1146                 :            :     DBG_ASSERT((m_xDoc.is() && m_xParent.is() ),
    1147                 :            :                 "SfxDocumentMetaData::checkInit: reference is null");
    1148                 :      33287 : }
    1149                 :            : 
    1150                 :            : // initialize state from DOM tree
    1151                 :       2988 : void SAL_CALL SfxDocumentMetaData::init(
    1152                 :            :         css::uno::Reference<css::xml::dom::XDocument> i_xDoc)
    1153                 :            : {
    1154         [ -  + ]:       2988 :     if (!i_xDoc.is()) throw css::uno::RuntimeException(
    1155                 :            :         ::rtl::OUString(
    1156 [ #  # ][ #  # ]:          0 :                 "SfxDocumentMetaData::init: no DOM tree given"), *this);
    1157                 :            : 
    1158                 :            :     css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
    1159 [ +  - ][ +  - ]:       2988 :         m_xContext->getServiceManager());
    1160                 :            :     css::uno::Reference<css::xml::xpath::XXPathAPI> xPath(
    1161         [ +  - ]:       2988 :         xMsf->createInstanceWithContext(::rtl::OUString(
    1162                 :       2988 :                 "com.sun.star.xml.xpath.XPathAPI"), m_xContext),
    1163 [ +  - ][ +  - ]:       2988 :         css::uno::UNO_QUERY_THROW );
    1164         [ -  + ]:       2988 :     if (!xPath.is()) throw css::uno::RuntimeException(
    1165                 :            :         ::rtl::OUString("SfxDocumentMetaData::init:"
    1166 [ #  # ][ #  # ]:          0 :                 " cannot create XPathAPI service"), *this);
    1167                 :            : 
    1168                 :       2988 :     m_isInitialized = false;
    1169         [ +  - ]:       2988 :     m_xDoc = i_xDoc;
    1170                 :            : 
    1171                 :            :     // select nodes for standard meta data stuff
    1172         [ +  - ]:       2988 :     xPath->registerNS(::rtl::OUString("xlink"),
    1173         [ +  - ]:       2988 :         ::rtl::OUString::createFromAscii(s_nsXLink));
    1174         [ +  - ]:       2988 :     xPath->registerNS(::rtl::OUString("dc"),
    1175         [ +  - ]:       2988 :         ::rtl::OUString::createFromAscii(s_nsDC));
    1176         [ +  - ]:       2988 :     xPath->registerNS(::rtl::OUString("office"),
    1177         [ +  - ]:       2988 :         ::rtl::OUString::createFromAscii(s_nsODF));
    1178         [ +  - ]:       2988 :     xPath->registerNS(::rtl::OUString("meta"),
    1179         [ +  - ]:       2988 :         ::rtl::OUString::createFromAscii(s_nsODFMeta));
    1180                 :            :     // NB: we do not handle the single-XML-file ODF variant, which would
    1181                 :            :     //     have the root element office:document.
    1182                 :            :     //     The root of such documents must be converted in the importer!
    1183                 :            :     ::rtl::OUString prefix(
    1184                 :       2988 :         "/child::office:document-meta/child::office:meta");
    1185                 :            :     css::uno::Reference<css::xml::dom::XNode> xDocNode(
    1186         [ +  - ]:       2988 :         m_xDoc, css::uno::UNO_QUERY_THROW);
    1187                 :       2988 :     m_xParent.clear();
    1188                 :            :     try {
    1189 [ +  + ][ +  - ]:       2988 :         m_xParent = xPath->selectSingleNode(xDocNode, prefix);
         [ -  + ][ +  - ]
    1190         [ +  - ]:       2634 :     } catch (const com::sun::star::uno::Exception &) {
    1191                 :            :     }
    1192                 :            : 
    1193         [ +  + ]:       2988 :     if (!m_xParent.is()) {
    1194                 :            :         // all this create/append stuff may throw DOMException
    1195                 :            :         try {
    1196                 :       2634 :             css::uno::Reference<css::xml::dom::XElement> xRElem;
    1197                 :            :             css::uno::Reference<css::xml::dom::XNode> xNode(
    1198 [ +  - ][ +  - ]:       2634 :                 i_xDoc->getFirstChild());
    1199         [ -  + ]:       2634 :             while (xNode.is()) {
    1200 [ #  # ][ #  # ]:          0 :                 if (css::xml::dom::NodeType_ELEMENT_NODE ==xNode->getNodeType())
                 [ #  # ]
    1201                 :            :                 {
    1202 [ #  # ][ #  # ]:          0 :                     if ( xNode->getNamespaceURI().equalsAscii(s_nsODF) && xNode->getLocalName() == "document-meta" )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  #  
                   #  # ]
    1203                 :            :                     {
    1204         [ #  # ]:          0 :                         xRElem.set(xNode, css::uno::UNO_QUERY_THROW);
    1205                 :          0 :                         break;
    1206                 :            :                     }
    1207                 :            :                     else
    1208                 :            :                     {
    1209                 :            :                         OSL_TRACE("SfxDocumentMetaData::init(): "
    1210                 :            :                                 "deleting unexpected root element: %s",
    1211                 :            :                             ::rtl::OUStringToOString(xNode->getLocalName(),
    1212                 :            :                                 RTL_TEXTENCODING_UTF8).getStr());
    1213 [ #  # ][ #  # ]:          0 :                         i_xDoc->removeChild(xNode);
    1214 [ #  # ][ #  # ]:          0 :                         xNode = i_xDoc->getFirstChild(); // start over
                 [ #  # ]
    1215                 :            :                     }
    1216                 :            :                 } else {
    1217 [ #  # ][ #  # ]:          0 :                     xNode = xNode->getNextSibling();
                 [ #  # ]
    1218                 :            :                 }
    1219                 :            :             }
    1220         [ +  - ]:       2634 :             if (!xRElem.is()) {
    1221         [ +  - ]:       2634 :                 xRElem = i_xDoc->createElementNS(
    1222                 :            :                     ::rtl::OUString::createFromAscii(s_nsODF),
    1223 [ +  - ][ +  - ]:       2634 :                     ::rtl::OUString("office:document-meta"));
    1224                 :            :                 css::uno::Reference<css::xml::dom::XNode> xRNode(xRElem,
    1225         [ +  - ]:       2634 :                     css::uno::UNO_QUERY_THROW);
    1226 [ +  - ][ +  - ]:       2634 :                 i_xDoc->appendChild(xRNode);
    1227                 :            :             }
    1228         [ +  - ]:       2634 :             xRElem->setAttributeNS(::rtl::OUString::createFromAscii(s_nsODF),
    1229                 :            :                         ::rtl::OUString("office:version"),
    1230         [ +  - ]:       2634 :                         ::rtl::OUString("1.0"));
    1231                 :            :             // does not exist, otherwise m_xParent would not be null
    1232                 :            :             css::uno::Reference<css::xml::dom::XNode> xParent (
    1233         [ +  - ]:       2634 :                 i_xDoc->createElementNS(
    1234                 :            :                     ::rtl::OUString::createFromAscii(s_nsODF),
    1235                 :       2634 :                     ::rtl::OUString("office:meta")),
    1236 [ +  - ][ +  - ]:       2634 :             css::uno::UNO_QUERY_THROW);
    1237 [ +  - ][ +  - ]:       2634 :             xRElem->appendChild(xParent);
    1238         [ +  - ]:       2634 :             m_xParent = xParent;
    1239         [ #  # ]:          0 :         } catch (const css::xml::dom::DOMException & e) {
    1240         [ #  # ]:          0 :             css::uno::Any a(e);
    1241                 :            :             throw css::lang::WrappedTargetRuntimeException(
    1242                 :            :                     ::rtl::OUString(
    1243                 :            :                             "SfxDocumentMetaData::init: DOM exception"),
    1244   [ #  #  #  # ]:          0 :                     css::uno::Reference<css::uno::XInterface>(*this), a);
    1245                 :            :         }
    1246                 :            :     }
    1247                 :            : 
    1248                 :            : 
    1249                 :            :     // select nodes for elements of which we only handle one occurrence
    1250         [ +  + ]:      53784 :     for (const char **pName = s_stdMeta; *pName != 0; ++pName) {
    1251                 :      50796 :         ::rtl::OUString name = ::rtl::OUString::createFromAscii(*pName);
    1252                 :            :         // NB: If a document contains more than one occurrence of a
    1253                 :            :         // meta-data element, we arbitrarily pick one of them here.
    1254                 :            :         // We do not remove the others, i.e., when we write the
    1255                 :            :         // document, it will contain the duplicates unchanged.
    1256                 :            :         // The ODF spec says that handling multiple occurrences is
    1257                 :            :         // application-specific.
    1258                 :            :         css::uno::Reference<css::xml::dom::XNode> xNode =
    1259         [ +  - ]:      50796 :             xPath->selectSingleNode(m_xParent,
    1260         [ +  - ]:      50796 :                 ::rtl::OUString("child::") + name);
    1261                 :            :         // Do not create an empty element if it is missing;
    1262                 :            :         // for certain elements, such as dateTime, this would be invalid
    1263 [ +  - ][ +  - ]:      50796 :         m_meta[name] = xNode;
    1264                 :      50796 :     }
    1265                 :            : 
    1266                 :            :     // select nodes for elements of which we handle all occurrences
    1267         [ +  + ]:       8964 :     for (const char **pName = s_stdMetaList; *pName != 0; ++pName) {
    1268                 :       5976 :         ::rtl::OUString name = ::rtl::OUString::createFromAscii(*pName);
    1269                 :            :         css::uno::Reference<css::xml::dom::XNodeList> nodes =
    1270         [ +  - ]:       5976 :             xPath->selectNodeList(m_xParent,
    1271         [ +  - ]:       5976 :                 ::rtl::OUString("child::") + name);
    1272         [ +  - ]:       5976 :         std::vector<css::uno::Reference<css::xml::dom::XNode> > v;
    1273 [ +  - ][ +  - ]:       6280 :         for (sal_Int32 i = 0; i < nodes->getLength(); ++i) {
                 [ +  + ]
    1274 [ +  - ][ +  - ]:        304 :             v.push_back(nodes->item(i));
                 [ +  - ]
    1275                 :            :         }
    1276 [ +  - ][ +  - ]:       5976 :         m_metaList[name] = v;
    1277                 :       5976 :     }
    1278                 :            : 
    1279                 :            :     // initialize members corresponding to attributes from DOM nodes
    1280         [ +  - ]:       2988 :     m_TemplateName  = getMetaAttr("meta:template", "xlink:title");
    1281         [ +  - ]:       2988 :     m_TemplateURL   = getMetaAttr("meta:template", "xlink:href");
    1282                 :            :     m_TemplateDate  =
    1283         [ +  - ]:       2988 :         textToDateTimeDefault(getMetaAttr("meta:template", "meta:date"));
    1284         [ +  - ]:       2988 :     m_AutoloadURL   = getMetaAttr("meta:auto-reload", "xlink:href");
    1285                 :            :     m_AutoloadSecs  =
    1286         [ +  - ]:       2988 :         textToDuration(getMetaAttr("meta:auto-reload", "meta:delay"));
    1287                 :            :     m_DefaultTarget =
    1288         [ +  - ]:       2988 :         getMetaAttr("meta:hyperlink-behaviour", "office:target-frame-name");
    1289                 :            : 
    1290                 :            : 
    1291                 :            :     std::vector<css::uno::Reference<css::xml::dom::XNode> > & vec =
    1292         [ +  - ]:       2988 :         m_metaList[::rtl::OUString("meta:user-defined")];
    1293                 :       2988 :     m_xUserDefined.clear(); // #i105826#: reset (may be re-initialization)
    1294         [ +  + ]:       2988 :     if ( !vec.empty() )
    1295                 :            :     {
    1296         [ +  - ]:         54 :         createUserDefined();
    1297                 :            :     }
    1298                 :            : 
    1299                 :            :     // user-defined meta data: initialize PropertySet from DOM nodes
    1300 [ +  - ][ +  + ]:       6548 :     for (std::vector<css::uno::Reference<css::xml::dom::XNode> >::iterator
    1301                 :       6262 :             it = vec.begin(); it != vec.end(); ++it) {
    1302                 :        286 :         css::uno::Reference<css::xml::dom::XElement> xElem(*it,
    1303         [ +  - ]:        286 :             css::uno::UNO_QUERY_THROW);
    1304                 :        286 :         css::uno::Any any;
    1305         [ +  - ]:        286 :         ::rtl::OUString name = xElem->getAttributeNS(
    1306                 :            :                 ::rtl::OUString::createFromAscii(s_nsODFMeta),
    1307         [ +  - ]:        286 :                 ::rtl::OUString("name"));
    1308         [ +  - ]:        286 :         ::rtl::OUString type = xElem->getAttributeNS(
    1309                 :            :                 ::rtl::OUString::createFromAscii(s_nsODFMeta),
    1310         [ +  - ]:        286 :                 ::rtl::OUString("value-type"));
    1311   [ #  #  #  # ]:        286 :         ::rtl::OUString text = getNodeText(*it);
                 [ +  - ]
    1312         [ +  + ]:        286 :         if ( type == "float" ) {
    1313                 :            :             double d;
    1314 [ +  - ][ +  - ]:         31 :             if (::sax::Converter::convertDouble(d, text)) {
    1315         [ +  - ]:         31 :                 any <<= d;
    1316                 :            :             } else {
    1317                 :            :                 DBG_WARNING1("SfxDocumentMetaData: invalid float: %s",
    1318                 :            :                     OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
    1319                 :         31 :                 continue;
    1320                 :            :             }
    1321         [ +  + ]:        255 :         } else if ( type == "date" ) {
    1322                 :            :             bool isDateTime;
    1323                 :          6 :             css::util::Date d;
    1324                 :          6 :             css::util::DateTime dt;
    1325         [ +  + ]:          6 :             if (textToDateOrDateTime(d, dt, isDateTime, text)) {
    1326         [ +  + ]:          4 :                 if (isDateTime) {
    1327         [ +  - ]:          2 :                     any <<= dt;
    1328                 :            :                 } else {
    1329         [ +  - ]:          2 :                     any <<= d;
    1330                 :            :                 }
    1331                 :            :             } else {
    1332                 :            :                 DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
    1333                 :            :                     OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
    1334                 :          6 :                 continue;
    1335                 :            :             }
    1336         [ +  + ]:        249 :         } else if ( type == "time" ) {
    1337                 :          4 :             css::util::Duration ud;
    1338         [ +  - ]:          4 :             if (textToDuration(ud, text)) {
    1339         [ +  - ]:          4 :                 any <<= ud;
    1340                 :            :             } else {
    1341                 :            :                 DBG_WARNING1("SfxDocumentMetaData: invalid time: %s",
    1342                 :            :                     OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
    1343                 :          4 :                 continue;
    1344                 :            :             }
    1345         [ +  + ]:        245 :         } else if ( type == "boolean" ) {
    1346                 :            :             bool b;
    1347 [ +  - ][ +  - ]:         90 :             if (::sax::Converter::convertBool(b, text)) {
    1348         [ +  - ]:         90 :                 any <<= b;
    1349                 :            :             } else {
    1350                 :            :                 DBG_WARNING1("SfxDocumentMetaData: invalid boolean: %s",
    1351                 :            :                     OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
    1352                 :         90 :                 continue;
    1353                 :            :             }
    1354         [ +  - ]:        155 :         } else if ( type == "string" || true) { // default
    1355         [ +  - ]:        155 :             any <<= text;
    1356                 :            :         }
    1357                 :            :         try {
    1358         [ +  - ]:        284 :             m_xUserDefined->addProperty(name,
    1359         [ +  - ]:        284 :                 css::beans::PropertyAttribute::REMOVEABLE, any);
    1360         [ #  # ]:          0 :         } catch (const css::beans::PropertyExistException &) {
    1361                 :            :             DBG_WARNING1("SfxDocumentMetaData: duplicate: %s",
    1362                 :            :                     OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr());
    1363                 :            :             // ignore; duplicate
    1364         [ #  # ]:          0 :         } catch (const css::beans::IllegalTypeException &) {
    1365                 :            :             OSL_TRACE("SfxDocumentMetaData: illegal type: %s",
    1366                 :            :                     OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr());
    1367         [ #  # ]:          0 :         } catch (const css::lang::IllegalArgumentException &) {
    1368                 :            :             OSL_TRACE("SfxDocumentMetaData: illegal arg: %s",
    1369                 :            :                     OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr());
    1370                 :            :         }
    1371 [ +  + ][ +  + ]:        286 :     }
         [ +  + ][ +  + ]
                 [ +  + ]
    1372                 :            : 
    1373                 :       2988 :     m_isModified = false;
    1374                 :       2988 :     m_isInitialized = true;
    1375                 :       2988 : }
    1376                 :            : 
    1377                 :            : 
    1378                 :            : 
    1379                 :       2632 : SfxDocumentMetaData::SfxDocumentMetaData(
    1380                 :            :         css::uno::Reference< css::uno::XComponentContext > const & context)
    1381                 :            :     : BaseMutex()
    1382                 :            :     , SfxDocumentMetaData_Base(m_aMutex)
    1383                 :            :     , m_xContext(context)
    1384                 :            :     , m_NotifyListeners(m_aMutex)
    1385                 :            :     , m_isInitialized(false)
    1386                 :            :     , m_isModified(false)
    1387 [ +  - ][ +  - ]:       2632 :     , m_AutoloadSecs(0)
                 [ +  - ]
    1388                 :            : {
    1389                 :            :     DBG_ASSERT(context.is(), "SfxDocumentMetaData: context is null");
    1390                 :            :     DBG_ASSERT(context->getServiceManager().is(),
    1391                 :            :         "SfxDocumentMetaData: context has no service manager");
    1392 [ +  - ][ +  - ]:       2632 :     init(createDOM());
    1393                 :       2632 : }
    1394                 :            : 
    1395                 :            : // com.sun.star.uno.XServiceInfo:
    1396                 :            : ::rtl::OUString SAL_CALL
    1397                 :          0 : SfxDocumentMetaData::getImplementationName() throw (css::uno::RuntimeException)
    1398                 :            : {
    1399                 :          0 :     return comp_SfxDocumentMetaData::_getImplementationName();
    1400                 :            : }
    1401                 :            : 
    1402                 :            : ::sal_Bool SAL_CALL
    1403                 :          0 : SfxDocumentMetaData::supportsService(::rtl::OUString const & serviceName)
    1404                 :            :         throw (css::uno::RuntimeException)
    1405                 :            : {
    1406                 :            :     css::uno::Sequence< ::rtl::OUString > serviceNames =
    1407         [ #  # ]:          0 :         comp_SfxDocumentMetaData::_getSupportedServiceNames();
    1408         [ #  # ]:          0 :     for (::sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {
    1409 [ #  # ][ #  # ]:          0 :         if (serviceNames[i] == serviceName)
    1410                 :          0 :             return sal_True;
    1411                 :            :     }
    1412         [ #  # ]:          0 :     return sal_False;
    1413                 :            : }
    1414                 :            : 
    1415                 :            : css::uno::Sequence< ::rtl::OUString > SAL_CALL
    1416                 :          0 : SfxDocumentMetaData::getSupportedServiceNames()
    1417                 :            :         throw (css::uno::RuntimeException)
    1418                 :            : {
    1419                 :          0 :     return comp_SfxDocumentMetaData::_getSupportedServiceNames();
    1420                 :            : }
    1421                 :            : 
    1422                 :            : 
    1423                 :            : // ::com::sun::star::lang::XComponent:
    1424                 :       2470 : void SAL_CALL SfxDocumentMetaData::dispose() throw (css::uno::RuntimeException)
    1425                 :            : {
    1426         [ +  - ]:       2470 :     ::osl::MutexGuard g(m_aMutex);
    1427         [ -  + ]:       2470 :     if (!m_isInitialized) {
    1428                 :       2470 :         return;
    1429                 :            :     }
    1430         [ +  - ]:       2470 :     WeakComponentImplHelperBase::dispose(); // superclass
    1431                 :            :     m_NotifyListeners.disposeAndClear(css::lang::EventObject(
    1432 [ +  - ][ +  - ]:       2470 :             static_cast< ::cppu::OWeakObject* >(this)));
         [ +  - ][ +  - ]
    1433                 :       2470 :     m_isInitialized = false;
    1434                 :       2470 :     m_meta.clear();
    1435                 :       2470 :     m_metaList.clear();
    1436                 :       2470 :     m_xParent.clear();
    1437                 :       2470 :     m_xDoc.clear();
    1438 [ +  - ][ +  - ]:       2470 :     m_xUserDefined.clear();
    1439                 :            : }
    1440                 :            : 
    1441                 :            : 
    1442                 :            : // ::com::sun::star::document::XDocumentProperties:
    1443                 :            : ::rtl::OUString SAL_CALL
    1444                 :       1468 : SfxDocumentMetaData::getAuthor() throw (css::uno::RuntimeException)
    1445                 :            : {
    1446         [ +  - ]:       1468 :     ::osl::MutexGuard g(m_aMutex);
    1447 [ +  - ][ +  - ]:       1468 :     return getMetaText("meta:initial-creator");
    1448                 :            : }
    1449                 :            : 
    1450                 :       1355 : void SAL_CALL SfxDocumentMetaData::setAuthor(const ::rtl::OUString & the_value)
    1451                 :            :         throw (css::uno::RuntimeException)
    1452                 :            : {
    1453                 :       1355 :     setMetaTextAndNotify("meta:initial-creator", the_value);
    1454                 :       1355 : }
    1455                 :            : 
    1456                 :            : 
    1457                 :            : ::rtl::OUString SAL_CALL
    1458                 :        513 : SfxDocumentMetaData::getGenerator() throw (css::uno::RuntimeException)
    1459                 :            : {
    1460         [ +  - ]:        513 :     ::osl::MutexGuard g(m_aMutex);
    1461 [ +  - ][ +  - ]:        513 :     return getMetaText("meta:generator");
    1462                 :            : }
    1463                 :            : 
    1464                 :            : void SAL_CALL
    1465                 :       1228 : SfxDocumentMetaData::setGenerator(const ::rtl::OUString & the_value)
    1466                 :            :         throw (css::uno::RuntimeException)
    1467                 :            : {
    1468                 :       1228 :     setMetaTextAndNotify("meta:generator", the_value);
    1469                 :       1228 : }
    1470                 :            : 
    1471                 :            : css::util::DateTime SAL_CALL
    1472                 :        167 : SfxDocumentMetaData::getCreationDate() throw (css::uno::RuntimeException)
    1473                 :            : {
    1474         [ +  - ]:        167 :     ::osl::MutexGuard g(m_aMutex);
    1475 [ +  - ][ +  - ]:        167 :     return textToDateTimeDefault(getMetaText("meta:creation-date"));
    1476                 :            : }
    1477                 :            : 
    1478                 :            : void SAL_CALL
    1479                 :       1541 : SfxDocumentMetaData::setCreationDate(const css::util::DateTime & the_value)
    1480                 :            :         throw (css::uno::RuntimeException)
    1481                 :            : {
    1482         [ +  - ]:       1541 :     setMetaTextAndNotify("meta:creation-date", dateTimeToText(the_value));
    1483                 :       1541 : }
    1484                 :            : 
    1485                 :            : ::rtl::OUString SAL_CALL
    1486                 :        425 : SfxDocumentMetaData::getTitle() throw (css::uno::RuntimeException)
    1487                 :            : {
    1488         [ +  - ]:        425 :     ::osl::MutexGuard g(m_aMutex);
    1489 [ +  - ][ +  - ]:        425 :     return getMetaText("dc:title");
    1490                 :            : }
    1491                 :            : 
    1492                 :        105 : void SAL_CALL SfxDocumentMetaData::setTitle(const ::rtl::OUString & the_value)
    1493                 :            :         throw (css::uno::RuntimeException)
    1494                 :            : {
    1495                 :        105 :     setMetaTextAndNotify("dc:title", the_value);
    1496                 :        105 : }
    1497                 :            : 
    1498                 :            : ::rtl::OUString SAL_CALL
    1499                 :        161 : SfxDocumentMetaData::getSubject() throw (css::uno::RuntimeException)
    1500                 :            : {
    1501         [ +  - ]:        161 :     ::osl::MutexGuard g(m_aMutex);
    1502 [ +  - ][ +  - ]:        161 :     return getMetaText("dc:subject");
    1503                 :            : }
    1504                 :            : 
    1505                 :            : void SAL_CALL
    1506                 :         88 : SfxDocumentMetaData::setSubject(const ::rtl::OUString & the_value)
    1507                 :            :         throw (css::uno::RuntimeException)
    1508                 :            : {
    1509                 :         88 :     setMetaTextAndNotify("dc:subject", the_value);
    1510                 :         88 : }
    1511                 :            : 
    1512                 :            : ::rtl::OUString SAL_CALL
    1513                 :        161 : SfxDocumentMetaData::getDescription() throw (css::uno::RuntimeException)
    1514                 :            : {
    1515         [ +  - ]:        161 :     ::osl::MutexGuard g(m_aMutex);
    1516 [ +  - ][ +  - ]:        161 :     return getMetaText("dc:description");
    1517                 :            : }
    1518                 :            : 
    1519                 :            : void SAL_CALL
    1520                 :         67 : SfxDocumentMetaData::setDescription(const ::rtl::OUString & the_value)
    1521                 :            :         throw (css::uno::RuntimeException)
    1522                 :            : {
    1523                 :         67 :     setMetaTextAndNotify("dc:description", the_value);
    1524                 :         67 : }
    1525                 :            : 
    1526                 :            : css::uno::Sequence< ::rtl::OUString >
    1527                 :        161 : SAL_CALL SfxDocumentMetaData::getKeywords() throw (css::uno::RuntimeException)
    1528                 :            : {
    1529         [ +  - ]:        161 :     ::osl::MutexGuard g(m_aMutex);
    1530 [ +  - ][ +  - ]:        161 :     return getMetaList("meta:keyword");
    1531                 :            : }
    1532                 :            : 
    1533                 :            : void SAL_CALL
    1534                 :         82 : SfxDocumentMetaData::setKeywords(
    1535                 :            :         const css::uno::Sequence< ::rtl::OUString > & the_value)
    1536                 :            :         throw (css::uno::RuntimeException)
    1537                 :            : {
    1538         [ +  - ]:         82 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1539 [ +  - ][ +  + ]:         82 :     if (setMetaList("meta:keyword", the_value)) {
    1540         [ +  - ]:          8 :         g.clear();
    1541         [ +  - ]:          8 :         setModified(true);
    1542         [ +  - ]:         82 :     }
    1543                 :         82 : }
    1544                 :            : 
    1545                 :            : css::lang::Locale SAL_CALL
    1546                 :         67 :         SfxDocumentMetaData::getLanguage() throw (css::uno::RuntimeException)
    1547                 :            : {
    1548         [ +  - ]:         67 :     ::osl::MutexGuard g(m_aMutex);
    1549                 :         67 :     css::lang::Locale loc;
    1550         [ +  - ]:         67 :     ::rtl::OUString text = getMetaText("dc:language");
    1551                 :         67 :     sal_Int32 ix = text.indexOf(static_cast<sal_Unicode> ('-'));
    1552         [ +  + ]:         67 :     if (ix == -1) {
    1553                 :         65 :         loc.Language = text;
    1554                 :            :     } else {
    1555                 :          2 :         loc.Language = text.copy(0, ix);
    1556                 :          2 :         loc.Country = text.copy(ix+1);
    1557                 :            :     }
    1558         [ +  - ]:         67 :     return loc;
    1559                 :            : }
    1560                 :            : 
    1561                 :            : void SAL_CALL
    1562                 :         10 : SfxDocumentMetaData::setLanguage(const css::lang::Locale & the_value)
    1563                 :            :         throw (css::uno::RuntimeException)
    1564                 :            : {
    1565                 :         10 :     ::rtl::OUString text = the_value.Language;
    1566         [ +  + ]:         10 :     if (!the_value.Country.isEmpty()) {
    1567                 :          2 :         text += ::rtl::OUString("-").concat(the_value.Country);
    1568                 :            :     }
    1569         [ +  - ]:         10 :     setMetaTextAndNotify("dc:language", text);
    1570                 :         10 : }
    1571                 :            : 
    1572                 :            : ::rtl::OUString SAL_CALL
    1573                 :       1464 : SfxDocumentMetaData::getModifiedBy() throw (css::uno::RuntimeException)
    1574                 :            : {
    1575         [ +  - ]:       1464 :     ::osl::MutexGuard g(m_aMutex);
    1576 [ +  - ][ +  - ]:       1464 :     return getMetaText("dc:creator");
    1577                 :            : }
    1578                 :            : 
    1579                 :            : void SAL_CALL
    1580                 :        275 : SfxDocumentMetaData::setModifiedBy(const ::rtl::OUString & the_value)
    1581                 :            :         throw (css::uno::RuntimeException)
    1582                 :            : {
    1583                 :        275 :     setMetaTextAndNotify("dc:creator", the_value);
    1584                 :        275 : }
    1585                 :            : 
    1586                 :            : css::util::DateTime SAL_CALL
    1587                 :        167 : SfxDocumentMetaData::getModificationDate() throw (css::uno::RuntimeException)
    1588                 :            : {
    1589         [ +  - ]:        167 :     ::osl::MutexGuard g(m_aMutex);
    1590 [ +  - ][ +  - ]:        167 :     return textToDateTimeDefault(getMetaText("dc:date"));
    1591                 :            : }
    1592                 :            : 
    1593                 :            : void SAL_CALL
    1594                 :        367 : SfxDocumentMetaData::setModificationDate(const css::util::DateTime & the_value)
    1595                 :            :         throw (css::uno::RuntimeException)
    1596                 :            : {
    1597         [ +  - ]:        367 :     setMetaTextAndNotify("dc:date", dateTimeToText(the_value));
    1598                 :        367 : }
    1599                 :            : 
    1600                 :            : ::rtl::OUString SAL_CALL
    1601                 :         12 : SfxDocumentMetaData::getPrintedBy() throw (css::uno::RuntimeException)
    1602                 :            : {
    1603         [ +  - ]:         12 :     ::osl::MutexGuard g(m_aMutex);
    1604 [ +  - ][ +  - ]:         12 :     return getMetaText("meta:printed-by");
    1605                 :            : }
    1606                 :            : 
    1607                 :            : void SAL_CALL
    1608                 :        161 : SfxDocumentMetaData::setPrintedBy(const ::rtl::OUString & the_value)
    1609                 :            :         throw (css::uno::RuntimeException)
    1610                 :            : {
    1611                 :        161 :     setMetaTextAndNotify("meta:printed-by", the_value);
    1612                 :        161 : }
    1613                 :            : 
    1614                 :            : css::util::DateTime SAL_CALL
    1615                 :        165 : SfxDocumentMetaData::getPrintDate() throw (css::uno::RuntimeException)
    1616                 :            : {
    1617         [ +  - ]:        165 :     ::osl::MutexGuard g(m_aMutex);
    1618 [ +  - ][ +  - ]:        165 :     return textToDateTimeDefault(getMetaText("meta:print-date"));
    1619                 :            : }
    1620                 :            : 
    1621                 :            : void SAL_CALL
    1622                 :        344 : SfxDocumentMetaData::setPrintDate(const css::util::DateTime & the_value)
    1623                 :            :         throw (css::uno::RuntimeException)
    1624                 :            : {
    1625         [ +  - ]:        344 :     setMetaTextAndNotify("meta:print-date", dateTimeToText(the_value));
    1626                 :        344 : }
    1627                 :            : 
    1628                 :            : ::rtl::OUString SAL_CALL
    1629                 :        172 : SfxDocumentMetaData::getTemplateName() throw (css::uno::RuntimeException)
    1630                 :            : {
    1631         [ +  - ]:        172 :     ::osl::MutexGuard g(m_aMutex);
    1632         [ +  - ]:        172 :     checkInit();
    1633         [ +  - ]:        172 :     return m_TemplateName;
    1634                 :            : }
    1635                 :            : 
    1636                 :            : void SAL_CALL
    1637                 :        200 : SfxDocumentMetaData::setTemplateName(const ::rtl::OUString & the_value)
    1638                 :            :         throw (css::uno::RuntimeException)
    1639                 :            : {
    1640         [ +  - ]:        200 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1641         [ +  - ]:        200 :     checkInit();
    1642         [ +  + ]:        200 :     if (m_TemplateName != the_value) {
    1643                 :        175 :         m_TemplateName = the_value;
    1644         [ +  - ]:        175 :         g.clear();
    1645         [ +  - ]:        175 :         setModified(true);
    1646         [ +  - ]:        200 :     }
    1647                 :        200 : }
    1648                 :            : 
    1649                 :            : ::rtl::OUString SAL_CALL
    1650                 :        403 : SfxDocumentMetaData::getTemplateURL() throw (css::uno::RuntimeException)
    1651                 :            : {
    1652         [ +  - ]:        403 :     ::osl::MutexGuard g(m_aMutex);
    1653         [ +  - ]:        403 :     checkInit();
    1654         [ +  - ]:        403 :     return m_TemplateURL;
    1655                 :            : }
    1656                 :            : 
    1657                 :            : void SAL_CALL
    1658                 :        297 : SfxDocumentMetaData::setTemplateURL(const ::rtl::OUString & the_value)
    1659                 :            :         throw (css::uno::RuntimeException)
    1660                 :            : {
    1661         [ +  - ]:        297 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1662         [ +  - ]:        297 :     checkInit();
    1663         [ +  + ]:        297 :     if (m_TemplateURL != the_value) {
    1664                 :         22 :         m_TemplateURL = the_value;
    1665         [ +  - ]:         22 :         g.clear();
    1666         [ +  - ]:         22 :         setModified(true);
    1667         [ +  - ]:        297 :     }
    1668                 :        297 : }
    1669                 :            : 
    1670                 :            : css::util::DateTime SAL_CALL
    1671                 :         12 : SfxDocumentMetaData::getTemplateDate() throw (css::uno::RuntimeException)
    1672                 :            : {
    1673         [ +  - ]:         12 :     ::osl::MutexGuard g(m_aMutex);
    1674         [ +  - ]:         12 :     checkInit();
    1675         [ +  - ]:         12 :     return m_TemplateDate;
    1676                 :            : }
    1677                 :            : 
    1678                 :            : void SAL_CALL
    1679                 :         15 : SfxDocumentMetaData::setTemplateDate(const css::util::DateTime & the_value)
    1680                 :            :         throw (css::uno::RuntimeException)
    1681                 :            : {
    1682         [ +  - ]:         15 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1683         [ +  - ]:         15 :     checkInit();
    1684         [ +  + ]:         15 :     if (!(m_TemplateDate == the_value)) {
    1685                 :          2 :         m_TemplateDate = the_value;
    1686         [ +  - ]:          2 :         g.clear();
    1687         [ +  - ]:          2 :         setModified(true);
    1688         [ +  - ]:         15 :     }
    1689                 :         15 : }
    1690                 :            : 
    1691                 :            : ::rtl::OUString SAL_CALL
    1692                 :       4263 : SfxDocumentMetaData::getAutoloadURL() throw (css::uno::RuntimeException)
    1693                 :            : {
    1694         [ +  - ]:       4263 :     ::osl::MutexGuard g(m_aMutex);
    1695         [ +  - ]:       4263 :     checkInit();
    1696         [ +  - ]:       4263 :     return m_AutoloadURL;
    1697                 :            : }
    1698                 :            : 
    1699                 :            : void SAL_CALL
    1700                 :        205 : SfxDocumentMetaData::setAutoloadURL(const ::rtl::OUString & the_value)
    1701                 :            :         throw (css::uno::RuntimeException)
    1702                 :            : {
    1703         [ +  - ]:        205 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1704         [ +  - ]:        205 :     checkInit();
    1705         [ +  + ]:        205 :     if (m_AutoloadURL != the_value) {
    1706                 :          2 :         m_AutoloadURL = the_value;
    1707         [ +  - ]:          2 :         g.clear();
    1708         [ +  - ]:          2 :         setModified(true);
    1709         [ +  - ]:        205 :     }
    1710                 :        205 : }
    1711                 :            : 
    1712                 :            : ::sal_Int32 SAL_CALL
    1713                 :       4070 : SfxDocumentMetaData::getAutoloadSecs() throw (css::uno::RuntimeException)
    1714                 :            : {
    1715         [ +  - ]:       4070 :     ::osl::MutexGuard g(m_aMutex);
    1716         [ +  - ]:       4070 :     checkInit();
    1717         [ +  - ]:       4070 :     return m_AutoloadSecs;
    1718                 :            : }
    1719                 :            : 
    1720                 :            : void SAL_CALL
    1721                 :         10 : SfxDocumentMetaData::setAutoloadSecs(::sal_Int32 the_value)
    1722                 :            :         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
    1723                 :            : {
    1724         [ -  + ]:         10 :     if (the_value < 0) throw css::lang::IllegalArgumentException(
    1725                 :            :         ::rtl::OUString(
    1726                 :            :             "SfxDocumentMetaData::setAutoloadSecs: argument is negative"),
    1727 [ #  # ][ #  # ]:          0 :             *this, 0);
    1728         [ +  - ]:         10 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1729         [ +  - ]:         10 :     checkInit();
    1730         [ +  + ]:         10 :     if (m_AutoloadSecs != the_value) {
    1731                 :          2 :         m_AutoloadSecs = the_value;
    1732         [ +  - ]:          2 :         g.clear();
    1733         [ +  - ]:          2 :         setModified(true);
    1734         [ +  - ]:         10 :     }
    1735                 :         10 : }
    1736                 :            : 
    1737                 :            : ::rtl::OUString SAL_CALL
    1738                 :         14 : SfxDocumentMetaData::getDefaultTarget() throw (css::uno::RuntimeException)
    1739                 :            : {
    1740         [ +  - ]:         14 :     ::osl::MutexGuard g(m_aMutex);
    1741         [ +  - ]:         14 :     checkInit();
    1742         [ +  - ]:         14 :     return m_DefaultTarget;
    1743                 :            : }
    1744                 :            : 
    1745                 :            : void SAL_CALL
    1746                 :         10 : SfxDocumentMetaData::setDefaultTarget(const ::rtl::OUString & the_value)
    1747                 :            :         throw (css::uno::RuntimeException)
    1748                 :            : {
    1749         [ +  - ]:         10 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1750         [ +  - ]:         10 :     checkInit();
    1751         [ -  + ]:         10 :     if (m_DefaultTarget != the_value) {
    1752                 :          0 :         m_DefaultTarget = the_value;
    1753         [ #  # ]:          0 :         g.clear();
    1754         [ #  # ]:          0 :         setModified(true);
    1755         [ +  - ]:         10 :     }
    1756                 :         10 : }
    1757                 :            : 
    1758                 :            : css::uno::Sequence< css::beans::NamedValue > SAL_CALL
    1759                 :        608 : SfxDocumentMetaData::getDocumentStatistics() throw (css::uno::RuntimeException)
    1760                 :            : {
    1761         [ +  - ]:        608 :     ::osl::MutexGuard g(m_aMutex);
    1762         [ +  - ]:        608 :     checkInit();
    1763         [ +  - ]:        608 :     ::comphelper::SequenceAsVector<css::beans::NamedValue> stats;
    1764         [ +  + ]:       9728 :     for (size_t i = 0; s_stdStats[i] != 0; ++i) {
    1765                 :       9120 :         const char * aName = s_stdStatAttrs[i];
    1766         [ +  - ]:       9120 :         ::rtl::OUString text = getMetaAttr("meta:document-statistic", aName);
    1767         [ +  + ]:       9120 :         if (text.isEmpty()) continue;
    1768                 :       1484 :         css::beans::NamedValue stat;
    1769                 :       1484 :         stat.Name = ::rtl::OUString::createFromAscii(s_stdStats[i]);
    1770                 :            :         sal_Int32 val;
    1771                 :       1484 :         css::uno::Any any;
    1772 [ +  - ][ -  + ]:       1484 :         if (!::sax::Converter::convertNumber(val, text, 0,
                 [ -  + ]
    1773         [ +  - ]:       1484 :                 std::numeric_limits<sal_Int32>::max()) || (val < 0)) {
    1774                 :          0 :             val = 0;
    1775                 :            :             DBG_WARNING1("SfxDocumentMetaData: invalid number: %s",
    1776                 :            :                 OUStringToOString(text, RTL_TEXTENCODING_UTF8).getStr());
    1777                 :            :         }
    1778         [ +  - ]:       1484 :         any <<= val;
    1779                 :       1484 :         stat.Value = any;
    1780         [ +  - ]:       1484 :         stats.push_back(stat);
    1781         [ +  + ]:       9120 :     }
    1782                 :            : 
    1783 [ +  - ][ +  - ]:        608 :     return stats.getAsConstList();
    1784                 :            : }
    1785                 :            : 
    1786                 :            : void SAL_CALL
    1787                 :       1817 : SfxDocumentMetaData::setDocumentStatistics(
    1788                 :            :         const css::uno::Sequence< css::beans::NamedValue > & the_value)
    1789                 :            :         throw (css::uno::RuntimeException)
    1790                 :            : {
    1791         [ +  - ]:       1817 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1792         [ +  - ]:       1817 :     checkInit();
    1793         [ +  - ]:       1817 :     std::vector<std::pair<const char *, ::rtl::OUString> > attributes;
    1794         [ +  + ]:      14323 :     for (sal_Int32 i = 0; i < the_value.getLength(); ++i) {
    1795                 :      12506 :         const ::rtl::OUString name = the_value[i].Name;
    1796                 :            :         // inefficently search for matching attribute
    1797         [ +  - ]:      77441 :         for (size_t j = 0; s_stdStats[j] != 0; ++j) {
    1798         [ +  + ]:      77441 :             if (name.equalsAscii(s_stdStats[j])) {
    1799                 :      12506 :                 const css::uno::Any any = the_value[i].Value;
    1800                 :      12506 :                 sal_Int32 val = 0;
    1801         [ +  - ]:      12506 :                 if (any >>= val) {
    1802                 :      12506 :                     ::rtl::OUStringBuffer buf;
    1803         [ +  - ]:      12506 :                     ::sax::Converter::convertNumber(buf, val);
    1804                 :            :                     attributes.push_back(std::make_pair(s_stdStatAttrs[j],
    1805 [ +  - ][ +  - ]:      12506 :                                 buf.makeStringAndClear()));
    1806                 :            :                 } else {
    1807                 :            :                     DBG_WARNING1("SfxDocumentMetaData: invalid statistic: %s",
    1808                 :            :                         OUStringToOString(name, RTL_TEXTENCODING_UTF8)
    1809                 :            :                             .getStr());
    1810                 :            :                 }
    1811                 :      12506 :                 break;
    1812                 :            :             }
    1813                 :            :         }
    1814                 :      12506 :     }
    1815         [ +  - ]:       1817 :     updateElement("meta:document-statistic", &attributes);
    1816         [ +  - ]:       1817 :     g.clear();
    1817 [ +  - ][ +  - ]:       1817 :     setModified(true);
    1818                 :       1817 : }
    1819                 :            : 
    1820                 :            : ::sal_Int16 SAL_CALL
    1821                 :         82 : SfxDocumentMetaData::getEditingCycles() throw (css::uno::RuntimeException)
    1822                 :            : {
    1823         [ +  - ]:         82 :     ::osl::MutexGuard g(m_aMutex);
    1824         [ +  - ]:         82 :     ::rtl::OUString text = getMetaText("meta:editing-cycles");
    1825                 :            :     sal_Int32 ret;
    1826 [ +  - ][ +  - ]:         82 :     if (::sax::Converter::convertNumber(ret, text,
    1827                 :         82 :             0, std::numeric_limits<sal_Int16>::max())) {
    1828                 :         82 :         return static_cast<sal_Int16>(ret);
    1829                 :            :     } else {
    1830                 :          0 :         return 0;
    1831         [ +  - ]:         82 :     }
    1832                 :            : }
    1833                 :            : 
    1834                 :            : void SAL_CALL
    1835                 :        337 : SfxDocumentMetaData::setEditingCycles(::sal_Int16 the_value)
    1836                 :            :         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
    1837                 :            : {
    1838         [ -  + ]:        337 :     if (the_value < 0) throw css::lang::IllegalArgumentException(
    1839                 :            :         ::rtl::OUString(
    1840                 :            :                 "SfxDocumentMetaData::setEditingCycles: argument is negative"),
    1841 [ #  # ][ #  # ]:          0 :                 *this, 0);
    1842                 :        337 :     ::rtl::OUStringBuffer buf;
    1843         [ +  - ]:        337 :     ::sax::Converter::convertNumber(buf, the_value);
    1844 [ +  - ][ +  - ]:        337 :     setMetaTextAndNotify("meta:editing-cycles", buf.makeStringAndClear());
    1845                 :        337 : }
    1846                 :            : 
    1847                 :            : ::sal_Int32 SAL_CALL
    1848                 :         82 : SfxDocumentMetaData::getEditingDuration() throw (css::uno::RuntimeException)
    1849                 :            : {
    1850         [ +  - ]:         82 :     ::osl::MutexGuard g(m_aMutex);
    1851 [ +  - ][ +  - ]:         82 :     return textToDuration(getMetaText("meta:editing-duration"));
    1852                 :            : }
    1853                 :            : 
    1854                 :            : void SAL_CALL
    1855                 :        343 : SfxDocumentMetaData::setEditingDuration(::sal_Int32 the_value)
    1856                 :            :         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
    1857                 :            : {
    1858         [ -  + ]:        343 :     if (the_value < 0) throw css::lang::IllegalArgumentException(
    1859                 :            :         ::rtl::OUString(
    1860                 :            :             "SfxDocumentMetaData::setEditingDuration: argument is negative"),
    1861 [ #  # ][ #  # ]:          0 :             *this, 0);
    1862         [ +  - ]:        343 :     setMetaTextAndNotify("meta:editing-duration", durationToText(the_value));
    1863                 :        343 : }
    1864                 :            : 
    1865                 :            : void SAL_CALL
    1866                 :          5 : SfxDocumentMetaData::resetUserData(const ::rtl::OUString & the_value)
    1867                 :            :     throw (css::uno::RuntimeException)
    1868                 :            : {
    1869         [ +  - ]:          5 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1870                 :            : 
    1871                 :          5 :     bool bModified( false );
    1872         [ +  - ]:          5 :     bModified |= setMetaText("meta:initial-creator", the_value);
    1873         [ +  - ]:          5 :     ::DateTime now( ::DateTime::SYSTEM );
    1874                 :          5 :     css::util::DateTime uDT(now.Get100Sec(), now.GetSec(), now.GetMin(),
    1875                 :         10 :         now.GetHour(), now.GetDay(), now.GetMonth(), now.GetYear());
    1876         [ +  - ]:          5 :     bModified |= setMetaText("meta:creation-date", dateTimeToText(uDT));
    1877         [ +  - ]:          5 :     bModified |= setMetaText("dc:creator", ::rtl::OUString());
    1878         [ +  - ]:          5 :     bModified |= setMetaText("meta:printed-by", ::rtl::OUString());
    1879         [ +  - ]:          5 :     bModified |= setMetaText("dc:date", dateTimeToText(css::util::DateTime()));
    1880                 :            :     bModified |= setMetaText("meta:print-date",
    1881         [ +  - ]:          5 :         dateTimeToText(css::util::DateTime()));
    1882         [ +  - ]:          5 :     bModified |= setMetaText("meta:editing-duration", durationToText(0));
    1883                 :            :     bModified |= setMetaText("meta:editing-cycles",
    1884         [ +  - ]:          5 :         ::rtl::OUString("1"));
    1885                 :            : 
    1886         [ +  - ]:          5 :     if (bModified) {
    1887         [ +  - ]:          5 :         g.clear();
    1888         [ +  - ]:          5 :         setModified(true);
    1889         [ +  - ]:          5 :     }
    1890                 :          5 : }
    1891                 :            : 
    1892                 :            : 
    1893                 :            : css::uno::Reference< css::beans::XPropertyContainer > SAL_CALL
    1894                 :       1047 : SfxDocumentMetaData::getUserDefinedProperties()
    1895                 :            :         throw (css::uno::RuntimeException)
    1896                 :            : {
    1897         [ +  - ]:       1047 :     ::osl::MutexGuard g(m_aMutex);
    1898         [ +  - ]:       1047 :     checkInit();
    1899         [ +  - ]:       1047 :     createUserDefined();
    1900         [ +  - ]:       1047 :     return m_xUserDefined;
    1901                 :            : }
    1902                 :            : 
    1903                 :            : 
    1904                 :            : void SAL_CALL
    1905                 :         28 : SfxDocumentMetaData::loadFromStorage(
    1906                 :            :         const css::uno::Reference< css::embed::XStorage > & xStorage,
    1907                 :            :         const css::uno::Sequence< css::beans::PropertyValue > & Medium)
    1908                 :            :     throw (css::uno::RuntimeException, css::lang::IllegalArgumentException,
    1909                 :            :            css::io::WrongFormatException,
    1910                 :            :            css::lang::WrappedTargetException, css::io::IOException)
    1911                 :            : {
    1912         [ -  + ]:         28 :     if (!xStorage.is()) throw css::lang::IllegalArgumentException(
    1913                 :            :         ::rtl::OUString("SfxDocumentMetaData::loadFromStorage:"
    1914 [ #  # ][ #  # ]:          0 :                 " argument is null"), *this, 0);
    1915         [ +  - ]:         28 :     ::osl::MutexGuard g(m_aMutex);
    1916                 :            : 
    1917                 :            :     // open meta data file
    1918                 :            :     css::uno::Reference<css::io::XStream> xStream(
    1919         [ +  - ]:         28 :         xStorage->openStreamElement(
    1920                 :            :             ::rtl::OUString(s_meta),
    1921         [ +  - ]:         28 :             css::embed::ElementModes::READ) );
    1922 [ #  # ][ -  + ]:         28 :     if (!xStream.is()) throw css::uno::RuntimeException();
    1923                 :            :     css::uno::Reference<css::io::XInputStream> xInStream =
    1924 [ +  - ][ +  - ]:         28 :         xStream->getInputStream();
    1925 [ -  + ][ #  # ]:         28 :     if (!xInStream.is()) throw css::uno::RuntimeException();
    1926                 :            : 
    1927                 :            :     // create DOM parser service
    1928                 :            :     css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
    1929 [ +  - ][ +  - ]:         28 :         m_xContext->getServiceManager());
    1930                 :            :     css::uno::Reference<css::xml::sax::XParser> xParser (
    1931         [ +  - ]:         28 :         xMsf->createInstanceWithContext(::rtl::OUString(
    1932                 :         28 :                 "com.sun.star.xml.sax.Parser"), m_xContext),
    1933 [ +  - ][ +  - ]:         28 :         css::uno::UNO_QUERY_THROW);
    1934         [ -  + ]:         28 :     if (!xParser.is()) throw css::uno::RuntimeException(
    1935                 :            :         ::rtl::OUString("SfxDocumentMetaData::loadFromStorage:"
    1936 [ #  # ][ #  # ]:          0 :                 " cannot create Parser service"), *this);
    1937         [ +  - ]:         28 :     css::xml::sax::InputSource input;
    1938         [ +  - ]:         28 :     input.aInputStream = xInStream;
    1939                 :            : 
    1940         [ +  - ]:         28 :     sal_uInt64 version = SotStorage::GetVersion( xStorage );
    1941                 :            :     // Oasis is also the default (0)
    1942 [ +  + ][ +  - ]:         28 :     sal_Bool bOasis = ( version > SOFFICE_FILEFORMAT_60 || version == 0 );
    1943                 :            :     const sal_Char *pServiceName = bOasis
    1944                 :            :         ? "com.sun.star.document.XMLOasisMetaImporter"
    1945         [ +  - ]:         28 :         : "com.sun.star.document.XMLMetaImporter";
    1946                 :            : 
    1947                 :            :     // set base URL
    1948                 :            :     css::uno::Reference<css::beans::XPropertySet> xPropArg =
    1949         [ +  - ]:         28 :         getURLProperties(Medium);
    1950                 :            :     try {
    1951         [ +  - ]:         28 :         xPropArg->getPropertyValue(::rtl::OUString("BaseURI"))
    1952 [ +  + ][ -  + ]:         28 :             >>= input.sSystemId;
    1953                 :            :         input.sSystemId += ::rtl::OUString("/").concat(
    1954                 :         20 :                 ::rtl::OUString(s_meta));
    1955         [ +  - ]:         16 :     } catch (const css::uno::Exception &) {
    1956                 :          8 :         input.sSystemId = ::rtl::OUString(s_meta);
    1957                 :            :     }
    1958         [ +  - ]:         28 :     css::uno::Sequence< css::uno::Any > args(1);
    1959 [ +  - ][ +  - ]:         28 :     args[0] <<= xPropArg;
    1960                 :            : 
    1961                 :            :     css::uno::Reference<css::xml::sax::XDocumentHandler> xDocHandler (
    1962         [ +  - ]:         28 :         xMsf->createInstanceWithArgumentsAndContext(
    1963                 :         28 :             ::rtl::OUString::createFromAscii(pServiceName), args, m_xContext),
    1964 [ +  - ][ +  - ]:         28 :         css::uno::UNO_QUERY_THROW);
    1965         [ -  + ]:         28 :     if (!xDocHandler.is()) throw css::uno::RuntimeException(
    1966                 :            :         ::rtl::OUString("SfxDocumentMetaData::loadFromStorage:"
    1967 [ #  # ][ #  # ]:          0 :                 " cannot create XMLOasisMetaImporter service"), *this);
    1968                 :            :     css::uno::Reference<css::document::XImporter> xImp (xDocHandler,
    1969         [ +  - ]:         28 :         css::uno::UNO_QUERY_THROW);
    1970 [ +  - ][ +  - ]:         28 :     xImp->setTargetDocument(css::uno::Reference<css::lang::XComponent>(this));
                 [ +  - ]
    1971 [ +  - ][ +  - ]:         28 :     xParser->setDocumentHandler(xDocHandler);
    1972                 :            :     try {
    1973 [ +  - ][ +  - ]:         28 :         xParser->parseStream(input);
    1974         [ #  # ]:          0 :     } catch (const css::xml::sax::SAXException &) {
    1975                 :            :         throw css::io::WrongFormatException(::rtl::OUString(
    1976                 :            :                 "SfxDocumentMetaData::loadFromStorage:"
    1977   [ #  #  #  # ]:          0 :                 " XML parsing exception"), *this);
    1978                 :            :     }
    1979                 :            :     // NB: the implementation of XMLOasisMetaImporter calls initialize
    1980 [ +  - ][ +  - ]:         28 :     checkInit();
         [ +  - ][ +  - ]
    1981                 :         28 : }
    1982                 :            : 
    1983                 :            : void SAL_CALL
    1984                 :          6 : SfxDocumentMetaData::storeToStorage(
    1985                 :            :         const css::uno::Reference< css::embed::XStorage > & xStorage,
    1986                 :            :         const css::uno::Sequence< css::beans::PropertyValue > & Medium)
    1987                 :            :     throw (css::uno::RuntimeException, css::lang::IllegalArgumentException,
    1988                 :            :            css::lang::WrappedTargetException, css::io::IOException)
    1989                 :            : {
    1990         [ -  + ]:          6 :     if (!xStorage.is()) throw css::lang::IllegalArgumentException(
    1991                 :            :         ::rtl::OUString("SfxDocumentMetaData::storeToStorage:"
    1992 [ #  # ][ #  # ]:          0 :                 " argument is null"), *this, 0);
    1993         [ +  - ]:          6 :     ::osl::MutexGuard g(m_aMutex);
    1994         [ +  - ]:          6 :     checkInit();
    1995                 :            : 
    1996                 :            :     // update user-defined meta data in DOM tree
    1997                 :            : //    updateUserDefinedAndAttributes(); // this will be done in serialize!
    1998                 :            : 
    1999                 :            :     // write into storage
    2000                 :            :     css::uno::Reference<css::io::XStream> xStream =
    2001         [ +  - ]:          6 :         xStorage->openStreamElement(::rtl::OUString(s_meta),
    2002                 :            :             css::embed::ElementModes::WRITE
    2003         [ +  - ]:          6 :             | css::embed::ElementModes::TRUNCATE);
    2004 [ #  # ][ -  + ]:          6 :     if (!xStream.is()) throw css::uno::RuntimeException();
    2005                 :            :     css::uno::Reference< css::beans::XPropertySet > xStreamProps(xStream,
    2006         [ +  - ]:          6 :         css::uno::UNO_QUERY_THROW);
    2007         [ +  - ]:          6 :     xStreamProps->setPropertyValue(
    2008                 :            :         ::rtl::OUString("MediaType"),
    2009 [ +  - ][ +  - ]:          6 :         css::uno::makeAny(::rtl::OUString("text/xml")));
    2010         [ +  - ]:          6 :     xStreamProps->setPropertyValue(
    2011                 :            :         ::rtl::OUString("Compressed"),
    2012 [ +  - ][ +  - ]:          6 :         css::uno::makeAny(static_cast<sal_Bool> (sal_False)));
    2013         [ +  - ]:          6 :     xStreamProps->setPropertyValue(
    2014                 :            :         ::rtl::OUString("UseCommonStoragePasswordEncryption"),
    2015 [ +  - ][ +  - ]:          6 :         css::uno::makeAny(static_cast<sal_Bool> (sal_False)));
    2016                 :            :     css::uno::Reference<css::io::XOutputStream> xOutStream =
    2017 [ +  - ][ +  - ]:          6 :         xStream->getOutputStream();
    2018 [ -  + ][ #  # ]:          6 :     if (!xOutStream.is()) throw css::uno::RuntimeException();
    2019                 :            :     css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
    2020 [ +  - ][ +  - ]:          6 :         m_xContext->getServiceManager());
    2021                 :            :     css::uno::Reference<css::io::XActiveDataSource> xSaxWriter(
    2022         [ +  - ]:          6 :         xMsf->createInstanceWithContext(::rtl::OUString(
    2023                 :          6 :                 "com.sun.star.xml.sax.Writer"), m_xContext),
    2024 [ +  - ][ +  - ]:          6 :         css::uno::UNO_QUERY_THROW);
    2025 [ +  - ][ +  - ]:          6 :     xSaxWriter->setOutputStream(xOutStream);
    2026                 :            :     css::uno::Reference<css::xml::sax::XDocumentHandler> xDocHandler (
    2027         [ +  - ]:          6 :         xSaxWriter, css::uno::UNO_QUERY_THROW);
    2028                 :            : 
    2029         [ +  - ]:          6 :     const sal_uInt64 version = SotStorage::GetVersion( xStorage );
    2030                 :            :     // Oasis is also the default (0)
    2031 [ -  + ][ #  # ]:          6 :     const sal_Bool bOasis = ( version > SOFFICE_FILEFORMAT_60 || version == 0 );
    2032                 :            :     const sal_Char *pServiceName = bOasis
    2033                 :            :         ? "com.sun.star.document.XMLOasisMetaExporter"
    2034         [ +  - ]:          6 :         : "com.sun.star.document.XMLMetaExporter";
    2035                 :            : 
    2036                 :            :     // set base URL
    2037                 :            :     css::uno::Reference<css::beans::XPropertySet> xPropArg =
    2038         [ +  - ]:          6 :         getURLProperties(Medium);
    2039         [ +  - ]:          6 :     css::uno::Sequence< css::uno::Any > args(2);
    2040 [ +  - ][ +  - ]:          6 :     args[0] <<= xDocHandler;
    2041 [ +  - ][ +  - ]:          6 :     args[1] <<= xPropArg;
    2042                 :            : 
    2043                 :            :     css::uno::Reference<css::document::XExporter> xExp(
    2044         [ +  - ]:          6 :         xMsf->createInstanceWithArgumentsAndContext(
    2045                 :          6 :             ::rtl::OUString::createFromAscii(pServiceName), args, m_xContext),
    2046 [ +  - ][ +  - ]:          6 :         css::uno::UNO_QUERY_THROW);
    2047 [ +  - ][ +  - ]:          6 :     xExp->setSourceDocument(css::uno::Reference<css::lang::XComponent>(this));
                 [ +  - ]
    2048                 :            :     css::uno::Reference<css::document::XFilter> xFilter(xExp,
    2049         [ +  - ]:          6 :         css::uno::UNO_QUERY_THROW);
    2050 [ +  - ][ +  - ]:          6 :     if (xFilter->filter(css::uno::Sequence< css::beans::PropertyValue >())) {
         [ +  - ][ +  - ]
                 [ +  - ]
    2051                 :            :         css::uno::Reference<css::embed::XTransactedObject> xTransaction(
    2052         [ +  - ]:          6 :             xStorage, css::uno::UNO_QUERY);
    2053         [ +  - ]:          6 :         if (xTransaction.is()) {
    2054 [ +  - ][ +  - ]:          6 :             xTransaction->commit();
    2055                 :          6 :         }
    2056                 :            :     } else {
    2057                 :            :         throw css::io::IOException(::rtl::OUString(
    2058 [ #  # ][ #  # ]:          0 :                 "SfxDocumentMetaData::storeToStorage: cannot filter"), *this);
    2059 [ +  - ][ +  - ]:          6 :     }
    2060                 :          6 : }
    2061                 :            : 
    2062                 :            : void SAL_CALL
    2063                 :          8 : SfxDocumentMetaData::loadFromMedium(const ::rtl::OUString & URL,
    2064                 :            :         const css::uno::Sequence< css::beans::PropertyValue > & Medium)
    2065                 :            :     throw (css::uno::RuntimeException, css::io::WrongFormatException,
    2066                 :            :            css::lang::WrappedTargetException, css::io::IOException)
    2067                 :            : {
    2068                 :          8 :     css::uno::Reference<css::io::XInputStream> xIn;
    2069         [ +  - ]:          8 :     ::comphelper::MediaDescriptor md(Medium);
    2070                 :            :     // if we have an URL parameter, it replaces the one in the media descriptor
    2071         [ +  + ]:          8 :     if (!URL.isEmpty()) {
    2072 [ +  - ][ +  - ]:          6 :         md[ ::comphelper::MediaDescriptor::PROP_URL() ] <<= URL;
                 [ +  - ]
    2073                 :            :     }
    2074 [ +  - ][ +  - ]:          8 :     if (sal_True == md.addInputStream()) {
    2075 [ +  - ][ +  - ]:          8 :         md[ ::comphelper::MediaDescriptor::PROP_INPUTSTREAM() ] >>= xIn;
                 [ +  - ]
    2076                 :            :     }
    2077                 :          8 :     css::uno::Reference<css::embed::XStorage> xStorage;
    2078                 :            :     css::uno::Reference<css::lang::XMultiServiceFactory> xMsf (
    2079 [ +  - ][ +  - ]:          8 :         m_xContext->getServiceManager(), css::uno::UNO_QUERY_THROW);
                 [ +  - ]
    2080                 :            :     try {
    2081         [ +  - ]:          8 :         if (xIn.is()) {
    2082                 :            :             xStorage = ::comphelper::OStorageHelper::GetStorageFromInputStream(
    2083 [ +  - ][ +  - ]:          8 :                             xIn, xMsf);
    2084                 :            :         } else { // fallback to url parameter
    2085                 :            :             xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
    2086 [ #  # ][ #  # ]:          0 :                             URL, css::embed::ElementModes::READ, xMsf);
    2087                 :            :         }
    2088                 :          0 :     } catch (const css::uno::RuntimeException &) {
    2089                 :          0 :         throw;
    2090                 :          0 :     } catch (const css::io::IOException &) {
    2091                 :          0 :         throw;
    2092   [ #  #  #  # ]:          0 :     } catch (const css::uno::Exception & e) {
    2093                 :            :         throw css::lang::WrappedTargetException(
    2094                 :            :                 ::rtl::OUString(
    2095                 :            :                     "SfxDocumentMetaData::loadFromMedium: exception"),
    2096                 :            :                 css::uno::Reference<css::uno::XInterface>(*this),
    2097   [ #  #  #  #  :          0 :                 css::uno::makeAny(e));
                   #  # ]
    2098                 :            :     }
    2099         [ -  + ]:          8 :     if (!xStorage.is()) {
    2100                 :            :         throw css::uno::RuntimeException(::rtl::OUString(
    2101                 :            :                 "SfxDocumentMetaData::loadFromMedium: cannot get Storage"),
    2102 [ #  # ][ #  # ]:          0 :                 *this);
    2103                 :            :     }
    2104 [ +  - ][ +  - ]:          8 :     loadFromStorage(xStorage, md.getAsConstPropertyValueList());
         [ +  - ][ +  - ]
    2105                 :          8 : }
    2106                 :            : 
    2107                 :            : void SAL_CALL
    2108                 :          6 : SfxDocumentMetaData::storeToMedium(const ::rtl::OUString & URL,
    2109                 :            :         const css::uno::Sequence< css::beans::PropertyValue > & Medium)
    2110                 :            :     throw (css::uno::RuntimeException,
    2111                 :            :            css::lang::WrappedTargetException, css::io::IOException)
    2112                 :            : {
    2113         [ +  - ]:          6 :     ::comphelper::MediaDescriptor md(Medium);
    2114         [ +  + ]:          6 :     if (!URL.isEmpty()) {
    2115 [ +  - ][ +  - ]:          4 :         md[ ::comphelper::MediaDescriptor::PROP_URL() ] <<= URL;
                 [ +  - ]
    2116                 :            :     }
    2117 [ +  - ][ +  - ]:          6 :     SfxMedium aMedium(md.getAsConstPropertyValueList());
                 [ +  - ]
    2118                 :            :     css::uno::Reference<css::embed::XStorage> xStorage
    2119         [ +  - ]:          6 :         = aMedium.GetOutputStorage();
    2120                 :            : 
    2121                 :            : 
    2122         [ -  + ]:          6 :     if (!xStorage.is()) {
    2123                 :            :         throw css::uno::RuntimeException(::rtl::OUString(
    2124                 :            :                 "SfxDocumentMetaData::storeToMedium: cannot get Storage"),
    2125 [ #  # ][ #  # ]:          0 :                 *this);
    2126                 :            :     }
    2127                 :            :     // set MIME type of the storage
    2128                 :            :     ::comphelper::MediaDescriptor::const_iterator iter
    2129 [ +  - ][ +  - ]:          6 :         = md.find(::comphelper::MediaDescriptor::PROP_MEDIATYPE());
    2130 [ +  - ][ +  - ]:          6 :     if (iter != md.end()) {
    2131                 :            :         css::uno::Reference< css::beans::XPropertySet > xProps(xStorage,
    2132         [ +  - ]:          6 :             css::uno::UNO_QUERY_THROW);
    2133         [ +  - ]:          6 :         xProps->setPropertyValue(
    2134         [ +  - ]:          6 :             ::comphelper::MediaDescriptor::PROP_MEDIATYPE(),
    2135 [ +  - ][ +  - ]:         12 :             iter->second);
    2136                 :            :     }
    2137 [ +  - ][ +  - ]:          6 :     storeToStorage(xStorage, md.getAsConstPropertyValueList());
                 [ +  - ]
    2138                 :            : 
    2139                 :            : 
    2140         [ +  - ]:          6 :     const sal_Bool bOk = aMedium.Commit();
    2141         [ +  - ]:          6 :     aMedium.Close();
    2142         [ -  + ]:          6 :     if ( !bOk ) {
    2143         [ #  # ]:          0 :         sal_uInt32 nError = aMedium.GetError();
    2144         [ #  # ]:          0 :         if ( nError == ERRCODE_NONE ) {
    2145                 :          0 :             nError = ERRCODE_IO_GENERAL;
    2146                 :            :         }
    2147                 :            : 
    2148                 :            :         throw css::task::ErrorCodeIOException( ::rtl::OUString(),
    2149         [ #  # ]:          0 :                 css::uno::Reference< css::uno::XInterface >(), nError);
    2150                 :            : 
    2151 [ +  - ][ +  - ]:          6 :     }
    2152                 :          6 : }
    2153                 :            : 
    2154                 :            : // ::com::sun::star::lang::XInitialization:
    2155                 :            : void SAL_CALL
    2156                 :        197 : SfxDocumentMetaData::initialize(
    2157                 :            :         const css::uno::Sequence< ::com::sun::star::uno::Any > & aArguments)
    2158                 :            :     throw (css::uno::RuntimeException, css::uno::Exception)
    2159                 :            : {
    2160                 :            :     // possible arguments:
    2161                 :            :     // - no argument: default initialization (empty DOM)
    2162                 :            :     // - 1 argument, XDocument: initialize with given DOM and empty base URL
    2163                 :            :     // NB: links in document must be absolute
    2164                 :            : 
    2165         [ +  - ]:        197 :     ::osl::MutexGuard g(m_aMutex);
    2166                 :        197 :     css::uno::Reference<css::xml::dom::XDocument> xDoc;
    2167                 :            : 
    2168         [ +  + ]:        392 :     for (sal_Int32 i = 0; i < aArguments.getLength(); ++i) {
    2169                 :        195 :         const css::uno::Any any = aArguments[i];
    2170 [ +  - ][ +  - ]:        195 :         if (any >>= xDoc) {
    2171         [ -  + ]:        195 :             if (!xDoc.is()) {
    2172                 :            :                 throw css::lang::IllegalArgumentException(
    2173                 :            :                     ::rtl::OUString("SfxDocumentMetaData::"
    2174                 :            :                         "initialize: argument is null"),
    2175 [ #  # ][ #  # ]:          0 :                     *this, static_cast<sal_Int16>(i));
    2176                 :            :             }
    2177                 :            :         } else {
    2178                 :            :             throw css::lang::IllegalArgumentException(
    2179                 :            :                 ::rtl::OUString("SfxDocumentMetaData::"
    2180                 :            :                     "initialize: argument must be XDocument"),
    2181 [ #  # ][ #  # ]:          0 :                 *this, static_cast<sal_Int16>(i));
    2182                 :            :         }
    2183                 :        195 :     }
    2184                 :            : 
    2185         [ +  + ]:        197 :     if (!xDoc.is()) {
    2186                 :            :         // For a new document, we create a new DOM tree here.
    2187 [ +  - ][ +  - ]:          2 :         xDoc = createDOM();
    2188                 :            :     }
    2189                 :            : 
    2190 [ +  - ][ +  - ]:        197 :     init(xDoc);
    2191                 :        197 : }
    2192                 :            : 
    2193                 :            : // ::com::sun::star::util::XCloneable:
    2194                 :            : css::uno::Reference<css::util::XCloneable> SAL_CALL
    2195                 :        159 : SfxDocumentMetaData::createClone()
    2196                 :            :     throw (css::uno::RuntimeException)
    2197                 :            : {
    2198         [ +  - ]:        159 :     ::osl::MutexGuard g(m_aMutex);
    2199         [ +  - ]:        159 :     checkInit();
    2200                 :            : 
    2201         [ +  - ]:        159 :     SfxDocumentMetaData *pNew = createMe(m_xContext);
    2202                 :            : 
    2203                 :            :     // NB: do not copy the modification listeners, only DOM
    2204         [ +  - ]:        159 :     css::uno::Reference<css::xml::dom::XDocument> xDoc = createDOM();
    2205                 :            :     try {
    2206         [ +  - ]:        159 :         updateUserDefinedAndAttributes();
    2207                 :            :         // deep copy of root node
    2208                 :            :         css::uno::Reference<css::xml::dom::XNode> xRoot(
    2209 [ +  - ][ +  - ]:        159 :             m_xDoc->getDocumentElement(), css::uno::UNO_QUERY_THROW);
                 [ +  - ]
    2210                 :            :         css::uno::Reference<css::xml::dom::XNode> xRootNew(
    2211 [ +  - ][ +  - ]:        159 :             xDoc->importNode(xRoot, true));
    2212 [ +  - ][ +  - ]:        159 :         xDoc->appendChild(xRootNew);
    2213         [ +  - ]:        159 :         pNew->init(xDoc);
    2214                 :          0 :     } catch (const css::uno::RuntimeException &) {
    2215                 :          0 :         throw;
    2216      [ #  #  # ]:          0 :     } catch (const css::uno::Exception & e) {
    2217         [ #  # ]:          0 :         css::uno::Any a(e);
    2218                 :            :         throw css::lang::WrappedTargetRuntimeException(
    2219                 :            :                 ::rtl::OUString(
    2220                 :            :                     "SfxDocumentMetaData::createClone: exception"),
    2221   [ #  #  #  # ]:          0 :                 css::uno::Reference<css::uno::XInterface>(*this), a);
    2222                 :            :     }
    2223 [ +  - ][ +  - ]:        159 :     return css::uno::Reference<css::util::XCloneable> (pNew);
                 [ +  - ]
    2224                 :            : }
    2225                 :            : 
    2226                 :            : // ::com::sun::star::util::XModifiable:
    2227                 :          0 : ::sal_Bool SAL_CALL SfxDocumentMetaData::isModified(  )
    2228                 :            :         throw (css::uno::RuntimeException)
    2229                 :            : {
    2230         [ #  # ]:          0 :     ::osl::MutexGuard g(m_aMutex);
    2231         [ #  # ]:          0 :     checkInit();
    2232                 :            :     css::uno::Reference<css::util::XModifiable> xMB(m_xUserDefined,
    2233         [ #  # ]:          0 :         css::uno::UNO_QUERY);
    2234 [ #  # ][ #  # ]:          0 :     return m_isModified || (xMB.is() ? xMB->isModified() : sal_False);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    2235                 :            : }
    2236                 :            : 
    2237                 :       5830 : void SAL_CALL SfxDocumentMetaData::setModified( ::sal_Bool bModified )
    2238                 :            :         throw (css::beans::PropertyVetoException, css::uno::RuntimeException)
    2239                 :            : {
    2240                 :       5830 :     css::uno::Reference<css::util::XModifiable> xMB;
    2241                 :            :     { // do not lock mutex while notifying (#i93514#) to prevent deadlock
    2242         [ +  - ]:       5830 :         ::osl::MutexGuard g(m_aMutex);
    2243         [ +  - ]:       5830 :         checkInit();
    2244                 :       5830 :         m_isModified = bModified;
    2245 [ -  + ][ #  # ]:       5830 :         if ( !bModified && m_xUserDefined.is() )
                 [ -  + ]
    2246                 :            :         {
    2247         [ #  # ]:          0 :             xMB.set(m_xUserDefined, css::uno::UNO_QUERY);
    2248                 :            :             DBG_ASSERT(xMB.is(),
    2249                 :            :                 "SfxDocumentMetaData::setModified: PropertyBag not Modifiable?");
    2250         [ +  - ]:       5830 :         }
    2251                 :            :     }
    2252         [ +  - ]:       5830 :     if (bModified) {
    2253                 :            :         try {
    2254         [ +  - ]:       5830 :             css::uno::Reference<css::uno::XInterface> xThis(*this);
    2255         [ +  - ]:       5830 :             css::lang::EventObject event(xThis);
    2256                 :            :             m_NotifyListeners.notifyEach(&css::util::XModifyListener::modified,
    2257 [ +  - ][ +  - ]:       5830 :                 event);
    2258      [ #  #  # ]:          0 :         } catch (const css::uno::RuntimeException &) {
    2259                 :          0 :             throw;
    2260         [ #  # ]:          0 :         } catch (const css::uno::Exception & e) {
    2261                 :            :             // ignore
    2262                 :            :             DBG_WARNING1("SfxDocumentMetaData::setModified: exception:\n%s",
    2263                 :            :                 OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
    2264                 :            :             (void) e;
    2265                 :            :         }
    2266                 :            :     } else {
    2267         [ #  # ]:          0 :         if (xMB.is()) {
    2268 [ #  # ][ #  # ]:          0 :             xMB->setModified(false);
    2269                 :            :         }
    2270                 :       5830 :     }
    2271                 :       5830 : }
    2272                 :            : 
    2273                 :            : // ::com::sun::star::util::XModifyBroadcaster:
    2274                 :       2422 : void SAL_CALL SfxDocumentMetaData::addModifyListener(
    2275                 :            :         const css::uno::Reference< css::util::XModifyListener > & xListener)
    2276                 :            :         throw (css::uno::RuntimeException)
    2277                 :            : {
    2278         [ +  - ]:       2422 :     ::osl::MutexGuard g(m_aMutex);
    2279         [ +  - ]:       2422 :     checkInit();
    2280         [ +  - ]:       2422 :     m_NotifyListeners.addInterface(xListener);
    2281                 :            :     css::uno::Reference<css::util::XModifyBroadcaster> xMB(m_xUserDefined,
    2282         [ +  - ]:       2422 :         css::uno::UNO_QUERY);
    2283         [ +  + ]:       2422 :     if (xMB.is()) {
    2284 [ +  - ][ +  - ]:          2 :         xMB->addModifyListener(xListener);
    2285         [ +  - ]:       2422 :     }
    2286                 :       2422 : }
    2287                 :            : 
    2288                 :          2 : void SAL_CALL SfxDocumentMetaData::removeModifyListener(
    2289                 :            :         const css::uno::Reference< css::util::XModifyListener > & xListener)
    2290                 :            :         throw (css::uno::RuntimeException)
    2291                 :            : {
    2292         [ +  - ]:          2 :     ::osl::MutexGuard g(m_aMutex);
    2293         [ +  - ]:          2 :     checkInit();
    2294         [ +  - ]:          2 :     m_NotifyListeners.removeInterface(xListener);
    2295                 :            :     css::uno::Reference<css::util::XModifyBroadcaster> xMB(m_xUserDefined,
    2296         [ +  - ]:          2 :         css::uno::UNO_QUERY);
    2297         [ +  - ]:          2 :     if (xMB.is()) {
    2298 [ +  - ][ +  - ]:          2 :         xMB->removeModifyListener(xListener);
    2299         [ +  - ]:          2 :     }
    2300                 :          2 : }
    2301                 :            : 
    2302                 :            : // ::com::sun::star::xml::sax::XSAXSerializable
    2303                 :         50 : void SAL_CALL SfxDocumentMetaData::serialize(
    2304                 :            :     const css::uno::Reference<css::xml::sax::XDocumentHandler>& i_xHandler,
    2305                 :            :     const css::uno::Sequence< css::beans::StringPair >& i_rNamespaces)
    2306                 :            :     throw (css::uno::RuntimeException, css::xml::sax::SAXException)
    2307                 :            : {
    2308         [ +  - ]:         50 :     ::osl::MutexGuard g(m_aMutex);
    2309         [ +  - ]:         50 :     checkInit();
    2310         [ +  - ]:         50 :     updateUserDefinedAndAttributes();
    2311                 :            :     css::uno::Reference<css::xml::sax::XSAXSerializable> xSAXable(m_xDoc,
    2312         [ +  - ]:         50 :         css::uno::UNO_QUERY_THROW);
    2313 [ +  - ][ +  - ]:         50 :     xSAXable->serialize(i_xHandler, i_rNamespaces);
                 [ +  - ]
    2314                 :         50 : }
    2315                 :            : 
    2316                 :       1310 : void SfxDocumentMetaData::createUserDefined()
    2317                 :            : {
    2318                 :            :     // user-defined meta data: create PropertyBag which only accepts property
    2319                 :            :     // values of allowed types
    2320         [ +  + ]:       1310 :     if ( !m_xUserDefined.is() )
    2321                 :            :     {
    2322         [ +  - ]:        536 :         css::uno::Sequence<css::uno::Type> types(11);
    2323         [ +  - ]:        536 :         types[0] = ::cppu::UnoType<bool>::get();
    2324         [ +  - ]:        536 :         types[1] = ::cppu::UnoType< ::rtl::OUString>::get();
    2325         [ +  - ]:        536 :         types[2] = ::cppu::UnoType<css::util::DateTime>::get();
    2326         [ +  - ]:        536 :         types[3] = ::cppu::UnoType<css::util::Date>::get();
    2327         [ +  - ]:        536 :         types[4] = ::cppu::UnoType<css::util::Duration>::get();
    2328         [ +  - ]:        536 :         types[5] = ::cppu::UnoType<float>::get();
    2329         [ +  - ]:        536 :         types[6] = ::cppu::UnoType<double>::get();
    2330         [ +  - ]:        536 :         types[7] = ::cppu::UnoType<sal_Int16>::get();
    2331         [ +  - ]:        536 :         types[8] = ::cppu::UnoType<sal_Int32>::get();
    2332         [ +  - ]:        536 :         types[9] = ::cppu::UnoType<sal_Int64>::get();
    2333                 :            :         // Time is supported for backward compatibility with OOo 3.x, x<=2
    2334         [ +  - ]:        536 :         types[10] = ::cppu::UnoType<css::util::Time>::get();
    2335         [ +  - ]:        536 :         css::uno::Sequence<css::uno::Any> args(2);
    2336         [ +  - ]:        536 :         args[0] <<= css::beans::NamedValue(
    2337                 :            :             ::rtl::OUString("AllowedTypes"),
    2338 [ +  - ][ +  - ]:       1072 :             css::uno::makeAny(types));
    2339                 :            :         // #i94175#:  ODF allows empty user-defined property names!
    2340         [ +  - ]:        536 :         args[1] <<= css::beans::NamedValue( ::rtl::OUString(
    2341                 :            :                         "AllowEmptyPropertyName"),
    2342 [ +  - ][ +  - ]:       1072 :             css::uno::makeAny(sal_True));
    2343                 :            : 
    2344                 :            :         const css::uno::Reference<css::lang::XMultiComponentFactory> xMsf(
    2345 [ +  - ][ +  - ]:        536 :                 m_xContext->getServiceManager());
    2346                 :            :         m_xUserDefined.set(
    2347         [ +  - ]:        536 :             xMsf->createInstanceWithContext(
    2348                 :            :                 ::rtl::OUString(
    2349                 :        536 :                     "com.sun.star.beans.PropertyBag"), m_xContext),
    2350 [ +  - ][ +  - ]:        536 :             css::uno::UNO_QUERY_THROW);
    2351                 :            :         const css::uno::Reference<css::lang::XInitialization> xInit(
    2352         [ +  - ]:        536 :             m_xUserDefined, css::uno::UNO_QUERY);
    2353         [ +  - ]:        536 :         if (xInit.is()) {
    2354 [ +  - ][ +  - ]:        536 :             xInit->initialize(args);
    2355                 :            :         }
    2356                 :            : 
    2357                 :            :         const css::uno::Reference<css::util::XModifyBroadcaster> xMB(
    2358         [ +  - ]:        536 :             m_xUserDefined, css::uno::UNO_QUERY);
    2359         [ +  - ]:        536 :         if (xMB.is())
    2360                 :            :         {
    2361                 :            :             const css::uno::Sequence<css::uno::Reference<css::uno::XInterface> >
    2362         [ +  - ]:        536 :                 listeners(m_NotifyListeners.getElements());
    2363         [ +  + ]:       1964 :             for (css::uno::Reference< css::uno::XInterface > const * iter =
    2364         [ +  - ]:        536 :                                 ::comphelper::stl_begin(listeners);
    2365         [ +  - ]:        982 :                         iter != ::comphelper::stl_end(listeners); ++iter) {
    2366         [ +  - ]:        446 :                 xMB->addModifyListener(
    2367                 :            :                     css::uno::Reference< css::util::XModifyListener >(*iter,
    2368 [ +  - ][ +  - ]:        446 :                         css::uno::UNO_QUERY));
    2369         [ +  - ]:        536 :             }
    2370 [ +  - ][ +  - ]:        536 :         }
    2371                 :            :     }
    2372                 :       1310 : }
    2373                 :            : 
    2374                 :            : } // closing anonymous implementation namespace
    2375                 :            : 
    2376                 :            : 
    2377                 :            : // component helper namespace
    2378                 :            : namespace comp_CompatWriterDocProps {
    2379                 :            : 
    2380                 :        546 :     ::rtl::OUString SAL_CALL _getImplementationName() {
    2381                 :            :         return ::rtl::OUString(
    2382                 :        546 :             "CompatWriterDocPropsImpl");
    2383                 :            : }
    2384                 :            : 
    2385                 :          0 :    css::uno::Sequence< ::rtl::OUString > SAL_CALL _getSupportedServiceNames()
    2386                 :            :    {
    2387                 :          0 :         css::uno::Sequence< rtl::OUString > aServiceNames(1);
    2388         [ #  # ]:          0 :         aServiceNames[ 0 ] = rtl::OUString( "com.sun.star.writer.DocumentProperties"  );
    2389                 :          0 :         return aServiceNames;
    2390                 :            :    }
    2391                 :          0 :     css::uno::Reference< css::uno::XInterface > SAL_CALL _create(
    2392                 :            :         const css::uno::Reference< css::uno::XComponentContext > & context)
    2393                 :            :             SAL_THROW((css::uno::Exception))
    2394                 :            :     {
    2395                 :            :         return static_cast< ::cppu::OWeakObject * >
    2396         [ #  # ]:          0 :                     (new CompatWriterDocPropsImpl(context));
    2397                 :            :     }
    2398                 :            : 
    2399                 :            : }
    2400                 :            : namespace comp_SfxDocumentMetaData {
    2401                 :            : 
    2402                 :        673 : ::rtl::OUString SAL_CALL _getImplementationName() {
    2403                 :            :     return ::rtl::OUString(
    2404                 :        673 :         "SfxDocumentMetaData");
    2405                 :            : }
    2406                 :            : 
    2407                 :        127 : css::uno::Sequence< ::rtl::OUString > SAL_CALL _getSupportedServiceNames()
    2408                 :            : {
    2409                 :        127 :     css::uno::Sequence< ::rtl::OUString > s(1);
    2410         [ +  - ]:        127 :     s[0] = ::rtl::OUString(
    2411                 :        254 :         "com.sun.star.document.DocumentProperties");
    2412                 :        127 :     return s;
    2413                 :            : }
    2414                 :            : 
    2415                 :       2473 : css::uno::Reference< css::uno::XInterface > SAL_CALL _create(
    2416                 :            :     const css::uno::Reference< css::uno::XComponentContext > & context)
    2417                 :            :         SAL_THROW((css::uno::Exception))
    2418                 :            : {
    2419                 :            :     return static_cast< ::cppu::OWeakObject * >
    2420         [ +  - ]:       2473 :                 (new SfxDocumentMetaData(context));
    2421                 :            : }
    2422                 :            : 
    2423                 :            : } // closing component helper namespace
    2424                 :            : 
    2425                 :            : static ::cppu::ImplementationEntry const entries[] = {
    2426                 :            :     { &comp_SfxDocumentMetaData::_create,
    2427                 :            :       &comp_SfxDocumentMetaData::_getImplementationName,
    2428                 :            :       &comp_SfxDocumentMetaData::_getSupportedServiceNames,
    2429                 :            :       &::cppu::createSingleComponentFactory, 0, 0 },
    2430                 :            :     { 0, 0, 0, 0, 0, 0 }
    2431                 :            : };
    2432                 :            : 
    2433                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10