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