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

Generated by: LCOV version 1.10