1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SfxDocumentMetaData.cxx,v $
10 * $Revision: 1.10.32.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "precompiled_sfx2.hxx"
33 #include "sal/config.h"
34 #include "cppuhelper/factory.hxx"
35 #include "cppuhelper/implementationentry.hxx"
36 #include "cppuhelper/compbase6.hxx"
37 #include "com/sun/star/lang/XServiceInfo.hpp"
38 #include "com/sun/star/document/XDocumentProperties.hpp"
39 #include "com/sun/star/lang/XInitialization.hpp"
40 #include "com/sun/star/util/XCloneable.hpp"
41 #include "com/sun/star/util/XModifiable.hpp"
42 #include "com/sun/star/xml/sax/XSAXSerializable.hpp"
44 #include "com/sun/star/lang/NullPointerException.hpp"
45 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
46 #include "com/sun/star/lang/EventObject.hpp"
47 #include "com/sun/star/beans/XPropertySet.hpp"
48 #include "com/sun/star/beans/XPropertySetInfo.hpp"
49 #include "com/sun/star/beans/PropertyAttribute.hpp"
50 #include "com/sun/star/task/ErrorCodeIOException.hpp"
51 #include "com/sun/star/embed/XStorage.hpp"
52 #include "com/sun/star/embed/XTransactedObject.hpp"
53 #include "com/sun/star/embed/ElementModes.hpp"
54 #include "com/sun/star/io/XActiveDataControl.hpp"
55 #include "com/sun/star/io/XActiveDataSource.hpp"
56 #include "com/sun/star/io/XStream.hpp"
57 #include "com/sun/star/document/XImporter.hpp"
58 #include "com/sun/star/document/XExporter.hpp"
59 #include "com/sun/star/document/XFilter.hpp"
60 #include "com/sun/star/xml/sax/XParser.hpp"
61 #include "com/sun/star/xml/dom/XDocument.hpp"
62 #include "com/sun/star/xml/dom/XElement.hpp"
63 #include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
64 #include "com/sun/star/xml/dom/XSAXDocumentBuilder.hpp"
65 #include "com/sun/star/xml/dom/NodeType.hpp"
66 #include "com/sun/star/xml/xpath/XXPathAPI.hpp"
67 #include "com/sun/star/util/Date.hpp"
68 #include "com/sun/star/util/Time.hpp"
70 #include "SfxDocumentMetaData.hxx"
71 #include "rtl/ustrbuf.hxx"
72 #include "tools/debug.hxx"
73 #include "tools/string.hxx" // for DBG
74 #include "tools/datetime.hxx"
75 #include "tools/urlobj.hxx"
76 #include "osl/mutex.hxx"
77 #include "cppuhelper/basemutex.hxx"
78 #include "cppuhelper/interfacecontainer.hxx"
79 #include "comphelper/storagehelper.hxx"
80 #include "comphelper/mediadescriptor.hxx"
81 #include "comphelper/sequenceasvector.hxx"
82 #include "sot/storage.hxx"
83 #include "sfx2/docfile.hxx"
84 #include "sax/tools/converter.hxx"
93 #include <cppuhelper/implbase1.hxx>
94 #include <com/sun/star/document/XCompatWriterDocProperties.hpp>
97 * This file contains the implementation of the service
98 * com.sun.star.document.DocumentProperties.
99 * This service enables access to the meta-data stored in documents.
100 * Currently, this service only handles documents in ODF format.
102 * The implementation uses an XML DOM to store the properties.
103 * This approach was taken because it allows for preserving arbitrary XML data
104 * in loaded documents, which will be stored unmodified when saving the
107 * Upon access, some properties are directly read from and updated in the DOM.
108 * Exception: it seems impossible to get notified upon addition of a property
109 * to a com.sun.star.beans.PropertyBag, which is used for storing user-defined
110 * properties; because of this, user-defined properties are updated in the
111 * XML DOM only when storing the document.
112 * Exception 2: when setting certain properties which correspond to attributes
113 * in the XML DOM, we want to remove the corresponding XML element. Detecting
114 * this condition can get messy, so we store all such properties as members,
115 * and update the DOM tree only when storing the document (in
116 * <method>updateUserDefinedAndAttributes</method>).
121 /// anonymous implementation namespace
124 namespace css
= ::com::sun::star
;
127 /// a list of attribute-lists, where attribute means name and content
128 typedef std::vector
<std::vector
<std::pair
<const char*, ::rtl::OUString
> > >
131 typedef ::cppu::WeakComponentImplHelper6
<
132 css::lang::XServiceInfo
,
133 css::document::XDocumentProperties
,
134 css::lang::XInitialization
,
135 css::util::XCloneable
,
136 css::util::XModifiable
,
137 css::xml::sax::XSAXSerializable
>
138 SfxDocumentMetaData_Base
;
140 class SfxDocumentMetaData
:
141 private ::cppu::BaseMutex
,
142 public SfxDocumentMetaData_Base
145 explicit SfxDocumentMetaData(
146 css::uno::Reference
< css::uno::XComponentContext
> const & context
);
148 // ::com::sun::star::lang::XServiceInfo:
149 virtual ::rtl::OUString SAL_CALL
getImplementationName()
150 throw (css::uno::RuntimeException
);
151 virtual ::sal_Bool SAL_CALL
supportsService(
152 const ::rtl::OUString
& ServiceName
) throw (css::uno::RuntimeException
);
153 virtual css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
154 getSupportedServiceNames() throw (css::uno::RuntimeException
);
156 // ::com::sun::star::lang::XComponent:
157 virtual void SAL_CALL
dispose() throw (css::uno::RuntimeException
);
159 // ::com::sun::star::document::XDocumentProperties:
160 virtual ::rtl::OUString SAL_CALL
getAuthor()
161 throw (css::uno::RuntimeException
);
162 virtual void SAL_CALL
setAuthor(const ::rtl::OUString
& the_value
)
163 throw (css::uno::RuntimeException
);
164 virtual ::rtl::OUString SAL_CALL
getGenerator()
165 throw (css::uno::RuntimeException
);
166 virtual void SAL_CALL
setGenerator(const ::rtl::OUString
& the_value
)
167 throw (css::uno::RuntimeException
);
168 virtual css::util::DateTime SAL_CALL
getCreationDate()
169 throw (css::uno::RuntimeException
);
170 virtual void SAL_CALL
setCreationDate(const css::util::DateTime
& the_value
)
171 throw (css::uno::RuntimeException
);
172 virtual ::rtl::OUString SAL_CALL
getTitle()
173 throw (css::uno::RuntimeException
);
174 virtual void SAL_CALL
setTitle(const ::rtl::OUString
& the_value
)
175 throw (css::uno::RuntimeException
);
176 virtual ::rtl::OUString SAL_CALL
getSubject()
177 throw (css::uno::RuntimeException
);
178 virtual void SAL_CALL
setSubject(const ::rtl::OUString
& the_value
)
179 throw (css::uno::RuntimeException
);
180 virtual ::rtl::OUString SAL_CALL
getDescription()
181 throw (css::uno::RuntimeException
);
182 virtual void SAL_CALL
setDescription(const ::rtl::OUString
& the_value
)
183 throw (css::uno::RuntimeException
);
184 virtual css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getKeywords()
185 throw (css::uno::RuntimeException
);
186 virtual void SAL_CALL
setKeywords(
187 const css::uno::Sequence
< ::rtl::OUString
> & the_value
)
188 throw (css::uno::RuntimeException
);
189 virtual css::lang::Locale SAL_CALL
getLanguage()
190 throw (css::uno::RuntimeException
);
191 virtual void SAL_CALL
setLanguage(const css::lang::Locale
& the_value
)
192 throw (css::uno::RuntimeException
);
193 virtual ::rtl::OUString SAL_CALL
getModifiedBy()
194 throw (css::uno::RuntimeException
);
195 virtual void SAL_CALL
setModifiedBy(const ::rtl::OUString
& the_value
)
196 throw (css::uno::RuntimeException
);
197 virtual css::util::DateTime SAL_CALL
getModificationDate()
198 throw (css::uno::RuntimeException
);
199 virtual void SAL_CALL
setModificationDate(
200 const css::util::DateTime
& the_value
)
201 throw (css::uno::RuntimeException
);
202 virtual ::rtl::OUString SAL_CALL
getPrintedBy()
203 throw (css::uno::RuntimeException
);
204 virtual void SAL_CALL
setPrintedBy(const ::rtl::OUString
& the_value
)
205 throw (css::uno::RuntimeException
);
206 virtual css::util::DateTime SAL_CALL
getPrintDate()
207 throw (css::uno::RuntimeException
);
208 virtual void SAL_CALL
setPrintDate(const css::util::DateTime
& the_value
)
209 throw (css::uno::RuntimeException
);
210 virtual ::rtl::OUString SAL_CALL
getTemplateName()
211 throw (css::uno::RuntimeException
);
212 virtual void SAL_CALL
setTemplateName(const ::rtl::OUString
& the_value
)
213 throw (css::uno::RuntimeException
);
214 virtual ::rtl::OUString SAL_CALL
getTemplateURL()
215 throw (css::uno::RuntimeException
);
216 virtual void SAL_CALL
setTemplateURL(const ::rtl::OUString
& the_value
)
217 throw (css::uno::RuntimeException
);
218 virtual css::util::DateTime SAL_CALL
getTemplateDate()
219 throw (css::uno::RuntimeException
);
220 virtual void SAL_CALL
setTemplateDate(const css::util::DateTime
& the_value
)
221 throw (css::uno::RuntimeException
);
222 virtual ::rtl::OUString SAL_CALL
getAutoloadURL()
223 throw (css::uno::RuntimeException
);
224 virtual void SAL_CALL
setAutoloadURL(const ::rtl::OUString
& the_value
)
225 throw (css::uno::RuntimeException
);
226 virtual ::sal_Int32 SAL_CALL
getAutoloadSecs()
227 throw (css::uno::RuntimeException
);
228 virtual void SAL_CALL
setAutoloadSecs(::sal_Int32 the_value
)
229 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
);
230 virtual ::rtl::OUString SAL_CALL
getDefaultTarget()
231 throw (css::uno::RuntimeException
);
232 virtual void SAL_CALL
setDefaultTarget(const ::rtl::OUString
& the_value
)
233 throw (css::uno::RuntimeException
);
234 virtual css::uno::Sequence
< css::beans::NamedValue
> SAL_CALL
235 getDocumentStatistics() throw (css::uno::RuntimeException
);
236 virtual void SAL_CALL
setDocumentStatistics(
237 const css::uno::Sequence
< css::beans::NamedValue
> & the_value
)
238 throw (css::uno::RuntimeException
);
239 virtual ::sal_Int16 SAL_CALL
getEditingCycles()
240 throw (css::uno::RuntimeException
);
241 virtual void SAL_CALL
setEditingCycles(::sal_Int16 the_value
)
242 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
);
243 virtual ::sal_Int32 SAL_CALL
getEditingDuration()
244 throw (css::uno::RuntimeException
);
245 virtual void SAL_CALL
setEditingDuration(::sal_Int32 the_value
)
246 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
);
247 virtual void SAL_CALL
resetUserData(const ::rtl::OUString
& the_value
)
248 throw (css::uno::RuntimeException
);
249 virtual css::uno::Reference
< css::beans::XPropertyContainer
> SAL_CALL
250 getUserDefinedProperties() throw (css::uno::RuntimeException
);
251 virtual void SAL_CALL
loadFromStorage(
252 const css::uno::Reference
< css::embed::XStorage
> & Storage
,
253 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
254 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
,
255 css::io::WrongFormatException
,
256 css::lang::WrappedTargetException
, css::io::IOException
,
257 css::uno::Exception
);
258 virtual void SAL_CALL
loadFromMedium(const ::rtl::OUString
& URL
,
259 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
260 throw (css::uno::RuntimeException
,
261 css::io::WrongFormatException
,
262 css::lang::WrappedTargetException
, css::io::IOException
,
263 css::uno::Exception
);
264 virtual void SAL_CALL
storeToStorage(
265 const css::uno::Reference
< css::embed::XStorage
> & Storage
,
266 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
267 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
,
268 css::lang::WrappedTargetException
, css::io::IOException
,
269 css::uno::Exception
);
270 virtual void SAL_CALL
storeToMedium(const ::rtl::OUString
& URL
,
271 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
272 throw (css::uno::RuntimeException
,
273 css::lang::WrappedTargetException
, css::io::IOException
,
274 css::uno::Exception
);
276 // ::com::sun::star::lang::XInitialization:
277 virtual void SAL_CALL
initialize(
278 const css::uno::Sequence
< css::uno::Any
> & aArguments
)
279 throw (css::uno::RuntimeException
, css::uno::Exception
);
281 // ::com::sun::star::util::XCloneable:
282 virtual css::uno::Reference
<css::util::XCloneable
> SAL_CALL
createClone()
283 throw (css::uno::RuntimeException
);
285 // ::com::sun::star::util::XModifiable:
286 virtual ::sal_Bool SAL_CALL
isModified( )
287 throw (css::uno::RuntimeException
);
288 virtual void SAL_CALL
setModified( ::sal_Bool bModified
)
289 throw (css::beans::PropertyVetoException
, css::uno::RuntimeException
);
291 // ::com::sun::star::util::XModifyBroadcaster:
292 virtual void SAL_CALL
addModifyListener(
293 const css::uno::Reference
< css::util::XModifyListener
> & xListener
)
294 throw (css::uno::RuntimeException
);
295 virtual void SAL_CALL
removeModifyListener(
296 const css::uno::Reference
< css::util::XModifyListener
> & xListener
)
297 throw (css::uno::RuntimeException
);
299 // ::com::sun::star::xml::sax::XSAXSerializable
300 virtual void SAL_CALL
serialize(
301 const css::uno::Reference
<css::xml::sax::XDocumentHandler
>& i_xHandler
,
302 const css::uno::Sequence
< css::beans::StringPair
>& i_rNamespaces
)
303 throw (css::uno::RuntimeException
, css::xml::sax::SAXException
);
306 SfxDocumentMetaData(SfxDocumentMetaData
&); // not defined
307 SfxDocumentMetaData
& operator =(SfxDocumentMetaData
&); // not defined
309 virtual ~SfxDocumentMetaData() {}
310 virtual SfxDocumentMetaData
* createMe( css::uno::Reference
< css::uno::XComponentContext
> const & context
) { return new SfxDocumentMetaData( context
); };
311 const css::uno::Reference
< css::uno::XComponentContext
> m_xContext
;
314 ::cppu::OInterfaceContainerHelper m_NotifyListeners
;
315 /// flag: false means not initialized yet, or disposed
316 bool m_isInitialized
;
319 /// meta-data DOM tree
320 css::uno::Reference
< css::xml::dom::XDocument
> m_xDoc
;
321 /// meta-data super node in the meta-data DOM tree
322 css::uno::Reference
< css::xml::dom::XNode
> m_xParent
;
323 /// standard meta data (single occurrence)
324 std::map
< ::rtl::OUString
, css::uno::Reference
<css::xml::dom::XNode
> >
326 /// standard meta data (multiple occurrences)
327 std::map
< ::rtl::OUString
,
328 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> > > m_metaList
;
329 /// user-defined meta data (meta:user-defined)
330 css::uno::Reference
<css::beans::XPropertyContainer
> m_xUserDefined
;
331 // now for some meta-data attributes; these are not updated directly in the
332 // DOM because updates (detecting "empty" elements) would be quite messy
333 ::rtl::OUString m_TemplateName
;
334 ::rtl::OUString m_TemplateURL
;
335 css::util::DateTime m_TemplateDate
;
336 ::rtl::OUString m_AutoloadURL
;
337 sal_Int32 m_AutoloadSecs
;
338 ::rtl::OUString m_DefaultTarget
;
340 /// check if we are initialized properly
341 void SAL_CALL
checkInit() const;
342 // throw (css::uno::RuntimeException);
343 /// initialize state from given DOM tree
344 void SAL_CALL
init(css::uno::Reference
<css::xml::dom::XDocument
> i_xDom
);
345 // throw (css::uno::RuntimeException, css::io::WrongFormatException,
346 // css::uno::Exception);
347 /// update element in DOM tree
348 void SAL_CALL
updateElement(const char *i_name
,
349 std::vector
<std::pair
<const char *, ::rtl::OUString
> >* i_pAttrs
= 0);
350 /// update user-defined meta data and attributes in DOM tree
351 void SAL_CALL
updateUserDefinedAndAttributes();
352 /// create empty DOM tree (XDocument)
353 css::uno::Reference
<css::xml::dom::XDocument
> SAL_CALL
createDOM() const;
354 /// extract base URL (necessary for converting relative links)
355 css::uno::Reference
<css::beans::XPropertySet
> SAL_CALL
getURLProperties(
356 const css::uno::Sequence
<css::beans::PropertyValue
> & i_rMedium
) const;
357 // throw (css::uno::RuntimeException);
358 /// get text of standard meta data element
359 ::rtl::OUString SAL_CALL
getMetaText(const char* i_name
) const;
360 // throw (css::uno::RuntimeException);
361 /// set text of standard meta data element iff not equal to existing text
362 bool SAL_CALL
setMetaText(const char* i_name
,
363 const ::rtl::OUString
& i_rValue
);
364 // throw (css::uno::RuntimeException);
365 /// set text of standard meta data element iff not equal to existing text
366 void SAL_CALL
setMetaTextAndNotify(const char* i_name
,
367 const ::rtl::OUString
& i_rValue
);
368 // throw (css::uno::RuntimeException);
369 /// get text of standard meta data element's attribute
370 ::rtl::OUString SAL_CALL
getMetaAttr(const char* i_name
,
371 const char* i_attr
) const;
372 // throw (css::uno::RuntimeException);
373 /// get text of a list of standard meta data elements (multiple occ.)
374 css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getMetaList(
375 const char* i_name
) const;
376 // throw (css::uno::RuntimeException);
377 /// set text of a list of standard meta data elements (multiple occ.)
378 bool SAL_CALL
setMetaList(const char* i_name
,
379 const css::uno::Sequence
< ::rtl::OUString
> & i_rValue
,
380 AttrVector
const* = 0);
381 // throw (css::uno::RuntimeException);
382 void createUserDefined();
385 typedef ::cppu::ImplInheritanceHelper1
< SfxDocumentMetaData
, css::document::XCompatWriterDocProperties
> CompatWriterDocPropsImpl_BASE
;
387 class CompatWriterDocPropsImpl
: public CompatWriterDocPropsImpl_BASE
389 rtl::OUString msManager
;
390 rtl::OUString msCategory
;
391 rtl::OUString msCompany
;
393 virtual SfxDocumentMetaData
* createMe( css::uno::Reference
< css::uno::XComponentContext
> const & context
) { return new CompatWriterDocPropsImpl( context
); };
395 CompatWriterDocPropsImpl( css::uno::Reference
< css::uno::XComponentContext
> const & context
) : CompatWriterDocPropsImpl_BASE( context
) {}
396 // XCompatWriterDocPropsImpl
397 virtual ::rtl::OUString SAL_CALL
getManager() throw (::com::sun::star::uno::RuntimeException
) { return msManager
; }
398 virtual void SAL_CALL
setManager( const ::rtl::OUString
& _manager
) throw (::com::sun::star::uno::RuntimeException
) { msManager
= _manager
; }
399 virtual ::rtl::OUString SAL_CALL
getCategory() throw (::com::sun::star::uno::RuntimeException
){ return msCategory
; }
400 virtual void SAL_CALL
setCategory( const ::rtl::OUString
& _category
) throw (::com::sun::star::uno::RuntimeException
){ msCategory
= _category
; }
401 virtual ::rtl::OUString SAL_CALL
getCompany() throw (::com::sun::star::uno::RuntimeException
){ return msCompany
; }
402 virtual void SAL_CALL
setCompany( const ::rtl::OUString
& _company
) throw (::com::sun::star::uno::RuntimeException
){ msCompany
= _company
; }
405 virtual ::rtl::OUString SAL_CALL
getImplementationName( ) throw (::com::sun::star::uno::RuntimeException
)
407 return comp_CompatWriterDocProps::_getImplementationName();
410 virtual ::sal_Bool SAL_CALL
supportsService( const ::rtl::OUString
& ServiceName
) throw (::com::sun::star::uno::RuntimeException
)
412 css::uno::Sequence
< rtl::OUString
> sServiceNames
= getSupportedServiceNames();
413 sal_Int32 nLen
= sServiceNames
.getLength();
414 rtl::OUString
* pIt
= sServiceNames
.getArray();
415 rtl::OUString
* pEnd
= ( pIt
+ nLen
);
416 sal_Bool bRes
= sal_False
;
417 for ( ; pIt
!= pEnd
; ++pIt
)
419 if ( pIt
->equals( ServiceName
) )
428 virtual ::com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException
)
430 return comp_CompatWriterDocProps::_getSupportedServiceNames();
433 ////////////////////////////////////////////////////////////////////////////
435 bool operator== (const css::util::DateTime
&i_rLeft
,
436 const css::util::DateTime
&i_rRight
)
438 return i_rLeft
.Year
== i_rRight
.Year
439 && i_rLeft
.Month
== i_rRight
.Month
440 && i_rLeft
.Day
== i_rRight
.Day
441 && i_rLeft
.Hours
== i_rRight
.Hours
442 && i_rLeft
.Minutes
== i_rRight
.Minutes
443 && i_rLeft
.Seconds
== i_rRight
.Seconds
444 && i_rLeft
.HundredthSeconds
== i_rRight
.HundredthSeconds
;
447 // NB: keep these two arrays in sync!
448 const char* s_stdStatAttrs
[] = {
454 "meta:ole-object-count",
455 "meta:paragraph-count",
457 "meta:character-count",
460 "meta:sentence-count",
461 "meta:syllable-count",
462 "meta:non-whitespace-character-count",
467 // NB: keep these two arrays in sync!
468 const char* s_stdStats
[] = {
482 "NonWhitespaceCharacterCount",
487 const char* s_stdMeta
[] = {
488 "meta:generator", // string
489 "dc:title", // string
490 "dc:description", // string
491 "dc:subject", // string
492 "meta:initial-creator", // string
493 "dc:creator", // string
494 "meta:printed-by", // string
495 "meta:creation-date", // dateTime
496 "dc:date", // dateTime
497 "meta:print-date", // dateTime
498 "meta:template", // XLink
499 "meta:auto-reload", // ...
500 "meta:hyperlink-behaviour", // ...
501 "dc:language", // language
502 "meta:editing-cycles", // nonNegativeInteger
503 "meta:editing-duration", // duration
504 "meta:document-statistic", // ... // note: statistic is singular, no s!
508 const char* s_stdMetaList
[] = {
509 "meta:keyword", // string*
510 "meta:user-defined", // ...*
514 const char* s_nsXLink
= "http://www.w3.org/1999/xlink";
515 const char* s_nsDC
= "http://purl.org/dc/elements/1.1/";
516 const char* s_nsODF
= "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
517 const char* s_nsODFMeta
= "urn:oasis:names:tc:opendocument:xmlns:meta:1.0";
518 // const char* s_nsOOo = "http://openoffice.org/2004/office"; // not used (yet?)
520 const char* s_metaXml
= "meta.xml";
523 bool isValidDateTime(const css::util::DateTime
& i_rDateTime
)
525 return i_rDateTime
.Month
> 0;
528 std::pair
< ::rtl::OUString
, ::rtl::OUString
> SAL_CALL
529 getQualifier(const char* i_name
) {
530 ::rtl::OUString nm
= ::rtl::OUString::createFromAscii(i_name
);
531 sal_Int32 ix
= nm
.indexOf(static_cast<sal_Unicode
> (':'));
533 return std::make_pair(::rtl::OUString(), nm
);
535 return std::make_pair(nm
.copy(0,ix
), nm
.copy(ix
+1));
539 // get namespace for standard qualified names
540 // NB: only call this with statically known strings!
541 ::rtl::OUString SAL_CALL
getNameSpace(const char* i_qname
) throw ()
543 DBG_ASSERT(i_qname
, "SfxDocumentMetaData: getNameSpace: argument is null");
544 const char * ns
= "";
545 ::rtl::OUString n
= getQualifier(i_qname
).first
;
546 if (n
.equalsAscii("xlink" )) ns
= s_nsXLink
;
547 if (n
.equalsAscii("dc" )) ns
= s_nsDC
;
548 if (n
.equalsAscii("office")) ns
= s_nsODF
;
549 if (n
.equalsAscii("meta" )) ns
= s_nsODFMeta
;
550 DBG_ASSERT(*ns
, "SfxDocumentMetaData: unknown namespace prefix");
551 return ::rtl::OUString::createFromAscii(ns
);
554 // convert string to date/time
556 textToDateTime(css::util::DateTime
& io_rdt
, ::rtl::OUString i_text
) throw ()
558 if (::sax::Converter::convertDateTime(io_rdt
, i_text
)) {
559 // NB: there may be rounding errors; handle these here
560 if (io_rdt
.HundredthSeconds
> 0) {
562 io_rdt
.HundredthSeconds
= 0;
566 DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
567 OUStringToOString(i_text
, RTL_TEXTENCODING_UTF8
).getStr());
572 // convert string to date/time with default return value
573 css::util::DateTime SAL_CALL
574 textToDateTimeDefault(::rtl::OUString i_text
) throw ()
576 css::util::DateTime dt
;
577 static_cast<void> (textToDateTime(dt
, i_text
));
578 // on conversion error: return default value (unchanged)
582 // convert date/time to string
583 ::rtl::OUString SAL_CALL
584 dateTimeToText(css::util::DateTime
const& i_rdt
) throw ()
586 if (isValidDateTime(i_rdt
)) {
587 ::rtl::OUStringBuffer buf
;
588 ::sax::Converter::convertDateTime(buf
, i_rdt
, true);
589 return buf
.makeStringAndClear();
591 return ::rtl::OUString();
595 // convert string to duration
597 textToDuration(css::util::Time
& io_rut
, ::rtl::OUString i_text
) throw ()
599 css::util::DateTime dt
;
600 if (::sax::Converter::convertTime(dt
, i_text
)) {
601 // NB: there may be rounding errors; handle these here
602 if (dt
.HundredthSeconds
> 0) {
604 dt
.HundredthSeconds
= 0;
606 io_rut
.Hours
= dt
.Hours
;
607 io_rut
.Minutes
= dt
.Minutes
;
608 io_rut
.Seconds
= dt
.Seconds
;
609 io_rut
.HundredthSeconds
= dt
.HundredthSeconds
;
612 DBG_WARNING1("SfxDocumentMetaData: invalid duration: %s",
613 OUStringToOString(i_text
, RTL_TEXTENCODING_UTF8
).getStr());
618 sal_Int32 SAL_CALL
textToDuration(::rtl::OUString i_text
) throw ()
621 if (textToDuration(t
, i_text
)) {
622 return t
.Hours
* 3600 + t
.Minutes
* 60 + t
.Seconds
;
628 // convert duration to string
629 ::rtl::OUString SAL_CALL
durationToText(css::util::Time
const& i_rut
) throw ()
631 css::util::DateTime dt
;
632 dt
.Hours
= i_rut
.Hours
;
633 dt
.Minutes
= i_rut
.Minutes
;
634 dt
.Seconds
= i_rut
.Seconds
;
635 dt
.HundredthSeconds
= i_rut
.HundredthSeconds
;
636 ::rtl::OUStringBuffer buf
;
637 ::sax::Converter::convertTime(buf
, dt
);
638 return buf
.makeStringAndClear();
641 // convert duration to string
642 ::rtl::OUString SAL_CALL
durationToText(sal_Int32 i_value
) throw ()
645 ut
.Hours
= static_cast<sal_Int16
>(i_value
/ 3600);
646 ut
.Minutes
= static_cast<sal_Int16
>((i_value
% 3600) / 60);
647 ut
.Seconds
= static_cast<sal_Int16
>(i_value
% 60);
648 ut
.HundredthSeconds
= 0;
649 return durationToText(ut
);
652 // extract base URL (necessary for converting relative links)
653 css::uno::Reference
< css::beans::XPropertySet
> SAL_CALL
654 SfxDocumentMetaData::getURLProperties(
655 const css::uno::Sequence
< css::beans::PropertyValue
> & i_rMedium
) const
657 css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf (
658 m_xContext
->getServiceManager());
659 css::uno::Reference
< css::beans::XPropertyContainer
> xPropArg(
660 xMsf
->createInstanceWithContext(::rtl::OUString::createFromAscii(
661 "com.sun.star.beans.PropertyBag"), m_xContext
),
662 css::uno::UNO_QUERY_THROW
);
664 ::rtl::OUString dburl
=
665 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentBaseURL"));
666 ::rtl::OUString hdn
=
667 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HierarchicalDocumentName"));
668 for (sal_Int32 i
= 0; i
< i_rMedium
.getLength(); ++i
) {
669 if (i_rMedium
[i
].Name
.equals(dburl
)) {
670 xPropArg
->addProperty(
671 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseURI")),
672 css::beans::PropertyAttribute::MAYBEVOID
,
674 } else if (i_rMedium
[i
].Name
.equals(hdn
)) {
675 xPropArg
->addProperty(
676 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath")),
677 css::beans::PropertyAttribute::MAYBEVOID
,
681 xPropArg
->addProperty(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StreamName")),
682 css::beans::PropertyAttribute::MAYBEVOID
,
683 css::uno::makeAny(::rtl::OUString::createFromAscii(s_metaXml
)));
684 } catch (css::uno::Exception
&) {
687 return css::uno::Reference
< css::beans::XPropertySet
>(xPropArg
,
688 css::uno::UNO_QUERY_THROW
);
691 // return the text of the (hopefully unique, i.e., normalize first!) text
692 // node _below_ the given node
693 ::rtl::OUString SAL_CALL
694 getNodeText(css::uno::Reference
<css::xml::dom::XNode
> i_xNode
)
695 throw (css::uno::RuntimeException
)
697 if (!i_xNode
.is()) throw css::uno::RuntimeException(
698 ::rtl::OUString::createFromAscii(
699 "SfxDocumentMetaData::getNodeText: argument is null"), i_xNode
);
700 for (css::uno::Reference
<css::xml::dom::XNode
> c
= i_xNode
->getFirstChild();
702 c
= c
->getNextSibling()) {
703 if (c
->getNodeType() == css::xml::dom::NodeType_TEXT_NODE
) {
705 return c
->getNodeValue();
706 } catch (css::xml::dom::DOMException
&) { // too big?
707 return ::rtl::OUString();
711 return ::rtl::OUString();
714 ::rtl::OUString SAL_CALL
715 SfxDocumentMetaData::getMetaText(const char* i_name
) const
716 // throw (css::uno::RuntimeException)
720 const ::rtl::OUString
name( ::rtl::OUString::createFromAscii(i_name
) );
721 DBG_ASSERT(m_meta
.find(name
) != m_meta
.end(),
722 "SfxDocumentMetaData::getMetaText: not found");
723 css::uno::Reference
<css::xml::dom::XNode
> xNode
= m_meta
.find(name
)->second
;
724 return (xNode
.is()) ? getNodeText(xNode
) : ::rtl::OUString();
728 SfxDocumentMetaData::setMetaText(const char* i_name
,
729 const ::rtl::OUString
& i_rValue
)
730 // throw (css::uno::RuntimeException)
734 const ::rtl::OUString
name( ::rtl::OUString::createFromAscii(i_name
) );
735 DBG_ASSERT(m_meta
.find(name
) != m_meta
.end(),
736 "SfxDocumentMetaData::setMetaText: not found");
737 css::uno::Reference
<css::xml::dom::XNode
> xNode
= m_meta
.find(name
)->second
;
740 if (i_rValue
.equalsAscii("")) {
741 if (xNode
.is()) { // delete
742 m_xParent
->removeChild(xNode
);
744 m_meta
[name
] = xNode
;
750 if (xNode
.is()) { // update
751 for (css::uno::Reference
<css::xml::dom::XNode
> c
=
752 xNode
->getFirstChild();
754 c
= c
->getNextSibling()) {
755 if (c
->getNodeType() == css::xml::dom::NodeType_TEXT_NODE
) {
756 if (!c
->getNodeValue().equals(i_rValue
)) {
757 c
->setNodeValue(i_rValue
);
765 xNode
.set(m_xDoc
->createElementNS(getNameSpace(i_name
), name
),
766 css::uno::UNO_QUERY_THROW
);
767 m_xParent
->appendChild(xNode
);
768 m_meta
[name
] = xNode
;
770 css::uno::Reference
<css::xml::dom::XNode
> xTextNode(
771 m_xDoc
->createTextNode(i_rValue
), css::uno::UNO_QUERY_THROW
);
772 xNode
->appendChild(xTextNode
);
775 } catch (css::xml::dom::DOMException
& e
) {
777 throw css::lang::WrappedTargetRuntimeException(
778 ::rtl::OUString::createFromAscii(
779 "SfxDocumentMetaData::setMetaText: DOM exception"),
780 css::uno::Reference
<css::uno::XInterface
>(*this), a
);
785 SfxDocumentMetaData::setMetaTextAndNotify(const char* i_name
,
786 const ::rtl::OUString
& i_rValue
)
787 // throw (css::uno::RuntimeException)
789 ::osl::ClearableMutexGuard
g(m_aMutex
);
790 if (setMetaText(i_name
, i_rValue
)) {
796 ::rtl::OUString SAL_CALL
797 SfxDocumentMetaData::getMetaAttr(const char* i_name
, const char* i_attr
) const
798 // throw (css::uno::RuntimeException)
801 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(i_name
);
802 DBG_ASSERT(m_meta
.find(name
) != m_meta
.end(),
803 "SfxDocumentMetaData::getMetaAttr: not found");
804 css::uno::Reference
<css::xml::dom::XNode
> xNode
= m_meta
.find(name
)->second
;
806 css::uno::Reference
<css::xml::dom::XElement
> xElem(xNode
,
807 css::uno::UNO_QUERY_THROW
);
808 return xElem
->getAttributeNS(getNameSpace(i_attr
),
809 getQualifier(i_attr
).second
);
811 return ::rtl::OUString();
815 css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
816 SfxDocumentMetaData::getMetaList(const char* i_name
) const
817 // throw (css::uno::RuntimeException)
820 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(i_name
);
821 DBG_ASSERT(m_metaList
.find(name
) != m_metaList
.end(),
822 "SfxDocumentMetaData::getMetaList: not found");
823 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> > const & vec
=
824 m_metaList
.find(name
)->second
;
825 css::uno::Sequence
< ::rtl::OUString
> ret(vec
.size());
826 for (size_t i
= 0; i
< vec
.size(); ++i
) {
827 ret
[i
] = getNodeText(vec
.at(i
));
833 SfxDocumentMetaData::setMetaList(const char* i_name
,
834 const css::uno::Sequence
< ::rtl::OUString
> & i_rValue
,
835 AttrVector
const* i_pAttrs
)
836 // throw (css::uno::RuntimeException)
839 DBG_ASSERT((i_pAttrs
== 0) ||
840 (static_cast<size_t>(i_rValue
.getLength()) == i_pAttrs
->size()),
841 "SfxDocumentMetaData::setMetaList: invalid args");
844 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(i_name
);
845 DBG_ASSERT(m_metaList
.find(name
) != m_metaList
.end(),
846 "SfxDocumentMetaData::setMetaList: not found");
847 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> > & vec
=
850 // if nothing changed, do nothing
851 // alas, this does not check for permutations, or attributes...
852 if ((0 == i_pAttrs
)) {
853 if (static_cast<size_t>(i_rValue
.getLength()) == vec
.size()) {
855 for (sal_Int32 i
= 0; i
< i_rValue
.getLength(); ++i
) {
856 css::uno::Reference
<css::xml::dom::XNode
> xNode(vec
.at(i
));
858 ::rtl::OUString val
= getNodeText(xNode
);
859 if (!val
.equals(i_rValue
[i
])) {
865 if (isEqual
) return false;
869 // remove old meta data nodes
871 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> >
872 ::reverse_iterator
it(vec
.rbegin());
874 for ( ;it
!= vec
.rend(); ++it
)
876 m_xParent
->removeChild(*it
);
881 // Clean up already removed nodes
882 vec
.erase(it
.base(), vec
.end());
888 // insert new meta data nodes into DOM tree
889 for (sal_Int32 i
= 0; i
< i_rValue
.getLength(); ++i
) {
890 css::uno::Reference
<css::xml::dom::XElement
> xElem(
891 m_xDoc
->createElementNS(getNameSpace(i_name
), name
),
892 css::uno::UNO_QUERY_THROW
);
893 css::uno::Reference
<css::xml::dom::XNode
> xNode(xElem
,
894 css::uno::UNO_QUERY_THROW
);
895 css::uno::Reference
<css::xml::dom::XNode
> xTextNode(
896 m_xDoc
->createTextNode(i_rValue
[i
]), css::uno::UNO_QUERY_THROW
);
899 for (std::vector
<std::pair
<const char*, ::rtl::OUString
> >
900 ::const_iterator it
= (*i_pAttrs
)[i
].begin();
901 it
!= (*i_pAttrs
)[i
].end(); ++it
) {
902 xElem
->setAttributeNS(getNameSpace(it
->first
),
903 ::rtl::OUString::createFromAscii(it
->first
),
907 xNode
->appendChild(xTextNode
);
908 m_xParent
->appendChild(xNode
);
909 vec
.push_back(xNode
);
913 } catch (css::xml::dom::DOMException
& e
) {
915 throw css::lang::WrappedTargetRuntimeException(
916 ::rtl::OUString::createFromAscii(
917 "SfxDocumentMetaData::setMetaList: DOM exception"),
918 css::uno::Reference
<css::uno::XInterface
>(*this), a
);
922 // convert property list to string list and attribute list
923 std::pair
<css::uno::Sequence
< ::rtl::OUString
>, AttrVector
> SAL_CALL
924 propsToStrings(css::uno::Reference
<css::beans::XPropertySet
> const & i_xPropSet
)
926 ::comphelper::SequenceAsVector
< ::rtl::OUString
> values
;
929 css::uno::Reference
<css::beans::XPropertySetInfo
> xSetInfo
930 = i_xPropSet
->getPropertySetInfo();
931 css::uno::Sequence
<css::beans::Property
> props
= xSetInfo
->getProperties();
933 for (sal_Int32 i
= 0; i
< props
.getLength(); ++i
) {
934 if (props
[i
].Attributes
& css::beans::PropertyAttribute::TRANSIENT
) {
937 const ::rtl::OUString name
= props
[i
].Name
;
940 any
= i_xPropSet
->getPropertyValue(name
);
941 } catch (css::uno::Exception
&) {
944 const css::uno::Type
& type
= any
.getValueType();
945 std::vector
<std::pair
<const char*, ::rtl::OUString
> > as
;
946 as
.push_back(std::make_pair(static_cast<const char*>("meta:name"),
948 const char* vt
= "meta:value-type";
950 // convert according to type
951 if (type
== ::cppu::UnoType
<bool>::get()) {
954 ::rtl::OUStringBuffer buf
;
955 ::sax::Converter::convertBool(buf
, b
);
956 values
.push_back(buf
.makeStringAndClear());
957 as
.push_back(std::make_pair(vt
,
958 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("boolean"))));
959 } else if (type
== ::cppu::UnoType
< ::rtl::OUString
>::get()) {
963 // #i90847# OOo 2.x does stupid things if value-type="string";
964 // fortunately string is default anyway, so we can just omit it
965 // as.push_back(std::make_pair(vt,
966 // ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("string"))));
967 } else if (type
== ::cppu::UnoType
<css::util::DateTime
>::get()) {
968 css::util::DateTime dt
;
970 values
.push_back(dateTimeToText(dt
));
971 as
.push_back(std::make_pair(vt
,
972 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date"))));
973 } else if (type
== ::cppu::UnoType
<css::util::Date
>::get()) {
976 css::util::DateTime dt
;
980 values
.push_back(dateTimeToText(dt
));
981 as
.push_back(std::make_pair(vt
,
982 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date"))));
983 } else if (type
== ::cppu::UnoType
<css::util::Time
>::get()) {
986 values
.push_back(durationToText(ut
));
987 as
.push_back(std::make_pair(vt
,
988 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time"))));
989 } else if (::cppu::UnoType
<double>::get().isAssignableFrom(type
)) {
990 // support not just double, but anything that can be converted
993 ::rtl::OUStringBuffer buf
;
994 ::sax::Converter::convertDouble(buf
, d
);
995 values
.push_back(buf
.makeStringAndClear());
996 as
.push_back(std::make_pair(vt
,
997 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("float"))));
999 DBG_WARNING1("SfxDocumentMetaData: unsupported property type: %s",
1000 OUStringToOString(any
.getValueTypeName(),
1001 RTL_TEXTENCODING_UTF8
).getStr());
1004 attrs
.push_back(as
);
1007 return std::make_pair(values
.getAsConstList(), attrs
);
1010 // remove the given element from the DOM, and iff i_pAttrs != 0 insert new one
1012 SfxDocumentMetaData::updateElement(const char *i_name
,
1013 std::vector
<std::pair
<const char *, ::rtl::OUString
> >* i_pAttrs
)
1015 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(i_name
);
1017 // remove old element
1018 css::uno::Reference
<css::xml::dom::XNode
> xNode
=
1019 m_meta
.find(name
)->second
;
1021 m_xParent
->removeChild(xNode
);
1025 if (0 != i_pAttrs
) {
1026 css::uno::Reference
<css::xml::dom::XElement
> xElem(
1027 m_xDoc
->createElementNS(getNameSpace(i_name
), name
),
1028 css::uno::UNO_QUERY_THROW
);
1029 xNode
.set(xElem
, css::uno::UNO_QUERY_THROW
);
1031 for (std::vector
<std::pair
<const char *, ::rtl::OUString
> >
1032 ::const_iterator it
= i_pAttrs
->begin();
1033 it
!= i_pAttrs
->end(); ++it
) {
1034 xElem
->setAttributeNS(getNameSpace(it
->first
),
1035 ::rtl::OUString::createFromAscii(it
->first
), it
->second
);
1037 m_xParent
->appendChild(xNode
);
1039 m_meta
[name
] = xNode
;
1040 } catch (css::xml::dom::DOMException
& e
) {
1042 throw css::lang::WrappedTargetRuntimeException(
1043 ::rtl::OUString::createFromAscii(
1044 "SfxDocumentMetaData::updateElement: DOM exception"),
1045 css::uno::Reference
<css::uno::XInterface
>(*this), a
);
1049 // update user-defined meta data in DOM tree
1050 void SAL_CALL
SfxDocumentMetaData::updateUserDefinedAndAttributes()
1052 createUserDefined();
1053 css::uno::Reference
<css::beans::XPropertySet
> xPSet(m_xUserDefined
,css::uno::UNO_QUERY_THROW
);
1054 std::pair
<css::uno::Sequence
< ::rtl::OUString
>, AttrVector
> udStringsAttrs
= propsToStrings(xPSet
);
1055 (void) setMetaList("meta:user-defined", udStringsAttrs
.first
,&udStringsAttrs
.second
);
1057 // update elements with attributes
1058 std::vector
<std::pair
<const char *, ::rtl::OUString
> > attributes
;
1059 if (!m_TemplateName
.equalsAscii("") || !m_TemplateURL
.equalsAscii("")
1060 || isValidDateTime(m_TemplateDate
)) {
1061 attributes
.push_back(std::make_pair(
1062 static_cast<const char*>("xlink:type"),
1063 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("simple"))));
1064 attributes
.push_back(std::make_pair(
1065 static_cast<const char*>("xlink:actuate"),
1066 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("onRequest"))));
1067 attributes
.push_back(std::make_pair(
1068 static_cast<const char*>("xlink:title"), m_TemplateName
));
1069 attributes
.push_back(std::make_pair(
1070 static_cast<const char*>("xlink:href" ), m_TemplateURL
));
1071 if (isValidDateTime(m_TemplateDate
)) {
1072 attributes
.push_back(std::make_pair(
1073 static_cast<const char*>("meta:date" ),
1074 dateTimeToText(m_TemplateDate
)));
1076 updateElement("meta:template", &attributes
);
1078 updateElement("meta:template");
1082 if (!m_AutoloadURL
.equalsAscii("") || (0 != m_AutoloadSecs
)) {
1083 attributes
.push_back(std::make_pair(
1084 static_cast<const char*>("xlink:href" ), m_AutoloadURL
));
1085 attributes
.push_back(std::make_pair(
1086 static_cast<const char*>("meta:delay" ),
1087 durationToText(m_AutoloadSecs
)));
1088 updateElement("meta:auto-reload", &attributes
);
1090 updateElement("meta:auto-reload");
1094 if (!m_DefaultTarget
.equalsAscii("")) {
1095 attributes
.push_back(std::make_pair(
1096 static_cast<const char*>("office:target-frame-name"),
1098 // xlink:show: _blank -> new, any other value -> replace
1099 const sal_Char
* show
= m_DefaultTarget
.equalsAscii("_blank")
1100 ? "new" : "replace";
1101 attributes
.push_back(std::make_pair(
1102 static_cast<const char*>("xlink:show"),
1103 ::rtl::OUString::createFromAscii(show
)));
1104 updateElement("meta:hyperlink-behaviour", &attributes
);
1106 updateElement("meta:hyperlink-behaviour");
1111 // create empty DOM tree (XDocument)
1112 css::uno::Reference
<css::xml::dom::XDocument
> SAL_CALL
1113 SfxDocumentMetaData::createDOM() const // throw (css::uno::RuntimeException)
1115 css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf (
1116 m_xContext
->getServiceManager());
1117 css::uno::Reference
<css::xml::dom::XDocumentBuilder
> xBuilder(
1118 xMsf
->createInstanceWithContext(::rtl::OUString::createFromAscii(
1119 "com.sun.star.xml.dom.DocumentBuilder"), m_xContext
),
1120 css::uno::UNO_QUERY_THROW
);
1121 if (!xBuilder
.is()) throw css::uno::RuntimeException(
1122 ::rtl::OUString::createFromAscii("SfxDocumentMetaData::createDOM: "
1123 "cannot create DocumentBuilder service"),
1124 *const_cast<SfxDocumentMetaData
*>(this));
1125 css::uno::Reference
<css::xml::dom::XDocument
> xDoc
=
1126 xBuilder
->newDocument();
1127 if (!xDoc
.is()) throw css::uno::RuntimeException(
1128 ::rtl::OUString::createFromAscii("SfxDocumentMetaData::createDOM: "
1129 "cannot create new document"),
1130 *const_cast<SfxDocumentMetaData
*>(this));
1135 SfxDocumentMetaData::checkInit() const // throw (css::uno::RuntimeException)
1137 if (!m_isInitialized
) {
1138 throw css::uno::RuntimeException(::rtl::OUString::createFromAscii(
1139 "SfxDocumentMetaData::checkInit: not initialized"),
1140 *const_cast<SfxDocumentMetaData
*>(this));
1142 DBG_ASSERT((m_xDoc
.is() && m_xParent
.is() ),
1143 "SfxDocumentMetaData::checkInit: reference is null");
1146 // initialize state from DOM tree
1147 void SAL_CALL
SfxDocumentMetaData::init(
1148 css::uno::Reference
<css::xml::dom::XDocument
> i_xDoc
)
1149 // throw (css::uno::RuntimeException, css::io::WrongFormatException,
1150 // css::uno::Exception)
1152 if (!i_xDoc
.is()) throw css::uno::RuntimeException(
1153 ::rtl::OUString::createFromAscii(
1154 "SfxDocumentMetaData::init: no DOM tree given"), *this);
1156 css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf (
1157 m_xContext
->getServiceManager());
1158 css::uno::Reference
<css::xml::xpath::XXPathAPI
> xPath(
1159 xMsf
->createInstanceWithContext(::rtl::OUString::createFromAscii(
1160 "com.sun.star.xml.xpath.XPathAPI"), m_xContext
),
1161 css::uno::UNO_QUERY_THROW
);
1162 if (!xPath
.is()) throw css::uno::RuntimeException(
1163 ::rtl::OUString::createFromAscii("SfxDocumentMetaData::init:"
1164 " cannot create XPathAPI service"), *this);
1166 m_isInitialized
= false;
1168 m_xDoc
->normalize();
1170 // select nodes for standard meta data stuff
1171 xPath
->registerNS(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xlink")),
1172 ::rtl::OUString::createFromAscii(s_nsXLink
));
1173 xPath
->registerNS(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("dc")),
1174 ::rtl::OUString::createFromAscii(s_nsDC
));
1175 xPath
->registerNS(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("office")),
1176 ::rtl::OUString::createFromAscii(s_nsODF
));
1177 xPath
->registerNS(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("meta")),
1178 ::rtl::OUString::createFromAscii(s_nsODFMeta
));
1179 // NB: we do not handle the single-XML-file ODF variant, which would
1180 // have the root element office:document.
1181 // The root of such documents must be converted in the importer!
1182 ::rtl::OUString prefix
= ::rtl::OUString::createFromAscii(
1183 "/child::office:document-meta/child::office:meta");
1184 css::uno::Reference
<css::xml::dom::XNode
> xDocNode(
1185 m_xDoc
, css::uno::UNO_QUERY_THROW
);
1188 m_xParent
= xPath
->selectSingleNode(xDocNode
, prefix
);
1189 } catch (com::sun::star::uno::Exception
&) {
1190 // DBG_WARNING("SfxDocumentMetaData::init: "
1191 // "caught RuntimeException from libxml!");
1194 if (!m_xParent
.is()) {
1195 // all this create/append stuff may throw DOMException
1197 css::uno::Reference
<css::xml::dom::XElement
> xRElem(
1198 i_xDoc
->createElementNS(
1199 ::rtl::OUString::createFromAscii(s_nsODF
),
1200 ::rtl::OUString::createFromAscii("office:document-meta")));
1201 css::uno::Reference
<css::xml::dom::XNode
> xRNode(xRElem
,
1202 css::uno::UNO_QUERY_THROW
);
1203 // NB: the following is a _bad_idea_ with our DOM implementation
1204 // do _not_ create attributes with xmlns prefix!
1205 // xRElem->setAttribute(::rtl::OUString::createFromAscii("xmlns:office"),
1206 // ::rtl::OUString::createFromAscii(s_nsODF));
1207 xRElem
->setAttributeNS(::rtl::OUString::createFromAscii(s_nsODF
),
1208 ::rtl::OUString::createFromAscii("office:version"),
1209 ::rtl::OUString::createFromAscii("1.0"));
1210 i_xDoc
->appendChild(xRNode
);
1211 css::uno::Reference
<css::xml::dom::XNode
> xParent (
1212 i_xDoc
->createElementNS(
1213 ::rtl::OUString::createFromAscii(s_nsODF
),
1214 ::rtl::OUString::createFromAscii("office:meta")),
1215 css::uno::UNO_QUERY_THROW
);
1216 xRNode
->appendChild(xParent
);
1217 m_xParent
= xParent
;
1218 } catch (css::xml::dom::DOMException
& e
) {
1220 throw css::lang::WrappedTargetRuntimeException(
1221 ::rtl::OUString::createFromAscii(
1222 "SfxDocumentMetaData::init: DOM exception"),
1223 css::uno::Reference
<css::uno::XInterface
>(*this), a
);
1228 // select nodes for elements of which we only handle one occurrence
1229 for (const char **pName
= s_stdMeta
; *pName
!= 0; ++pName
) {
1230 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(*pName
);
1231 // NB: If a document contains more than one occurrence of a
1232 // meta-data element, we arbitrarily pick one of them here.
1233 // We do not remove the others, i.e., when we write the
1234 // document, it will contain the duplicates unchanged.
1235 // The ODF spec says that handling multiple occurrences is
1236 // application-specific.
1237 css::uno::Reference
<css::xml::dom::XNode
> xNode
=
1238 xPath
->selectSingleNode(m_xParent
,
1239 ::rtl::OUString::createFromAscii("child::") + name
);
1240 // Do not create an empty element if it is missing;
1241 // for certain elements, such as dateTime, this would be invalid
1242 m_meta
[name
] = xNode
;
1245 // select nodes for elements of which we handle all occurrences
1246 for (const char **pName
= s_stdMetaList
; *pName
!= 0; ++pName
) {
1247 ::rtl::OUString name
= ::rtl::OUString::createFromAscii(*pName
);
1248 css::uno::Reference
<css::xml::dom::XNodeList
> nodes
=
1249 xPath
->selectNodeList(m_xParent
,
1250 ::rtl::OUString::createFromAscii("child::") + name
);
1251 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> > v
;
1252 for (sal_Int32 i
= 0; i
< nodes
->getLength(); ++i
) {
1253 v
.push_back(nodes
->item(i
));
1255 m_metaList
[name
] = v
;
1258 // initialize members corresponding to attributes from DOM nodes
1259 m_TemplateName
= getMetaAttr("meta:template", "xlink:title");
1260 m_TemplateURL
= getMetaAttr("meta:template", "xlink:href");
1262 textToDateTimeDefault(getMetaAttr("meta:template", "meta:date"));
1263 m_AutoloadURL
= getMetaAttr("meta:auto-reload", "xlink:href");
1265 textToDuration(getMetaAttr("meta:auto-reload", "meta:delay"));
1267 getMetaAttr("meta:hyperlink-behaviour", "office:target-frame-name");
1270 std::vector
<css::uno::Reference
<css::xml::dom::XNode
> > & vec
=
1271 m_metaList
[::rtl::OUString::createFromAscii("meta:user-defined")];
1272 // user-defined meta data: create PropertyBag which only accepts property
1273 // values of allowed types
1276 createUserDefined();
1279 // user-defined meta data: initialize PropertySet from DOM nodes
1281 for (std::vector
<css::uno::Reference
<css::xml::dom::XNode
> >::iterator
1282 it
= vec
.begin(); it
!= vec
.end(); ++it
) {
1283 css::uno::Reference
<css::xml::dom::XElement
> xElem(*it
,
1284 css::uno::UNO_QUERY_THROW
);
1286 ::rtl::OUString name
= xElem
->getAttributeNS(
1287 ::rtl::OUString::createFromAscii(s_nsODFMeta
),
1288 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("name")));
1289 ::rtl::OUString type
= xElem
->getAttributeNS(
1290 ::rtl::OUString::createFromAscii(s_nsODFMeta
),
1291 ::rtl::OUString::createFromAscii("value-type"));
1292 ::rtl::OUString text
= getNodeText(*it
);
1293 if (type
.equalsAscii("float")) {
1295 if (::sax::Converter::convertDouble(d
, text
)) {
1298 DBG_WARNING1("SfxDocumentMetaData: invalid float: %s",
1299 OUStringToOString(text
, RTL_TEXTENCODING_UTF8
).getStr());
1302 } else if (type
.equalsAscii("date")) {
1303 css::util::DateTime dt
;
1304 if (textToDateTime(dt
, text
)) {
1307 DBG_WARNING1("SfxDocumentMetaData: invalid date: %s",
1308 OUStringToOString(text
, RTL_TEXTENCODING_UTF8
).getStr());
1311 } else if (type
.equalsAscii("time")) {
1313 if (textToDuration(ut
, text
)) {
1316 DBG_WARNING1("SfxDocumentMetaData: invalid time: %s",
1317 OUStringToOString(text
, RTL_TEXTENCODING_UTF8
).getStr());
1320 } else if (type
.equalsAscii("boolean")) {
1322 if (::sax::Converter::convertBool(b
, text
)) {
1325 DBG_WARNING1("SfxDocumentMetaData: invalid boolean: %s",
1326 OUStringToOString(text
, RTL_TEXTENCODING_UTF8
).getStr());
1329 } else if (type
.equalsAscii("string") || true) { // default
1333 m_xUserDefined
->addProperty(name
,
1334 css::beans::PropertyAttribute::REMOVEABLE
, any
);
1335 } catch (css::beans::PropertyExistException
&) {
1336 DBG_WARNING1("SfxDocumentMetaData: duplicate: %s",
1337 OUStringToOString(name
, RTL_TEXTENCODING_UTF8
).getStr());
1338 // ignore; duplicate
1339 } catch (css::beans::IllegalTypeException
&) {
1340 DBG_ERROR1("SfxDocumentMetaData: illegal type: %s",
1341 OUStringToOString(name
, RTL_TEXTENCODING_UTF8
).getStr());
1342 } catch (css::lang::IllegalArgumentException
&) {
1343 DBG_ERROR1("SfxDocumentMetaData: illegal arg: %s",
1344 OUStringToOString(name
, RTL_TEXTENCODING_UTF8
).getStr());
1348 m_isModified
= false;
1349 m_isInitialized
= true;
1353 ////////////////////////////////////////////////////////////////////////////
1355 SfxDocumentMetaData::SfxDocumentMetaData(
1356 css::uno::Reference
< css::uno::XComponentContext
> const & context
) :
1357 BaseMutex(), SfxDocumentMetaData_Base(m_aMutex
),
1358 m_xContext(context
), m_NotifyListeners(m_aMutex
),
1359 m_isInitialized(false), m_isModified(false)
1361 DBG_ASSERT(context
.is(), "SfxDocumentMetaData: context is null");
1362 DBG_ASSERT(context
->getServiceManager().is(),
1363 "SfxDocumentMetaData: context has no service manager");
1367 // com.sun.star.uno.XServiceInfo:
1368 ::rtl::OUString SAL_CALL
1369 SfxDocumentMetaData::getImplementationName() throw (css::uno::RuntimeException
)
1371 return comp_SfxDocumentMetaData::_getImplementationName();
1375 SfxDocumentMetaData::supportsService(::rtl::OUString
const & serviceName
)
1376 throw (css::uno::RuntimeException
)
1378 css::uno::Sequence
< ::rtl::OUString
> serviceNames
=
1379 comp_SfxDocumentMetaData::_getSupportedServiceNames();
1380 for (::sal_Int32 i
= 0; i
< serviceNames
.getLength(); ++i
) {
1381 if (serviceNames
[i
] == serviceName
)
1387 css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
1388 SfxDocumentMetaData::getSupportedServiceNames()
1389 throw (css::uno::RuntimeException
)
1391 return comp_SfxDocumentMetaData::_getSupportedServiceNames();
1395 // ::com::sun::star::lang::XComponent:
1396 void SAL_CALL
SfxDocumentMetaData::dispose() throw (css::uno::RuntimeException
)
1398 ::osl::MutexGuard
g(m_aMutex
);
1399 if (!m_isInitialized
) {
1402 WeakComponentImplHelperBase::dispose(); // superclass
1403 m_NotifyListeners
.disposeAndClear(css::lang::EventObject(
1404 static_cast< ::cppu::OWeakObject
* >(this)));
1405 m_isInitialized
= false;
1410 m_xUserDefined
.clear();
1414 // ::com::sun::star::document::XDocumentProperties:
1415 ::rtl::OUString SAL_CALL
1416 SfxDocumentMetaData::getAuthor() throw (css::uno::RuntimeException
)
1418 ::osl::MutexGuard
g(m_aMutex
);
1419 return getMetaText("meta:initial-creator");
1422 void SAL_CALL
SfxDocumentMetaData::setAuthor(const ::rtl::OUString
& the_value
)
1423 throw (css::uno::RuntimeException
)
1425 setMetaTextAndNotify("meta:initial-creator", the_value
);
1429 ::rtl::OUString SAL_CALL
1430 SfxDocumentMetaData::getGenerator() throw (css::uno::RuntimeException
)
1432 ::osl::MutexGuard
g(m_aMutex
);
1433 return getMetaText("meta:generator");
1437 SfxDocumentMetaData::setGenerator(const ::rtl::OUString
& the_value
)
1438 throw (css::uno::RuntimeException
)
1440 setMetaTextAndNotify("meta:generator", the_value
);
1443 css::util::DateTime SAL_CALL
1444 SfxDocumentMetaData::getCreationDate() throw (css::uno::RuntimeException
)
1446 ::osl::MutexGuard
g(m_aMutex
);
1447 return textToDateTimeDefault(getMetaText("meta:creation-date"));
1451 SfxDocumentMetaData::setCreationDate(const css::util::DateTime
& the_value
)
1452 throw (css::uno::RuntimeException
)
1454 setMetaTextAndNotify("meta:creation-date", dateTimeToText(the_value
));
1457 ::rtl::OUString SAL_CALL
1458 SfxDocumentMetaData::getTitle() throw (css::uno::RuntimeException
)
1460 ::osl::MutexGuard
g(m_aMutex
);
1461 return getMetaText("dc:title");
1464 void SAL_CALL
SfxDocumentMetaData::setTitle(const ::rtl::OUString
& the_value
)
1465 throw (css::uno::RuntimeException
)
1467 setMetaTextAndNotify("dc:title", the_value
);
1470 ::rtl::OUString SAL_CALL
1471 SfxDocumentMetaData::getSubject() throw (css::uno::RuntimeException
)
1473 ::osl::MutexGuard
g(m_aMutex
);
1474 return getMetaText("dc:subject");
1478 SfxDocumentMetaData::setSubject(const ::rtl::OUString
& the_value
)
1479 throw (css::uno::RuntimeException
)
1481 setMetaTextAndNotify("dc:subject", the_value
);
1484 ::rtl::OUString SAL_CALL
1485 SfxDocumentMetaData::getDescription() throw (css::uno::RuntimeException
)
1487 ::osl::MutexGuard
g(m_aMutex
);
1488 return getMetaText("dc:description");
1492 SfxDocumentMetaData::setDescription(const ::rtl::OUString
& the_value
)
1493 throw (css::uno::RuntimeException
)
1495 setMetaTextAndNotify("dc:description", the_value
);
1498 css::uno::Sequence
< ::rtl::OUString
>
1499 SAL_CALL
SfxDocumentMetaData::getKeywords() throw (css::uno::RuntimeException
)
1501 ::osl::MutexGuard
g(m_aMutex
);
1502 return getMetaList("meta:keyword");
1506 SfxDocumentMetaData::setKeywords(
1507 const css::uno::Sequence
< ::rtl::OUString
> & the_value
)
1508 throw (css::uno::RuntimeException
)
1510 ::osl::ClearableMutexGuard
g(m_aMutex
);
1511 if (setMetaList("meta:keyword", the_value
)) {
1517 css::lang::Locale SAL_CALL
1518 SfxDocumentMetaData::getLanguage() throw (css::uno::RuntimeException
)
1520 ::osl::MutexGuard
g(m_aMutex
);
1521 css::lang::Locale loc
;
1522 ::rtl::OUString text
= getMetaText("dc:language");
1523 sal_Int32 ix
= text
.indexOf(static_cast<sal_Unicode
> ('-'));
1525 loc
.Language
= text
;
1527 loc
.Language
= text
.copy(0, ix
);
1528 loc
.Country
= text
.copy(ix
+1);
1534 SfxDocumentMetaData::setLanguage(const css::lang::Locale
& the_value
)
1535 throw (css::uno::RuntimeException
)
1537 ::rtl::OUString text
= the_value
.Language
;
1538 if (the_value
.Country
.getLength() > 0) {
1539 text
+= ::rtl::OUString::createFromAscii("-").concat(the_value
.Country
);
1541 setMetaTextAndNotify("dc:language", text
);
1544 ::rtl::OUString SAL_CALL
1545 SfxDocumentMetaData::getModifiedBy() throw (css::uno::RuntimeException
)
1547 ::osl::MutexGuard
g(m_aMutex
);
1548 return getMetaText("dc:creator");
1552 SfxDocumentMetaData::setModifiedBy(const ::rtl::OUString
& the_value
)
1553 throw (css::uno::RuntimeException
)
1555 setMetaTextAndNotify("dc:creator", the_value
);
1558 css::util::DateTime SAL_CALL
1559 SfxDocumentMetaData::getModificationDate() throw (css::uno::RuntimeException
)
1561 ::osl::MutexGuard
g(m_aMutex
);
1562 return textToDateTimeDefault(getMetaText("dc:date"));
1566 SfxDocumentMetaData::setModificationDate(const css::util::DateTime
& the_value
)
1567 throw (css::uno::RuntimeException
)
1569 setMetaTextAndNotify("dc:date", dateTimeToText(the_value
));
1572 ::rtl::OUString SAL_CALL
1573 SfxDocumentMetaData::getPrintedBy() throw (css::uno::RuntimeException
)
1575 ::osl::MutexGuard
g(m_aMutex
);
1576 return getMetaText("meta:printed-by");
1580 SfxDocumentMetaData::setPrintedBy(const ::rtl::OUString
& the_value
)
1581 throw (css::uno::RuntimeException
)
1583 setMetaTextAndNotify("meta:printed-by", the_value
);
1586 css::util::DateTime SAL_CALL
1587 SfxDocumentMetaData::getPrintDate() throw (css::uno::RuntimeException
)
1589 ::osl::MutexGuard
g(m_aMutex
);
1590 return textToDateTimeDefault(getMetaText("meta:print-date"));
1594 SfxDocumentMetaData::setPrintDate(const css::util::DateTime
& the_value
)
1595 throw (css::uno::RuntimeException
)
1597 setMetaTextAndNotify("meta:print-date", dateTimeToText(the_value
));
1600 ::rtl::OUString SAL_CALL
1601 SfxDocumentMetaData::getTemplateName() throw (css::uno::RuntimeException
)
1603 ::osl::MutexGuard
g(m_aMutex
);
1605 return m_TemplateName
;
1609 SfxDocumentMetaData::setTemplateName(const ::rtl::OUString
& the_value
)
1610 throw (css::uno::RuntimeException
)
1612 ::osl::ClearableMutexGuard
g(m_aMutex
);
1614 if (m_TemplateName
!= the_value
) {
1615 m_TemplateName
= the_value
;
1621 ::rtl::OUString SAL_CALL
1622 SfxDocumentMetaData::getTemplateURL() throw (css::uno::RuntimeException
)
1624 ::osl::MutexGuard
g(m_aMutex
);
1626 return m_TemplateURL
;
1630 SfxDocumentMetaData::setTemplateURL(const ::rtl::OUString
& the_value
)
1631 throw (css::uno::RuntimeException
)
1633 ::osl::ClearableMutexGuard
g(m_aMutex
);
1635 if (m_TemplateURL
!= the_value
) {
1636 m_TemplateURL
= the_value
;
1642 css::util::DateTime SAL_CALL
1643 SfxDocumentMetaData::getTemplateDate() throw (css::uno::RuntimeException
)
1645 ::osl::MutexGuard
g(m_aMutex
);
1647 return m_TemplateDate
;
1651 SfxDocumentMetaData::setTemplateDate(const css::util::DateTime
& the_value
)
1652 throw (css::uno::RuntimeException
)
1654 ::osl::ClearableMutexGuard
g(m_aMutex
);
1656 if (!(m_TemplateDate
== the_value
)) {
1657 m_TemplateDate
= the_value
;
1663 ::rtl::OUString SAL_CALL
1664 SfxDocumentMetaData::getAutoloadURL() throw (css::uno::RuntimeException
)
1666 ::osl::MutexGuard
g(m_aMutex
);
1668 return m_AutoloadURL
;
1672 SfxDocumentMetaData::setAutoloadURL(const ::rtl::OUString
& the_value
)
1673 throw (css::uno::RuntimeException
)
1675 ::osl::ClearableMutexGuard
g(m_aMutex
);
1677 if (m_AutoloadURL
!= the_value
) {
1678 m_AutoloadURL
= the_value
;
1684 ::sal_Int32 SAL_CALL
1685 SfxDocumentMetaData::getAutoloadSecs() throw (css::uno::RuntimeException
)
1687 ::osl::MutexGuard
g(m_aMutex
);
1689 return m_AutoloadSecs
;
1693 SfxDocumentMetaData::setAutoloadSecs(::sal_Int32 the_value
)
1694 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
)
1696 if (the_value
< 0) throw css::lang::IllegalArgumentException(
1697 ::rtl::OUString::createFromAscii(
1698 "SfxDocumentMetaData::setAutoloadSecs: argument is negative"),
1700 ::osl::ClearableMutexGuard
g(m_aMutex
);
1702 if (m_AutoloadSecs
!= the_value
) {
1703 m_AutoloadSecs
= the_value
;
1709 ::rtl::OUString SAL_CALL
1710 SfxDocumentMetaData::getDefaultTarget() throw (css::uno::RuntimeException
)
1712 ::osl::MutexGuard
g(m_aMutex
);
1714 return m_DefaultTarget
;
1718 SfxDocumentMetaData::setDefaultTarget(const ::rtl::OUString
& the_value
)
1719 throw (css::uno::RuntimeException
)
1721 ::osl::ClearableMutexGuard
g(m_aMutex
);
1723 if (m_DefaultTarget
!= the_value
) {
1724 m_DefaultTarget
= the_value
;
1730 css::uno::Sequence
< css::beans::NamedValue
> SAL_CALL
1731 SfxDocumentMetaData::getDocumentStatistics() throw (css::uno::RuntimeException
)
1733 ::osl::MutexGuard
g(m_aMutex
);
1735 ::comphelper::SequenceAsVector
<css::beans::NamedValue
> stats
;
1736 for (size_t i
= 0; s_stdStats
[i
] != 0; ++i
) {
1737 const char * aName
= s_stdStatAttrs
[i
];
1738 ::rtl::OUString text
= getMetaAttr("meta:document-statistic", aName
);
1739 if (text
.equalsAscii("")) continue;
1740 css::beans::NamedValue stat
;
1741 stat
.Name
= ::rtl::OUString::createFromAscii(s_stdStats
[i
]);
1744 if (!::sax::Converter::convertNumber(val
, text
, 0,
1745 std::numeric_limits
<sal_Int32
>::max()) || (val
< 0)) {
1747 DBG_WARNING1("SfxDocumentMetaData: invalid number: %s",
1748 OUStringToOString(text
, RTL_TEXTENCODING_UTF8
).getStr());
1752 stats
.push_back(stat
);
1755 return stats
.getAsConstList();
1759 SfxDocumentMetaData::setDocumentStatistics(
1760 const css::uno::Sequence
< css::beans::NamedValue
> & the_value
)
1761 throw (css::uno::RuntimeException
)
1763 ::osl::ClearableMutexGuard
g(m_aMutex
);
1765 std::vector
<std::pair
<const char *, ::rtl::OUString
> > attributes
;
1766 for (sal_Int32 i
= 0; i
< the_value
.getLength(); ++i
) {
1767 const ::rtl::OUString name
= the_value
[i
].Name
;
1768 // inefficently search for matching attribute
1769 for (size_t j
= 0; s_stdStats
[j
] != 0; ++j
) {
1770 if (name
.equalsAscii(s_stdStats
[j
])) {
1771 const css::uno::Any any
= the_value
[i
].Value
;
1774 ::rtl::OUStringBuffer buf
;
1775 ::sax::Converter::convertNumber(buf
, val
);
1776 attributes
.push_back(std::make_pair(s_stdStatAttrs
[j
],
1777 buf
.makeStringAndClear()));
1779 DBG_WARNING1("SfxDocumentMetaData: invalid statistic: %s",
1780 OUStringToOString(name
, RTL_TEXTENCODING_UTF8
)
1787 updateElement("meta:document-statistic", &attributes
);
1792 ::sal_Int16 SAL_CALL
1793 SfxDocumentMetaData::getEditingCycles() throw (css::uno::RuntimeException
)
1795 ::osl::MutexGuard
g(m_aMutex
);
1796 ::rtl::OUString text
= getMetaText("meta:editing-cycles");
1798 if (::sax::Converter::convertNumber(ret
, text
,
1799 0, std::numeric_limits
<sal_Int16
>::max())) {
1800 return static_cast<sal_Int16
>(ret
);
1807 SfxDocumentMetaData::setEditingCycles(::sal_Int16 the_value
)
1808 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
)
1810 if (the_value
< 0) throw css::lang::IllegalArgumentException(
1811 ::rtl::OUString::createFromAscii(
1812 "SfxDocumentMetaData::setEditingCycles: argument is negative"),
1814 ::rtl::OUStringBuffer buf
;
1815 ::sax::Converter::convertNumber(buf
, the_value
);
1816 setMetaTextAndNotify("meta:editing-cycles", buf
.makeStringAndClear());
1819 ::sal_Int32 SAL_CALL
1820 SfxDocumentMetaData::getEditingDuration() throw (css::uno::RuntimeException
)
1822 ::osl::MutexGuard
g(m_aMutex
);
1823 return textToDuration(getMetaText("meta:editing-duration"));
1827 SfxDocumentMetaData::setEditingDuration(::sal_Int32 the_value
)
1828 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
)
1830 if (the_value
< 0) throw css::lang::IllegalArgumentException(
1831 ::rtl::OUString::createFromAscii(
1832 "SfxDocumentMetaData::setEditingDuration: argument is negative"),
1834 setMetaTextAndNotify("meta:editing-duration", durationToText(the_value
));
1838 SfxDocumentMetaData::resetUserData(const ::rtl::OUString
& the_value
)
1839 throw (css::uno::RuntimeException
)
1841 ::osl::ClearableMutexGuard
g(m_aMutex
);
1843 bool bModified( false );
1844 bModified
|= setMetaText("meta:initial-creator", the_value
);
1845 ::DateTime now
= DateTime();
1846 css::util::DateTime
uDT(now
.Get100Sec(), now
.GetSec(), now
.GetMin(),
1847 now
.GetHour(), now
.GetDay(), now
.GetMonth(), now
.GetYear());
1848 bModified
|= setMetaText("meta:creation-date", dateTimeToText(uDT
));
1849 bModified
|= setMetaText("dc:creator", ::rtl::OUString());
1850 bModified
|= setMetaText("meta:printed-by", ::rtl::OUString());
1851 bModified
|= setMetaText("dc:date", dateTimeToText(css::util::DateTime()));
1852 bModified
|= setMetaText("meta:print-date",
1853 dateTimeToText(css::util::DateTime()));
1854 bModified
|= setMetaText("meta:editing-duration", durationToText(0));
1855 bModified
|= setMetaText("meta:editing-cycles",
1856 ::rtl::OUString::createFromAscii("1"));
1865 css::uno::Reference
< css::beans::XPropertyContainer
> SAL_CALL
1866 SfxDocumentMetaData::getUserDefinedProperties()
1867 throw (css::uno::RuntimeException
)
1869 ::osl::MutexGuard
g(m_aMutex
);
1871 createUserDefined();
1872 return m_xUserDefined
;
1877 SfxDocumentMetaData::loadFromStorage(
1878 const css::uno::Reference
< css::embed::XStorage
> & xStorage
,
1879 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
1880 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
,
1881 css::io::WrongFormatException
,
1882 css::lang::WrappedTargetException
, css::io::IOException
,
1883 css::uno::Exception
)
1885 if (!xStorage
.is()) throw css::lang::IllegalArgumentException(
1886 ::rtl::OUString::createFromAscii("SfxDocumentMetaData::loadFromStorage:"
1887 " argument is null"), *this, 0);
1888 ::osl::MutexGuard
g(m_aMutex
);
1890 // open meta data file
1891 css::uno::Reference
<css::io::XStream
> xStream(
1892 xStorage
->openStreamElement(
1893 ::rtl::OUString::createFromAscii(s_metaXml
),
1894 css::embed::ElementModes::READ
) );
1895 if (!xStream
.is()) throw css::lang::NullPointerException();
1896 css::uno::Reference
<css::io::XInputStream
> xInStream
=
1897 xStream
->getInputStream();
1898 if (!xInStream
.is()) throw css::lang::NullPointerException();
1900 // create DOM parser service
1901 css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf (
1902 m_xContext
->getServiceManager());
1903 css::uno::Reference
<css::xml::sax::XParser
> xParser (
1904 xMsf
->createInstanceWithContext(::rtl::OUString::createFromAscii(
1905 "com.sun.star.xml.sax.Parser"), m_xContext
),
1906 css::uno::UNO_QUERY_THROW
);
1907 if (!xParser
.is()) throw css::uno::RuntimeException(
1908 ::rtl::OUString::createFromAscii("SfxDocumentMetaData::loadFromStorage:"
1909 " cannot create Parser service"), *this);
1910 css::xml::sax::InputSource input
;
1911 input
.aInputStream
= xInStream
;
1913 sal_uInt64 version
= SotStorage::GetVersion( xStorage
);
1914 // Oasis is also the default (0)
1915 sal_Bool bOasis
= ( version
> SOFFICE_FILEFORMAT_60
|| version
== 0 );
1916 const sal_Char
*pServiceName
= bOasis
1917 ? "com.sun.star.document.XMLOasisMetaImporter"
1918 : "com.sun.star.document.XMLMetaImporter";
1921 css::uno::Reference
<css::beans::XPropertySet
> xPropArg
=
1922 getURLProperties(Medium
);
1924 xPropArg
->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseURI")))
1925 >>= input
.sSystemId
;
1926 input
.sSystemId
+= ::rtl::OUString::createFromAscii("/").concat(
1927 ::rtl::OUString::createFromAscii(s_metaXml
));
1928 } catch (css::uno::Exception
&) {
1929 input
.sSystemId
= ::rtl::OUString::createFromAscii(s_metaXml
);
1931 css::uno::Sequence
< css::uno::Any
> args(1);
1932 args
[0] <<= xPropArg
;
1934 css::uno::Reference
<css::xml::sax::XDocumentHandler
> xDocHandler (
1935 xMsf
->createInstanceWithArgumentsAndContext(
1936 ::rtl::OUString::createFromAscii(pServiceName
), args
, m_xContext
),
1937 css::uno::UNO_QUERY_THROW
);
1938 if (!xDocHandler
.is()) throw css::uno::RuntimeException(
1939 ::rtl::OUString::createFromAscii("SfxDocumentMetaData::loadFromStorage:"
1940 " cannot create XMLOasisMetaImporter service"), *this);
1941 css::uno::Reference
<css::document::XImporter
> xImp (xDocHandler
,
1942 css::uno::UNO_QUERY_THROW
);
1943 xImp
->setTargetDocument(css::uno::Reference
<css::lang::XComponent
>(this));
1944 xParser
->setDocumentHandler(xDocHandler
);
1946 xParser
->parseStream(input
);
1947 } catch (css::xml::sax::SAXException
&) {
1948 throw css::io::WrongFormatException(::rtl::OUString::createFromAscii(
1949 "SfxDocumentMetaData::loadFromStorage:"
1950 " XML parsing exception"), *this);
1952 // NB: the implementation of XMLOasisMetaImporter calls initialize
1953 // init(xDocBuilder->getDocument());
1958 SfxDocumentMetaData::storeToStorage(
1959 const css::uno::Reference
< css::embed::XStorage
> & xStorage
,
1960 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
1961 throw (css::uno::RuntimeException
, css::lang::IllegalArgumentException
,
1962 css::lang::WrappedTargetException
, css::io::IOException
,
1963 css::uno::Exception
)
1965 if (!xStorage
.is()) throw css::lang::IllegalArgumentException(
1966 ::rtl::OUString::createFromAscii("SfxDocumentMetaData::storeToStorage:"
1967 " argument is null"), *this, 0);
1968 ::osl::MutexGuard
g(m_aMutex
);
1971 // update user-defined meta data in DOM tree
1972 // updateUserDefinedAndAttributes(); // this will be done in serialize!
1974 // write into storage
1975 css::uno::Reference
<css::io::XStream
> xStream
=
1976 xStorage
->openStreamElement(::rtl::OUString::createFromAscii(s_metaXml
),
1977 css::embed::ElementModes::WRITE
1978 | css::embed::ElementModes::TRUNCATE
);
1979 if (!xStream
.is()) throw css::lang::NullPointerException();
1980 css::uno::Reference
< css::beans::XPropertySet
> xStreamProps(xStream
,
1981 css::uno::UNO_QUERY_THROW
);
1982 xStreamProps
->setPropertyValue(
1983 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")),
1984 css::uno::makeAny(::rtl::OUString::createFromAscii("text/xml")));
1985 xStreamProps
->setPropertyValue(
1986 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")),
1987 css::uno::makeAny(static_cast<sal_Bool
> (sal_False
)));
1988 xStreamProps
->setPropertyValue(
1989 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption")),
1990 css::uno::makeAny(static_cast<sal_Bool
> (sal_False
)));
1991 css::uno::Reference
<css::io::XOutputStream
> xOutStream
=
1992 xStream
->getOutputStream();
1993 if (!xOutStream
.is()) throw css::lang::NullPointerException();
1994 css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf (
1995 m_xContext
->getServiceManager());
1996 css::uno::Reference
<css::io::XActiveDataSource
> xSaxWriter(
1997 xMsf
->createInstanceWithContext(::rtl::OUString::createFromAscii(
1998 "com.sun.star.xml.sax.Writer"), m_xContext
),
1999 css::uno::UNO_QUERY_THROW
);
2000 xSaxWriter
->setOutputStream(xOutStream
);
2001 css::uno::Reference
<css::xml::sax::XDocumentHandler
> xDocHandler (
2002 xSaxWriter
, css::uno::UNO_QUERY_THROW
);
2004 const sal_uInt64 version
= SotStorage::GetVersion( xStorage
);
2005 // Oasis is also the default (0)
2006 const sal_Bool bOasis
= ( version
> SOFFICE_FILEFORMAT_60
|| version
== 0 );
2007 const sal_Char
*pServiceName
= bOasis
2008 ? "com.sun.star.document.XMLOasisMetaExporter"
2009 : "com.sun.star.document.XMLMetaExporter";
2012 css::uno::Reference
<css::beans::XPropertySet
> xPropArg
=
2013 getURLProperties(Medium
);
2014 css::uno::Sequence
< css::uno::Any
> args(2);
2015 args
[0] <<= xDocHandler
;
2016 args
[1] <<= xPropArg
;
2018 css::uno::Reference
<css::document::XExporter
> xExp(
2019 xMsf
->createInstanceWithArgumentsAndContext(
2020 ::rtl::OUString::createFromAscii(pServiceName
), args
, m_xContext
),
2021 css::uno::UNO_QUERY_THROW
);
2022 xExp
->setSourceDocument(css::uno::Reference
<css::lang::XComponent
>(this));
2023 css::uno::Reference
<css::document::XFilter
> xFilter(xExp
,
2024 css::uno::UNO_QUERY_THROW
);
2025 if (xFilter
->filter(css::uno::Sequence
< css::beans::PropertyValue
>())) {
2026 css::uno::Reference
<css::embed::XTransactedObject
> xTransaction(
2027 xStorage
, css::uno::UNO_QUERY
);
2028 if (xTransaction
.is()) {
2029 xTransaction
->commit();
2032 throw css::io::IOException(::rtl::OUString::createFromAscii(
2033 "SfxDocumentMetaData::storeToStorage: cannot filter"), *this);
2038 SfxDocumentMetaData::loadFromMedium(const ::rtl::OUString
& URL
,
2039 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
2040 throw (css::uno::RuntimeException
, css::io::WrongFormatException
,
2041 css::lang::WrappedTargetException
, css::io::IOException
,
2042 css::uno::Exception
)
2044 css::uno::Reference
<css::io::XInputStream
> xIn
;
2045 ::comphelper::MediaDescriptor
md(Medium
);
2046 // if we have an URL parameter, it replaces the one in the media descriptor
2047 if (!URL
.equalsAscii("")) {
2048 md
[ ::comphelper::MediaDescriptor::PROP_URL() ] <<= URL
;
2050 if (sal_True
== md
.addInputStream()) {
2051 md
[ ::comphelper::MediaDescriptor::PROP_INPUTSTREAM() ] >>= xIn
;
2053 css::uno::Reference
<css::embed::XStorage
> xStorage
;
2054 css::uno::Reference
<css::lang::XMultiServiceFactory
> xMsf (
2055 m_xContext
->getServiceManager(), css::uno::UNO_QUERY_THROW
);
2058 xStorage
= ::comphelper::OStorageHelper::GetStorageFromInputStream(
2060 } else { // fallback to url parameter
2061 xStorage
= ::comphelper::OStorageHelper::GetStorageFromURL(
2062 URL
, css::embed::ElementModes::READ
, xMsf
);
2064 } catch (css::uno::RuntimeException
&) {
2066 } catch (css::io::IOException
&) {
2068 } catch (css::uno::Exception
& e
) {
2069 throw css::lang::WrappedTargetException(
2070 ::rtl::OUString::createFromAscii(
2071 "SfxDocumentMetaData::loadFromMedium: exception"),
2072 css::uno::Reference
<css::uno::XInterface
>(*this),
2073 css::uno::makeAny(e
));
2075 if (!xStorage
.is()) {
2076 throw css::lang::NullPointerException(::rtl::OUString::createFromAscii(
2077 "SfxDocumentMetaData::loadFromMedium: cannot get Storage"),
2080 loadFromStorage(xStorage
, md
.getAsConstPropertyValueList());
2084 SfxDocumentMetaData::storeToMedium(const ::rtl::OUString
& URL
,
2085 const css::uno::Sequence
< css::beans::PropertyValue
> & Medium
)
2086 throw (css::uno::RuntimeException
,
2087 css::lang::WrappedTargetException
, css::io::IOException
,
2088 css::uno::Exception
)
2090 ::comphelper::MediaDescriptor
md(Medium
);
2091 if (!URL
.equalsAscii("")) {
2092 md
[ ::comphelper::MediaDescriptor::PROP_URL() ] <<= URL
;
2094 SfxMedium
aMedium(md
.getAsConstPropertyValueList());
2095 css::uno::Reference
<css::embed::XStorage
> xStorage
2096 = aMedium
.GetOutputStorage();
2099 if (!xStorage
.is()) {
2100 throw css::lang::NullPointerException(::rtl::OUString::createFromAscii(
2101 "SfxDocumentMetaData::storeToMedium: cannot get Storage"),
2104 // set MIME type of the storage
2105 ::comphelper::MediaDescriptor::const_iterator iter
2106 = md
.find(::comphelper::MediaDescriptor::PROP_MEDIATYPE());
2107 if (iter
!= md
.end()) {
2108 css::uno::Reference
< css::beans::XPropertySet
> xProps(xStorage
,
2109 css::uno::UNO_QUERY_THROW
);
2110 xProps
->setPropertyValue(
2111 ::comphelper::MediaDescriptor::PROP_MEDIATYPE(),
2114 storeToStorage(xStorage
, md
.getAsConstPropertyValueList());
2117 const sal_Bool bOk
= aMedium
.Commit();
2120 sal_uInt32 nError
= aMedium
.GetError();
2121 if ( nError
== ERRCODE_NONE
) {
2122 nError
= ERRCODE_IO_GENERAL
;
2125 throw css::task::ErrorCodeIOException( ::rtl::OUString(),
2126 css::uno::Reference
< css::uno::XInterface
>(), nError
);
2131 // ::com::sun::star::lang::XInitialization:
2133 SfxDocumentMetaData::initialize(
2134 const css::uno::Sequence
< ::com::sun::star::uno::Any
> & aArguments
)
2135 throw (css::uno::RuntimeException
, css::uno::Exception
)
2137 // possible arguments:
2138 // - no argument: default initialization (empty DOM)
2139 // - 1 argument, XDocument: initialize with given DOM and empty base URL
2140 // NB: links in document must be absolute
2142 ::osl::MutexGuard
g(m_aMutex
);
2143 css::uno::Reference
<css::xml::dom::XDocument
> xDoc
;
2145 for (sal_Int32 i
= 0; i
< aArguments
.getLength(); ++i
) {
2146 const css::uno::Any any
= aArguments
[i
];
2149 throw css::lang::IllegalArgumentException(
2150 ::rtl::OUString::createFromAscii("SfxDocumentMetaData::"
2151 "initialize: argument is null"),
2152 *this, static_cast<sal_Int16
>(i
));
2155 throw css::lang::IllegalArgumentException(
2156 ::rtl::OUString::createFromAscii("SfxDocumentMetaData::"
2157 "initialize: argument must be XDocument"),
2158 *this, static_cast<sal_Int16
>(i
));
2163 // For a new document, we create a new DOM tree here.
2170 // ::com::sun::star::util::XCloneable:
2171 css::uno::Reference
<css::util::XCloneable
> SAL_CALL
2172 SfxDocumentMetaData::createClone()
2173 throw (css::uno::RuntimeException
)
2175 ::osl::MutexGuard
g(m_aMutex
);
2178 SfxDocumentMetaData
*pNew
= createMe(m_xContext
);
2180 // NB: do not copy the modification listeners, only DOM
2181 css::uno::Reference
<css::xml::dom::XDocument
> xDoc
= createDOM();
2183 updateUserDefinedAndAttributes();
2184 // deep copy of root node
2185 css::uno::Reference
<css::xml::dom::XNode
> xRoot(
2186 m_xDoc
->getDocumentElement(), css::uno::UNO_QUERY_THROW
);
2187 css::uno::Reference
<css::xml::dom::XNode
> xRootNew(
2188 xDoc
->importNode(xRoot
, true));
2189 xDoc
->appendChild(xRootNew
);
2191 } catch (css::uno::RuntimeException
&) {
2193 } catch (css::uno::Exception
& e
) {
2195 throw css::lang::WrappedTargetRuntimeException(
2196 ::rtl::OUString::createFromAscii(
2197 "SfxDocumentMetaData::createClone: exception"),
2198 css::uno::Reference
<css::uno::XInterface
>(*this), a
);
2200 // return static_cast< ::cppu::OWeakObject * > (pNew);
2201 return css::uno::Reference
<css::util::XCloneable
> (pNew
);
2204 // ::com::sun::star::util::XModifiable:
2205 ::sal_Bool SAL_CALL
SfxDocumentMetaData::isModified( )
2206 throw (css::uno::RuntimeException
)
2208 ::osl::MutexGuard
g(m_aMutex
);
2210 css::uno::Reference
<css::util::XModifiable
> xMB(m_xUserDefined
,
2211 css::uno::UNO_QUERY
);
2212 return m_isModified
|| (xMB
.is() ? xMB
->isModified() : sal_False
);
2215 void SAL_CALL
SfxDocumentMetaData::setModified( ::sal_Bool bModified
)
2216 throw (css::beans::PropertyVetoException
, css::uno::RuntimeException
)
2218 css::uno::Reference
<css::util::XModifiable
> xMB
;
2219 { // do not lock mutex while notifying (#i93514#) to prevent deadlock
2220 ::osl::MutexGuard
g(m_aMutex
);
2222 m_isModified
= bModified
;
2225 xMB
.set(m_xUserDefined
, css::uno::UNO_QUERY
);
2226 DBG_ASSERT(xMB
.is(),
2227 "SfxDocumentMetaData::setModified: PropertyBag not Modifiable?");
2232 css::uno::Reference
<css::uno::XInterface
> xThis(*this);
2233 css::lang::EventObject
event(xThis
);
2234 m_NotifyListeners
.notifyEach(&css::util::XModifyListener::modified
,
2236 } catch (css::uno::RuntimeException
&) {
2238 } catch (css::uno::Exception
& e
) {
2240 DBG_WARNING1("SfxDocumentMetaData::setModified: exception:\n%s",
2241 OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).getStr());
2246 xMB
->setModified(false);
2251 // ::com::sun::star::util::XModifyBroadcaster:
2252 void SAL_CALL
SfxDocumentMetaData::addModifyListener(
2253 const css::uno::Reference
< css::util::XModifyListener
> & xListener
)
2254 throw (css::uno::RuntimeException
)
2256 ::osl::MutexGuard
g(m_aMutex
);
2258 m_NotifyListeners
.addInterface(xListener
);
2259 css::uno::Reference
<css::util::XModifyBroadcaster
> xMB(m_xUserDefined
,
2260 css::uno::UNO_QUERY
);
2262 xMB
->addModifyListener(xListener
);
2266 void SAL_CALL
SfxDocumentMetaData::removeModifyListener(
2267 const css::uno::Reference
< css::util::XModifyListener
> & xListener
)
2268 throw (css::uno::RuntimeException
)
2270 ::osl::MutexGuard
g(m_aMutex
);
2272 m_NotifyListeners
.removeInterface(xListener
);
2273 css::uno::Reference
<css::util::XModifyBroadcaster
> xMB(m_xUserDefined
,
2274 css::uno::UNO_QUERY
);
2276 xMB
->removeModifyListener(xListener
);
2280 // ::com::sun::star::xml::sax::XSAXSerializable
2281 void SAL_CALL
SfxDocumentMetaData::serialize(
2282 const css::uno::Reference
<css::xml::sax::XDocumentHandler
>& i_xHandler
,
2283 const css::uno::Sequence
< css::beans::StringPair
>& i_rNamespaces
)
2284 throw (css::uno::RuntimeException
, css::xml::sax::SAXException
)
2286 ::osl::MutexGuard
g(m_aMutex
);
2288 updateUserDefinedAndAttributes();
2289 css::uno::Reference
<css::xml::sax::XSAXSerializable
> xSAXable(m_xDoc
,
2290 css::uno::UNO_QUERY_THROW
);
2291 xSAXable
->serialize(i_xHandler
, i_rNamespaces
);
2294 void SfxDocumentMetaData::createUserDefined()
2296 if ( !m_xUserDefined
.is() )
2298 css::uno::Sequence
<css::uno::Type
> types(10);
2299 types
[0] = ::cppu::UnoType
<bool>::get();
2300 types
[1] = ::cppu::UnoType
< ::rtl::OUString
>::get();
2301 types
[2] = ::cppu::UnoType
<css::util::DateTime
>::get();
2302 types
[3] = ::cppu::UnoType
<css::util::Date
>::get();
2303 types
[4] = ::cppu::UnoType
<css::util::Time
>::get();
2304 types
[5] = ::cppu::UnoType
<float>::get();
2305 types
[6] = ::cppu::UnoType
<double>::get();
2306 types
[7] = ::cppu::UnoType
<sal_Int16
>::get();
2307 types
[8] = ::cppu::UnoType
<sal_Int32
>::get();
2308 types
[9] = ::cppu::UnoType
<sal_Int64
>::get();
2309 css::uno::Sequence
<css::uno::Any
> args(2);
2310 args
[0] <<= css::beans::NamedValue(
2311 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowedTypes")),
2312 css::uno::makeAny(types
));
2313 // #i94175#: ODF 1.1 allows empty user-defined property names!
2314 args
[1] <<= css::beans::NamedValue(
2315 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowEmptyPropertyName")),
2316 css::uno::makeAny(sal_True
));
2318 css::uno::Reference
<css::lang::XMultiComponentFactory
> xMsf (m_xContext
->getServiceManager());
2320 xMsf
->createInstanceWithContext(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.PropertyBag")), m_xContext
),
2321 css::uno::UNO_QUERY_THROW
);
2322 css::uno::Reference
<css::lang::XInitialization
> xInit(m_xUserDefined
,
2323 css::uno::UNO_QUERY
);
2325 xInit
->initialize(args
);
2328 css::uno::Reference
<css::util::XModifyBroadcaster
> xMB(m_xUserDefined
,css::uno::UNO_QUERY
);
2331 css::uno::Sequence
< css::uno::Reference
< css::uno::XInterface
> > aListener
= m_NotifyListeners
.getElements();
2332 const css::uno::Reference
< css::uno::XInterface
>* pIter
= aListener
.getConstArray();
2333 const css::uno::Reference
< css::uno::XInterface
>* pEnd
= pIter
+ aListener
.getLength();
2334 for(;pIter
!= pEnd
;++pIter
)
2335 xMB
->addModifyListener(css::uno::Reference
< css::util::XModifyListener
>(*pIter
,css::uno::UNO_QUERY
));
2340 } // closing anonymous implementation namespace
2343 // component helper namespace
2344 namespace comp_CompatWriterDocProps
{
2346 ::rtl::OUString SAL_CALL
_getImplementationName() {
2347 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
2348 "CompatWriterDocPropsImpl"));
2351 css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
_getSupportedServiceNames()
2353 static css::uno::Sequence
< rtl::OUString
> aServiceNames
;
2354 if ( aServiceNames
.getLength() == 0 )
2356 aServiceNames
.realloc( 1 );
2357 aServiceNames
[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.writer.DocumentProperties" ) );
2359 return aServiceNames
;
2361 css::uno::Reference
< css::uno::XInterface
> SAL_CALL
_create(
2362 const css::uno::Reference
< css::uno::XComponentContext
> & context
)
2363 SAL_THROW((css::uno::Exception
))
2365 return static_cast< ::cppu::OWeakObject
* >
2366 (new CompatWriterDocPropsImpl(context
));
2370 namespace comp_SfxDocumentMetaData
{
2372 ::rtl::OUString SAL_CALL
_getImplementationName() {
2373 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
2374 "SfxDocumentMetaData"));
2377 css::uno::Sequence
< ::rtl::OUString
> SAL_CALL
_getSupportedServiceNames()
2379 css::uno::Sequence
< ::rtl::OUString
> s(1);
2380 s
[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
2381 "com.sun.star.document.DocumentProperties"));
2385 css::uno::Reference
< css::uno::XInterface
> SAL_CALL
_create(
2386 const css::uno::Reference
< css::uno::XComponentContext
> & context
)
2387 SAL_THROW((css::uno::Exception
))
2389 return static_cast< ::cppu::OWeakObject
* >
2390 (new SfxDocumentMetaData(context
));
2393 } // closing component helper namespace
2395 static ::cppu::ImplementationEntry
const entries
[] = {
2396 { &comp_SfxDocumentMetaData::_create
,
2397 &comp_SfxDocumentMetaData::_getImplementationName
,
2398 &comp_SfxDocumentMetaData::_getSupportedServiceNames
,
2399 &::cppu::createSingleComponentFactory
, 0, 0 },
2400 { 0, 0, 0, 0, 0, 0 }
2404 extern "C" void SAL_CALL
component_getImplementationEnvironment(
2405 const char ** envTypeName
, uno_Environment
**)
2407 *envTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
2410 extern "C" void * SAL_CALL
component_getFactory(
2411 const char * implName
, void * serviceManager
, void * registryKey
)
2413 return ::cppu::component_getFactoryHelper(
2414 implName
, serviceManager
, registryKey
, entries
);
2417 extern "C" sal_Bool SAL_CALL
component_writeInfo(
2418 void * serviceManager
, void * registryKey
)
2420 return ::cppu::component_writeInfoHelper(serviceManager
, registryKey
,