1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "sal/config.h"
31 #include "cppuhelper/factory.hxx"
32 #include "cppuhelper/implementationentry.hxx"
33 #include "cppuhelper/compbase6.hxx"
34 #include "com/sun/star/lang/XServiceInfo.hpp"
35 #include "com/sun/star/document/XDocumentProperties.hpp"
36 #include "com/sun/star/lang/XInitialization.hpp"
37 #include "com/sun/star/util/XCloneable.hpp"
38 #include "com/sun/star/util/XModifiable.hpp"
39 #include "com/sun/star/xml/sax/XSAXSerializable.hpp"
41 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
42 #include "com/sun/star/lang/EventObject.hpp"
43 #include "com/sun/star/beans/XPropertySet.hpp"
44 #include "com/sun/star/beans/XPropertySetInfo.hpp"
45 #include "com/sun/star/beans/PropertyAttribute.hpp"
46 #include "com/sun/star/task/ErrorCodeIOException.hpp"
47 #include "com/sun/star/embed/XStorage.hpp"
48 #include "com/sun/star/embed/XTransactedObject.hpp"
49 #include "com/sun/star/embed/ElementModes.hpp"
50 #include "com/sun/star/io/XActiveDataControl.hpp"
51 #include "com/sun/star/io/XActiveDataSource.hpp"
52 #include "com/sun/star/io/XStream.hpp"
53 #include "com/sun/star/document/XImporter.hpp"
54 #include "com/sun/star/document/XExporter.hpp"
55 #include "com/sun/star/document/XFilter.hpp"
56 #include "com/sun/star/xml/sax/XParser.hpp"
57 #include "com/sun/star/xml/dom/XDocument.hpp"
58 #include "com/sun/star/xml/dom/XElement.hpp"
59 #include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
60 #include "com/sun/star/xml/dom/XSAXDocumentBuilder.hpp"
61 #include "com/sun/star/xml/dom/NodeType.hpp"
62 #include "com/sun/star/xml/xpath/XXPathAPI.hpp"
63 #include "com/sun/star/util/Date.hpp"
64 #include "com/sun/star/util/Time.hpp"
65 #include "com/sun/star/util/Duration.hpp"
67 #include "SfxDocumentMetaData.hxx"
68 #include "rtl/ustrbuf.hxx"
69 #include "tools/debug.hxx"
70 #include "tools/datetime.hxx"
71 #include "osl/mutex.hxx"
72 #include "cppuhelper/basemutex.hxx"
73 #include "cppuhelper/interfacecontainer.hxx"
74 #include "comphelper/storagehelper.hxx"
75 #include "comphelper/mediadescriptor.hxx"
76 #include "comphelper/sequenceasvector.hxx"
77 #include "comphelper/stlunosequence.hxx"
78 #include "sot/storage.hxx"
79 #include "sfx2/docfile.hxx"
80 #include "sax/tools/converter.hxx"
89 #include <cppuhelper/implbase1.hxx>
90 #include <com/sun/star/document/XCompatWriterDocProperties.hpp>
93 * This file contains the implementation of the service
94 * com.sun.star.document.DocumentProperties.
95 * This service enables access to the meta-data stored in documents.
96 * Currently, this service only handles documents in ODF format.
98 * The implementation uses an XML DOM to store the properties.
99 * This approach was taken because it allows for preserving arbitrary XML data
100 * in loaded documents, which will be stored unmodified when saving the
103 * Upon access, some properties are directly read from and updated in the DOM.
104 * Exception: it seems impossible to get notified upon addition of a property
105 * to a com.sun.star.beans.PropertyBag, which is used for storing user-defined
106 * properties; because of this, user-defined properties are updated in the
107 * XML DOM only when storing the document.
108 * Exception 2: when setting certain properties which correspond to attributes
109 * in the XML DOM, we want to remove the corresponding XML element. Detecting
110 * this condition can get messy, so we store all such properties as members,
111 * and update the DOM tree only when storing the document (in
112 * <method>updateUserDefinedAndAttributes</method>).
117 /// anonymous implementation namespace
120 namespace css
= ::com::sun::star
;
123 /// a list of attribute-lists, where attribute means name and content
124 typedef std::vector
<std::vector
<std::pair
<const char*, ::rtl::OUString
> > >
127 typedef ::cppu::WeakComponentImplHelper6
<
128 css::lang::XServiceInfo
,
129 css::document::XDocumentProperties
,
130 css::lang::XInitialization
,
131 css::util::XCloneable
,
132 css::util::XModifiable
,
133 css::xml::sax::XSAXSerializable
>
134 SfxDocumentMetaData_Base
;
136 class SfxDocumentMetaData
:
137 private ::cppu::BaseMutex
,
138 public SfxDocumentMetaData_Base
141 explicit SfxDocumentMetaData(
142 css::uno::Reference
< css::uno::XComponentContext
> const & context
);
144 // ::com::sun::star::lang::XServiceInfo:
145 virtual ::rtl::OUString SAL_CALL
getImplementationName()
146 throw (css::uno::RuntimeException
);
147 virtual ::sal_Bool SAL_CALL
supportsService(
148 const ::rtl::OUString
& ServiceName
) throw (css::uno::RuntimeException
);
149 virtual css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
150 getSupportedServiceNames() throw (css::uno::RuntimeException
);
152 // ::com::sun::star::lang::XComponent:
153 virtual void SAL_CALL
dispose() throw (css::uno::RuntimeException
);
155 // ::com::sun::star::document::XDocumentProperties:
156 virtual ::rtl::OUString SAL_CALL
getAuthor()
157 throw (css::uno::RuntimeException
);
158 virtual void SAL_CALL
setAuthor(const ::rtl::OUString
& the_value
)
159 throw (css::uno::RuntimeException
);
160 virtual ::rtl::OUString SAL_CALL
getGenerator()
161 throw (css::uno::RuntimeException
);
162 virtual void SAL_CALL
setGenerator(const ::rtl::OUString
& the_value
)
163 throw (css::uno::RuntimeException
);
164 virtual css::util::DateTime SAL_CALL
getCreationDate()
165 throw (css::uno::RuntimeException
);
166 virtual void SAL_CALL
setCreationDate(const css::util::DateTime
& the_value
)
167 throw (css::uno::RuntimeException
);
168 virtual ::rtl::OUString SAL_CALL
getTitle()
169 throw (css::uno::RuntimeException
);
170 virtual void SAL_CALL
setTitle(const ::rtl::OUString
& the_value
)
171 throw (css::uno::RuntimeException
);
172 virtual ::rtl::OUString SAL_CALL
getSubject()
173 throw (css::uno::RuntimeException
);
174 virtual void SAL_CALL
setSubject(const ::rtl::OUString
& the_value
)
175 throw (css::uno::RuntimeException
);
176 virtual ::rtl::OUString SAL_CALL
getDescription()
177 throw (css::uno::RuntimeException
);
178 virtual void SAL_CALL
setDescription(const ::rtl::OUString
& the_value
)
179 throw (css::uno::RuntimeException
);
180 virtual css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getKeywords()
181 throw (css::uno::RuntimeException
);
182 virtual void SAL_CALL
setKeywords(
183 const css::uno::Sequence
< ::rtl::OUString
> & the_value
)
184 throw (css::uno::RuntimeException
);
185 virtual css::lang::Locale SAL_CALL
getLanguage()
186 throw (css::uno::RuntimeException
);
187 virtual void SAL_CALL
setLanguage(const css::lang::Locale
& the_value
)
188 throw (css::uno::RuntimeException
);
189 virtual ::rtl::OUString SAL_CALL
getModifiedBy()
190 throw (css::uno::RuntimeException
);
191 virtual void SAL_CALL
setModifiedBy(const ::rtl::OUString
& the_value
)
192 throw (css::uno::RuntimeException
);
193 virtual css::util::DateTime SAL_CALL
getModificationDate()
194 throw (css::uno::RuntimeException
);
195 virtual void SAL_CALL
setModificationDate(
196 const css::util::DateTime
& the_value
)
197 throw (css::uno::RuntimeException
);
198 virtual ::rtl::OUString SAL_CALL
getPrintedBy()
199 throw (css::uno::RuntimeException
);
200 virtual void SAL_CALL
setPrintedBy(const ::rtl::OUString
& the_value
)
201 throw (css::uno::RuntimeException
);
202 virtual css::util::DateTime SAL_CALL
getPrintDate()
203 throw (css::uno::RuntimeException
);
204 virtual void SAL_CALL
setPrintDate(const css::util::DateTime
& the_value
)
205 throw (css::uno::RuntimeException
);
206 virtual ::rtl::OUString SAL_CALL
getTemplateName()
207 throw (css::uno::RuntimeException
);
208 virtual void SAL_CALL
setTemplateName(const ::rtl::OUString
& the_value
)
209 throw (css::uno::RuntimeException
);
210 virtual ::rtl::OUString SAL_CALL
getTemplateURL()
211 throw (css::uno::RuntimeException
);
212 virtual void SAL_CALL
setTemplateURL(const ::rtl::OUString
& the_value
)
213 throw (css::uno::RuntimeException
);
214 virtual css::util::DateTime SAL_CALL
getTemplateDate()
215 throw (css::uno::RuntimeException
);
216 virtual void SAL_CALL
setTemplateDate(const css::util::DateTime
& the_value
)
217 throw (css::uno::RuntimeException
);
218 virtual ::rtl::OUString SAL_CALL
getAutoloadURL()
219 throw (css::uno::RuntimeException
);
220 virtual void SAL_CALL
setAutoloadURL(const ::rtl::OUString
& the_value
)
221 throw (css::uno::RuntimeException
);
222 virtual ::sal_Int32 SAL_CALL
getAutoloadSecs()
223 throw (css::uno::RuntimeException
);
224 virtual void SAL_CALL
setAutoloadSecs(::sal_Int32 the_value
)
225 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
);
226 virtual ::rtl::OUString SAL_CALL
getDefaultTarget()
227 throw (css::uno::RuntimeException
);
228 virtual void SAL_CALL
setDefaultTarget(const ::rtl::OUString
& the_value
)
229 throw (css::uno::RuntimeException
);
230 virtual css::uno::Sequence
< css::beans::NamedValue
> SAL_CALL
231 getDocumentStatistics() throw (css::uno::RuntimeException
);
232 virtual void SAL_CALL
setDocumentStatistics(
233 const css::uno::Sequence
< css::beans::NamedValue
> & the_value
)
234 throw (css::uno::RuntimeException
);
235 virtual ::sal_Int16 SAL_CALL
getEditingCycles()
236 throw (css::uno::RuntimeException
);
237 virtual void SAL_CALL
setEditingCycles(::sal_Int16 the_value
)
238 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
);
239 virtual ::sal_Int32 SAL_CALL
getEditingDuration()
240 throw (css::uno::RuntimeException
);
241 virtual void SAL_CALL
setEditingDuration(::sal_Int32 the_value
)
242 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
);
243 virtual void SAL_CALL
resetUserData(const ::rtl::OUString
& the_value
)
244 throw (css::uno::RuntimeException
);
245 virtual css::uno::Reference
< css::beans::XPropertyContainer
> SAL_CALL
246 getUserDefinedProperties() throw (css::uno::RuntimeException
);
247 virtual void SAL_CALL
loadFromStorage(
248 const css::uno::Reference
< css::embed::XStorage
> & Storage
,
249 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
250 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
,
251 css::io::WrongFormatException
,
252 css::lang::WrappedTargetException
, css::io::IOException
);
253 virtual void SAL_CALL
loadFromMedium(const ::rtl::OUString
& URL
,
254 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
255 throw (css::uno::RuntimeException
,
256 css::io::WrongFormatException
,
257 css::lang::WrappedTargetException
, css::io::IOException
);
258 virtual void SAL_CALL
storeToStorage(
259 const css::uno::Reference
< css::embed::XStorage
> & Storage
,
260 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
261 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
,
262 css::lang::WrappedTargetException
, css::io::IOException
);
263 virtual void SAL_CALL
storeToMedium(const ::rtl::OUString
& URL
,
264 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
265 throw (css::uno::RuntimeException
,
266 css::lang::WrappedTargetException
, css::io::IOException
);
268 // ::com::sun::star::lang::XInitialization:
269 virtual void SAL_CALL
initialize(
270 const css::uno::Sequence
< css::uno::Any
> & aArguments
)
271 throw (css::uno::RuntimeException
, css::uno::Exception
);
273 // ::com::sun::star::util::XCloneable:
274 virtual css::uno::Reference
<css::util::XCloneable
> SAL_CALL
createClone()
275 throw (css::uno::RuntimeException
);
277 // ::com::sun::star::util::XModifiable:
278 virtual ::sal_Bool SAL_CALL
isModified( )
279 throw (css::uno::RuntimeException
);
280 virtual void SAL_CALL
setModified( ::sal_Bool bModified
)
281 throw (css::beans::PropertyVetoException
, css::uno::RuntimeException
);
283 // ::com::sun::star::util::XModifyBroadcaster:
284 virtual void SAL_CALL
addModifyListener(
285 const css::uno::Reference
< css::util::XModifyListener
> & xListener
)
286 throw (css::uno::RuntimeException
);
287 virtual void SAL_CALL
removeModifyListener(
288 const css::uno::Reference
< css::util::XModifyListener
> & xListener
)
289 throw (css::uno::RuntimeException
);
291 // ::com::sun::star::xml::sax::XSAXSerializable
292 virtual void SAL_CALL
serialize(
293 const css::uno::Reference
<css::xml::sax::XDocumentHandler
>& i_xHandler
,
294 const css::uno::Sequence
< css::beans::StringPair
>& i_rNamespaces
)
295 throw (css::uno::RuntimeException
, css::xml::sax::SAXException
);
298 SfxDocumentMetaData(SfxDocumentMetaData
&); // not defined
299 SfxDocumentMetaData
& operator =(SfxDocumentMetaData
&); // not defined
301 virtual ~SfxDocumentMetaData() {}
302 virtual SfxDocumentMetaData
* createMe( css::uno::Reference
< css::uno::XComponentContext
> const & context
) { return new SfxDocumentMetaData( context
); };
303 const css::uno::Reference
< css::uno::XComponentContext
> m_xContext
;
306 ::cppu::OInterfaceContainerHelper m_NotifyListeners
;
307 /// flag: false means not initialized yet, or disposed
308 bool m_isInitialized
;
311 /// meta-data DOM tree
312 css::uno::Reference
< css::xml::dom::XDocument
> m_xDoc
;
313 /// meta-data super node in the meta-data DOM tree
314 css::uno::Reference
< css::xml::dom::XNode
> m_xParent
;
315 /// standard meta data (single occurrence)
316 std::map
< ::rtl::OUString
, css::uno::Reference
<css::xml::dom::XNode
> >
318 /// standard meta data (multiple occurrences)
319 std::map
< ::rtl::OUString
,
320 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> > > m_metaList
;
321 /// user-defined meta data (meta:user-defined) @ATTENTION may be null!
322 css::uno::Reference
<css::beans::XPropertyContainer
> m_xUserDefined
;
323 // now for some meta-data attributes; these are not updated directly in the
324 // DOM because updates (detecting "empty" elements) would be quite messy
325 ::rtl::OUString m_TemplateName
;
326 ::rtl::OUString m_TemplateURL
;
327 css::util::DateTime m_TemplateDate
;
328 ::rtl::OUString m_AutoloadURL
;
329 sal_Int32 m_AutoloadSecs
;
330 ::rtl::OUString m_DefaultTarget
;
332 /// check if we are initialized properly
333 void SAL_CALL
checkInit() const;
334 /// initialize state from given DOM tree
335 void SAL_CALL
init(css::uno::Reference
<css::xml::dom::XDocument
> i_xDom
);
336 /// update element in DOM tree
337 void SAL_CALL
updateElement(const char *i_name
,
338 std::vector
<std::pair
<const char *, ::rtl::OUString
> >* i_pAttrs
= 0);
339 /// update user-defined meta data and attributes in DOM tree
340 void SAL_CALL
updateUserDefinedAndAttributes();
341 /// create empty DOM tree (XDocument)
342 css::uno::Reference
<css::xml::dom::XDocument
> SAL_CALL
createDOM() const;
343 /// extract base URL (necessary for converting relative links)
344 css::uno::Reference
<css::beans::XPropertySet
> SAL_CALL
getURLProperties(
345 const css::uno::Sequence
<css::beans::PropertyValue
> & i_rMedium
) const;
346 /// get text of standard meta data element
347 ::rtl::OUString SAL_CALL
getMetaText(const char* i_name
) const;
348 /// set text of standard meta data element iff not equal to existing text
349 bool SAL_CALL
setMetaText(const char* i_name
,
350 const ::rtl::OUString
& i_rValue
);
351 /// set text of standard meta data element iff not equal to existing text
352 void SAL_CALL
setMetaTextAndNotify(const char* i_name
,
353 const ::rtl::OUString
& i_rValue
);
354 /// get text of standard meta data element's attribute
355 ::rtl::OUString SAL_CALL
getMetaAttr(const char* i_name
,
356 const char* i_attr
) const;
357 /// get text of a list of standard meta data elements (multiple occ.)
358 css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getMetaList(
359 const char* i_name
) const;
360 /// set text of a list of standard meta data elements (multiple occ.)
361 bool SAL_CALL
setMetaList(const char* i_name
,
362 const css::uno::Sequence
< ::rtl::OUString
> & i_rValue
,
363 AttrVector
const* = 0);
364 void createUserDefined();
367 typedef ::cppu::ImplInheritanceHelper1
< SfxDocumentMetaData
, css::document::XCompatWriterDocProperties
> CompatWriterDocPropsImpl_BASE
;
369 class CompatWriterDocPropsImpl
: public CompatWriterDocPropsImpl_BASE
371 rtl::OUString msManager
;
372 rtl::OUString msCategory
;
373 rtl::OUString msCompany
;
375 virtual SfxDocumentMetaData
* createMe( css::uno::Reference
< css::uno::XComponentContext
> const & context
) { return new CompatWriterDocPropsImpl( context
); };
377 CompatWriterDocPropsImpl( css::uno::Reference
< css::uno::XComponentContext
> const & context
) : CompatWriterDocPropsImpl_BASE( context
) {}
378 // XCompatWriterDocPropsImpl
379 virtual ::rtl::OUString SAL_CALL
getManager() throw (::com::sun::star::uno::RuntimeException
) { return msManager
; }
380 virtual void SAL_CALL
setManager( const ::rtl::OUString
& _manager
) throw (::com::sun::star::uno::RuntimeException
) { msManager
= _manager
; }
381 virtual ::rtl::OUString SAL_CALL
getCategory() throw (::com::sun::star::uno::RuntimeException
){ return msCategory
; }
382 virtual void SAL_CALL
setCategory( const ::rtl::OUString
& _category
) throw (::com::sun::star::uno::RuntimeException
){ msCategory
= _category
; }
383 virtual ::rtl::OUString SAL_CALL
getCompany() throw (::com::sun::star::uno::RuntimeException
){ return msCompany
; }
384 virtual void SAL_CALL
setCompany( const ::rtl::OUString
& _company
) throw (::com::sun::star::uno::RuntimeException
){ msCompany
= _company
; }
387 virtual ::rtl::OUString SAL_CALL
getImplementationName( ) throw (::com::sun::star::uno::RuntimeException
)
389 return comp_CompatWriterDocProps::_getImplementationName();
392 virtual ::sal_Bool SAL_CALL
supportsService( const ::rtl::OUString
& ServiceName
) throw (::com::sun::star::uno::RuntimeException
)
394 css::uno::Sequence
< rtl::OUString
> sServiceNames
= getSupportedServiceNames();
395 sal_Int32 nLen
= sServiceNames
.getLength();
396 rtl::OUString
* pIt
= sServiceNames
.getArray();
397 rtl::OUString
* pEnd
= ( pIt
+ nLen
);
398 sal_Bool bRes
= sal_False
;
399 for ( ; pIt
!= pEnd
; ++pIt
)
401 if ( pIt
->equals( ServiceName
) )
410 virtual ::com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException
)
412 return comp_CompatWriterDocProps::_getSupportedServiceNames();
416 bool operator== (const css::util::DateTime
&i_rLeft
,
417 const css::util::DateTime
&i_rRight
)
419 return i_rLeft
.Year
== i_rRight
.Year
420 && i_rLeft
.Month
== i_rRight
.Month
421 && i_rLeft
.Day
== i_rRight
.Day
422 && i_rLeft
.Hours
== i_rRight
.Hours
423 && i_rLeft
.Minutes
== i_rRight
.Minutes
424 && i_rLeft
.Seconds
== i_rRight
.Seconds
425 && i_rLeft
.HundredthSeconds
== i_rRight
.HundredthSeconds
;
428 // NB: keep these two arrays in sync!
429 const char* s_stdStatAttrs
[] = {
435 "meta:ole-object-count",
436 "meta:paragraph-count",
438 "meta:character-count",
441 "meta:sentence-count",
442 "meta:syllable-count",
443 "meta:non-whitespace-character-count",
448 // NB: keep these two arrays in sync!
449 const char* s_stdStats
[] = {
463 "NonWhitespaceCharacterCount",
468 const char* s_stdMeta
[] = {
469 "meta:generator", // string
470 "dc:title", // string
471 "dc:description", // string
472 "dc:subject", // string
473 "meta:initial-creator", // string
474 "dc:creator", // string
475 "meta:printed-by", // string
476 "meta:creation-date", // dateTime
477 "dc:date", // dateTime
478 "meta:print-date", // dateTime
479 "meta:template", // XLink
480 "meta:auto-reload", // ...
481 "meta:hyperlink-behaviour", // ...
482 "dc:language", // language
483 "meta:editing-cycles", // nonNegativeInteger
484 "meta:editing-duration", // duration
485 "meta:document-statistic", // ... // note: statistic is singular, no s!
489 const char* s_stdMetaList
[] = {
490 "meta:keyword", // string*
491 "meta:user-defined", // ...*
495 const char* s_nsXLink
= "http://www.w3.org/1999/xlink";
496 const char* s_nsDC
= "http://purl.org/dc/elements/1.1/";
497 const char* s_nsODF
= "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
498 const char* s_nsODFMeta
= "urn:oasis:names:tc:opendocument:xmlns:meta:1.0";
499 // const char* s_nsOOo = "http://openoffice.org/2004/office"; // not used (yet?)
501 static const char s_meta
[] = "meta.xml";
503 bool isValidDate(const css::util::Date
& i_rDate
)
505 return i_rDate
.Month
> 0;
508 bool isValidDateTime(const css::util::DateTime
& i_rDateTime
)
510 return i_rDateTime
.Month
> 0;
513 std::pair
< ::rtl::OUString
, ::rtl::OUString
> SAL_CALL
514 getQualifier(const char* i_name
) {
515 ::rtl::OUString nm
= ::rtl::OUString::createFromAscii(i_name
);
516 sal_Int32 ix
= nm
.indexOf(static_cast<sal_Unicode
> (':'));
518 return std::make_pair(::rtl::OUString(), nm
);
520 return std::make_pair(nm
.copy(0,ix
), nm
.copy(ix
+1));
524 // get namespace for standard qualified names
525 // NB: only call this with statically known strings!
526 ::rtl::OUString SAL_CALL
getNameSpace(const char* i_qname
) throw ()
528 DBG_ASSERT(i_qname
, "SfxDocumentMetaData: getNameSpace: argument is null");
529 const char * ns
= "";
530 ::rtl::OUString n
= getQualifier(i_qname
).first
;
531 if ( n
== "xlink" ) ns
= s_nsXLink
;
532 if ( n
== "dc" ) ns
= s_nsDC
;
533 if ( n
== "office" ) ns
= s_nsODF
;
534 if ( n
== "meta" ) ns
= s_nsODFMeta
;
535 DBG_ASSERT(*ns
, "SfxDocumentMetaData: unknown namespace prefix");
536 return ::rtl::OUString::createFromAscii(ns
);
540 textToDateOrDateTime(css::util::Date
& io_rd
, css::util::DateTime
& io_rdt
,
541 bool & o_rIsDateTime
, ::rtl::OUString i_text
) throw ()
543 if (::sax::Converter::convertDateOrDateTime(
544 io_rd
, io_rdt
, o_rIsDateTime
, i_text
)) {
547 DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
548 OUStringToOString(i_text
, RTL_TEXTENCODING_UTF8
).getStr());
553 // convert string to date/time
555 textToDateTime(css::util::DateTime
& io_rdt
, ::rtl::OUString i_text
) throw ()
557 if (::sax::Converter::convertDateTime(io_rdt
, i_text
)) {
560 DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
561 OUStringToOString(i_text
, RTL_TEXTENCODING_UTF8
).getStr());
566 // convert string to date/time with default return value
567 css::util::DateTime SAL_CALL
568 textToDateTimeDefault(::rtl::OUString i_text
) throw ()
570 css::util::DateTime dt
;
571 static_cast<void> (textToDateTime(dt
, i_text
));
572 // on conversion error: return default value (unchanged)
576 // convert date to string
577 ::rtl::OUString SAL_CALL
578 dateToText(css::util::Date
const& i_rd
) throw ()
580 if (isValidDate(i_rd
)) {
581 ::rtl::OUStringBuffer buf
;
582 ::sax::Converter::convertDate(buf
, i_rd
);
583 return buf
.makeStringAndClear();
585 return ::rtl::OUString();
590 // convert date/time to string
591 ::rtl::OUString SAL_CALL
592 dateTimeToText(css::util::DateTime
const& i_rdt
) throw ()
594 if (isValidDateTime(i_rdt
)) {
595 ::rtl::OUStringBuffer buf
;
596 ::sax::Converter::convertDateTime(buf
, i_rdt
, true);
597 return buf
.makeStringAndClear();
599 return ::rtl::OUString();
603 // convert string to duration
605 textToDuration(css::util::Duration
& io_rDur
, ::rtl::OUString
const& i_rText
)
608 if (::sax::Converter::convertDuration(io_rDur
, i_rText
)) {
611 DBG_WARNING1("SfxDocumentMetaData: invalid duration: %s",
612 OUStringToOString(i_rText
, RTL_TEXTENCODING_UTF8
).getStr());
617 sal_Int32
textToDuration(::rtl::OUString
const& i_rText
) throw ()
619 css::util::Duration d
;
620 if (textToDuration(d
, i_rText
)) {
621 // #i107372#: approximate years/months
622 const sal_Int32
days( (d
.Years
* 365) + (d
.Months
* 30) + d
.Days
);
623 return (days
* (24*3600))
624 + (d
.Hours
* 3600) + (d
.Minutes
* 60) + d
.Seconds
;
630 // convert duration to string
631 ::rtl::OUString
durationToText(css::util::Duration
const& i_rDur
) throw ()
633 ::rtl::OUStringBuffer buf
;
634 ::sax::Converter::convertDuration(buf
, i_rDur
);
635 return buf
.makeStringAndClear();
638 // convert duration to string
639 ::rtl::OUString SAL_CALL
durationToText(sal_Int32 i_value
) throw ()
641 css::util::Duration ud
;
642 ud
.Days
= static_cast<sal_Int16
>(i_value
/ (24 * 3600));
643 ud
.Hours
= static_cast<sal_Int16
>((i_value
% (24 * 3600)) / 3600);
644 ud
.Minutes
= static_cast<sal_Int16
>((i_value
% 3600) / 60);
645 ud
.Seconds
= static_cast<sal_Int16
>(i_value
% 60);
647 return durationToText(ud
);
650 // extract base URL (necessary for converting relative links)
651 css::uno::Reference
< css::beans::XPropertySet
> SAL_CALL
652 SfxDocumentMetaData::getURLProperties(
653 const css::uno::Sequence
< css::beans::PropertyValue
> & i_rMedium
) const
655 css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf (
656 m_xContext
->getServiceManager());
657 css::uno::Reference
< css::beans::XPropertyContainer
> xPropArg(
658 xMsf
->createInstanceWithContext(::rtl::OUString(
659 "com.sun.star.beans.PropertyBag"), m_xContext
),
660 css::uno::UNO_QUERY_THROW
);
662 ::rtl::OUString dburl
=
663 ::rtl::OUString("DocumentBaseURL");
664 ::rtl::OUString hdn
=
665 ::rtl::OUString("HierarchicalDocumentName");
666 for (sal_Int32 i
= 0; i
< i_rMedium
.getLength(); ++i
) {
667 if (i_rMedium
[i
].Name
.equals(dburl
)) {
668 xPropArg
->addProperty(
669 ::rtl::OUString("BaseURI"),
670 css::beans::PropertyAttribute::MAYBEVOID
,
672 } else if (i_rMedium
[i
].Name
.equals(hdn
)) {
673 xPropArg
->addProperty(
674 ::rtl::OUString("StreamRelPath"),
675 css::beans::PropertyAttribute::MAYBEVOID
,
679 xPropArg
->addProperty(::rtl::OUString("StreamName"),
680 css::beans::PropertyAttribute::MAYBEVOID
,
681 css::uno::makeAny(::rtl::OUString(s_meta
)));
682 } catch (const css::uno::Exception
&) {
685 return css::uno::Reference
< css::beans::XPropertySet
>(xPropArg
,
686 css::uno::UNO_QUERY_THROW
);
689 // return the text of the (hopefully unique, i.e., normalize first!) text
690 // node _below_ the given node
691 ::rtl::OUString SAL_CALL
692 getNodeText(css::uno::Reference
<css::xml::dom::XNode
> i_xNode
)
693 throw (css::uno::RuntimeException
)
695 if (!i_xNode
.is()) throw css::uno::RuntimeException(
697 "SfxDocumentMetaData::getNodeText: argument is null"), i_xNode
);
698 for (css::uno::Reference
<css::xml::dom::XNode
> c
= i_xNode
->getFirstChild();
700 c
= c
->getNextSibling()) {
701 if (c
->getNodeType() == css::xml::dom::NodeType_TEXT_NODE
) {
703 return c
->getNodeValue();
704 } catch (const css::xml::dom::DOMException
&) { // too big?
705 return ::rtl::OUString();
709 return ::rtl::OUString();
712 ::rtl::OUString SAL_CALL
713 SfxDocumentMetaData::getMetaText(const char* i_name
) const
714 // throw (css::uno::RuntimeException)
718 const ::rtl::OUString
name( ::rtl::OUString::createFromAscii(i_name
) );
719 DBG_ASSERT(m_meta
.find(name
) != m_meta
.end(),
720 "SfxDocumentMetaData::getMetaText: not found");
721 css::uno::Reference
<css::xml::dom::XNode
> xNode
= m_meta
.find(name
)->second
;
722 return (xNode
.is()) ? getNodeText(xNode
) : ::rtl::OUString();
726 SfxDocumentMetaData::setMetaText(const char* i_name
,
727 const ::rtl::OUString
& i_rValue
)
728 // throw (css::uno::RuntimeException)
732 const ::rtl::OUString
name( ::rtl::OUString::createFromAscii(i_name
) );
733 DBG_ASSERT(m_meta
.find(name
) != m_meta
.end(),
734 "SfxDocumentMetaData::setMetaText: not found");
735 css::uno::Reference
<css::xml::dom::XNode
> xNode
= m_meta
.find(name
)->second
;
738 if (i_rValue
.isEmpty()) {
739 if (xNode
.is()) { // delete
740 m_xParent
->removeChild(xNode
);
742 m_meta
[name
] = xNode
;
748 if (xNode
.is()) { // update
749 for (css::uno::Reference
<css::xml::dom::XNode
> c
=
750 xNode
->getFirstChild();
752 c
= c
->getNextSibling()) {
753 if (c
->getNodeType() == css::xml::dom::NodeType_TEXT_NODE
) {
754 if (!c
->getNodeValue().equals(i_rValue
)) {
755 c
->setNodeValue(i_rValue
);
763 xNode
.set(m_xDoc
->createElementNS(getNameSpace(i_name
), name
),
764 css::uno::UNO_QUERY_THROW
);
765 m_xParent
->appendChild(xNode
);
766 m_meta
[name
] = xNode
;
768 css::uno::Reference
<css::xml::dom::XNode
> xTextNode(
769 m_xDoc
->createTextNode(i_rValue
), css::uno::UNO_QUERY_THROW
);
770 xNode
->appendChild(xTextNode
);
773 } catch (const css::xml::dom::DOMException
& e
) {
775 throw css::lang::WrappedTargetRuntimeException(
777 "SfxDocumentMetaData::setMetaText: DOM exception"),
778 css::uno::Reference
<css::uno::XInterface
>(*this), a
);
783 SfxDocumentMetaData::setMetaTextAndNotify(const char* i_name
,
784 const ::rtl::OUString
& i_rValue
)
785 // throw (css::uno::RuntimeException)
787 ::osl::ClearableMutexGuard
g(m_aMutex
);
788 if (setMetaText(i_name
, i_rValue
)) {
794 ::rtl::OUString SAL_CALL
795 SfxDocumentMetaData::getMetaAttr(const char* i_name
, const char* i_attr
) const
796 // throw (css::uno::RuntimeException)
798 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(i_name
);
799 DBG_ASSERT(m_meta
.find(name
) != m_meta
.end(),
800 "SfxDocumentMetaData::getMetaAttr: not found");
801 css::uno::Reference
<css::xml::dom::XNode
> xNode
= m_meta
.find(name
)->second
;
803 css::uno::Reference
<css::xml::dom::XElement
> xElem(xNode
,
804 css::uno::UNO_QUERY_THROW
);
805 return xElem
->getAttributeNS(getNameSpace(i_attr
),
806 getQualifier(i_attr
).second
);
808 return ::rtl::OUString();
812 css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
813 SfxDocumentMetaData::getMetaList(const char* i_name
) const
814 // throw (css::uno::RuntimeException)
817 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(i_name
);
818 DBG_ASSERT(m_metaList
.find(name
) != m_metaList
.end(),
819 "SfxDocumentMetaData::getMetaList: not found");
820 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> > const & vec
=
821 m_metaList
.find(name
)->second
;
822 css::uno::Sequence
< ::rtl::OUString
> ret(vec
.size());
823 for (size_t i
= 0; i
< vec
.size(); ++i
) {
824 ret
[i
] = getNodeText(vec
.at(i
));
830 SfxDocumentMetaData::setMetaList(const char* i_name
,
831 const css::uno::Sequence
< ::rtl::OUString
> & i_rValue
,
832 AttrVector
const* i_pAttrs
)
833 // throw (css::uno::RuntimeException)
836 DBG_ASSERT((i_pAttrs
== 0) ||
837 (static_cast<size_t>(i_rValue
.getLength()) == i_pAttrs
->size()),
838 "SfxDocumentMetaData::setMetaList: invalid args");
841 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(i_name
);
842 DBG_ASSERT(m_metaList
.find(name
) != m_metaList
.end(),
843 "SfxDocumentMetaData::setMetaList: not found");
844 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> > & vec
=
847 // if nothing changed, do nothing
848 // alas, this does not check for permutations, or attributes...
849 if ((0 == i_pAttrs
)) {
850 if (static_cast<size_t>(i_rValue
.getLength()) == vec
.size()) {
852 for (sal_Int32 i
= 0; i
< i_rValue
.getLength(); ++i
) {
853 css::uno::Reference
<css::xml::dom::XNode
> xNode(vec
.at(i
));
855 ::rtl::OUString val
= getNodeText(xNode
);
856 if (!val
.equals(i_rValue
[i
])) {
862 if (isEqual
) return false;
866 // remove old meta data nodes
868 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> >
869 ::reverse_iterator
it(vec
.rbegin());
871 for ( ;it
!= vec
.rend(); ++it
)
873 m_xParent
->removeChild(*it
);
878 // Clean up already removed nodes
879 vec
.erase(it
.base(), vec
.end());
885 // insert new meta data nodes into DOM tree
886 for (sal_Int32 i
= 0; i
< i_rValue
.getLength(); ++i
) {
887 css::uno::Reference
<css::xml::dom::XElement
> xElem(
888 m_xDoc
->createElementNS(getNameSpace(i_name
), name
),
889 css::uno::UNO_QUERY_THROW
);
890 css::uno::Reference
<css::xml::dom::XNode
> xNode(xElem
,
891 css::uno::UNO_QUERY_THROW
);
892 css::uno::Reference
<css::xml::dom::XNode
> xTextNode(
893 m_xDoc
->createTextNode(i_rValue
[i
]), css::uno::UNO_QUERY_THROW
);
896 for (std::vector
<std::pair
<const char*, ::rtl::OUString
> >
897 ::const_iterator it
= (*i_pAttrs
)[i
].begin();
898 it
!= (*i_pAttrs
)[i
].end(); ++it
) {
899 xElem
->setAttributeNS(getNameSpace(it
->first
),
900 ::rtl::OUString::createFromAscii(it
->first
),
904 xNode
->appendChild(xTextNode
);
905 m_xParent
->appendChild(xNode
);
906 vec
.push_back(xNode
);
910 } catch (const css::xml::dom::DOMException
& e
) {
912 throw css::lang::WrappedTargetRuntimeException(
914 "SfxDocumentMetaData::setMetaList: DOM exception"),
915 css::uno::Reference
<css::uno::XInterface
>(*this), a
);
919 // convert property list to string list and attribute list
920 std::pair
<css::uno::Sequence
< ::rtl::OUString
>, AttrVector
> SAL_CALL
921 propsToStrings(css::uno::Reference
<css::beans::XPropertySet
> const & i_xPropSet
)
923 ::comphelper::SequenceAsVector
< ::rtl::OUString
> values
;
926 css::uno::Reference
<css::beans::XPropertySetInfo
> xSetInfo
927 = i_xPropSet
->getPropertySetInfo();
928 css::uno::Sequence
<css::beans::Property
> props
= xSetInfo
->getProperties();
930 for (sal_Int32 i
= 0; i
< props
.getLength(); ++i
) {
931 if (props
[i
].Attributes
& css::beans::PropertyAttribute::TRANSIENT
) {
934 const ::rtl::OUString name
= props
[i
].Name
;
937 any
= i_xPropSet
->getPropertyValue(name
);
938 } catch (const css::uno::Exception
&) {
941 const css::uno::Type
& type
= any
.getValueType();
942 std::vector
<std::pair
<const char*, ::rtl::OUString
> > as
;
943 as
.push_back(std::make_pair(static_cast<const char*>("meta:name"),
945 const char* vt
= "meta:value-type";
947 // convert according to type
948 if (type
== ::cppu::UnoType
<bool>::get()) {
951 ::rtl::OUStringBuffer buf
;
952 ::sax::Converter::convertBool(buf
, b
);
953 values
.push_back(buf
.makeStringAndClear());
954 as
.push_back(std::make_pair(vt
,
955 ::rtl::OUString("boolean")));
956 } else if (type
== ::cppu::UnoType
< ::rtl::OUString
>::get()) {
960 // #i90847# OOo 2.x does stupid things if value-type="string";
961 // fortunately string is default anyway, so we can just omit it
962 // #i107502#: however, OOo 2.x only reads 4 user-defined without @value-type
963 // => best backward compatibility: first 4 without @value-type, rest with
966 as
.push_back(std::make_pair(vt
,
967 ::rtl::OUString("string")));
969 } else if (type
== ::cppu::UnoType
<css::util::DateTime
>::get()) {
970 css::util::DateTime dt
;
972 values
.push_back(dateTimeToText(dt
));
973 as
.push_back(std::make_pair(vt
,
974 ::rtl::OUString("date")));
975 } else if (type
== ::cppu::UnoType
<css::util::Date
>::get()) {
978 values
.push_back(dateToText(d
));
979 as
.push_back(std::make_pair(vt
,
980 ::rtl::OUString("date")));
981 } else if (type
== ::cppu::UnoType
<css::util::Time
>::get()) {
982 // #i97029#: replaced by Duration
983 // Time is supported for backward compatibility with OOo 3.x, x<=2
986 css::util::Duration ud
;
988 ud
.Minutes
= ut
.Minutes
;
989 ud
.Seconds
= ut
.Seconds
;
990 ud
.MilliSeconds
= 10 * ut
.HundredthSeconds
;
991 values
.push_back(durationToText(ud
));
992 as
.push_back(std::make_pair(vt
,
993 ::rtl::OUString("time")));
994 } else if (type
== ::cppu::UnoType
<css::util::Duration
>::get()) {
995 css::util::Duration ud
;
997 values
.push_back(durationToText(ud
));
998 as
.push_back(std::make_pair(vt
,
999 ::rtl::OUString("time")));
1000 } else if (::cppu::UnoType
<double>::get().isAssignableFrom(type
)) {
1001 // support not just double, but anything that can be converted
1004 ::rtl::OUStringBuffer buf
;
1005 ::sax::Converter::convertDouble(buf
, d
);
1006 values
.push_back(buf
.makeStringAndClear());
1007 as
.push_back(std::make_pair(vt
,
1008 ::rtl::OUString("float")));
1010 DBG_WARNING1("SfxDocumentMetaData: unsupported property type: %s",
1011 OUStringToOString(any
.getValueTypeName(),
1012 RTL_TEXTENCODING_UTF8
).getStr());
1015 attrs
.push_back(as
);
1018 return std::make_pair(values
.getAsConstList(), attrs
);
1021 // remove the given element from the DOM, and iff i_pAttrs != 0 insert new one
1023 SfxDocumentMetaData::updateElement(const char *i_name
,
1024 std::vector
<std::pair
<const char *, ::rtl::OUString
> >* i_pAttrs
)
1026 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(i_name
);
1028 // remove old element
1029 css::uno::Reference
<css::xml::dom::XNode
> xNode
=
1030 m_meta
.find(name
)->second
;
1032 m_xParent
->removeChild(xNode
);
1036 if (0 != i_pAttrs
) {
1037 css::uno::Reference
<css::xml::dom::XElement
> xElem(
1038 m_xDoc
->createElementNS(getNameSpace(i_name
), name
),
1039 css::uno::UNO_QUERY_THROW
);
1040 xNode
.set(xElem
, css::uno::UNO_QUERY_THROW
);
1042 for (std::vector
<std::pair
<const char *, ::rtl::OUString
> >
1043 ::const_iterator it
= i_pAttrs
->begin();
1044 it
!= i_pAttrs
->end(); ++it
) {
1045 xElem
->setAttributeNS(getNameSpace(it
->first
),
1046 ::rtl::OUString::createFromAscii(it
->first
), it
->second
);
1048 m_xParent
->appendChild(xNode
);
1050 m_meta
[name
] = xNode
;
1051 } catch (const css::xml::dom::DOMException
& e
) {
1053 throw css::lang::WrappedTargetRuntimeException(
1055 "SfxDocumentMetaData::updateElement: DOM exception"),
1056 css::uno::Reference
<css::uno::XInterface
>(*this), a
);
1060 // update user-defined meta data in DOM tree
1061 void SAL_CALL
SfxDocumentMetaData::updateUserDefinedAndAttributes()
1063 createUserDefined();
1064 const css::uno::Reference
<css::beans::XPropertySet
> xPSet(m_xUserDefined
,
1065 css::uno::UNO_QUERY_THROW
);
1066 const std::pair
<css::uno::Sequence
< ::rtl::OUString
>, AttrVector
>
1067 udStringsAttrs( propsToStrings(xPSet
) );
1068 (void) setMetaList("meta:user-defined", udStringsAttrs
.first
,
1069 &udStringsAttrs
.second
);
1071 // update elements with attributes
1072 std::vector
<std::pair
<const char *, ::rtl::OUString
> > attributes
;
1073 if (!m_TemplateName
.isEmpty() || !m_TemplateURL
.isEmpty()
1074 || isValidDateTime(m_TemplateDate
)) {
1075 attributes
.push_back(std::make_pair(
1076 static_cast<const char*>("xlink:type"),
1077 ::rtl::OUString("simple")));
1078 attributes
.push_back(std::make_pair(
1079 static_cast<const char*>("xlink:actuate"),
1080 ::rtl::OUString("onRequest")));
1081 attributes
.push_back(std::make_pair(
1082 static_cast<const char*>("xlink:title"), m_TemplateName
));
1083 attributes
.push_back(std::make_pair(
1084 static_cast<const char*>("xlink:href" ), m_TemplateURL
));
1085 if (isValidDateTime(m_TemplateDate
)) {
1086 attributes
.push_back(std::make_pair(
1087 static_cast<const char*>("meta:date" ),
1088 dateTimeToText(m_TemplateDate
)));
1090 updateElement("meta:template", &attributes
);
1092 updateElement("meta:template");
1096 if (!m_AutoloadURL
.isEmpty() || (0 != m_AutoloadSecs
)) {
1097 attributes
.push_back(std::make_pair(
1098 static_cast<const char*>("xlink:href" ), m_AutoloadURL
));
1099 attributes
.push_back(std::make_pair(
1100 static_cast<const char*>("meta:delay" ),
1101 durationToText(m_AutoloadSecs
)));
1102 updateElement("meta:auto-reload", &attributes
);
1104 updateElement("meta:auto-reload");
1108 if (!m_DefaultTarget
.isEmpty()) {
1109 attributes
.push_back(std::make_pair(
1110 static_cast<const char*>("office:target-frame-name"),
1112 // xlink:show: _blank -> new, any other value -> replace
1113 const sal_Char
* show
= m_DefaultTarget
== "_blank" ? "new" : "replace";
1114 attributes
.push_back(std::make_pair(
1115 static_cast<const char*>("xlink:show"),
1116 ::rtl::OUString::createFromAscii(show
)));
1117 updateElement("meta:hyperlink-behaviour", &attributes
);
1119 updateElement("meta:hyperlink-behaviour");
1124 // create empty DOM tree (XDocument)
1125 css::uno::Reference
<css::xml::dom::XDocument
> SAL_CALL
1126 SfxDocumentMetaData::createDOM() const // throw (css::uno::RuntimeException)
1128 css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf (
1129 m_xContext
->getServiceManager());
1130 css::uno::Reference
<css::xml::dom::XDocumentBuilder
> xBuilder(
1131 xMsf
->createInstanceWithContext(::rtl::OUString(
1132 "com.sun.star.xml.dom.DocumentBuilder"), m_xContext
),
1133 css::uno::UNO_QUERY_THROW
);
1134 if (!xBuilder
.is()) throw css::uno::RuntimeException(
1135 ::rtl::OUString("SfxDocumentMetaData::createDOM: "
1136 "cannot create DocumentBuilder service"),
1137 *const_cast<SfxDocumentMetaData
*>(this));
1138 css::uno::Reference
<css::xml::dom::XDocument
> xDoc
=
1139 xBuilder
->newDocument();
1140 if (!xDoc
.is()) throw css::uno::RuntimeException(
1141 ::rtl::OUString("SfxDocumentMetaData::createDOM: "
1142 "cannot create new document"),
1143 *const_cast<SfxDocumentMetaData
*>(this));
1148 SfxDocumentMetaData::checkInit() const // throw (css::uno::RuntimeException)
1150 if (!m_isInitialized
) {
1151 throw css::uno::RuntimeException(::rtl::OUString(
1152 "SfxDocumentMetaData::checkInit: not initialized"),
1153 *const_cast<SfxDocumentMetaData
*>(this));
1155 DBG_ASSERT((m_xDoc
.is() && m_xParent
.is() ),
1156 "SfxDocumentMetaData::checkInit: reference is null");
1159 // initialize state from DOM tree
1160 void SAL_CALL
SfxDocumentMetaData::init(
1161 css::uno::Reference
<css::xml::dom::XDocument
> i_xDoc
)
1163 if (!i_xDoc
.is()) throw css::uno::RuntimeException(
1165 "SfxDocumentMetaData::init: no DOM tree given"), *this);
1167 css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf (
1168 m_xContext
->getServiceManager());
1169 css::uno::Reference
<css::xml::xpath::XXPathAPI
> xPath(
1170 xMsf
->createInstanceWithContext(::rtl::OUString(
1171 "com.sun.star.xml.xpath.XPathAPI"), m_xContext
),
1172 css::uno::UNO_QUERY_THROW
);
1173 if (!xPath
.is()) throw css::uno::RuntimeException(
1174 ::rtl::OUString("SfxDocumentMetaData::init:"
1175 " cannot create XPathAPI service"), *this);
1177 m_isInitialized
= false;
1180 // select nodes for standard meta data stuff
1181 xPath
->registerNS(::rtl::OUString("xlink"),
1182 ::rtl::OUString::createFromAscii(s_nsXLink
));
1183 xPath
->registerNS(::rtl::OUString("dc"),
1184 ::rtl::OUString::createFromAscii(s_nsDC
));
1185 xPath
->registerNS(::rtl::OUString("office"),
1186 ::rtl::OUString::createFromAscii(s_nsODF
));
1187 xPath
->registerNS(::rtl::OUString("meta"),
1188 ::rtl::OUString::createFromAscii(s_nsODFMeta
));
1189 // NB: we do not handle the single-XML-file ODF variant, which would
1190 // have the root element office:document.
1191 // The root of such documents must be converted in the importer!
1192 ::rtl::OUString
prefix(
1193 "/child::office:document-meta/child::office:meta");
1194 css::uno::Reference
<css::xml::dom::XNode
> xDocNode(
1195 m_xDoc
, css::uno::UNO_QUERY_THROW
);
1198 m_xParent
= xPath
->selectSingleNode(xDocNode
, prefix
);
1199 } catch (const com::sun::star::uno::Exception
&) {
1202 if (!m_xParent
.is()) {
1203 // all this create/append stuff may throw DOMException
1205 css::uno::Reference
<css::xml::dom::XElement
> xRElem
;
1206 css::uno::Reference
<css::xml::dom::XNode
> xNode(
1207 i_xDoc
->getFirstChild());
1208 while (xNode
.is()) {
1209 if (css::xml::dom::NodeType_ELEMENT_NODE
==xNode
->getNodeType())
1211 if ( xNode
->getNamespaceURI().equalsAscii(s_nsODF
) && xNode
->getLocalName() == "document-meta" )
1213 xRElem
.set(xNode
, css::uno::UNO_QUERY_THROW
);
1218 OSL_TRACE("SfxDocumentMetaData::init(): "
1219 "deleting unexpected root element: %s",
1220 ::rtl::OUStringToOString(xNode
->getLocalName(),
1221 RTL_TEXTENCODING_UTF8
).getStr());
1222 i_xDoc
->removeChild(xNode
);
1223 xNode
= i_xDoc
->getFirstChild(); // start over
1226 xNode
= xNode
->getNextSibling();
1230 xRElem
= i_xDoc
->createElementNS(
1231 ::rtl::OUString::createFromAscii(s_nsODF
),
1232 ::rtl::OUString("office:document-meta"));
1233 css::uno::Reference
<css::xml::dom::XNode
> xRNode(xRElem
,
1234 css::uno::UNO_QUERY_THROW
);
1235 i_xDoc
->appendChild(xRNode
);
1237 xRElem
->setAttributeNS(::rtl::OUString::createFromAscii(s_nsODF
),
1238 ::rtl::OUString("office:version"),
1239 ::rtl::OUString("1.0"));
1240 // does not exist, otherwise m_xParent would not be null
1241 css::uno::Reference
<css::xml::dom::XNode
> xParent (
1242 i_xDoc
->createElementNS(
1243 ::rtl::OUString::createFromAscii(s_nsODF
),
1244 ::rtl::OUString("office:meta")),
1245 css::uno::UNO_QUERY_THROW
);
1246 xRElem
->appendChild(xParent
);
1247 m_xParent
= xParent
;
1248 } catch (const css::xml::dom::DOMException
& e
) {
1250 throw css::lang::WrappedTargetRuntimeException(
1252 "SfxDocumentMetaData::init: DOM exception"),
1253 css::uno::Reference
<css::uno::XInterface
>(*this), a
);
1258 // select nodes for elements of which we only handle one occurrence
1259 for (const char **pName
= s_stdMeta
; *pName
!= 0; ++pName
) {
1260 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(*pName
);
1261 // NB: If a document contains more than one occurrence of a
1262 // meta-data element, we arbitrarily pick one of them here.
1263 // We do not remove the others, i.e., when we write the
1264 // document, it will contain the duplicates unchanged.
1265 // The ODF spec says that handling multiple occurrences is
1266 // application-specific.
1267 css::uno::Reference
<css::xml::dom::XNode
> xNode
=
1268 xPath
->selectSingleNode(m_xParent
,
1269 ::rtl::OUString("child::") + name
);
1270 // Do not create an empty element if it is missing;
1271 // for certain elements, such as dateTime, this would be invalid
1272 m_meta
[name
] = xNode
;
1275 // select nodes for elements of which we handle all occurrences
1276 for (const char **pName
= s_stdMetaList
; *pName
!= 0; ++pName
) {
1277 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(*pName
);
1278 css::uno::Reference
<css::xml::dom::XNodeList
> nodes
=
1279 xPath
->selectNodeList(m_xParent
,
1280 ::rtl::OUString("child::") + name
);
1281 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> > v
;
1282 for (sal_Int32 i
= 0; i
< nodes
->getLength(); ++i
) {
1283 v
.push_back(nodes
->item(i
));
1285 m_metaList
[name
] = v
;
1288 // initialize members corresponding to attributes from DOM nodes
1289 m_TemplateName
= getMetaAttr("meta:template", "xlink:title");
1290 m_TemplateURL
= getMetaAttr("meta:template", "xlink:href");
1292 textToDateTimeDefault(getMetaAttr("meta:template", "meta:date"));
1293 m_AutoloadURL
= getMetaAttr("meta:auto-reload", "xlink:href");
1295 textToDuration(getMetaAttr("meta:auto-reload", "meta:delay"));
1297 getMetaAttr("meta:hyperlink-behaviour", "office:target-frame-name");
1300 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> > & vec
=
1301 m_metaList
[::rtl::OUString("meta:user-defined")];
1302 m_xUserDefined
.clear(); // #i105826#: reset (may be re-initialization)
1305 createUserDefined();
1308 // user-defined meta data: initialize PropertySet from DOM nodes
1309 for (std::vector
<css::uno::Reference
<css::xml::dom::XNode
> >::iterator
1310 it
= vec
.begin(); it
!= vec
.end(); ++it
) {
1311 css::uno::Reference
<css::xml::dom::XElement
> xElem(*it
,
1312 css::uno::UNO_QUERY_THROW
);
1314 ::rtl::OUString name
= xElem
->getAttributeNS(
1315 ::rtl::OUString::createFromAscii(s_nsODFMeta
),
1316 ::rtl::OUString("name"));
1317 ::rtl::OUString type
= xElem
->getAttributeNS(
1318 ::rtl::OUString::createFromAscii(s_nsODFMeta
),
1319 ::rtl::OUString("value-type"));
1320 ::rtl::OUString text
= getNodeText(*it
);
1321 if ( type
== "float" ) {
1323 if (::sax::Converter::convertDouble(d
, text
)) {
1326 DBG_WARNING1("SfxDocumentMetaData: invalid float: %s",
1327 OUStringToOString(text
, RTL_TEXTENCODING_UTF8
).getStr());
1330 } else if ( type
== "date" ) {
1333 css::util::DateTime dt
;
1334 if (textToDateOrDateTime(d
, dt
, isDateTime
, text
)) {
1341 DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
1342 OUStringToOString(text
, RTL_TEXTENCODING_UTF8
).getStr());
1345 } else if ( type
== "time" ) {
1346 css::util::Duration ud
;
1347 if (textToDuration(ud
, text
)) {
1350 DBG_WARNING1("SfxDocumentMetaData: invalid time: %s",
1351 OUStringToOString(text
, RTL_TEXTENCODING_UTF8
).getStr());
1354 } else if ( type
== "boolean" ) {
1356 if (::sax::Converter::convertBool(b
, text
)) {
1359 DBG_WARNING1("SfxDocumentMetaData: invalid boolean: %s",
1360 OUStringToOString(text
, RTL_TEXTENCODING_UTF8
).getStr());
1363 } else if ( type
== "string" || true) { // default
1367 m_xUserDefined
->addProperty(name
,
1368 css::beans::PropertyAttribute::REMOVEABLE
, any
);
1369 } catch (const css::beans::PropertyExistException
&) {
1370 DBG_WARNING1("SfxDocumentMetaData: duplicate: %s",
1371 OUStringToOString(name
, RTL_TEXTENCODING_UTF8
).getStr());
1372 // ignore; duplicate
1373 } catch (const css::beans::IllegalTypeException
&) {
1374 OSL_TRACE("SfxDocumentMetaData: illegal type: %s",
1375 OUStringToOString(name
, RTL_TEXTENCODING_UTF8
).getStr());
1376 } catch (const css::lang::IllegalArgumentException
&) {
1377 OSL_TRACE("SfxDocumentMetaData: illegal arg: %s",
1378 OUStringToOString(name
, RTL_TEXTENCODING_UTF8
).getStr());
1382 m_isModified
= false;
1383 m_isInitialized
= true;
1388 SfxDocumentMetaData::SfxDocumentMetaData(
1389 css::uno::Reference
< css::uno::XComponentContext
> const & context
)
1391 , SfxDocumentMetaData_Base(m_aMutex
)
1392 , m_xContext(context
)
1393 , m_NotifyListeners(m_aMutex
)
1394 , m_isInitialized(false)
1395 , m_isModified(false)
1398 DBG_ASSERT(context
.is(), "SfxDocumentMetaData: context is null");
1399 DBG_ASSERT(context
->getServiceManager().is(),
1400 "SfxDocumentMetaData: context has no service manager");
1404 // com.sun.star.uno.XServiceInfo:
1405 ::rtl::OUString SAL_CALL
1406 SfxDocumentMetaData::getImplementationName() throw (css::uno::RuntimeException
)
1408 return comp_SfxDocumentMetaData::_getImplementationName();
1412 SfxDocumentMetaData::supportsService(::rtl::OUString
const & serviceName
)
1413 throw (css::uno::RuntimeException
)
1415 css::uno::Sequence
< ::rtl::OUString
> serviceNames
=
1416 comp_SfxDocumentMetaData::_getSupportedServiceNames();
1417 for (::sal_Int32 i
= 0; i
< serviceNames
.getLength(); ++i
) {
1418 if (serviceNames
[i
] == serviceName
)
1424 css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
1425 SfxDocumentMetaData::getSupportedServiceNames()
1426 throw (css::uno::RuntimeException
)
1428 return comp_SfxDocumentMetaData::_getSupportedServiceNames();
1432 // ::com::sun::star::lang::XComponent:
1433 void SAL_CALL
SfxDocumentMetaData::dispose() throw (css::uno::RuntimeException
)
1435 ::osl::MutexGuard
g(m_aMutex
);
1436 if (!m_isInitialized
) {
1439 WeakComponentImplHelperBase::dispose(); // superclass
1440 m_NotifyListeners
.disposeAndClear(css::lang::EventObject(
1441 static_cast< ::cppu::OWeakObject
* >(this)));
1442 m_isInitialized
= false;
1447 m_xUserDefined
.clear();
1451 // ::com::sun::star::document::XDocumentProperties:
1452 ::rtl::OUString SAL_CALL
1453 SfxDocumentMetaData::getAuthor() throw (css::uno::RuntimeException
)
1455 ::osl::MutexGuard
g(m_aMutex
);
1456 return getMetaText("meta:initial-creator");
1459 void SAL_CALL
SfxDocumentMetaData::setAuthor(const ::rtl::OUString
& the_value
)
1460 throw (css::uno::RuntimeException
)
1462 setMetaTextAndNotify("meta:initial-creator", the_value
);
1466 ::rtl::OUString SAL_CALL
1467 SfxDocumentMetaData::getGenerator() throw (css::uno::RuntimeException
)
1469 ::osl::MutexGuard
g(m_aMutex
);
1470 return getMetaText("meta:generator");
1474 SfxDocumentMetaData::setGenerator(const ::rtl::OUString
& the_value
)
1475 throw (css::uno::RuntimeException
)
1477 setMetaTextAndNotify("meta:generator", the_value
);
1480 css::util::DateTime SAL_CALL
1481 SfxDocumentMetaData::getCreationDate() throw (css::uno::RuntimeException
)
1483 ::osl::MutexGuard
g(m_aMutex
);
1484 return textToDateTimeDefault(getMetaText("meta:creation-date"));
1488 SfxDocumentMetaData::setCreationDate(const css::util::DateTime
& the_value
)
1489 throw (css::uno::RuntimeException
)
1491 setMetaTextAndNotify("meta:creation-date", dateTimeToText(the_value
));
1494 ::rtl::OUString SAL_CALL
1495 SfxDocumentMetaData::getTitle() throw (css::uno::RuntimeException
)
1497 ::osl::MutexGuard
g(m_aMutex
);
1498 return getMetaText("dc:title");
1501 void SAL_CALL
SfxDocumentMetaData::setTitle(const ::rtl::OUString
& the_value
)
1502 throw (css::uno::RuntimeException
)
1504 setMetaTextAndNotify("dc:title", the_value
);
1507 ::rtl::OUString SAL_CALL
1508 SfxDocumentMetaData::getSubject() throw (css::uno::RuntimeException
)
1510 ::osl::MutexGuard
g(m_aMutex
);
1511 return getMetaText("dc:subject");
1515 SfxDocumentMetaData::setSubject(const ::rtl::OUString
& the_value
)
1516 throw (css::uno::RuntimeException
)
1518 setMetaTextAndNotify("dc:subject", the_value
);
1521 ::rtl::OUString SAL_CALL
1522 SfxDocumentMetaData::getDescription() throw (css::uno::RuntimeException
)
1524 ::osl::MutexGuard
g(m_aMutex
);
1525 return getMetaText("dc:description");
1529 SfxDocumentMetaData::setDescription(const ::rtl::OUString
& the_value
)
1530 throw (css::uno::RuntimeException
)
1532 setMetaTextAndNotify("dc:description", the_value
);
1535 css::uno::Sequence
< ::rtl::OUString
>
1536 SAL_CALL
SfxDocumentMetaData::getKeywords() throw (css::uno::RuntimeException
)
1538 ::osl::MutexGuard
g(m_aMutex
);
1539 return getMetaList("meta:keyword");
1543 SfxDocumentMetaData::setKeywords(
1544 const css::uno::Sequence
< ::rtl::OUString
> & the_value
)
1545 throw (css::uno::RuntimeException
)
1547 ::osl::ClearableMutexGuard
g(m_aMutex
);
1548 if (setMetaList("meta:keyword", the_value
)) {
1554 css::lang::Locale SAL_CALL
1555 SfxDocumentMetaData::getLanguage() throw (css::uno::RuntimeException
)
1557 ::osl::MutexGuard
g(m_aMutex
);
1558 css::lang::Locale loc
;
1559 ::rtl::OUString text
= getMetaText("dc:language");
1560 sal_Int32 ix
= text
.indexOf(static_cast<sal_Unicode
> ('-'));
1562 loc
.Language
= text
;
1564 loc
.Language
= text
.copy(0, ix
);
1565 loc
.Country
= text
.copy(ix
+1);
1571 SfxDocumentMetaData::setLanguage(const css::lang::Locale
& the_value
)
1572 throw (css::uno::RuntimeException
)
1574 ::rtl::OUString text
= the_value
.Language
;
1575 if (!the_value
.Country
.isEmpty()) {
1576 text
+= ::rtl::OUString("-").concat(the_value
.Country
);
1578 setMetaTextAndNotify("dc:language", text
);
1581 ::rtl::OUString SAL_CALL
1582 SfxDocumentMetaData::getModifiedBy() throw (css::uno::RuntimeException
)
1584 ::osl::MutexGuard
g(m_aMutex
);
1585 return getMetaText("dc:creator");
1589 SfxDocumentMetaData::setModifiedBy(const ::rtl::OUString
& the_value
)
1590 throw (css::uno::RuntimeException
)
1592 setMetaTextAndNotify("dc:creator", the_value
);
1595 css::util::DateTime SAL_CALL
1596 SfxDocumentMetaData::getModificationDate() throw (css::uno::RuntimeException
)
1598 ::osl::MutexGuard
g(m_aMutex
);
1599 return textToDateTimeDefault(getMetaText("dc:date"));
1603 SfxDocumentMetaData::setModificationDate(const css::util::DateTime
& the_value
)
1604 throw (css::uno::RuntimeException
)
1606 setMetaTextAndNotify("dc:date", dateTimeToText(the_value
));
1609 ::rtl::OUString SAL_CALL
1610 SfxDocumentMetaData::getPrintedBy() throw (css::uno::RuntimeException
)
1612 ::osl::MutexGuard
g(m_aMutex
);
1613 return getMetaText("meta:printed-by");
1617 SfxDocumentMetaData::setPrintedBy(const ::rtl::OUString
& the_value
)
1618 throw (css::uno::RuntimeException
)
1620 setMetaTextAndNotify("meta:printed-by", the_value
);
1623 css::util::DateTime SAL_CALL
1624 SfxDocumentMetaData::getPrintDate() throw (css::uno::RuntimeException
)
1626 ::osl::MutexGuard
g(m_aMutex
);
1627 return textToDateTimeDefault(getMetaText("meta:print-date"));
1631 SfxDocumentMetaData::setPrintDate(const css::util::DateTime
& the_value
)
1632 throw (css::uno::RuntimeException
)
1634 setMetaTextAndNotify("meta:print-date", dateTimeToText(the_value
));
1637 ::rtl::OUString SAL_CALL
1638 SfxDocumentMetaData::getTemplateName() throw (css::uno::RuntimeException
)
1640 ::osl::MutexGuard
g(m_aMutex
);
1642 return m_TemplateName
;
1646 SfxDocumentMetaData::setTemplateName(const ::rtl::OUString
& the_value
)
1647 throw (css::uno::RuntimeException
)
1649 ::osl::ClearableMutexGuard
g(m_aMutex
);
1651 if (m_TemplateName
!= the_value
) {
1652 m_TemplateName
= the_value
;
1658 ::rtl::OUString SAL_CALL
1659 SfxDocumentMetaData::getTemplateURL() throw (css::uno::RuntimeException
)
1661 ::osl::MutexGuard
g(m_aMutex
);
1663 return m_TemplateURL
;
1667 SfxDocumentMetaData::setTemplateURL(const ::rtl::OUString
& the_value
)
1668 throw (css::uno::RuntimeException
)
1670 ::osl::ClearableMutexGuard
g(m_aMutex
);
1672 if (m_TemplateURL
!= the_value
) {
1673 m_TemplateURL
= the_value
;
1679 css::util::DateTime SAL_CALL
1680 SfxDocumentMetaData::getTemplateDate() throw (css::uno::RuntimeException
)
1682 ::osl::MutexGuard
g(m_aMutex
);
1684 return m_TemplateDate
;
1688 SfxDocumentMetaData::setTemplateDate(const css::util::DateTime
& the_value
)
1689 throw (css::uno::RuntimeException
)
1691 ::osl::ClearableMutexGuard
g(m_aMutex
);
1693 if (!(m_TemplateDate
== the_value
)) {
1694 m_TemplateDate
= the_value
;
1700 ::rtl::OUString SAL_CALL
1701 SfxDocumentMetaData::getAutoloadURL() throw (css::uno::RuntimeException
)
1703 ::osl::MutexGuard
g(m_aMutex
);
1705 return m_AutoloadURL
;
1709 SfxDocumentMetaData::setAutoloadURL(const ::rtl::OUString
& the_value
)
1710 throw (css::uno::RuntimeException
)
1712 ::osl::ClearableMutexGuard
g(m_aMutex
);
1714 if (m_AutoloadURL
!= the_value
) {
1715 m_AutoloadURL
= the_value
;
1721 ::sal_Int32 SAL_CALL
1722 SfxDocumentMetaData::getAutoloadSecs() throw (css::uno::RuntimeException
)
1724 ::osl::MutexGuard
g(m_aMutex
);
1726 return m_AutoloadSecs
;
1730 SfxDocumentMetaData::setAutoloadSecs(::sal_Int32 the_value
)
1731 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
)
1733 if (the_value
< 0) throw css::lang::IllegalArgumentException(
1735 "SfxDocumentMetaData::setAutoloadSecs: argument is negative"),
1737 ::osl::ClearableMutexGuard
g(m_aMutex
);
1739 if (m_AutoloadSecs
!= the_value
) {
1740 m_AutoloadSecs
= the_value
;
1746 ::rtl::OUString SAL_CALL
1747 SfxDocumentMetaData::getDefaultTarget() throw (css::uno::RuntimeException
)
1749 ::osl::MutexGuard
g(m_aMutex
);
1751 return m_DefaultTarget
;
1755 SfxDocumentMetaData::setDefaultTarget(const ::rtl::OUString
& the_value
)
1756 throw (css::uno::RuntimeException
)
1758 ::osl::ClearableMutexGuard
g(m_aMutex
);
1760 if (m_DefaultTarget
!= the_value
) {
1761 m_DefaultTarget
= the_value
;
1767 css::uno::Sequence
< css::beans::NamedValue
> SAL_CALL
1768 SfxDocumentMetaData::getDocumentStatistics() throw (css::uno::RuntimeException
)
1770 ::osl::MutexGuard
g(m_aMutex
);
1772 ::comphelper::SequenceAsVector
<css::beans::NamedValue
> stats
;
1773 for (size_t i
= 0; s_stdStats
[i
] != 0; ++i
) {
1774 const char * aName
= s_stdStatAttrs
[i
];
1775 ::rtl::OUString text
= getMetaAttr("meta:document-statistic", aName
);
1776 if (text
.isEmpty()) continue;
1777 css::beans::NamedValue stat
;
1778 stat
.Name
= ::rtl::OUString::createFromAscii(s_stdStats
[i
]);
1781 if (!::sax::Converter::convertNumber(val
, text
, 0,
1782 std::numeric_limits
<sal_Int32
>::max()) || (val
< 0)) {
1784 DBG_WARNING1("SfxDocumentMetaData: invalid number: %s",
1785 OUStringToOString(text
, RTL_TEXTENCODING_UTF8
).getStr());
1789 stats
.push_back(stat
);
1792 return stats
.getAsConstList();
1796 SfxDocumentMetaData::setDocumentStatistics(
1797 const css::uno::Sequence
< css::beans::NamedValue
> & the_value
)
1798 throw (css::uno::RuntimeException
)
1800 ::osl::ClearableMutexGuard
g(m_aMutex
);
1802 std::vector
<std::pair
<const char *, ::rtl::OUString
> > attributes
;
1803 for (sal_Int32 i
= 0; i
< the_value
.getLength(); ++i
) {
1804 const ::rtl::OUString name
= the_value
[i
].Name
;
1805 // inefficently search for matching attribute
1806 for (size_t j
= 0; s_stdStats
[j
] != 0; ++j
) {
1807 if (name
.equalsAscii(s_stdStats
[j
])) {
1808 const css::uno::Any any
= the_value
[i
].Value
;
1811 ::rtl::OUStringBuffer buf
;
1812 ::sax::Converter::convertNumber(buf
, val
);
1813 attributes
.push_back(std::make_pair(s_stdStatAttrs
[j
],
1814 buf
.makeStringAndClear()));
1816 DBG_WARNING1("SfxDocumentMetaData: invalid statistic: %s",
1817 OUStringToOString(name
, RTL_TEXTENCODING_UTF8
)
1824 updateElement("meta:document-statistic", &attributes
);
1829 ::sal_Int16 SAL_CALL
1830 SfxDocumentMetaData::getEditingCycles() throw (css::uno::RuntimeException
)
1832 ::osl::MutexGuard
g(m_aMutex
);
1833 ::rtl::OUString text
= getMetaText("meta:editing-cycles");
1835 if (::sax::Converter::convertNumber(ret
, text
,
1836 0, std::numeric_limits
<sal_Int16
>::max())) {
1837 return static_cast<sal_Int16
>(ret
);
1844 SfxDocumentMetaData::setEditingCycles(::sal_Int16 the_value
)
1845 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
)
1847 if (the_value
< 0) throw css::lang::IllegalArgumentException(
1849 "SfxDocumentMetaData::setEditingCycles: argument is negative"),
1851 ::rtl::OUStringBuffer buf
;
1852 ::sax::Converter::convertNumber(buf
, the_value
);
1853 setMetaTextAndNotify("meta:editing-cycles", buf
.makeStringAndClear());
1856 ::sal_Int32 SAL_CALL
1857 SfxDocumentMetaData::getEditingDuration() throw (css::uno::RuntimeException
)
1859 ::osl::MutexGuard
g(m_aMutex
);
1860 return textToDuration(getMetaText("meta:editing-duration"));
1864 SfxDocumentMetaData::setEditingDuration(::sal_Int32 the_value
)
1865 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
)
1867 if (the_value
< 0) throw css::lang::IllegalArgumentException(
1869 "SfxDocumentMetaData::setEditingDuration: argument is negative"),
1871 setMetaTextAndNotify("meta:editing-duration", durationToText(the_value
));
1875 SfxDocumentMetaData::resetUserData(const ::rtl::OUString
& the_value
)
1876 throw (css::uno::RuntimeException
)
1878 ::osl::ClearableMutexGuard
g(m_aMutex
);
1880 bool bModified( false );
1881 bModified
|= setMetaText("meta:initial-creator", the_value
);
1882 ::DateTime
now( ::DateTime::SYSTEM
);
1883 css::util::DateTime
uDT(now
.Get100Sec(), now
.GetSec(), now
.GetMin(),
1884 now
.GetHour(), now
.GetDay(), now
.GetMonth(), now
.GetYear());
1885 bModified
|= setMetaText("meta:creation-date", dateTimeToText(uDT
));
1886 bModified
|= setMetaText("dc:creator", ::rtl::OUString());
1887 bModified
|= setMetaText("meta:printed-by", ::rtl::OUString());
1888 bModified
|= setMetaText("dc:date", dateTimeToText(css::util::DateTime()));
1889 bModified
|= setMetaText("meta:print-date",
1890 dateTimeToText(css::util::DateTime()));
1891 bModified
|= setMetaText("meta:editing-duration", durationToText(0));
1892 bModified
|= setMetaText("meta:editing-cycles",
1893 ::rtl::OUString("1"));
1902 css::uno::Reference
< css::beans::XPropertyContainer
> SAL_CALL
1903 SfxDocumentMetaData::getUserDefinedProperties()
1904 throw (css::uno::RuntimeException
)
1906 ::osl::MutexGuard
g(m_aMutex
);
1908 createUserDefined();
1909 return m_xUserDefined
;
1914 SfxDocumentMetaData::loadFromStorage(
1915 const css::uno::Reference
< css::embed::XStorage
> & xStorage
,
1916 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
1917 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
,
1918 css::io::WrongFormatException
,
1919 css::lang::WrappedTargetException
, css::io::IOException
)
1921 if (!xStorage
.is()) throw css::lang::IllegalArgumentException(
1922 ::rtl::OUString("SfxDocumentMetaData::loadFromStorage:"
1923 " argument is null"), *this, 0);
1924 ::osl::MutexGuard
g(m_aMutex
);
1926 // open meta data file
1927 css::uno::Reference
<css::io::XStream
> xStream(
1928 xStorage
->openStreamElement(
1929 ::rtl::OUString(s_meta
),
1930 css::embed::ElementModes::READ
) );
1931 if (!xStream
.is()) throw css::uno::RuntimeException();
1932 css::uno::Reference
<css::io::XInputStream
> xInStream
=
1933 xStream
->getInputStream();
1934 if (!xInStream
.is()) throw css::uno::RuntimeException();
1936 // create DOM parser service
1937 css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf (
1938 m_xContext
->getServiceManager());
1939 css::uno::Reference
<css::xml::sax::XParser
> xParser (
1940 xMsf
->createInstanceWithContext(::rtl::OUString(
1941 "com.sun.star.xml.sax.Parser"), m_xContext
),
1942 css::uno::UNO_QUERY_THROW
);
1943 if (!xParser
.is()) throw css::uno::RuntimeException(
1944 ::rtl::OUString("SfxDocumentMetaData::loadFromStorage:"
1945 " cannot create Parser service"), *this);
1946 css::xml::sax::InputSource input
;
1947 input
.aInputStream
= xInStream
;
1949 sal_uInt64 version
= SotStorage::GetVersion( xStorage
);
1950 // Oasis is also the default (0)
1951 sal_Bool bOasis
= ( version
> SOFFICE_FILEFORMAT_60
|| version
== 0 );
1952 const sal_Char
*pServiceName
= bOasis
1953 ? "com.sun.star.document.XMLOasisMetaImporter"
1954 : "com.sun.star.document.XMLMetaImporter";
1957 css::uno::Reference
<css::beans::XPropertySet
> xPropArg
=
1958 getURLProperties(Medium
);
1960 xPropArg
->getPropertyValue(::rtl::OUString("BaseURI"))
1961 >>= input
.sSystemId
;
1962 input
.sSystemId
+= ::rtl::OUString("/").concat(
1963 ::rtl::OUString(s_meta
));
1964 } catch (const css::uno::Exception
&) {
1965 input
.sSystemId
= ::rtl::OUString(s_meta
);
1967 css::uno::Sequence
< css::uno::Any
> args(1);
1968 args
[0] <<= xPropArg
;
1970 css::uno::Reference
<css::xml::sax::XDocumentHandler
> xDocHandler (
1971 xMsf
->createInstanceWithArgumentsAndContext(
1972 ::rtl::OUString::createFromAscii(pServiceName
), args
, m_xContext
),
1973 css::uno::UNO_QUERY_THROW
);
1974 if (!xDocHandler
.is()) throw css::uno::RuntimeException(
1975 ::rtl::OUString("SfxDocumentMetaData::loadFromStorage:"
1976 " cannot create XMLOasisMetaImporter service"), *this);
1977 css::uno::Reference
<css::document::XImporter
> xImp (xDocHandler
,
1978 css::uno::UNO_QUERY_THROW
);
1979 xImp
->setTargetDocument(css::uno::Reference
<css::lang::XComponent
>(this));
1980 xParser
->setDocumentHandler(xDocHandler
);
1982 xParser
->parseStream(input
);
1983 } catch (const css::xml::sax::SAXException
&) {
1984 throw css::io::WrongFormatException(::rtl::OUString(
1985 "SfxDocumentMetaData::loadFromStorage:"
1986 " XML parsing exception"), *this);
1988 // NB: the implementation of XMLOasisMetaImporter calls initialize
1993 SfxDocumentMetaData::storeToStorage(
1994 const css::uno::Reference
< css::embed::XStorage
> & xStorage
,
1995 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
1996 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
,
1997 css::lang::WrappedTargetException
, css::io::IOException
)
1999 if (!xStorage
.is()) throw css::lang::IllegalArgumentException(
2000 ::rtl::OUString("SfxDocumentMetaData::storeToStorage:"
2001 " argument is null"), *this, 0);
2002 ::osl::MutexGuard
g(m_aMutex
);
2005 // update user-defined meta data in DOM tree
2006 // updateUserDefinedAndAttributes(); // this will be done in serialize!
2008 // write into storage
2009 css::uno::Reference
<css::io::XStream
> xStream
=
2010 xStorage
->openStreamElement(::rtl::OUString(s_meta
),
2011 css::embed::ElementModes::WRITE
2012 | css::embed::ElementModes::TRUNCATE
);
2013 if (!xStream
.is()) throw css::uno::RuntimeException();
2014 css::uno::Reference
< css::beans::XPropertySet
> xStreamProps(xStream
,
2015 css::uno::UNO_QUERY_THROW
);
2016 xStreamProps
->setPropertyValue(
2017 ::rtl::OUString("MediaType"),
2018 css::uno::makeAny(::rtl::OUString("text/xml")));
2019 xStreamProps
->setPropertyValue(
2020 ::rtl::OUString("Compressed"),
2021 css::uno::makeAny(static_cast<sal_Bool
> (sal_False
)));
2022 xStreamProps
->setPropertyValue(
2023 ::rtl::OUString("UseCommonStoragePasswordEncryption"),
2024 css::uno::makeAny(static_cast<sal_Bool
> (sal_False
)));
2025 css::uno::Reference
<css::io::XOutputStream
> xOutStream
=
2026 xStream
->getOutputStream();
2027 if (!xOutStream
.is()) throw css::uno::RuntimeException();
2028 css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf (
2029 m_xContext
->getServiceManager());
2030 css::uno::Reference
<css::io::XActiveDataSource
> xSaxWriter(
2031 xMsf
->createInstanceWithContext(::rtl::OUString(
2032 "com.sun.star.xml.sax.Writer"), m_xContext
),
2033 css::uno::UNO_QUERY_THROW
);
2034 xSaxWriter
->setOutputStream(xOutStream
);
2035 css::uno::Reference
<css::xml::sax::XDocumentHandler
> xDocHandler (
2036 xSaxWriter
, css::uno::UNO_QUERY_THROW
);
2038 const sal_uInt64 version
= SotStorage::GetVersion( xStorage
);
2039 // Oasis is also the default (0)
2040 const sal_Bool bOasis
= ( version
> SOFFICE_FILEFORMAT_60
|| version
== 0 );
2041 const sal_Char
*pServiceName
= bOasis
2042 ? "com.sun.star.document.XMLOasisMetaExporter"
2043 : "com.sun.star.document.XMLMetaExporter";
2046 css::uno::Reference
<css::beans::XPropertySet
> xPropArg
=
2047 getURLProperties(Medium
);
2048 css::uno::Sequence
< css::uno::Any
> args(2);
2049 args
[0] <<= xDocHandler
;
2050 args
[1] <<= xPropArg
;
2052 css::uno::Reference
<css::document::XExporter
> xExp(
2053 xMsf
->createInstanceWithArgumentsAndContext(
2054 ::rtl::OUString::createFromAscii(pServiceName
), args
, m_xContext
),
2055 css::uno::UNO_QUERY_THROW
);
2056 xExp
->setSourceDocument(css::uno::Reference
<css::lang::XComponent
>(this));
2057 css::uno::Reference
<css::document::XFilter
> xFilter(xExp
,
2058 css::uno::UNO_QUERY_THROW
);
2059 if (xFilter
->filter(css::uno::Sequence
< css::beans::PropertyValue
>())) {
2060 css::uno::Reference
<css::embed::XTransactedObject
> xTransaction(
2061 xStorage
, css::uno::UNO_QUERY
);
2062 if (xTransaction
.is()) {
2063 xTransaction
->commit();
2066 throw css::io::IOException(::rtl::OUString(
2067 "SfxDocumentMetaData::storeToStorage: cannot filter"), *this);
2072 SfxDocumentMetaData::loadFromMedium(const ::rtl::OUString
& URL
,
2073 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
2074 throw (css::uno::RuntimeException
, css::io::WrongFormatException
,
2075 css::lang::WrappedTargetException
, css::io::IOException
)
2077 css::uno::Reference
<css::io::XInputStream
> xIn
;
2078 ::comphelper::MediaDescriptor
md(Medium
);
2079 // if we have an URL parameter, it replaces the one in the media descriptor
2080 if (!URL
.isEmpty()) {
2081 md
[ ::comphelper::MediaDescriptor::PROP_URL() ] <<= URL
;
2083 if (sal_True
== md
.addInputStream()) {
2084 md
[ ::comphelper::MediaDescriptor::PROP_INPUTSTREAM() ] >>= xIn
;
2086 css::uno::Reference
<css::embed::XStorage
> xStorage
;
2087 css::uno::Reference
<css::lang::XMultiServiceFactory
> xMsf (
2088 m_xContext
->getServiceManager(), css::uno::UNO_QUERY_THROW
);
2091 xStorage
= ::comphelper::OStorageHelper::GetStorageFromInputStream(
2093 } else { // fallback to url parameter
2094 xStorage
= ::comphelper::OStorageHelper::GetStorageFromURL(
2095 URL
, css::embed::ElementModes::READ
, xMsf
);
2097 } catch (const css::uno::RuntimeException
&) {
2099 } catch (const css::io::IOException
&) {
2101 } catch (const css::uno::Exception
& e
) {
2102 throw css::lang::WrappedTargetException(
2104 "SfxDocumentMetaData::loadFromMedium: exception"),
2105 css::uno::Reference
<css::uno::XInterface
>(*this),
2106 css::uno::makeAny(e
));
2108 if (!xStorage
.is()) {
2109 throw css::uno::RuntimeException(::rtl::OUString(
2110 "SfxDocumentMetaData::loadFromMedium: cannot get Storage"),
2113 loadFromStorage(xStorage
, md
.getAsConstPropertyValueList());
2117 SfxDocumentMetaData::storeToMedium(const ::rtl::OUString
& URL
,
2118 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
2119 throw (css::uno::RuntimeException
,
2120 css::lang::WrappedTargetException
, css::io::IOException
)
2122 ::comphelper::MediaDescriptor
md(Medium
);
2123 if (!URL
.isEmpty()) {
2124 md
[ ::comphelper::MediaDescriptor::PROP_URL() ] <<= URL
;
2126 SfxMedium
aMedium(md
.getAsConstPropertyValueList());
2127 css::uno::Reference
<css::embed::XStorage
> xStorage
2128 = aMedium
.GetOutputStorage();
2131 if (!xStorage
.is()) {
2132 throw css::uno::RuntimeException(::rtl::OUString(
2133 "SfxDocumentMetaData::storeToMedium: cannot get Storage"),
2136 // set MIME type of the storage
2137 ::comphelper::MediaDescriptor::const_iterator iter
2138 = md
.find(::comphelper::MediaDescriptor::PROP_MEDIATYPE());
2139 if (iter
!= md
.end()) {
2140 css::uno::Reference
< css::beans::XPropertySet
> xProps(xStorage
,
2141 css::uno::UNO_QUERY_THROW
);
2142 xProps
->setPropertyValue(
2143 ::comphelper::MediaDescriptor::PROP_MEDIATYPE(),
2146 storeToStorage(xStorage
, md
.getAsConstPropertyValueList());
2149 const sal_Bool bOk
= aMedium
.Commit();
2152 sal_uInt32 nError
= aMedium
.GetError();
2153 if ( nError
== ERRCODE_NONE
) {
2154 nError
= ERRCODE_IO_GENERAL
;
2157 throw css::task::ErrorCodeIOException( ::rtl::OUString(),
2158 css::uno::Reference
< css::uno::XInterface
>(), nError
);
2163 // ::com::sun::star::lang::XInitialization:
2165 SfxDocumentMetaData::initialize(
2166 const css::uno::Sequence
< ::com::sun::star::uno::Any
> & aArguments
)
2167 throw (css::uno::RuntimeException
, css::uno::Exception
)
2169 // possible arguments:
2170 // - no argument: default initialization (empty DOM)
2171 // - 1 argument, XDocument: initialize with given DOM and empty base URL
2172 // NB: links in document must be absolute
2174 ::osl::MutexGuard
g(m_aMutex
);
2175 css::uno::Reference
<css::xml::dom::XDocument
> xDoc
;
2177 for (sal_Int32 i
= 0; i
< aArguments
.getLength(); ++i
) {
2178 const css::uno::Any any
= aArguments
[i
];
2181 throw css::lang::IllegalArgumentException(
2182 ::rtl::OUString("SfxDocumentMetaData::"
2183 "initialize: argument is null"),
2184 *this, static_cast<sal_Int16
>(i
));
2187 throw css::lang::IllegalArgumentException(
2188 ::rtl::OUString("SfxDocumentMetaData::"
2189 "initialize: argument must be XDocument"),
2190 *this, static_cast<sal_Int16
>(i
));
2195 // For a new document, we create a new DOM tree here.
2202 // ::com::sun::star::util::XCloneable:
2203 css::uno::Reference
<css::util::XCloneable
> SAL_CALL
2204 SfxDocumentMetaData::createClone()
2205 throw (css::uno::RuntimeException
)
2207 ::osl::MutexGuard
g(m_aMutex
);
2210 SfxDocumentMetaData
*pNew
= createMe(m_xContext
);
2212 // NB: do not copy the modification listeners, only DOM
2213 css::uno::Reference
<css::xml::dom::XDocument
> xDoc
= createDOM();
2215 updateUserDefinedAndAttributes();
2216 // deep copy of root node
2217 css::uno::Reference
<css::xml::dom::XNode
> xRoot(
2218 m_xDoc
->getDocumentElement(), css::uno::UNO_QUERY_THROW
);
2219 css::uno::Reference
<css::xml::dom::XNode
> xRootNew(
2220 xDoc
->importNode(xRoot
, true));
2221 xDoc
->appendChild(xRootNew
);
2223 } catch (const css::uno::RuntimeException
&) {
2225 } catch (const css::uno::Exception
& e
) {
2227 throw css::lang::WrappedTargetRuntimeException(
2229 "SfxDocumentMetaData::createClone: exception"),
2230 css::uno::Reference
<css::uno::XInterface
>(*this), a
);
2232 return css::uno::Reference
<css::util::XCloneable
> (pNew
);
2235 // ::com::sun::star::util::XModifiable:
2236 ::sal_Bool SAL_CALL
SfxDocumentMetaData::isModified( )
2237 throw (css::uno::RuntimeException
)
2239 ::osl::MutexGuard
g(m_aMutex
);
2241 css::uno::Reference
<css::util::XModifiable
> xMB(m_xUserDefined
,
2242 css::uno::UNO_QUERY
);
2243 return m_isModified
|| (xMB
.is() ? xMB
->isModified() : sal_False
);
2246 void SAL_CALL
SfxDocumentMetaData::setModified( ::sal_Bool bModified
)
2247 throw (css::beans::PropertyVetoException
, css::uno::RuntimeException
)
2249 css::uno::Reference
<css::util::XModifiable
> xMB
;
2250 { // do not lock mutex while notifying (#i93514#) to prevent deadlock
2251 ::osl::MutexGuard
g(m_aMutex
);
2253 m_isModified
= bModified
;
2254 if ( !bModified
&& m_xUserDefined
.is() )
2256 xMB
.set(m_xUserDefined
, css::uno::UNO_QUERY
);
2257 DBG_ASSERT(xMB
.is(),
2258 "SfxDocumentMetaData::setModified: PropertyBag not Modifiable?");
2263 css::uno::Reference
<css::uno::XInterface
> xThis(*this);
2264 css::lang::EventObject
event(xThis
);
2265 m_NotifyListeners
.notifyEach(&css::util::XModifyListener::modified
,
2267 } catch (const css::uno::RuntimeException
&) {
2269 } catch (const css::uno::Exception
& e
) {
2271 DBG_WARNING1("SfxDocumentMetaData::setModified: exception:\n%s",
2272 OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).getStr());
2277 xMB
->setModified(false);
2282 // ::com::sun::star::util::XModifyBroadcaster:
2283 void SAL_CALL
SfxDocumentMetaData::addModifyListener(
2284 const css::uno::Reference
< css::util::XModifyListener
> & xListener
)
2285 throw (css::uno::RuntimeException
)
2287 ::osl::MutexGuard
g(m_aMutex
);
2289 m_NotifyListeners
.addInterface(xListener
);
2290 css::uno::Reference
<css::util::XModifyBroadcaster
> xMB(m_xUserDefined
,
2291 css::uno::UNO_QUERY
);
2293 xMB
->addModifyListener(xListener
);
2297 void SAL_CALL
SfxDocumentMetaData::removeModifyListener(
2298 const css::uno::Reference
< css::util::XModifyListener
> & xListener
)
2299 throw (css::uno::RuntimeException
)
2301 ::osl::MutexGuard
g(m_aMutex
);
2303 m_NotifyListeners
.removeInterface(xListener
);
2304 css::uno::Reference
<css::util::XModifyBroadcaster
> xMB(m_xUserDefined
,
2305 css::uno::UNO_QUERY
);
2307 xMB
->removeModifyListener(xListener
);
2311 // ::com::sun::star::xml::sax::XSAXSerializable
2312 void SAL_CALL
SfxDocumentMetaData::serialize(
2313 const css::uno::Reference
<css::xml::sax::XDocumentHandler
>& i_xHandler
,
2314 const css::uno::Sequence
< css::beans::StringPair
>& i_rNamespaces
)
2315 throw (css::uno::RuntimeException
, css::xml::sax::SAXException
)
2317 ::osl::MutexGuard
g(m_aMutex
);
2319 updateUserDefinedAndAttributes();
2320 css::uno::Reference
<css::xml::sax::XSAXSerializable
> xSAXable(m_xDoc
,
2321 css::uno::UNO_QUERY_THROW
);
2322 xSAXable
->serialize(i_xHandler
, i_rNamespaces
);
2325 void SfxDocumentMetaData::createUserDefined()
2327 // user-defined meta data: create PropertyBag which only accepts property
2328 // values of allowed types
2329 if ( !m_xUserDefined
.is() )
2331 css::uno::Sequence
<css::uno::Type
> types(11);
2332 types
[0] = ::cppu::UnoType
<bool>::get();
2333 types
[1] = ::cppu::UnoType
< ::rtl::OUString
>::get();
2334 types
[2] = ::cppu::UnoType
<css::util::DateTime
>::get();
2335 types
[3] = ::cppu::UnoType
<css::util::Date
>::get();
2336 types
[4] = ::cppu::UnoType
<css::util::Duration
>::get();
2337 types
[5] = ::cppu::UnoType
<float>::get();
2338 types
[6] = ::cppu::UnoType
<double>::get();
2339 types
[7] = ::cppu::UnoType
<sal_Int16
>::get();
2340 types
[8] = ::cppu::UnoType
<sal_Int32
>::get();
2341 types
[9] = ::cppu::UnoType
<sal_Int64
>::get();
2342 // Time is supported for backward compatibility with OOo 3.x, x<=2
2343 types
[10] = ::cppu::UnoType
<css::util::Time
>::get();
2344 css::uno::Sequence
<css::uno::Any
> args(2);
2345 args
[0] <<= css::beans::NamedValue(
2346 ::rtl::OUString("AllowedTypes"),
2347 css::uno::makeAny(types
));
2348 // #i94175#: ODF allows empty user-defined property names!
2349 args
[1] <<= css::beans::NamedValue( ::rtl::OUString(
2350 "AllowEmptyPropertyName"),
2351 css::uno::makeAny(sal_True
));
2353 const css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf(
2354 m_xContext
->getServiceManager());
2356 xMsf
->createInstanceWithContext(
2358 "com.sun.star.beans.PropertyBag"), m_xContext
),
2359 css::uno::UNO_QUERY_THROW
);
2360 const css::uno::Reference
<css::lang::XInitialization
> xInit(
2361 m_xUserDefined
, css::uno::UNO_QUERY
);
2363 xInit
->initialize(args
);
2366 const css::uno::Reference
<css::util::XModifyBroadcaster
> xMB(
2367 m_xUserDefined
, css::uno::UNO_QUERY
);
2370 const css::uno::Sequence
<css::uno::Reference
<css::uno::XInterface
> >
2371 listeners(m_NotifyListeners
.getElements());
2372 for (css::uno::Reference
< css::uno::XInterface
> const * iter
=
2373 ::comphelper::stl_begin(listeners
);
2374 iter
!= ::comphelper::stl_end(listeners
); ++iter
) {
2375 xMB
->addModifyListener(
2376 css::uno::Reference
< css::util::XModifyListener
>(*iter
,
2377 css::uno::UNO_QUERY
));
2383 } // closing anonymous implementation namespace
2386 // component helper namespace
2387 namespace comp_CompatWriterDocProps
{
2389 ::rtl::OUString SAL_CALL
_getImplementationName() {
2390 return ::rtl::OUString(
2391 "CompatWriterDocPropsImpl");
2394 css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
_getSupportedServiceNames()
2396 css::uno::Sequence
< rtl::OUString
> aServiceNames(1);
2397 aServiceNames
[ 0 ] = rtl::OUString( "com.sun.star.writer.DocumentProperties" );
2398 return aServiceNames
;
2400 css::uno::Reference
< css::uno::XInterface
> SAL_CALL
_create(
2401 const css::uno::Reference
< css::uno::XComponentContext
> & context
)
2402 SAL_THROW((css::uno::Exception
))
2404 return static_cast< ::cppu::OWeakObject
* >
2405 (new CompatWriterDocPropsImpl(context
));
2409 namespace comp_SfxDocumentMetaData
{
2411 ::rtl::OUString SAL_CALL
_getImplementationName() {
2412 return ::rtl::OUString(
2413 "SfxDocumentMetaData");
2416 css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
_getSupportedServiceNames()
2418 css::uno::Sequence
< ::rtl::OUString
> s(1);
2419 s
[0] = ::rtl::OUString(
2420 "com.sun.star.document.DocumentProperties");
2424 css::uno::Reference
< css::uno::XInterface
> SAL_CALL
_create(
2425 const css::uno::Reference
< css::uno::XComponentContext
> & context
)
2426 SAL_THROW((css::uno::Exception
))
2428 return static_cast< ::cppu::OWeakObject
* >
2429 (new SfxDocumentMetaData(context
));
2432 } // closing component helper namespace
2434 static ::cppu::ImplementationEntry
const entries
[] = {
2435 { &comp_SfxDocumentMetaData::_create
,
2436 &comp_SfxDocumentMetaData::_getImplementationName
,
2437 &comp_SfxDocumentMetaData::_getSupportedServiceNames
,
2438 &::cppu::createSingleComponentFactory
, 0, 0 },
2439 { 0, 0, 0, 0, 0, 0 }
2442 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */