LCOV - code coverage report
Current view: top level - sfx2/source/doc - SfxDocumentMetaData.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 862 992 86.9 %
Date: 2014-11-03 Functions: 89 107 83.2 %
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       16686 :     virtual ~SfxDocumentMetaData() {}
     292        1096 :     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          32 : bool operator== (const css::util::DateTime &i_rLeft,
     396             :                  const css::util::DateTime &i_rRight)
     397             : {
     398          32 :     return i_rLeft.Year             == i_rRight.Year
     399          30 :         && i_rLeft.Month            == i_rRight.Month
     400          30 :         && i_rLeft.Day              == i_rRight.Day
     401          30 :         && i_rLeft.Hours            == i_rRight.Hours
     402          30 :         && i_rLeft.Minutes          == i_rRight.Minutes
     403          30 :         && i_rLeft.Seconds          == i_rRight.Seconds
     404          30 :         && i_rLeft.NanoSeconds      == i_rRight.NanoSeconds
     405          62 :         && 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           2 : bool isValidDate(const css::util::Date & i_rDate)
     484             : {
     485           2 :     return i_rDate.Month > 0;
     486             : }
     487             : 
     488       10836 : bool isValidDateTime(const css::util::DateTime & i_rDateTime)
     489             : {
     490       10836 :     return i_rDateTime.Month > 0;
     491             : }
     492             : 
     493             : std::pair< OUString, OUString > SAL_CALL
     494      448341 : getQualifier(const char* i_name) {
     495      448341 :     OUString nm = OUString::createFromAscii(i_name);
     496      448341 :     sal_Int32 ix = nm.indexOf(static_cast<sal_Unicode> (':'));
     497      448341 :     if (ix == -1) {
     498           0 :         return std::make_pair(OUString(), nm);
     499             :     } else {
     500      448341 :         return std::make_pair(nm.copy(0,ix), nm.copy(ix+1));
     501      448341 :     }
     502             : }
     503             : 
     504             : // get namespace for standard qualified names
     505             : // NB: only call this with statically known strings!
     506      265755 : OUString SAL_CALL getNameSpace(const char* i_qname) throw ()
     507             : {
     508             :     DBG_ASSERT(i_qname, "SfxDocumentMetaData: getNameSpace: argument is null");
     509      265755 :     const char * ns = "";
     510      265755 :     OUString n = getQualifier(i_qname).first;
     511      265755 :     if ( n == "xlink" ) ns = s_nsXLink;
     512      265755 :     if ( n == "dc" ) ns = s_nsDC;
     513      265755 :     if ( n == "office" ) ns = s_nsODF;
     514      265755 :     if ( n == "meta" ) ns = s_nsODFMeta;
     515             :     DBG_ASSERT(*ns, "SfxDocumentMetaData: unknown namespace prefix");
     516      265755 :     return OUString::createFromAscii(ns);
     517             : }
     518             : 
     519             : bool SAL_CALL
     520           8 : 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           8 :     if (::sax::Converter::parseDateOrDateTime(
     525             :                 &io_rd, io_rdt, o_rIsDateTime, &o_rTimeZone, i_text)) {
     526           8 :         return true;
     527             :     } else {
     528             :         SAL_WARN_IF(!i_text.isEmpty(), "sfx.doc", "Invalid date: " << i_text);
     529           0 :         return false;
     530             :     }
     531             : }
     532             : 
     533             : // convert string to date/time
     534             : bool SAL_CALL
     535       21420 : textToDateTime(css::util::DateTime & io_rdt, const OUString& i_text) throw ()
     536             : {
     537       21420 :     if (::sax::Converter::parseDateTime(io_rdt, 0, i_text)) {
     538        2424 :         return true;
     539             :     } else {
     540             :         SAL_WARN_IF(!i_text.isEmpty(), "sfx.doc", "Invalid date: " << i_text);
     541       18996 :         return false;
     542             :     }
     543             : }
     544             : 
     545             : // convert string to date/time with default return value
     546             : css::util::DateTime SAL_CALL
     547       21420 : textToDateTimeDefault(const OUString& i_text) throw ()
     548             : {
     549       21420 :     css::util::DateTime dt;
     550       21420 :     static_cast<void> (textToDateTime(dt, i_text));
     551             :     // on conversion error: return default value (unchanged)
     552       21420 :     return dt;
     553             : }
     554             : 
     555             : // convert date to string
     556             : OUString SAL_CALL
     557           2 : dateToText(css::util::Date const& i_rd,
     558             :            sal_Int16 const*const pTimeZone = 0) throw ()
     559             : {
     560           2 :     if (isValidDate(i_rd)) {
     561           2 :         OUStringBuffer buf;
     562           2 :         ::sax::Converter::convertDate(buf, i_rd, pTimeZone);
     563           2 :         return buf.makeStringAndClear();
     564             :     } else {
     565           0 :         return OUString();
     566             :     }
     567             : }
     568             : 
     569             : 
     570             : // convert date/time to string
     571             : OUString SAL_CALL
     572        9116 : dateTimeToText(css::util::DateTime const& i_rdt,
     573             :                sal_Int16 const*const pTimeZone = 0) throw ()
     574             : {
     575        9116 :     if (isValidDateTime(i_rdt)) {
     576        8236 :         OUStringBuffer buf;
     577        8236 :         ::sax::Converter::convertDateTime(buf, i_rdt, pTimeZone, true);
     578        8236 :         return buf.makeStringAndClear();
     579             :     } else {
     580         880 :         return OUString();
     581             :     }
     582             : }
     583             : 
     584             : // convert string to duration
     585             : bool
     586       18756 : textToDuration(css::util::Duration& io_rDur, OUString const& i_rText)
     587             : throw ()
     588             : {
     589       18756 :     if (::sax::Converter::convertDuration(io_rDur, i_rText)) {
     590        1014 :         return true;
     591             :     } else {
     592             :         SAL_WARN_IF(!i_rText.isEmpty(), "sfx.doc", "Invalid duration: " << i_rText);
     593       17742 :         return false;
     594             :     }
     595             : }
     596             : 
     597       18752 : sal_Int32 textToDuration(OUString const& i_rText) throw ()
     598             : {
     599       18752 :     css::util::Duration d;
     600       18752 :     if (textToDuration(d, i_rText)) {
     601             :         // #i107372#: approximate years/months
     602        1010 :         const sal_Int32 days( (d.Years * 365) + (d.Months * 30) + d.Days );
     603        1010 :         return  (days * (24*3600))
     604        1010 :                 + (d.Hours * 3600) + (d.Minutes * 60) + d.Seconds;
     605             :     } else {
     606       17742 :         return 0; // default
     607             :     }
     608             : }
     609             : 
     610             : // convert duration to string
     611        3128 : OUString durationToText(css::util::Duration const& i_rDur) throw ()
     612             : {
     613        3128 :     OUStringBuffer buf;
     614        3128 :     ::sax::Converter::convertDuration(buf, i_rDur);
     615        3128 :     return buf.makeStringAndClear();
     616             : }
     617             : 
     618             : // convert duration to string
     619        3124 : OUString SAL_CALL durationToText(sal_Int32 i_value) throw ()
     620             : {
     621        3124 :     css::util::Duration ud;
     622        3124 :     ud.Days    = static_cast<sal_Int16>(i_value / (24 * 3600));
     623        3124 :     ud.Hours   = static_cast<sal_Int16>((i_value % (24 * 3600)) / 3600);
     624        3124 :     ud.Minutes = static_cast<sal_Int16>((i_value % 3600) / 60);
     625        3124 :     ud.Seconds = static_cast<sal_Int16>(i_value % 60);
     626        3124 :     ud.NanoSeconds = 0;
     627        3124 :     return durationToText(ud);
     628             : }
     629             : 
     630             : // extract base URL (necessary for converting relative links)
     631             : css::uno::Reference< css::beans::XPropertySet > SAL_CALL
     632          34 : SfxDocumentMetaData::getURLProperties(
     633             :     const css::uno::Sequence< css::beans::PropertyValue > & i_rMedium) const
     634             : {
     635          34 :     css::uno::Reference< css::beans::XPropertyBag> xPropArg = css::beans::PropertyBag::createDefault( m_xContext );
     636             :     try {
     637          34 :         css::uno::Any baseUri;
     638         160 :         for (sal_Int32 i = 0; i < i_rMedium.getLength(); ++i) {
     639         126 :             if (i_rMedium[i].Name == "DocumentBaseURL") {
     640           0 :                 baseUri = i_rMedium[i].Value;
     641         126 :             } else if (i_rMedium[i].Name == "URL") {
     642          34 :                 if (!baseUri.hasValue()) {
     643          34 :                     baseUri = i_rMedium[i].Value;
     644             :                 }
     645          92 :             } 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          34 :         if (baseUri.hasValue()) {
     653          34 :             xPropArg->addProperty(
     654             :                 "BaseURI", css::beans::PropertyAttribute::MAYBEVOID,
     655          34 :                 baseUri);
     656             :         }
     657          34 :         xPropArg->addProperty(OUString("StreamName"),
     658             :                 css::beans::PropertyAttribute::MAYBEVOID,
     659          34 :                 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          34 :                 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       21682 : getNodeText(css::uno::Reference<css::xml::dom::XNode> i_xNode)
     671             :         throw (css::uno::RuntimeException)
     672             : {
     673       21682 :     if (!i_xNode.is()) throw css::uno::RuntimeException(
     674           0 :         OUString("SfxDocumentMetaData::getNodeText: argument is null"), i_xNode);
     675       43364 :     for (css::uno::Reference<css::xml::dom::XNode> c = i_xNode->getFirstChild();
     676             :             c.is();
     677           0 :             c = c->getNextSibling()) {
     678       21464 :         if (c->getNodeType() == css::xml::dom::NodeType_TEXT_NODE) {
     679             :             try {
     680       21464 :                 return c->getNodeValue();
     681           0 :             } catch (const css::xml::dom::DOMException &) { // too big?
     682           0 :                 return OUString();
     683             :             }
     684             :         }
     685         218 :     }
     686         218 :     return OUString();
     687             : }
     688             : 
     689             : OUString SAL_CALL
     690       28332 : SfxDocumentMetaData::getMetaText(const char* i_name) const
     691             : //        throw (css::uno::RuntimeException)
     692             : {
     693       28332 :     checkInit();
     694             : 
     695       28332 :     const OUString name( OUString::createFromAscii(i_name) );
     696             :     DBG_ASSERT(m_meta.find(name) != m_meta.end(),
     697             :         "SfxDocumentMetaData::getMetaText: not found");
     698       56664 :     css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
     699       56664 :     return (xNode.is()) ? getNodeText(xNode) : OUString();
     700             : }
     701             : 
     702             : bool SAL_CALL
     703       29666 : SfxDocumentMetaData::setMetaText(const char* i_name,
     704             :         const OUString & i_rValue)
     705             :     // throw (css::uno::RuntimeException)
     706             : {
     707       29666 :     checkInit();
     708             : 
     709       29666 :     const OUString name( OUString::createFromAscii(i_name) );
     710             :     DBG_ASSERT(m_meta.find(name) != m_meta.end(),
     711             :         "SfxDocumentMetaData::setMetaText: not found");
     712       59332 :     css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
     713             : 
     714             :     try {
     715       29666 :         if (i_rValue.isEmpty()) {
     716        3126 :             if (xNode.is()) { // delete
     717          28 :                 m_xParent->removeChild(xNode);
     718          28 :                 xNode.clear();
     719          28 :                 m_meta[name] = xNode;
     720          28 :                 return true;
     721             :             } else {
     722        3098 :                 return false;
     723             :             }
     724             :         } else {
     725       26540 :             if (xNode.is()) { // update
     726        2280 :                 for (css::uno::Reference<css::xml::dom::XNode> c =
     727        1140 :                             xNode->getFirstChild();
     728             :                         c.is();
     729           0 :                         c = c->getNextSibling()) {
     730        1138 :                     if (c->getNodeType() == css::xml::dom::NodeType_TEXT_NODE) {
     731        1138 :                         if (!c->getNodeValue().equals(i_rValue)) {
     732         188 :                             c->setNodeValue(i_rValue);
     733         188 :                             return true;
     734             :                         } else {
     735         950 :                             return false;
     736             :                         }
     737             :                     }
     738           2 :                 }
     739             :             } else { // insert
     740       25400 :                 xNode.set(m_xDoc->createElementNS(getNameSpace(i_name), name),
     741       25400 :                             css::uno::UNO_QUERY_THROW);
     742       25400 :                 m_xParent->appendChild(xNode);
     743       25400 :                 m_meta[name] = xNode;
     744             :             }
     745             :             css::uno::Reference<css::xml::dom::XNode> xTextNode(
     746       25402 :                 m_xDoc->createTextNode(i_rValue), css::uno::UNO_QUERY_THROW);
     747       25402 :             xNode->appendChild(xTextNode);
     748       25402 :             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       29666 :     }
     756             : }
     757             : 
     758             : void SAL_CALL
     759       29602 : SfxDocumentMetaData::setMetaTextAndNotify(const char* i_name,
     760             :         const OUString & i_rValue)
     761             :     // throw (css::uno::RuntimeException)
     762             : {
     763       29602 :     ::osl::ClearableMutexGuard g(m_aMutex);
     764       29602 :     if (setMetaText(i_name, i_rValue)) {
     765       25572 :         g.clear();
     766       25572 :         setModified(true);
     767       29602 :     }
     768       29602 : }
     769             : 
     770             : OUString SAL_CALL
     771      336384 : SfxDocumentMetaData::getMetaAttr(const char* i_name, const char* i_attr) const
     772             : //        throw (css::uno::RuntimeException)
     773             : {
     774      336384 :     OUString name = OUString::createFromAscii(i_name);
     775             :     DBG_ASSERT(m_meta.find(name) != m_meta.end(),
     776             :         "SfxDocumentMetaData::getMetaAttr: not found");
     777      672768 :     css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
     778      336384 :     if (xNode.is()) {
     779             :         css::uno::Reference<css::xml::dom::XElement> xElem(xNode,
     780      182586 :             css::uno::UNO_QUERY_THROW);
     781      182586 :         return xElem->getAttributeNS(getNameSpace(i_attr),
     782      182586 :                     getQualifier(i_attr).second);
     783             :     } else {
     784      153798 :         return OUString();
     785      336384 :     }
     786             : }
     787             : 
     788             : css::uno::Sequence< OUString> SAL_CALL
     789        1172 : SfxDocumentMetaData::getMetaList(const char* i_name) const
     790             : //        throw (css::uno::RuntimeException)
     791             : {
     792        1172 :     checkInit();
     793        1172 :     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        1172 :         m_metaList.find(name)->second;
     798        1172 :     css::uno::Sequence< OUString> ret(vec.size());
     799        1214 :     for (size_t i = 0; i < vec.size(); ++i) {
     800          42 :         ret[i] = getNodeText(vec.at(i));
     801             :     }
     802        1172 :     return ret;
     803             : }
     804             : 
     805             : bool SAL_CALL
     806        1932 : 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        1932 :     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        1932 :         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        1932 :             m_metaList[name];
     822             : 
     823             :         // if nothing changed, do nothing
     824             :         // alas, this does not check for permutations, or attributes...
     825        1932 :         if ((0 == i_pAttrs)) {
     826         212 :             if (static_cast<size_t>(i_rValue.getLength()) == vec.size()) {
     827         182 :                 bool isEqual(true);
     828         182 :                 for (sal_Int32 i = 0; i < i_rValue.getLength(); ++i) {
     829           2 :                     css::uno::Reference<css::xml::dom::XNode> xNode(vec.at(i));
     830           2 :                     if (xNode.is()) {
     831           2 :                         OUString val = getNodeText(xNode);
     832           2 :                         if (!val.equals(i_rValue[i])) {
     833           2 :                             isEqual = false;
     834           2 :                             break;
     835           0 :                         }
     836             :                     }
     837           0 :                 }
     838         182 :                 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        1752 :                 ::reverse_iterator it(vec.rbegin());
     846             :             try {
     847        2068 :                 for ( ;it != vec.rend(); ++it)
     848             :                 {
     849         316 :                     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        1752 :             vec.clear();
     859             :         }
     860             : 
     861             :         // insert new meta data nodes into DOM tree
     862        7014 :         for (sal_Int32 i = 0; i < i_rValue.getLength(); ++i) {
     863             :             css::uno::Reference<css::xml::dom::XElement> xElem(
     864        5262 :                 m_xDoc->createElementNS(getNameSpace(i_name), name),
     865        5262 :                 css::uno::UNO_QUERY_THROW);
     866             :             css::uno::Reference<css::xml::dom::XNode> xNode(xElem,
     867       10524 :                 css::uno::UNO_QUERY_THROW);
     868             :             css::uno::Reference<css::xml::dom::XNode> xTextNode(
     869       10524 :                 m_xDoc->createTextNode(i_rValue[i]), css::uno::UNO_QUERY_THROW);
     870             :             // set attributes
     871        5262 :             if (i_pAttrs != 0) {
     872       43512 :                 for (std::vector<std::pair<const char*, OUString> >
     873        5184 :                                 ::const_iterator it = (*i_pAttrs)[i].begin();
     874       29008 :                         it != (*i_pAttrs)[i].end(); ++it) {
     875       18640 :                     xElem->setAttributeNS(getNameSpace(it->first),
     876        9320 :                         OUString::createFromAscii(it->first),
     877       27960 :                         it->second);
     878             :                 }
     879             :             }
     880        5262 :             xNode->appendChild(xTextNode);
     881        5262 :             m_xParent->appendChild(xNode);
     882        5262 :             vec.push_back(xNode);
     883        5262 :         }
     884             : 
     885        1752 :         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        1720 : propsToStrings(css::uno::Reference<css::beans::XPropertySet> const & i_xPropSet)
     897             : {
     898        1720 :     ::comphelper::SequenceAsVector< OUString > values;
     899        3440 :     AttrVector attrs;
     900             : 
     901             :     css::uno::Reference<css::beans::XPropertySetInfo> xSetInfo
     902        3440 :         = i_xPropSet->getPropertySetInfo();
     903        3440 :     css::uno::Sequence<css::beans::Property> props = xSetInfo->getProperties();
     904             : 
     905        6904 :     for (sal_Int32 i = 0; i < props.getLength(); ++i) {
     906        5184 :         if (props[i].Attributes & css::beans::PropertyAttribute::TRANSIENT) {
     907           0 :             continue;
     908             :         }
     909        5184 :         const OUString name = props[i].Name;
     910       10368 :         css::uno::Any any;
     911             :         try {
     912        5184 :             any = i_xPropSet->getPropertyValue(name);
     913           0 :         } catch (const css::uno::Exception &) {
     914             :             // ignore
     915             :         }
     916        5184 :         const css::uno::Type & type = any.getValueType();
     917       10368 :         std::vector<std::pair<const char*, OUString> > as;
     918             :         as.push_back(std::make_pair(static_cast<const char*>("meta:name"),
     919        5184 :                                         name));
     920        5184 :         const char* vt = "meta:value-type";
     921             : 
     922             :         // convert according to type
     923        5184 :         if (type == ::cppu::UnoType<bool>::get()) {
     924        3232 :             bool b = false;
     925        3232 :             any >>= b;
     926        3232 :             OUStringBuffer buf;
     927        3232 :             ::sax::Converter::convertBool(buf, b);
     928        3232 :             values.push_back(buf.makeStringAndClear());
     929             :             as.push_back(std::make_pair(vt,
     930        3232 :                 OUString("boolean")));
     931        1952 :         } else if (type == ::cppu::UnoType< OUString>::get()) {
     932        1110 :             OUString s;
     933        1110 :             any >>= s;
     934        1110 :             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        1110 :             if (4 <= i)
     940             :             {
     941             :                 as.push_back(std::make_pair(vt,
     942          62 :                     OUString("string")));
     943        1110 :             }
     944         842 :         } else if (type == ::cppu::UnoType<css::util::DateTime>::get()) {
     945           6 :             css::util::DateTime dt;
     946           6 :             any >>= dt;
     947           6 :             values.push_back(dateTimeToText(dt));
     948             :             as.push_back(std::make_pair(vt,
     949           6 :                 OUString("date")));
     950         836 :         } else if (type == ::cppu::UnoType<css::util::Date>::get()) {
     951           2 :             css::util::Date d;
     952           2 :             any >>= d;
     953           2 :             values.push_back(dateToText(d));
     954             :             as.push_back(std::make_pair(vt,
     955           2 :                 OUString("date")));
     956         834 :         } 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         834 :         } 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         834 :         } 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           2 :             css::util::Time ut;
     972           2 :             any >>= ut;
     973           2 :             css::util::Duration ud;
     974           2 :             ud.Hours   = ut.Hours;
     975           2 :             ud.Minutes = ut.Minutes;
     976           2 :             ud.Seconds = ut.Seconds;
     977           2 :             ud.NanoSeconds = ut.NanoSeconds;
     978           2 :             values.push_back(durationToText(ud));
     979             :             as.push_back(std::make_pair(vt,
     980           2 :                 OUString("time")));
     981         832 :         } else if (type == ::cppu::UnoType<css::util::Duration>::get()) {
     982           2 :             css::util::Duration ud;
     983           2 :             any >>= ud;
     984           2 :             values.push_back(durationToText(ud));
     985             :             as.push_back(std::make_pair(vt,
     986           2 :                 OUString("time")));
     987         830 :         } else if (::cppu::UnoType<double>::get().isAssignableFrom(type)) {
     988             :             // support not just double, but anything that can be converted
     989         830 :             double d = 0;
     990         830 :             any >>= d;
     991         830 :             OUStringBuffer buf;
     992         830 :             ::sax::Converter::convertDouble(buf, d);
     993         830 :             values.push_back(buf.makeStringAndClear());
     994             :             as.push_back(std::make_pair(vt,
     995         830 :                 OUString("float")));
     996             :         } else {
     997             :             SAL_WARN("sfx.doc", "Unsupported property type: " << any.getValueTypeName() );
     998           0 :             continue;
     999             :         }
    1000        5184 :         attrs.push_back(as);
    1001        5184 :     }
    1002             : 
    1003        3440 :     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       14575 : SfxDocumentMetaData::updateElement(const char *i_name,
    1009             :         std::vector<std::pair<const char *, OUString> >* i_pAttrs)
    1010             : {
    1011       14575 :     OUString name = OUString::createFromAscii(i_name);
    1012             :     try {
    1013             :         // remove old element
    1014             :         css::uno::Reference<css::xml::dom::XNode> xNode =
    1015       14575 :             m_meta.find(name)->second;
    1016       14575 :         if (xNode.is()) {
    1017        5897 :             m_xParent->removeChild(xNode);
    1018        5897 :             xNode.clear();
    1019             :         }
    1020             :         // add new element
    1021       14575 :         if (0 != i_pAttrs) {
    1022             :             css::uno::Reference<css::xml::dom::XElement> xElem(
    1023       10261 :                 m_xDoc->createElementNS(getNameSpace(i_name), name),
    1024       10261 :                     css::uno::UNO_QUERY_THROW);
    1025       10261 :             xNode.set(xElem, css::uno::UNO_QUERY_THROW);
    1026             :             // set attributes
    1027      129561 :             for (std::vector<std::pair<const char *, OUString> >
    1028       10261 :                     ::const_iterator it = i_pAttrs->begin();
    1029       86374 :                     it != i_pAttrs->end(); ++it) {
    1030       65852 :                 xElem->setAttributeNS(getNameSpace(it->first),
    1031       65852 :                     OUString::createFromAscii(it->first), it->second);
    1032             :             }
    1033       10261 :             m_xParent->appendChild(xNode);
    1034             :         }
    1035       14575 :         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       14575 :     }
    1042       14575 : }
    1043             : 
    1044             : // update user-defined meta data in DOM tree
    1045        1720 : void SAL_CALL SfxDocumentMetaData::updateUserDefinedAndAttributes()
    1046             : {
    1047        1720 :     createUserDefined();
    1048             :     const css::uno::Reference<css::beans::XPropertySet> xPSet(m_xUserDefined,
    1049        1720 :             css::uno::UNO_QUERY_THROW);
    1050             :     const std::pair<css::uno::Sequence< OUString>, AttrVector>
    1051        3440 :         udStringsAttrs( propsToStrings(xPSet) );
    1052             :     (void) setMetaList("meta:user-defined", udStringsAttrs.first,
    1053        1720 :             &udStringsAttrs.second);
    1054             : 
    1055             :     // update elements with attributes
    1056        3440 :     std::vector<std::pair<const char *, OUString> > attributes;
    1057        4318 :     if (!m_TemplateName.isEmpty() || !m_TemplateURL.isEmpty()
    1058        2598 :             || isValidDateTime(m_TemplateDate)) {
    1059             :         attributes.push_back(std::make_pair(
    1060             :                 static_cast<const char*>("xlink:type"),
    1061         842 :                 OUString("simple")));
    1062             :         attributes.push_back(std::make_pair(
    1063             :                 static_cast<const char*>("xlink:actuate"),
    1064         842 :                 OUString("onRequest")));
    1065             :         attributes.push_back(std::make_pair(
    1066         842 :                 static_cast<const char*>("xlink:title"), m_TemplateName));
    1067             :         attributes.push_back(std::make_pair(
    1068         842 :                 static_cast<const char*>("xlink:href" ), m_TemplateURL ));
    1069         842 :         if (isValidDateTime(m_TemplateDate)) {
    1070             :             attributes.push_back(std::make_pair(
    1071             :                 static_cast<const char*>("meta:date"  ),
    1072           2 :                 dateTimeToText(m_TemplateDate)));
    1073             :         }
    1074         842 :         updateElement("meta:template", &attributes);
    1075             :     } else {
    1076         878 :         updateElement("meta:template");
    1077             :     }
    1078        1720 :     attributes.clear();
    1079             : 
    1080        1720 :     if (!m_AutoloadURL.isEmpty() || (0 != m_AutoloadSecs)) {
    1081             :         attributes.push_back(std::make_pair(
    1082           2 :                 static_cast<const char*>("xlink:href" ), m_AutoloadURL ));
    1083             :         attributes.push_back(std::make_pair(
    1084             :                 static_cast<const char*>("meta:delay" ),
    1085           2 :                 durationToText(m_AutoloadSecs)));
    1086           2 :         updateElement("meta:auto-reload", &attributes);
    1087             :     } else {
    1088        1718 :         updateElement("meta:auto-reload");
    1089             :     }
    1090        1720 :     attributes.clear();
    1091             : 
    1092        1720 :     if (!m_DefaultTarget.isEmpty()) {
    1093             :         attributes.push_back(std::make_pair(
    1094             :                 static_cast<const char*>("office:target-frame-name"),
    1095           2 :                 m_DefaultTarget));
    1096             :         // xlink:show: _blank -> new, any other value -> replace
    1097           2 :         const sal_Char* show = m_DefaultTarget == "_blank" ? "new" : "replace";
    1098             :         attributes.push_back(std::make_pair(
    1099             :                 static_cast<const char*>("xlink:show"),
    1100           2 :                 OUString::createFromAscii(show)));
    1101           2 :         updateElement("meta:hyperlink-behaviour", &attributes);
    1102             :     } else {
    1103        1718 :         updateElement("meta:hyperlink-behaviour");
    1104             :     }
    1105        3440 :     attributes.clear();
    1106        1720 : }
    1107             : 
    1108             : // create empty DOM tree (XDocument)
    1109             : css::uno::Reference<css::xml::dom::XDocument> SAL_CALL
    1110       16702 : SfxDocumentMetaData::createDOM() const // throw (css::uno::RuntimeException)
    1111             : {
    1112       16702 :     css::uno::Reference<css::lang::XMultiComponentFactory> xMsf ( m_xContext->getServiceManager());
    1113       33404 :     css::uno::Reference<css::xml::dom::XDocumentBuilder> xBuilder( css::xml::dom::DocumentBuilder::create(m_xContext) );
    1114       16702 :     css::uno::Reference<css::xml::dom::XDocument> xDoc = xBuilder->newDocument();
    1115       16702 :     if (!xDoc.is()) throw css::uno::RuntimeException(
    1116             :         OUString("SfxDocumentMetaData::createDOM: "
    1117             :                 "cannot create new document"),
    1118           0 :                 *const_cast<SfxDocumentMetaData*>(this));
    1119       33404 :     return xDoc;
    1120             : }
    1121             : 
    1122             : void SAL_CALL
    1123      177658 : SfxDocumentMetaData::checkInit() const // throw (css::uno::RuntimeException)
    1124             : {
    1125      177658 :     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      177658 : }
    1133             : 
    1134             : // initialize state from DOM tree
    1135       17684 : void SAL_CALL SfxDocumentMetaData::init(
    1136             :         css::uno::Reference<css::xml::dom::XDocument> i_xDoc)
    1137             : {
    1138       17684 :     if (!i_xDoc.is()) throw css::uno::RuntimeException(
    1139           0 :         OUString("SfxDocumentMetaData::init: no DOM tree given"), *this);
    1140             : 
    1141       17684 :     css::uno::Reference<css::xml::xpath::XXPathAPI> xPath = css::xml::xpath::XPathAPI::create(m_xContext);
    1142             : 
    1143       17684 :     m_isInitialized = false;
    1144       17684 :     m_xDoc = i_xDoc;
    1145             : 
    1146             :     // select nodes for standard meta data stuff
    1147       17684 :     xPath->registerNS(OUString("xlink"),
    1148       17684 :         OUString::createFromAscii(s_nsXLink));
    1149       17684 :     xPath->registerNS(OUString("dc"),
    1150       17684 :         OUString::createFromAscii(s_nsDC));
    1151       17684 :     xPath->registerNS(OUString("office"),
    1152       17684 :         OUString::createFromAscii(s_nsODF));
    1153       17684 :     xPath->registerNS(OUString("meta"),
    1154       17684 :         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       35368 :         "/child::office:document-meta/child::office:meta");
    1160             :     css::uno::Reference<css::xml::dom::XNode> xDocNode(
    1161       35368 :         m_xDoc, css::uno::UNO_QUERY_THROW);
    1162       17684 :     m_xParent.clear();
    1163             :     try {
    1164       17684 :         m_xParent = xPath->selectSingleNode(xDocNode, prefix);
    1165       15606 :     } catch (const com::sun::star::uno::Exception &) {
    1166             :     }
    1167             : 
    1168       17684 :     if (!m_xParent.is()) {
    1169             :         // all this create/append stuff may throw DOMException
    1170             :         try {
    1171       15742 :             css::uno::Reference<css::xml::dom::XElement> xRElem;
    1172             :             css::uno::Reference<css::xml::dom::XNode> xNode(
    1173       31484 :                 i_xDoc->getFirstChild());
    1174       31484 :             while (xNode.is()) {
    1175         136 :                 if (css::xml::dom::NodeType_ELEMENT_NODE ==xNode->getNodeType())
    1176             :                 {
    1177         136 :                     if ( xNode->getNamespaceURI().equalsAscii(s_nsODF) && xNode->getLocalName() == "document-meta" )
    1178             :                     {
    1179         136 :                         xRElem.set(xNode, css::uno::UNO_QUERY_THROW);
    1180         136 :                         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       15742 :             if (!xRElem.is()) {
    1196       46818 :                 xRElem = i_xDoc->createElementNS(
    1197             :                     OUString::createFromAscii(s_nsODF),
    1198       31212 :                     OUString("office:document-meta"));
    1199             :                 css::uno::Reference<css::xml::dom::XNode> xRNode(xRElem,
    1200       15606 :                     css::uno::UNO_QUERY_THROW);
    1201       15606 :                 i_xDoc->appendChild(xRNode);
    1202             :             }
    1203       15742 :             xRElem->setAttributeNS(OUString::createFromAscii(s_nsODF),
    1204             :                         OUString("office:version"),
    1205       15742 :                         OUString("1.0"));
    1206             :             // does not exist, otherwise m_xParent would not be null
    1207             :             css::uno::Reference<css::xml::dom::XNode> xParent (
    1208       15742 :                 i_xDoc->createElementNS(
    1209             :                     OUString::createFromAscii(s_nsODF),
    1210       15742 :                     OUString("office:meta")),
    1211       31484 :             css::uno::UNO_QUERY_THROW);
    1212       15742 :             xRElem->appendChild(xParent);
    1213       31484 :             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      318312 :     for (const char **pName = s_stdMeta; *pName != 0; ++pName) {
    1225      300628 :         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      300628 :             xPath->selectSingleNode(m_xParent,
    1234      601256 :                 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      300628 :         m_meta[name] = xNode;
    1238      300628 :     }
    1239             : 
    1240             :     // select nodes for elements of which we handle all occurrences
    1241       53052 :     for (const char **pName = s_stdMetaList; *pName != 0; ++pName) {
    1242       35368 :         OUString name = OUString::createFromAscii(*pName);
    1243             :         css::uno::Reference<css::xml::dom::XNodeList> nodes =
    1244       35368 :             xPath->selectNodeList(m_xParent,
    1245       70736 :                 OUString("child::") + name);
    1246       70736 :         std::vector<css::uno::Reference<css::xml::dom::XNode> > v;
    1247       41070 :         for (sal_Int32 i = 0; i < nodes->getLength(); ++i) {
    1248        5702 :             v.push_back(nodes->item(i));
    1249             :         }
    1250       35368 :         m_metaList[name] = v;
    1251       35368 :     }
    1252             : 
    1253             :     // initialize members corresponding to attributes from DOM nodes
    1254       17684 :     m_TemplateName  = getMetaAttr("meta:template", "xlink:title");
    1255       17684 :     m_TemplateURL   = getMetaAttr("meta:template", "xlink:href");
    1256             :     m_TemplateDate  =
    1257       17684 :         textToDateTimeDefault(getMetaAttr("meta:template", "meta:date"));
    1258       17684 :     m_AutoloadURL   = getMetaAttr("meta:auto-reload", "xlink:href");
    1259             :     m_AutoloadSecs  =
    1260       17684 :         textToDuration(getMetaAttr("meta:auto-reload", "meta:delay"));
    1261       35368 :     m_DefaultTarget =
    1262       17684 :         getMetaAttr("meta:hyperlink-behaviour", "office:target-frame-name");
    1263             : 
    1264             : 
    1265             :     std::vector<css::uno::Reference<css::xml::dom::XNode> > & vec =
    1266       17684 :         m_metaList[OUString("meta:user-defined")];
    1267       17684 :     m_xUserDefined.clear(); // #i105826#: reset (may be re-initialization)
    1268       17684 :     if ( !vec.empty() )
    1269             :     {
    1270         916 :         createUserDefined();
    1271             :     }
    1272             : 
    1273             :     // user-defined meta data: initialize PropertySet from DOM nodes
    1274       70056 :     for (std::vector<css::uno::Reference<css::xml::dom::XNode> >::iterator
    1275       64388 :             it = vec.begin(); it != vec.end(); ++it) {
    1276        5668 :         css::uno::Reference<css::xml::dom::XElement> xElem(*it,
    1277        5668 :             css::uno::UNO_QUERY_THROW);
    1278       11336 :         css::uno::Any any;
    1279        5668 :         OUString name = xElem->getAttributeNS(
    1280             :                 OUString::createFromAscii(s_nsODFMeta),
    1281       11336 :                 OUString("name"));
    1282        5668 :         OUString type = xElem->getAttributeNS(
    1283             :                 OUString::createFromAscii(s_nsODFMeta),
    1284       11336 :                 OUString("value-type"));
    1285       11336 :         OUString text = getNodeText(*it);
    1286        5668 :         if ( type == "float" ) {
    1287             :             double d;
    1288         876 :             if (::sax::Converter::convertDouble(d, text)) {
    1289         876 :                 any <<= d;
    1290             :             } else {
    1291             :                 SAL_WARN("sfx.doc", "Invalid float: " << text);
    1292           0 :                 continue;
    1293             :             }
    1294        4792 :         } else if ( type == "date" ) {
    1295             :             bool isDateTime;
    1296           8 :             css::util::Date d;
    1297           8 :             css::util::DateTime dt;
    1298           8 :             boost::optional<sal_Int16> nTimeZone;
    1299           8 :             if (textToDateOrDateTime(d, dt, isDateTime, nTimeZone, text)) {
    1300           8 :                 if (isDateTime) {
    1301           6 :                     if (nTimeZone.is_initialized()) {
    1302           0 :                         any <<= css::util::DateTimeWithTimezone(dt,
    1303           0 :                                     nTimeZone.get());
    1304             :                     } else {
    1305           6 :                         any <<= dt;
    1306             :                     }
    1307             :                 } else {
    1308           2 :                     if (nTimeZone.is_initialized()) {
    1309           0 :                         any <<= css::util::DateWithTimezone(d, nTimeZone.get());
    1310             :                     } else {
    1311           2 :                         any <<= d;
    1312             :                     }
    1313             :                 }
    1314             :             } else {
    1315             :                 SAL_WARN("sfx.doc", "Invalid date: " << text);
    1316           0 :                 continue;
    1317           8 :             }
    1318        4784 :         } else if ( type == "time" ) {
    1319           4 :             css::util::Duration ud;
    1320           4 :             if (textToDuration(ud, text)) {
    1321           4 :                 any <<= ud;
    1322             :             } else {
    1323             :                 SAL_WARN("sfx.doc", "Invalid time: " << text);
    1324           0 :                 continue;
    1325             :             }
    1326        4780 :         } else if ( type == "boolean" ) {
    1327             :             bool b;
    1328        3416 :             if (::sax::Converter::convertBool(b, text)) {
    1329        3416 :                 any <<= b;
    1330             :             } else {
    1331             :                 SAL_WARN("sfx.doc", "Invalid boolean: " << text);
    1332           0 :                 continue;
    1333             :             }
    1334        1364 :         } else if ( type == "string" || true) { // default
    1335        1364 :             any <<= text;
    1336             :         }
    1337             :         try {
    1338        5668 :             m_xUserDefined->addProperty(name,
    1339        5668 :                 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        5668 :     }
    1351             : 
    1352       17684 :     m_isModified = false;
    1353       35368 :     m_isInitialized = true;
    1354       17684 : }
    1355             : 
    1356             : 
    1357             : 
    1358        8352 : 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        8352 :     , 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        8352 :     init(createDOM());
    1372        8352 : }
    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        8343 : void SAL_CALL SfxDocumentMetaData::dispose() throw (css::uno::RuntimeException, std::exception)
    1400             : {
    1401        8343 :     ::osl::MutexGuard g(m_aMutex);
    1402        8343 :     if (!m_isInitialized) {
    1403        8343 :         return;
    1404             :     }
    1405        8343 :     WeakComponentImplHelperBase::dispose(); // superclass
    1406             :     m_NotifyListeners.disposeAndClear(css::lang::EventObject(
    1407        8343 :             static_cast< ::cppu::OWeakObject* >(this)));
    1408        8343 :     m_isInitialized = false;
    1409        8343 :     m_meta.clear();
    1410        8343 :     m_metaList.clear();
    1411        8343 :     m_xParent.clear();
    1412        8343 :     m_xDoc.clear();
    1413        8343 :     m_xUserDefined.clear();
    1414             : }
    1415             : 
    1416             : 
    1417             : // ::com::sun::star::document::XDocumentProperties:
    1418             : OUString SAL_CALL
    1419        5914 : SfxDocumentMetaData::getAuthor() throw (css::uno::RuntimeException, std::exception)
    1420             : {
    1421        5914 :     ::osl::MutexGuard g(m_aMutex);
    1422        5914 :     return getMetaText("meta:initial-creator");
    1423             : }
    1424             : 
    1425        4060 : void SAL_CALL SfxDocumentMetaData::setAuthor(const OUString & the_value)
    1426             :         throw (css::uno::RuntimeException, std::exception)
    1427             : {
    1428        4060 :     setMetaTextAndNotify("meta:initial-creator", the_value);
    1429        4060 : }
    1430             : 
    1431             : 
    1432             : OUString SAL_CALL
    1433        4580 : SfxDocumentMetaData::getGenerator() throw (css::uno::RuntimeException, std::exception)
    1434             : {
    1435        4580 :     ::osl::MutexGuard g(m_aMutex);
    1436        4580 :     return getMetaText("meta:generator");
    1437             : }
    1438             : 
    1439             : void SAL_CALL
    1440        4738 : SfxDocumentMetaData::setGenerator(const OUString & the_value)
    1441             :         throw (css::uno::RuntimeException, std::exception)
    1442             : {
    1443        4738 :     setMetaTextAndNotify("meta:generator", the_value);
    1444        4738 : }
    1445             : 
    1446             : css::util::DateTime SAL_CALL
    1447        1282 : SfxDocumentMetaData::getCreationDate() throw (css::uno::RuntimeException, std::exception)
    1448             : {
    1449        1282 :     ::osl::MutexGuard g(m_aMutex);
    1450        1282 :     return textToDateTimeDefault(getMetaText("meta:creation-date"));
    1451             : }
    1452             : 
    1453             : void SAL_CALL
    1454        4676 : SfxDocumentMetaData::setCreationDate(const css::util::DateTime & the_value)
    1455             :         throw (css::uno::RuntimeException, std::exception)
    1456             : {
    1457        4676 :     setMetaTextAndNotify("meta:creation-date", dateTimeToText(the_value));
    1458        4676 : }
    1459             : 
    1460             : OUString SAL_CALL
    1461        2632 : SfxDocumentMetaData::getTitle() throw (css::uno::RuntimeException, std::exception)
    1462             : {
    1463        2632 :     ::osl::MutexGuard g(m_aMutex);
    1464        2632 :     return getMetaText("dc:title");
    1465             : }
    1466             : 
    1467         670 : void SAL_CALL SfxDocumentMetaData::setTitle(const OUString & the_value)
    1468             :         throw (css::uno::RuntimeException, std::exception)
    1469             : {
    1470         670 :     setMetaTextAndNotify("dc:title", the_value);
    1471         670 : }
    1472             : 
    1473             : OUString SAL_CALL
    1474        1282 : SfxDocumentMetaData::getSubject() throw (css::uno::RuntimeException, std::exception)
    1475             : {
    1476        1282 :     ::osl::MutexGuard g(m_aMutex);
    1477        1282 :     return getMetaText("dc:subject");
    1478             : }
    1479             : 
    1480             : void SAL_CALL
    1481         298 : SfxDocumentMetaData::setSubject(const OUString & the_value)
    1482             :         throw (css::uno::RuntimeException, std::exception)
    1483             : {
    1484         298 :     setMetaTextAndNotify("dc:subject", the_value);
    1485         298 : }
    1486             : 
    1487             : OUString SAL_CALL
    1488        1172 : SfxDocumentMetaData::getDescription() throw (css::uno::RuntimeException, std::exception)
    1489             : {
    1490        1172 :     ::osl::MutexGuard g(m_aMutex);
    1491        1172 :     return getMetaText("dc:description");
    1492             : }
    1493             : 
    1494             : void SAL_CALL
    1495         176 : SfxDocumentMetaData::setDescription(const OUString & the_value)
    1496             :         throw (css::uno::RuntimeException, std::exception)
    1497             : {
    1498         176 :     setMetaTextAndNotify("dc:description", the_value);
    1499         176 : }
    1500             : 
    1501             : css::uno::Sequence< OUString >
    1502        1172 : SAL_CALL SfxDocumentMetaData::getKeywords() throw (css::uno::RuntimeException, std::exception)
    1503             : {
    1504        1172 :     ::osl::MutexGuard g(m_aMutex);
    1505        1172 :     return getMetaList("meta:keyword");
    1506             : }
    1507             : 
    1508             : void SAL_CALL
    1509         212 : SfxDocumentMetaData::setKeywords(
    1510             :         const css::uno::Sequence< OUString > & the_value)
    1511             :         throw (css::uno::RuntimeException, std::exception)
    1512             : {
    1513         212 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1514         212 :     if (setMetaList("meta:keyword", the_value)) {
    1515          32 :         g.clear();
    1516          32 :         setModified(true);
    1517         212 :     }
    1518         212 : }
    1519             : 
    1520             : css::lang::Locale SAL_CALL
    1521         942 :         SfxDocumentMetaData::getLanguage() throw (css::uno::RuntimeException, std::exception)
    1522             : {
    1523         942 :     ::osl::MutexGuard g(m_aMutex);
    1524         942 :     css::lang::Locale loc( LanguageTag( getMetaText("dc:language")).getLocale( false));
    1525         942 :     return loc;
    1526             : }
    1527             : 
    1528             : void SAL_CALL
    1529        1042 : SfxDocumentMetaData::setLanguage(const css::lang::Locale & the_value)
    1530             :         throw (css::uno::RuntimeException, std::exception)
    1531             : {
    1532        1042 :     OUString text( LanguageTag::convertToBcp47( the_value, false));
    1533        1042 :     setMetaTextAndNotify("dc:language", text);
    1534        1042 : }
    1535             : 
    1536             : OUString SAL_CALL
    1537        5908 : SfxDocumentMetaData::getModifiedBy() throw (css::uno::RuntimeException, std::exception)
    1538             : {
    1539        5908 :     ::osl::MutexGuard g(m_aMutex);
    1540        5908 :     return getMetaText("dc:creator");
    1541             : }
    1542             : 
    1543             : void SAL_CALL
    1544        2896 : SfxDocumentMetaData::setModifiedBy(const OUString & the_value)
    1545             :         throw (css::uno::RuntimeException, std::exception)
    1546             : {
    1547        2896 :     setMetaTextAndNotify("dc:creator", the_value);
    1548        2896 : }
    1549             : 
    1550             : css::util::DateTime SAL_CALL
    1551        1280 : SfxDocumentMetaData::getModificationDate() throw (css::uno::RuntimeException, std::exception)
    1552             : {
    1553        1280 :     ::osl::MutexGuard g(m_aMutex);
    1554        1280 :     return textToDateTimeDefault(getMetaText("dc:date"));
    1555             : }
    1556             : 
    1557             : void SAL_CALL
    1558        3346 : SfxDocumentMetaData::setModificationDate(const css::util::DateTime & the_value)
    1559             :         throw (css::uno::RuntimeException, std::exception)
    1560             : {
    1561        3346 :     setMetaTextAndNotify("dc:date", dateTimeToText(the_value));
    1562        3346 : }
    1563             : 
    1564             : OUString SAL_CALL
    1565          30 : SfxDocumentMetaData::getPrintedBy() throw (css::uno::RuntimeException, std::exception)
    1566             : {
    1567          30 :     ::osl::MutexGuard g(m_aMutex);
    1568          30 :     return getMetaText("meta:printed-by");
    1569             : }
    1570             : 
    1571             : void SAL_CALL
    1572         354 : SfxDocumentMetaData::setPrintedBy(const OUString & the_value)
    1573             :         throw (css::uno::RuntimeException, std::exception)
    1574             : {
    1575         354 :     setMetaTextAndNotify("meta:printed-by", the_value);
    1576         354 : }
    1577             : 
    1578             : css::util::DateTime SAL_CALL
    1579        1174 : SfxDocumentMetaData::getPrintDate() throw (css::uno::RuntimeException, std::exception)
    1580             : {
    1581        1174 :     ::osl::MutexGuard g(m_aMutex);
    1582        1174 :     return textToDateTimeDefault(getMetaText("meta:print-date"));
    1583             : }
    1584             : 
    1585             : void SAL_CALL
    1586        1062 : SfxDocumentMetaData::setPrintDate(const css::util::DateTime & the_value)
    1587             :         throw (css::uno::RuntimeException, std::exception)
    1588             : {
    1589        1062 :     setMetaTextAndNotify("meta:print-date", dateTimeToText(the_value));
    1590        1062 : }
    1591             : 
    1592             : OUString SAL_CALL
    1593        1398 : SfxDocumentMetaData::getTemplateName() throw (css::uno::RuntimeException, std::exception)
    1594             : {
    1595        1398 :     ::osl::MutexGuard g(m_aMutex);
    1596        1398 :     checkInit();
    1597        1398 :     return m_TemplateName;
    1598             : }
    1599             : 
    1600             : void SAL_CALL
    1601        2850 : SfxDocumentMetaData::setTemplateName(const OUString & the_value)
    1602             :         throw (css::uno::RuntimeException, std::exception)
    1603             : {
    1604        2850 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1605        2850 :     checkInit();
    1606        2850 :     if (m_TemplateName != the_value) {
    1607        2748 :         m_TemplateName = the_value;
    1608        2748 :         g.clear();
    1609        2748 :         setModified(true);
    1610        2850 :     }
    1611        2850 : }
    1612             : 
    1613             : OUString SAL_CALL
    1614        1584 : SfxDocumentMetaData::getTemplateURL() throw (css::uno::RuntimeException, std::exception)
    1615             : {
    1616        1584 :     ::osl::MutexGuard g(m_aMutex);
    1617        1584 :     checkInit();
    1618        1584 :     return m_TemplateURL;
    1619             : }
    1620             : 
    1621             : void SAL_CALL
    1622        1158 : SfxDocumentMetaData::setTemplateURL(const OUString & the_value)
    1623             :         throw (css::uno::RuntimeException, std::exception)
    1624             : {
    1625        1158 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1626        1158 :     checkInit();
    1627        1158 :     if (m_TemplateURL != the_value) {
    1628          34 :         m_TemplateURL = the_value;
    1629          34 :         g.clear();
    1630          34 :         setModified(true);
    1631        1158 :     }
    1632        1158 : }
    1633             : 
    1634             : css::util::DateTime SAL_CALL
    1635          26 : SfxDocumentMetaData::getTemplateDate() throw (css::uno::RuntimeException, std::exception)
    1636             : {
    1637          26 :     ::osl::MutexGuard g(m_aMutex);
    1638          26 :     checkInit();
    1639          26 :     return m_TemplateDate;
    1640             : }
    1641             : 
    1642             : void SAL_CALL
    1643          32 : SfxDocumentMetaData::setTemplateDate(const css::util::DateTime & the_value)
    1644             :         throw (css::uno::RuntimeException, std::exception)
    1645             : {
    1646          32 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1647          32 :     checkInit();
    1648          32 :     if (!(m_TemplateDate == the_value)) {
    1649           2 :         m_TemplateDate = the_value;
    1650           2 :         g.clear();
    1651           2 :         setModified(true);
    1652          32 :     }
    1653          32 : }
    1654             : 
    1655             : OUString SAL_CALL
    1656        9031 : SfxDocumentMetaData::getAutoloadURL() throw (css::uno::RuntimeException, std::exception)
    1657             : {
    1658        9031 :     ::osl::MutexGuard g(m_aMutex);
    1659        9031 :     checkInit();
    1660        9031 :     return m_AutoloadURL;
    1661             : }
    1662             : 
    1663             : void SAL_CALL
    1664        1006 : SfxDocumentMetaData::setAutoloadURL(const OUString & the_value)
    1665             :         throw (css::uno::RuntimeException, std::exception)
    1666             : {
    1667        1006 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1668        1006 :     checkInit();
    1669        1006 :     if (m_AutoloadURL != the_value) {
    1670           4 :         m_AutoloadURL = the_value;
    1671           4 :         g.clear();
    1672           4 :         setModified(true);
    1673        1006 :     }
    1674        1006 : }
    1675             : 
    1676             : ::sal_Int32 SAL_CALL
    1677        8071 : SfxDocumentMetaData::getAutoloadSecs() throw (css::uno::RuntimeException, std::exception)
    1678             : {
    1679        8071 :     ::osl::MutexGuard g(m_aMutex);
    1680        8071 :     checkInit();
    1681        8071 :     return m_AutoloadSecs;
    1682             : }
    1683             : 
    1684             : void SAL_CALL
    1685          24 : SfxDocumentMetaData::setAutoloadSecs(::sal_Int32 the_value)
    1686             :         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException, std::exception)
    1687             : {
    1688          24 :     if (the_value < 0) throw css::lang::IllegalArgumentException(
    1689             :         OUString("SfxDocumentMetaData::setAutoloadSecs: argument is negative"),
    1690           0 :         *this, 0);
    1691          24 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1692          24 :     checkInit();
    1693          24 :     if (m_AutoloadSecs != the_value) {
    1694           2 :         m_AutoloadSecs = the_value;
    1695           2 :         g.clear();
    1696           2 :         setModified(true);
    1697          24 :     }
    1698          24 : }
    1699             : 
    1700             : OUString SAL_CALL
    1701          54 : SfxDocumentMetaData::getDefaultTarget() throw (css::uno::RuntimeException, std::exception)
    1702             : {
    1703          54 :     ::osl::MutexGuard g(m_aMutex);
    1704          54 :     checkInit();
    1705          54 :     return m_DefaultTarget;
    1706             : }
    1707             : 
    1708             : void SAL_CALL
    1709          24 : SfxDocumentMetaData::setDefaultTarget(const OUString & the_value)
    1710             :         throw (css::uno::RuntimeException, std::exception)
    1711             : {
    1712          24 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1713          24 :     checkInit();
    1714          24 :     if (m_DefaultTarget != the_value) {
    1715           0 :         m_DefaultTarget = the_value;
    1716           0 :         g.clear();
    1717           0 :         setModified(true);
    1718          24 :     }
    1719          24 : }
    1720             : 
    1721             : css::uno::Sequence< css::beans::NamedValue > SAL_CALL
    1722       15352 : SfxDocumentMetaData::getDocumentStatistics() throw (css::uno::RuntimeException, std::exception)
    1723             : {
    1724       15352 :     ::osl::MutexGuard g(m_aMutex);
    1725       15352 :     checkInit();
    1726       30704 :     ::comphelper::SequenceAsVector<css::beans::NamedValue> stats;
    1727      245632 :     for (size_t i = 0; s_stdStats[i] != 0; ++i) {
    1728      230280 :         const char * aName = s_stdStatAttrs[i];
    1729      230280 :         OUString text = getMetaAttr("meta:document-statistic", aName);
    1730      230280 :         if (text.isEmpty()) continue;
    1731       68376 :         css::beans::NamedValue stat;
    1732       34188 :         stat.Name = OUString::createFromAscii(s_stdStats[i]);
    1733             :         sal_Int32 val;
    1734       68376 :         css::uno::Any any;
    1735       34188 :         if (!::sax::Converter::convertNumber(val, text, 0,
    1736       34188 :                 std::numeric_limits<sal_Int32>::max()) || (val < 0)) {
    1737           0 :             val = 0;
    1738             :             SAL_WARN("sfx.doc", "Invalid number: " << text);
    1739             :         }
    1740       34188 :         any <<= val;
    1741       34188 :         stat.Value = any;
    1742       34188 :         stats.push_back(stat);
    1743       34188 :     }
    1744             : 
    1745       30704 :     return stats.getAsConstList();
    1746             : }
    1747             : 
    1748             : void SAL_CALL
    1749        9415 : SfxDocumentMetaData::setDocumentStatistics(
    1750             :         const css::uno::Sequence< css::beans::NamedValue > & the_value)
    1751             :         throw (css::uno::RuntimeException, std::exception)
    1752             : {
    1753        9415 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1754        9415 :     checkInit();
    1755       18830 :     std::vector<std::pair<const char *, OUString> > attributes;
    1756       38963 :     for (sal_Int32 i = 0; i < the_value.getLength(); ++i) {
    1757       29548 :         const OUString name = the_value[i].Name;
    1758             :         // inefficently search for matching attribute
    1759      168942 :         for (size_t j = 0; s_stdStats[j] != 0; ++j) {
    1760      168942 :             if (name.equalsAscii(s_stdStats[j])) {
    1761       29548 :                 const css::uno::Any any = the_value[i].Value;
    1762       29548 :                 sal_Int32 val = 0;
    1763       29548 :                 if (any >>= val) {
    1764       29548 :                     OUStringBuffer buf;
    1765       29548 :                     ::sax::Converter::convertNumber(buf, val);
    1766             :                     attributes.push_back(std::make_pair(s_stdStatAttrs[j],
    1767       29548 :                                 buf.makeStringAndClear()));
    1768             :                 } else {
    1769             :                     SAL_WARN("sfx.doc", "Invalid statistic: " << name);
    1770             :                 }
    1771       29548 :                 break;
    1772             :             }
    1773             :         }
    1774       29548 :     }
    1775        9415 :     updateElement("meta:document-statistic", &attributes);
    1776        9415 :     g.clear();
    1777       18830 :     setModified(true);
    1778        9415 : }
    1779             : 
    1780             : ::sal_Int16 SAL_CALL
    1781        1068 : SfxDocumentMetaData::getEditingCycles() throw (css::uno::RuntimeException, std::exception)
    1782             : {
    1783        1068 :     ::osl::MutexGuard g(m_aMutex);
    1784        2136 :     OUString text = getMetaText("meta:editing-cycles");
    1785             :     sal_Int32 ret;
    1786        1068 :     if (::sax::Converter::convertNumber(ret, text,
    1787        1068 :             0, std::numeric_limits<sal_Int16>::max())) {
    1788        1068 :         return static_cast<sal_Int16>(ret);
    1789             :     } else {
    1790           0 :         return 0;
    1791        1068 :     }
    1792             : }
    1793             : 
    1794             : void SAL_CALL
    1795        3170 : SfxDocumentMetaData::setEditingCycles(::sal_Int16 the_value)
    1796             :         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException, std::exception)
    1797             : {
    1798        3170 :     if (the_value < 0) throw css::lang::IllegalArgumentException(
    1799             :         OUString("SfxDocumentMetaData::setEditingCycles: argument is negative"),
    1800           0 :         *this, 0);
    1801        3170 :     OUStringBuffer buf;
    1802        3170 :     ::sax::Converter::convertNumber(buf, the_value);
    1803        3170 :     setMetaTextAndNotify("meta:editing-cycles", buf.makeStringAndClear());
    1804        3170 : }
    1805             : 
    1806             : ::sal_Int32 SAL_CALL
    1807        1068 : SfxDocumentMetaData::getEditingDuration() throw (css::uno::RuntimeException, std::exception)
    1808             : {
    1809        1068 :     ::osl::MutexGuard g(m_aMutex);
    1810        1068 :     return textToDuration(getMetaText("meta:editing-duration"));
    1811             : }
    1812             : 
    1813             : void SAL_CALL
    1814        3114 : SfxDocumentMetaData::setEditingDuration(::sal_Int32 the_value)
    1815             :         throw (css::uno::RuntimeException, css::lang::IllegalArgumentException, std::exception)
    1816             : {
    1817        3114 :     if (the_value < 0) throw css::lang::IllegalArgumentException(
    1818             :         OUString("SfxDocumentMetaData::setEditingDuration: argument is negative"),
    1819           0 :         *this, 0);
    1820        3114 :     setMetaTextAndNotify("meta:editing-duration", durationToText(the_value));
    1821        3114 : }
    1822             : 
    1823             : void SAL_CALL
    1824           8 : SfxDocumentMetaData::resetUserData(const OUString & the_value)
    1825             :     throw (css::uno::RuntimeException, std::exception)
    1826             : {
    1827           8 :     ::osl::ClearableMutexGuard g(m_aMutex);
    1828             : 
    1829           8 :     bool bModified( false );
    1830           8 :     bModified |= setMetaText("meta:initial-creator", the_value);
    1831           8 :     ::DateTime now( ::DateTime::SYSTEM );
    1832          24 :     css::util::DateTime uDT(now.GetNanoSec(), now.GetSec(), now.GetMin(),
    1833          32 :         now.GetHour(), now.GetDay(), now.GetMonth(), now.GetYear(), false);
    1834           8 :     bModified |= setMetaText("meta:creation-date", dateTimeToText(uDT));
    1835           8 :     bModified |= setMetaText("dc:creator", OUString());
    1836           8 :     bModified |= setMetaText("meta:printed-by", OUString());
    1837           8 :     bModified |= setMetaText("dc:date", dateTimeToText(css::util::DateTime()));
    1838             :     bModified |= setMetaText("meta:print-date",
    1839           8 :         dateTimeToText(css::util::DateTime()));
    1840           8 :     bModified |= setMetaText("meta:editing-duration", durationToText(0));
    1841             :     bModified |= setMetaText("meta:editing-cycles",
    1842           8 :         OUString("1"));
    1843             : 
    1844           8 :     if (bModified) {
    1845           8 :         g.clear();
    1846           8 :         setModified(true);
    1847           8 :     }
    1848           8 : }
    1849             : 
    1850             : 
    1851             : css::uno::Reference< css::beans::XPropertyContainer > SAL_CALL
    1852       20210 : SfxDocumentMetaData::getUserDefinedProperties()
    1853             :         throw (css::uno::RuntimeException, std::exception)
    1854             : {
    1855       20210 :     ::osl::MutexGuard g(m_aMutex);
    1856       20210 :     checkInit();
    1857       20210 :     createUserDefined();
    1858       20210 :     return m_xUserDefined;
    1859             : }
    1860             : 
    1861             : 
    1862             : void SAL_CALL
    1863          28 : 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          28 :     if (!xStorage.is()) throw css::lang::IllegalArgumentException(
    1871           0 :         OUString("SfxDocumentMetaData::loadFromStorage: argument is null"), *this, 0);
    1872          28 :     ::osl::MutexGuard g(m_aMutex);
    1873             : 
    1874             :     // open meta data file
    1875             :     css::uno::Reference<css::io::XStream> xStream(
    1876          28 :         xStorage->openStreamElement(
    1877             :             OUString(s_meta),
    1878          56 :             css::embed::ElementModes::READ) );
    1879          28 :     if (!xStream.is()) throw css::uno::RuntimeException();
    1880             :     css::uno::Reference<css::io::XInputStream> xInStream =
    1881          56 :         xStream->getInputStream();
    1882          28 :     if (!xInStream.is()) throw css::uno::RuntimeException();
    1883             : 
    1884             :     // create DOM parser service
    1885             :     css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
    1886          56 :         m_xContext->getServiceManager());
    1887          56 :     css::uno::Reference<css::xml::sax::XParser> xParser = css::xml::sax::Parser::create(m_xContext);
    1888          56 :     css::xml::sax::InputSource input;
    1889          28 :     input.aInputStream = xInStream;
    1890             : 
    1891          28 :     sal_uInt64 version = SotStorage::GetVersion( xStorage );
    1892             :     // Oasis is also the default (0)
    1893          28 :     bool bOasis = ( version > SOFFICE_FILEFORMAT_60 || version == 0 );
    1894             :     const sal_Char *pServiceName = bOasis
    1895             :         ? "com.sun.star.document.XMLOasisMetaImporter"
    1896          28 :         : "com.sun.star.document.XMLMetaImporter";
    1897             : 
    1898             :     // set base URL
    1899             :     css::uno::Reference<css::beans::XPropertySet> xPropArg =
    1900          56 :         getURLProperties(Medium);
    1901             :     try {
    1902          28 :         xPropArg->getPropertyValue("BaseURI")
    1903          28 :             >>= input.sSystemId;
    1904          28 :         input.sSystemId += "/" + OUString(s_meta);
    1905           0 :     } catch (const css::uno::Exception &) {
    1906           0 :         input.sSystemId = OUString(s_meta);
    1907             :     }
    1908          56 :     css::uno::Sequence< css::uno::Any > args(1);
    1909          28 :     args[0] <<= xPropArg;
    1910             : 
    1911             :     css::uno::Reference<css::xml::sax::XDocumentHandler> xDocHandler (
    1912          28 :         xMsf->createInstanceWithArgumentsAndContext(
    1913          28 :             OUString::createFromAscii(pServiceName), args, m_xContext),
    1914          56 :         css::uno::UNO_QUERY_THROW);
    1915          28 :     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          56 :         css::uno::UNO_QUERY_THROW);
    1920          28 :     xImp->setTargetDocument(css::uno::Reference<css::lang::XComponent>(this));
    1921          28 :     xParser->setDocumentHandler(xDocHandler);
    1922             :     try {
    1923          28 :         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          56 :     checkInit();
    1931          28 : }
    1932             : 
    1933             : void SAL_CALL
    1934           6 : 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           6 :     if (!xStorage.is()) throw css::lang::IllegalArgumentException(
    1941             :         OUString("SfxDocumentMetaData::storeToStorage:"
    1942           0 :                 " argument is null"), *this, 0);
    1943           6 :     ::osl::MutexGuard g(m_aMutex);
    1944           6 :     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           6 :         xStorage->openStreamElement(OUString(s_meta),
    1952             :             css::embed::ElementModes::WRITE
    1953          12 :             | css::embed::ElementModes::TRUNCATE);
    1954           6 :     if (!xStream.is()) throw css::uno::RuntimeException();
    1955             :     css::uno::Reference< css::beans::XPropertySet > xStreamProps(xStream,
    1956          12 :         css::uno::UNO_QUERY_THROW);
    1957           6 :     xStreamProps->setPropertyValue(
    1958             :         OUString("MediaType"),
    1959           6 :         css::uno::makeAny(OUString("text/xml")));
    1960           6 :     xStreamProps->setPropertyValue(
    1961             :         OUString("Compressed"),
    1962           6 :         css::uno::makeAny(false));
    1963           6 :     xStreamProps->setPropertyValue(
    1964             :         OUString("UseCommonStoragePasswordEncryption"),
    1965           6 :         css::uno::makeAny(false));
    1966             :     css::uno::Reference<css::io::XOutputStream> xOutStream =
    1967          12 :         xStream->getOutputStream();
    1968           6 :     if (!xOutStream.is()) throw css::uno::RuntimeException();
    1969             :     css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
    1970          12 :         m_xContext->getServiceManager());
    1971             :     css::uno::Reference<css::xml::sax::XWriter> xSaxWriter(
    1972          12 :         css::xml::sax::Writer::create(m_xContext));
    1973           6 :     xSaxWriter->setOutputStream(xOutStream);
    1974             : 
    1975           6 :     const sal_uInt64 version = SotStorage::GetVersion( xStorage );
    1976             :     // Oasis is also the default (0)
    1977           6 :     const bool bOasis = ( version > SOFFICE_FILEFORMAT_60 || version == 0 );
    1978             :     const sal_Char *pServiceName = bOasis
    1979             :         ? "com.sun.star.document.XMLOasisMetaExporter"
    1980           6 :         : "com.sun.star.document.XMLMetaExporter";
    1981             : 
    1982             :     // set base URL
    1983             :     css::uno::Reference<css::beans::XPropertySet> xPropArg =
    1984          12 :         getURLProperties(Medium);
    1985          12 :     css::uno::Sequence< css::uno::Any > args(2);
    1986           6 :     args[0] <<= xSaxWriter;
    1987           6 :     args[1] <<= xPropArg;
    1988             : 
    1989             :     css::uno::Reference<css::document::XExporter> xExp(
    1990           6 :         xMsf->createInstanceWithArgumentsAndContext(
    1991           6 :             OUString::createFromAscii(pServiceName), args, m_xContext),
    1992          12 :         css::uno::UNO_QUERY_THROW);
    1993           6 :     xExp->setSourceDocument(css::uno::Reference<css::lang::XComponent>(this));
    1994             :     css::uno::Reference<css::document::XFilter> xFilter(xExp,
    1995          12 :         css::uno::UNO_QUERY_THROW);
    1996           6 :     if (xFilter->filter(css::uno::Sequence< css::beans::PropertyValue >())) {
    1997             :         css::uno::Reference<css::embed::XTransactedObject> xTransaction(
    1998           6 :             xStorage, css::uno::UNO_QUERY);
    1999           6 :         if (xTransaction.is()) {
    2000           6 :             xTransaction->commit();
    2001           6 :         }
    2002             :     } else {
    2003             :         throw css::io::IOException(OUString(
    2004           0 :                 "SfxDocumentMetaData::storeToStorage: cannot filter"), *this);
    2005           6 :     }
    2006           6 : }
    2007             : 
    2008             : void SAL_CALL
    2009          34 : 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          34 :     css::uno::Reference<css::io::XInputStream> xIn;
    2015          68 :     utl::MediaDescriptor md(Medium);
    2016             :     // if we have an URL parameter, it replaces the one in the media descriptor
    2017          34 :     if (!URL.isEmpty()) {
    2018          32 :         md[ utl::MediaDescriptor::PROP_URL() ] <<= URL;
    2019             :     }
    2020          34 :     if (md.addInputStream()) {
    2021          28 :         md[ utl::MediaDescriptor::PROP_INPUTSTREAM() ] >>= xIn;
    2022             :     }
    2023          68 :     css::uno::Reference<css::embed::XStorage> xStorage;
    2024             :     try {
    2025          34 :         if (xIn.is()) {
    2026          56 :             xStorage = ::comphelper::OStorageHelper::GetStorageFromInputStream(
    2027          28 :                             xIn, m_xContext);
    2028             :         } else { // fallback to url parameter
    2029           6 :             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          12 :     } 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           6 :                 css::uno::makeAny(e));
    2041             :     }
    2042          28 :     if (!xStorage.is()) {
    2043             :         throw css::uno::RuntimeException(OUString(
    2044             :                 "SfxDocumentMetaData::loadFromMedium: cannot get Storage"),
    2045           0 :                 *this);
    2046             :     }
    2047          62 :     loadFromStorage(xStorage, md.getAsConstPropertyValueList());
    2048          28 : }
    2049             : 
    2050             : void SAL_CALL
    2051           6 : 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           6 :     utl::MediaDescriptor md(Medium);
    2057           6 :     if (!URL.isEmpty()) {
    2058           4 :         md[ utl::MediaDescriptor::PROP_URL() ] <<= URL;
    2059             :     }
    2060          12 :     SfxMedium aMedium(md.getAsConstPropertyValueList());
    2061             :     css::uno::Reference<css::embed::XStorage> xStorage
    2062          12 :         = aMedium.GetOutputStorage();
    2063             : 
    2064             : 
    2065           6 :     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           6 :         = md.find(utl::MediaDescriptor::PROP_MEDIATYPE());
    2073           6 :     if (iter != md.end()) {
    2074             :         css::uno::Reference< css::beans::XPropertySet > xProps(xStorage,
    2075           6 :             css::uno::UNO_QUERY_THROW);
    2076           6 :         xProps->setPropertyValue(
    2077           6 :             utl::MediaDescriptor::PROP_MEDIATYPE(),
    2078          12 :             iter->second);
    2079             :     }
    2080           6 :     storeToStorage(xStorage, md.getAsConstPropertyValueList());
    2081             : 
    2082             : 
    2083           6 :     const bool bOk = aMedium.Commit();
    2084           6 :     aMedium.Close();
    2085           6 :     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           6 :     }
    2097           6 : }
    2098             : 
    2099             : // ::com::sun::star::lang::XInitialization:
    2100             : void SAL_CALL
    2101        8236 : 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        8236 :     ::osl::MutexGuard g(m_aMutex);
    2111       16472 :     css::uno::Reference<css::xml::dom::XDocument> xDoc;
    2112             : 
    2113        9218 :     for (sal_Int32 i = 0; i < aArguments.getLength(); ++i) {
    2114         982 :         const css::uno::Any any = aArguments[i];
    2115         982 :         if (any >>= xDoc) {
    2116         982 :             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         982 :     }
    2129             : 
    2130        8236 :     if (!xDoc.is()) {
    2131             :         // For a new document, we create a new DOM tree here.
    2132        7254 :         xDoc = createDOM();
    2133             :     }
    2134             : 
    2135       16472 :     init(xDoc);
    2136        8236 : }
    2137             : 
    2138             : // ::com::sun::star::util::XCloneable:
    2139             : css::uno::Reference<css::util::XCloneable> SAL_CALL
    2140        1096 : SfxDocumentMetaData::createClone()
    2141             :     throw (css::uno::RuntimeException, std::exception)
    2142             : {
    2143        1096 :     ::osl::MutexGuard g(m_aMutex);
    2144        1096 :     checkInit();
    2145             : 
    2146        1096 :     SfxDocumentMetaData *pNew = createMe(m_xContext);
    2147             : 
    2148             :     // NB: do not copy the modification listeners, only DOM
    2149        2192 :     css::uno::Reference<css::xml::dom::XDocument> xDoc = createDOM();
    2150             :     try {
    2151        1096 :         updateUserDefinedAndAttributes();
    2152             :         // deep copy of root node
    2153             :         css::uno::Reference<css::xml::dom::XNode> xRoot(
    2154        1096 :             m_xDoc->getDocumentElement(), css::uno::UNO_QUERY_THROW);
    2155             :         css::uno::Reference<css::xml::dom::XNode> xRootNew(
    2156        2192 :             xDoc->importNode(xRoot, true));
    2157        1096 :         xDoc->appendChild(xRootNew);
    2158        2192 :         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        2192 :     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       37817 : void SAL_CALL SfxDocumentMetaData::setModified( sal_Bool bModified )
    2182             :         throw (css::beans::PropertyVetoException, css::uno::RuntimeException, std::exception)
    2183             : {
    2184       37817 :     css::uno::Reference<css::util::XModifiable> xMB;
    2185             :     { // do not lock mutex while notifying (#i93514#) to prevent deadlock
    2186       37817 :         ::osl::MutexGuard g(m_aMutex);
    2187       37817 :         checkInit();
    2188       37817 :         m_isModified = bModified;
    2189       37817 :         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       37817 :         }
    2195             :     }
    2196       37817 :     if (bModified) {
    2197             :         try {
    2198       37817 :             css::uno::Reference<css::uno::XInterface> xThis(*this);
    2199       75634 :             css::lang::EventObject event(xThis);
    2200             :             m_NotifyListeners.notifyEach(&css::util::XModifyListener::modified,
    2201       75634 :                 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       37817 :     }
    2213       37817 : }
    2214             : 
    2215             : // ::com::sun::star::util::XModifyBroadcaster:
    2216        6748 : void SAL_CALL SfxDocumentMetaData::addModifyListener(
    2217             :         const css::uno::Reference< css::util::XModifyListener > & xListener)
    2218             :         throw (css::uno::RuntimeException, std::exception)
    2219             : {
    2220        6748 :     ::osl::MutexGuard g(m_aMutex);
    2221        6748 :     checkInit();
    2222        6748 :     m_NotifyListeners.addInterface(xListener);
    2223             :     css::uno::Reference<css::util::XModifyBroadcaster> xMB(m_xUserDefined,
    2224       13496 :         css::uno::UNO_QUERY);
    2225        6748 :     if (xMB.is()) {
    2226           2 :         xMB->addModifyListener(xListener);
    2227        6748 :     }
    2228        6748 : }
    2229             : 
    2230           2 : void SAL_CALL SfxDocumentMetaData::removeModifyListener(
    2231             :         const css::uno::Reference< css::util::XModifyListener > & xListener)
    2232             :         throw (css::uno::RuntimeException, std::exception)
    2233             : {
    2234           2 :     ::osl::MutexGuard g(m_aMutex);
    2235           2 :     checkInit();
    2236           2 :     m_NotifyListeners.removeInterface(xListener);
    2237             :     css::uno::Reference<css::util::XModifyBroadcaster> xMB(m_xUserDefined,
    2238           4 :         css::uno::UNO_QUERY);
    2239           2 :     if (xMB.is()) {
    2240           2 :         xMB->removeModifyListener(xListener);
    2241           2 :     }
    2242           2 : }
    2243             : 
    2244             : // ::com::sun::star::xml::sax::XSAXSerializable
    2245         624 : 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         624 :     ::osl::MutexGuard g(m_aMutex);
    2251         624 :     checkInit();
    2252         624 :     updateUserDefinedAndAttributes();
    2253             :     css::uno::Reference<css::xml::sax::XSAXSerializable> xSAXable(m_xDoc,
    2254        1248 :         css::uno::UNO_QUERY_THROW);
    2255        1248 :     xSAXable->serialize(i_xHandler, i_rNamespaces);
    2256         624 : }
    2257             : 
    2258       22846 : void SfxDocumentMetaData::createUserDefined()
    2259             : {
    2260             :     // user-defined meta data: create PropertyBag which only accepts property
    2261             :     // values of allowed types
    2262       22846 :     if ( !m_xUserDefined.is() )
    2263             :     {
    2264        4618 :         css::uno::Sequence<css::uno::Type> types(13);
    2265        4618 :         types[ 0] = ::cppu::UnoType<bool>::get();
    2266        4618 :         types[ 1] = ::cppu::UnoType< OUString>::get();
    2267        4618 :         types[ 2] = ::cppu::UnoType<css::util::DateTime>::get();
    2268        4618 :         types[ 3] = ::cppu::UnoType<css::util::Date>::get();
    2269        4618 :         types[ 4] = ::cppu::UnoType<css::util::DateTimeWithTimezone>::get();
    2270        4618 :         types[ 5] = ::cppu::UnoType<css::util::DateWithTimezone>::get();
    2271        4618 :         types[ 6] = ::cppu::UnoType<css::util::Duration>::get();
    2272        4618 :         types[ 7] = ::cppu::UnoType<float>::get();
    2273        4618 :         types[ 8] = ::cppu::UnoType<double>::get();
    2274        4618 :         types[ 9] = ::cppu::UnoType<sal_Int16>::get();
    2275        4618 :         types[10] = ::cppu::UnoType<sal_Int32>::get();
    2276        4618 :         types[11] = ::cppu::UnoType<sal_Int64>::get();
    2277             :         // Time is supported for backward compatibility with OOo 3.x, x<=2
    2278        4618 :         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        4618 :             css::uno::UNO_QUERY_THROW);
    2283             : 
    2284             :         const css::uno::Reference<css::util::XModifyBroadcaster> xMB(
    2285        9236 :             m_xUserDefined, css::uno::UNO_QUERY);
    2286        4618 :         if (xMB.is())
    2287             :         {
    2288             :             const css::uno::Sequence<css::uno::Reference<css::uno::XInterface> >
    2289        4618 :                 listeners(m_NotifyListeners.getElements());
    2290        8060 :             for (css::uno::Reference< css::uno::XInterface > const * iter = listeners.begin(); iter != listeners.end(); ++iter) {
    2291        3442 :                 xMB->addModifyListener(
    2292             :                     css::uno::Reference< css::util::XModifyListener >(*iter,
    2293        3442 :                         css::uno::UNO_QUERY));
    2294        4618 :             }
    2295        4618 :         }
    2296             :     }
    2297       22846 : }
    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        7256 : SfxDocumentMetaData_get_implementation(
    2311             :     css::uno::XComponentContext *context,
    2312             :     css::uno::Sequence<css::uno::Any> const &)
    2313             : {
    2314        7256 :     return cppu::acquire(new SfxDocumentMetaData(context));
    2315             : }
    2316             : 
    2317             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10