LCOV - code coverage report
Current view: top level - sfx2/source/doc - SfxDocumentMetaData.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 866 990 87.5 %
Date: 2015-06-13 12:38:46 Functions: 91 107 85.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11