25#include <com/sun/star/lang/XServiceInfo.hpp>
26#include <com/sun/star/document/XDocumentProperties.hpp>
27#include <com/sun/star/lang/XInitialization.hpp>
28#include <com/sun/star/util/XCloneable.hpp>
29#include <com/sun/star/util/XModifiable.hpp>
30#include <com/sun/star/xml/sax/SAXException.hpp>
31#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
33#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
34#include <com/sun/star/lang/EventObject.hpp>
35#include <com/sun/star/beans/IllegalTypeException.hpp>
36#include <com/sun/star/beans/PropertyExistException.hpp>
37#include <com/sun/star/beans/XPropertySet.hpp>
38#include <com/sun/star/beans/XPropertySetInfo.hpp>
39#include <com/sun/star/beans/PropertyAttribute.hpp>
40#include <com/sun/star/task/ErrorCodeIOException.hpp>
41#include <com/sun/star/embed/XStorage.hpp>
42#include <com/sun/star/embed/XTransactedObject.hpp>
43#include <com/sun/star/embed/ElementModes.hpp>
44#include <com/sun/star/io/WrongFormatException.hpp>
45#include <com/sun/star/io/XStream.hpp>
46#include <com/sun/star/document/XImporter.hpp>
47#include <com/sun/star/document/XExporter.hpp>
48#include <com/sun/star/document/XFilter.hpp>
49#include <com/sun/star/xml/sax/Writer.hpp>
50#include <com/sun/star/xml/sax/Parser.hpp>
51#include <com/sun/star/xml/sax/XFastParser.hpp>
52#include <com/sun/star/xml/dom/DOMException.hpp>
53#include <com/sun/star/xml/dom/XDocument.hpp>
54#include <com/sun/star/xml/dom/XElement.hpp>
55#include <com/sun/star/xml/dom/DocumentBuilder.hpp>
56#include <com/sun/star/xml/dom/NodeType.hpp>
57#include <com/sun/star/xml/xpath/XPathAPI.hpp>
58#include <com/sun/star/util/Date.hpp>
59#include <com/sun/star/util/Time.hpp>
60#include <com/sun/star/util/DateWithTimezone.hpp>
61#include <com/sun/star/util/DateTimeWithTimezone.hpp>
62#include <com/sun/star/util/Duration.hpp>
64#include <rtl/ustrbuf.hxx>
65#include <tools/datetime.hxx>
67#include <osl/mutex.hxx>
90#include <com/sun/star/document/XCompatWriterDocProperties.hpp>
91#include <com/sun/star/beans/PropertyBag.hpp>
121typedef std::vector<std::vector<std::pair<OUString, OUString> > >
124typedef ::cppu::WeakComponentImplHelper<
125 css::lang::XServiceInfo,
126 css::document::XDocumentProperties,
127 css::lang::XInitialization,
128 css::util::XCloneable,
129 css::util::XModifiable,
130 css::xml::sax::XSAXSerializable>
131 SfxDocumentMetaData_Base;
133class SfxDocumentMetaData:
135 public SfxDocumentMetaData_Base
138 explicit SfxDocumentMetaData(
139 css::uno::Reference< css::uno::XComponentContext >
const & context);
140 SfxDocumentMetaData(
const SfxDocumentMetaData&) =
delete;
141 SfxDocumentMetaData& operator=(
const SfxDocumentMetaData&) =
delete;
146 const OUString & ServiceName)
override;
147 virtual css::uno::Sequence< OUString > SAL_CALL
151 virtual void SAL_CALL
dispose()
override;
154 virtual OUString SAL_CALL getAuthor()
override;
155 virtual void SAL_CALL setAuthor(
const OUString & the_value)
override;
156 virtual OUString SAL_CALL getGenerator()
override;
157 virtual void SAL_CALL setGenerator(
const OUString & the_value)
override;
158 virtual css::util::DateTime SAL_CALL getCreationDate()
override;
159 virtual void SAL_CALL setCreationDate(
const css::util::DateTime & the_value)
override;
160 virtual OUString SAL_CALL
getTitle()
override;
161 virtual void SAL_CALL setTitle(
const OUString & the_value)
override;
162 virtual OUString SAL_CALL getSubject()
override;
163 virtual void SAL_CALL setSubject(
const OUString & the_value)
override;
164 virtual OUString SAL_CALL getDescription()
override;
165 virtual void SAL_CALL setDescription(
const OUString & the_value)
override;
166 virtual css::uno::Sequence< OUString > SAL_CALL getKeywords()
override;
167 virtual void SAL_CALL setKeywords(
168 const css::uno::Sequence< OUString > & the_value)
override;
169 virtual css::lang::Locale SAL_CALL getLanguage()
override;
170 virtual void SAL_CALL setLanguage(
const css::lang::Locale & the_value)
override;
171 virtual OUString SAL_CALL getModifiedBy()
override;
172 virtual void SAL_CALL setModifiedBy(
const OUString & the_value)
override;
173 virtual css::util::DateTime SAL_CALL getModificationDate()
override;
174 virtual void SAL_CALL setModificationDate(
175 const css::util::DateTime & the_value)
override;
176 virtual OUString SAL_CALL getPrintedBy()
override;
177 virtual void SAL_CALL setPrintedBy(
const OUString & the_value)
override;
178 virtual css::util::DateTime SAL_CALL getPrintDate()
override;
179 virtual void SAL_CALL setPrintDate(
const css::util::DateTime & the_value)
override;
180 virtual OUString SAL_CALL getTemplateName()
override;
181 virtual void SAL_CALL setTemplateName(
const OUString & the_value)
override;
182 virtual OUString SAL_CALL getTemplateURL()
override;
183 virtual void SAL_CALL setTemplateURL(
const OUString & the_value)
override;
184 virtual css::util::DateTime SAL_CALL getTemplateDate()
override;
185 virtual void SAL_CALL setTemplateDate(
const css::util::DateTime & the_value)
override;
186 virtual OUString SAL_CALL getAutoloadURL()
override;
187 virtual void SAL_CALL setAutoloadURL(
const OUString & the_value)
override;
188 virtual ::sal_Int32 SAL_CALL getAutoloadSecs()
override;
189 virtual void SAL_CALL setAutoloadSecs(::sal_Int32 the_value)
override;
190 virtual OUString SAL_CALL getDefaultTarget()
override;
191 virtual void SAL_CALL setDefaultTarget(
const OUString & the_value)
override;
192 virtual css::uno::Sequence< css::beans::NamedValue > SAL_CALL
193 getDocumentStatistics()
override;
194 virtual void SAL_CALL setDocumentStatistics(
195 const css::uno::Sequence< css::beans::NamedValue > & the_value)
override;
196 virtual ::sal_Int16 SAL_CALL getEditingCycles()
override;
197 virtual void SAL_CALL setEditingCycles(::sal_Int16 the_value)
override;
198 virtual ::sal_Int32 SAL_CALL getEditingDuration()
override;
199 virtual void SAL_CALL setEditingDuration(::sal_Int32 the_value)
override;
200 virtual void SAL_CALL resetUserData(
const OUString & the_value)
override;
201 virtual css::uno::Reference< css::beans::XPropertyContainer > SAL_CALL
202 getUserDefinedProperties()
override;
203 virtual void SAL_CALL loadFromStorage(
204 const css::uno::Reference< css::embed::XStorage > & Storage,
205 const css::uno::Sequence< css::beans::PropertyValue > & Medium)
override;
206 virtual void SAL_CALL loadFromMedium(
const OUString & URL,
207 const css::uno::Sequence< css::beans::PropertyValue > & Medium)
override;
208 virtual void SAL_CALL storeToStorage(
209 const css::uno::Reference< css::embed::XStorage > & Storage,
210 const css::uno::Sequence< css::beans::PropertyValue > & Medium)
override;
211 virtual void SAL_CALL storeToMedium(
const OUString & URL,
212 const css::uno::Sequence< css::beans::PropertyValue > & Medium)
override;
215 virtual void SAL_CALL initialize(
216 const css::uno::Sequence< css::uno::Any > & aArguments)
override;
219 virtual css::uno::Reference<css::util::XCloneable> SAL_CALL createClone()
override;
222 virtual sal_Bool SAL_CALL isModified( )
override;
223 virtual void SAL_CALL setModified(
sal_Bool bModified )
override;
226 virtual void SAL_CALL addModifyListener(
227 const css::uno::Reference< css::util::XModifyListener > & xListener)
override;
228 virtual void SAL_CALL removeModifyListener(
229 const css::uno::Reference< css::util::XModifyListener > & xListener)
override;
232 virtual void SAL_CALL serialize(
233 const css::uno::Reference<css::xml::sax::XDocumentHandler>& i_xHandler,
234 const css::uno::Sequence< css::beans::StringPair >& i_rNamespaces)
override;
237 virtual ~SfxDocumentMetaData()
override {}
239 const css::uno::Reference< css::uno::XComponentContext >
m_xContext;
244 bool m_isInitialized;
248 css::uno::Reference< css::xml::dom::XDocument > m_xDoc;
250 css::uno::Reference< css::xml::dom::XNode> m_xParent;
252 std::map< OUString, css::uno::Reference<css::xml::dom::XNode> >
256 std::vector<css::uno::Reference<css::xml::dom::XNode> > > m_metaList;
258 css::uno::Reference<css::beans::XPropertyContainer> m_xUserDefined;
261 OUString m_TemplateName;
262 OUString m_TemplateURL;
263 css::util::DateTime m_TemplateDate;
264 OUString m_AutoloadURL;
265 sal_Int32 m_AutoloadSecs;
266 OUString m_DefaultTarget;
269 void checkInit()
const;
271 void init(
const css::uno::Reference<css::xml::dom::XDocument>& i_xDom);
273 void updateElement(
const OUString & i_name,
274 std::vector<std::pair<OUString, OUString> >* i_pAttrs =
nullptr);
276 void updateUserDefinedAndAttributes();
278 css::uno::Reference<css::xml::dom::XDocument> createDOM()
const;
280 css::uno::Reference<css::beans::XPropertySet> getURLProperties(
281 const css::uno::Sequence<css::beans::PropertyValue> & i_rMedium)
const;
283 OUString getMetaText(
const char* i_name)
const;
285 bool setMetaText(
const OUString& i_name,
286 const OUString & i_rValue);
288 void setMetaTextAndNotify(
const OUString& i_name,
289 const OUString & i_rValue);
291 OUString getMetaAttr(
const OUString& i_name,
292 const OUString& i_attr)
const;
294 css::uno::Sequence< OUString > getMetaList(
295 const char* i_name)
const;
297 bool setMetaList(
const OUString& i_name,
298 const css::uno::Sequence< OUString > & i_rValue,
300 void createUserDefined();
303typedef ::cppu::ImplInheritanceHelper< SfxDocumentMetaData, css::document::XCompatWriterDocProperties > CompatWriterDocPropsImpl_BASE;
305class CompatWriterDocPropsImpl :
public CompatWriterDocPropsImpl_BASE
311 virtual rtl::Reference<SfxDocumentMetaData> createMe( css::uno::Reference< css::uno::XComponentContext >
const & context )
override {
return new CompatWriterDocPropsImpl( context ); };
313 explicit CompatWriterDocPropsImpl( css::uno::Reference< css::uno::XComponentContext >
const & context) : CompatWriterDocPropsImpl_BASE( context ) {}
316 virtual OUString SAL_CALL getManager()
override {
return msManager; }
317 virtual void SAL_CALL setManager(
const OUString& _manager )
override { msManager = _manager; }
318 virtual OUString SAL_CALL getCategory()
override {
return msCategory; }
319 virtual void SAL_CALL setCategory(
const OUString& _category )
override { msCategory = _category; }
320 virtual OUString SAL_CALL getCompany()
override {
return msCompany; }
321 virtual void SAL_CALL setCompany(
const OUString& _company )
override { msCompany = _company; }
326 return "CompatWriterDocPropsImpl";
336 css::uno::Sequence<OUString>
aServiceNames {
"com.sun.star.writer.DocumentProperties" };
341constexpr OUStringLiteral sMetaPageCount =
u"meta:page-count";
342constexpr OUStringLiteral sMetaTableCount =
u"meta:table-count";
343constexpr OUStringLiteral sMetaDrawCount =
u"meta:draw-count";
344constexpr OUStringLiteral sMetaImageCount =
u"meta:image-count";
345constexpr OUStringLiteral sMetaObjectCount =
u"meta:object-count";
346constexpr OUStringLiteral sMetaOleObjectCount =
u"meta:ole-object-count";
347constexpr OUStringLiteral sMetaParagraphCount =
u"meta:paragraph-count";
348constexpr OUStringLiteral sMetaWordCount =
u"meta:word-count";
349constexpr OUStringLiteral sMetaCharacterCount =
u"meta:character-count";
350constexpr OUStringLiteral sMetaRowCount =
u"meta:row-count";
351constexpr OUStringLiteral sMetaFrameCount =
u"meta:frame-count";
352constexpr OUStringLiteral sMetaSentenceCount =
u"meta:sentence-count";
353constexpr OUStringLiteral sMetaSyllableCount =
u"meta:syllable-count";
354constexpr OUStringLiteral sMetaNonWhitespaceCharacterCount =
u"meta:non-whitespace-character-count";
355constexpr OUStringLiteral sMetaCellCount =
u"meta:cell-count";
358constexpr rtl::OUStringConstExpr s_stdStatAttrs[] = {
372 sMetaNonWhitespaceCharacterCount,
377const char* s_stdStats[] = {
391 "NonWhitespaceCharacterCount",
396const char* s_stdMeta[] = {
401 "meta:initial-creator",
404 "meta:creation-date",
409 "meta:hyperlink-behaviour",
411 "meta:editing-cycles",
412 "meta:editing-duration",
413 "meta:document-statistic",
417constexpr OUStringLiteral sMetaKeyword =
u"meta:keyword";
418constexpr OUStringLiteral sMetaUserDefined =
u"meta:user-defined";
419constexpr rtl::OUStringConstExpr s_stdMetaList[] {
424constexpr OUStringLiteral s_nsXLink =
u"http://www.w3.org/1999/xlink";
425constexpr OUStringLiteral s_nsDC =
u"http://purl.org/dc/elements/1.1/";
426constexpr OUStringLiteral s_nsODF =
u"urn:oasis:names:tc:opendocument:xmlns:office:1.0";
427constexpr OUStringLiteral s_nsODFMeta =
u"urn:oasis:names:tc:opendocument:xmlns:meta:1.0";
430constexpr OUStringLiteral
s_meta =
u"meta.xml";
434 return i_rDate.Month > 0;
437bool isValidDateTime(
const css::util::DateTime & i_rDateTime)
439 return i_rDateTime.Month > 0;
442std::pair< OUString, OUString >
443getQualifier(
const OUString& nm) {
444 sal_Int32 ix = nm.indexOf(u
':');
446 return std::make_pair(OUString(), nm);
448 return std::make_pair(nm.copy(0,ix), nm.copy(ix+1));
454OUString getNameSpace(
const OUString& i_qname)
noexcept
457 OUString
n = getQualifier(i_qname).first;
458 if ( n ==
"xlink" )
ns = s_nsXLink;
459 if ( n ==
"dc" )
ns = s_nsDC;
460 if ( n ==
"office" )
ns = s_nsODF;
461 if ( n ==
"meta" )
ns = s_nsODFMeta;
462 assert(!
ns.isEmpty());
467textToDateOrDateTime(css::util::Date & io_rd, css::util::DateTime & io_rdt,
468 bool & o_rIsDateTime, std::optional<sal_Int16> & o_rTimeZone,
469 const OUString& i_text)
noexcept
472 &io_rd, io_rdt, o_rIsDateTime, &o_rTimeZone, i_text)) {
475 SAL_WARN_IF(!i_text.isEmpty(),
"sfx.doc",
"Invalid date: " << i_text);
482textToDateTime(css::util::DateTime & io_rdt,
const OUString& i_text)
noexcept
487 SAL_WARN_IF(!i_text.isEmpty(),
"sfx.doc",
"Invalid date: " << i_text);
494textToDateTimeDefault(
const OUString& i_text)
noexcept
496 css::util::DateTime dt;
497 static_cast<void> (textToDateTime(dt, i_text));
504dateToText(css::util::Date
const& i_rd,
505 sal_Int16
const*
const pTimeZone)
noexcept
510 return buf.makeStringAndClear();
519dateTimeToText(css::util::DateTime
const& i_rdt,
520 sal_Int16
const*
const pTimeZone =
nullptr) noexcept
522 if (isValidDateTime(i_rdt)) {
523 OUStringBuffer buf(32);
525 return buf.makeStringAndClear();
533textToDuration(css::util::Duration& io_rDur, OUString
const& i_rText)
539 SAL_WARN_IF(!i_rText.isEmpty(),
"sfx.doc",
"Invalid duration: " << i_rText);
544sal_Int32 textToDuration(OUString
const& i_rText)
noexcept
546 css::util::Duration
d;
547 if (textToDuration(d, i_rText)) {
549 const sal_Int32 days( (
d.Years * 365) + (
d.Months * 30) +
d.Days );
550 return (days * (24*3600))
551 + (
d.Hours * 3600) + (
d.Minutes * 60) +
d.Seconds;
558OUString durationToText(css::util::Duration
const& i_rDur)
noexcept
562 return buf.makeStringAndClear();
566OUString durationToText(sal_Int32 i_value)
noexcept
568 css::util::Duration ud;
569 ud.Days =
static_cast<sal_Int16
>(i_value / (24 * 3600));
570 ud.Hours =
static_cast<sal_Int16
>((i_value % (24 * 3600)) / 3600);
571 ud.Minutes =
static_cast<sal_Int16
>((i_value % 3600) / 60);
572 ud.Seconds =
static_cast<sal_Int16
>(i_value % 60);
574 return durationToText(ud);
578css::uno::Reference< css::beans::XPropertySet >
579SfxDocumentMetaData::getURLProperties(
580 const css::uno::Sequence< css::beans::PropertyValue > & i_rMedium)
const
582 css::uno::Reference< css::beans::XPropertyBag> xPropArg = css::beans::PropertyBag::createDefault( m_xContext );
584 css::uno::Any baseUri;
585 for (
const auto& rProp : i_rMedium) {
586 if (rProp.Name ==
"DocumentBaseURL") {
587 baseUri = rProp.Value;
588 }
else if (rProp.Name ==
"URL") {
589 if (!baseUri.hasValue()) {
590 baseUri = rProp.Value;
592 }
else if (rProp.Name ==
"HierarchicalDocumentName") {
593 xPropArg->addProperty(
595 css::beans::PropertyAttribute::MAYBEVOID,
599 if (baseUri.hasValue()) {
600 xPropArg->addProperty(
601 "BaseURI", css::beans::PropertyAttribute::MAYBEVOID,
604 xPropArg->addProperty(
"StreamName",
605 css::beans::PropertyAttribute::MAYBEVOID,
606 css::uno::Any(OUString(s_meta)));
607 }
catch (
const css::uno::Exception &) {
610 return css::uno::Reference< css::beans::XPropertySet>(xPropArg,
611 css::uno::UNO_QUERY_THROW);
618getNodeText(
const css::uno::Reference<css::xml::dom::XNode>& i_xNode)
621 throw css::uno::RuntimeException(
"SfxDocumentMetaData::getNodeText: argument is null", i_xNode);
622 for (css::uno::Reference<css::xml::dom::XNode> c = i_xNode->getFirstChild();
624 c = c->getNextSibling()) {
625 if (c->getNodeType() == css::xml::dom::NodeType_TEXT_NODE) {
627 return c->getNodeValue();
628 }
catch (
const css::xml::dom::DOMException &) {
637SfxDocumentMetaData::getMetaText(
const char* i_name)
const
642 const OUString
name( OUString::createFromAscii(i_name) );
643 assert(m_meta.find(name) != m_meta.end());
644 css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
645 return (xNode.is()) ? getNodeText(xNode) : OUString();
649SfxDocumentMetaData::setMetaText(
const OUString& name,
650 const OUString & i_rValue)
655 assert(m_meta.find(name) != m_meta.end());
656 css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
659 if (i_rValue.isEmpty()) {
661 m_xParent->removeChild(xNode);
663 m_meta[
name] = xNode;
670 for (css::uno::Reference<css::xml::dom::XNode> c =
671 xNode->getFirstChild();
673 c = c->getNextSibling()) {
674 if (c->getNodeType() == css::xml::dom::NodeType_TEXT_NODE) {
675 if (c->getNodeValue() != i_rValue) {
676 c->setNodeValue(i_rValue);
684 xNode.set(m_xDoc->createElementNS(getNameSpace(name), name),
685 css::uno::UNO_QUERY_THROW);
686 m_xParent->appendChild(xNode);
687 m_meta[
name] = xNode;
689 css::uno::Reference<css::xml::dom::XNode> xTextNode(
690 m_xDoc->createTextNode(i_rValue), css::uno::UNO_QUERY_THROW);
691 xNode->appendChild(xTextNode);
694 }
catch (
const css::xml::dom::DOMException &) {
696 throw css::lang::WrappedTargetRuntimeException(
697 "SfxDocumentMetaData::setMetaText: DOM exception",
698 css::uno::Reference<css::uno::XInterface>(*
this), anyEx);
703SfxDocumentMetaData::setMetaTextAndNotify(
const OUString & i_name,
704 const OUString & i_rValue)
707 ::osl::ClearableMutexGuard g(m_aMutex);
708 if (setMetaText(i_name, i_rValue)) {
715SfxDocumentMetaData::getMetaAttr(
const OUString& name,
const OUString& i_attr)
const
718 assert(m_meta.find(name) != m_meta.end());
719 css::uno::Reference<css::xml::dom::XNode> xNode = m_meta.find(name)->second;
721 css::uno::Reference<css::xml::dom::XElement> xElem(xNode,
722 css::uno::UNO_QUERY_THROW);
723 return xElem->getAttributeNS(getNameSpace(i_attr),
724 getQualifier(i_attr).second);
730css::uno::Sequence< OUString>
731SfxDocumentMetaData::getMetaList(
const char* i_name)
const
735 OUString
name = OUString::createFromAscii(i_name);
736 assert(m_metaList.find(name) != m_metaList.end());
737 std::vector<css::uno::Reference<css::xml::dom::XNode> >
const & vec =
738 m_metaList.find(name)->second;
739 css::uno::Sequence< OUString> ret(vec.size());
740 std::transform(vec.begin(), vec.end(), ret.getArray(),
741 [](
const auto& node) { return getNodeText(node); });
746SfxDocumentMetaData::setMetaList(
const OUString& name,
747 const css::uno::Sequence<OUString> & i_rValue,
748 AttrVector
const* i_pAttrs)
752 assert((i_pAttrs ==
nullptr) ||
753 (
static_cast<size_t>(i_rValue.getLength()) == i_pAttrs->size()));
756 assert(m_metaList.find(name) != m_metaList.end());
757 std::vector<css::uno::Reference<css::xml::dom::XNode> > & vec =
762 if (
nullptr == i_pAttrs) {
763 if (
static_cast<size_t>(i_rValue.getLength()) == vec.size()) {
765 for (sal_Int32 i = 0;
i < i_rValue.getLength(); ++
i) {
766 css::uno::Reference<css::xml::dom::XNode> xNode(vec.at(i));
768 OUString val = getNodeText(xNode);
769 if (val != i_rValue[i]) {
775 if (isEqual)
return false;
781 std::vector<css::uno::Reference<css::xml::dom::XNode> >
782 ::reverse_iterator it(vec.rbegin());
784 for ( ;it != vec.rend(); ++it)
786 m_xParent->removeChild(*it);
792 vec.erase(it.base(), vec.end());
799 for (sal_Int32 i = 0;
i < i_rValue.getLength(); ++
i) {
800 css::uno::Reference<css::xml::dom::XElement> xElem(
801 m_xDoc->createElementNS(getNameSpace(name), name),
802 css::uno::UNO_SET_THROW);
803 css::uno::Reference<css::xml::dom::XNode> xNode(xElem,
804 css::uno::UNO_QUERY_THROW);
805 css::uno::Reference<css::xml::dom::XNode> xTextNode(
806 m_xDoc->createTextNode(i_rValue[i]), css::uno::UNO_QUERY_THROW);
808 if (i_pAttrs !=
nullptr) {
809 for (
auto const& elem : (*i_pAttrs)[i])
811 xElem->setAttributeNS(getNameSpace(elem.first),
812 elem.first, elem.second);
815 xNode->appendChild(xTextNode);
816 m_xParent->appendChild(xNode);
817 vec.push_back(xNode);
821 }
catch (
const css::xml::dom::DOMException &) {
823 throw css::lang::WrappedTargetRuntimeException(
824 "SfxDocumentMetaData::setMetaList: DOM exception",
825 css::uno::Reference<css::uno::XInterface>(*
this), anyEx);
830std::pair<css::uno::Sequence< OUString>, AttrVector>
831propsToStrings(css::uno::Reference<css::beans::XPropertySet>
const & i_xPropSet)
833 ::std::vector< OUString >
values;
836 css::uno::Reference<css::beans::XPropertySetInfo> xSetInfo
837 = i_xPropSet->getPropertySetInfo();
838 css::uno::Sequence<css::beans::Property>
props = xSetInfo->getProperties();
840 for (sal_Int32 i = 0;
i <
props.getLength(); ++
i) {
841 if (props[i].Attributes & css::beans::PropertyAttribute::TRANSIENT) {
847 any = i_xPropSet->getPropertyValue(name);
848 }
catch (
const css::uno::Exception &) {
851 const css::uno::Type &
type =
any.getValueType();
852 std::vector<std::pair<OUString, OUString> > as;
853 as.emplace_back(
"meta:name", name);
854 static constexpr OUStringLiteral vt =
u"meta:value-type";
862 values.push_back(buf.makeStringAndClear());
863 as.emplace_back(vt, OUString(
"boolean"));
874 as.emplace_back(vt, OUString(
"string"));
877 css::util::DateTime dt;
879 values.push_back(dateTimeToText(dt));
880 as.emplace_back(vt, OUString(
"date"));
884 values.push_back(dateToText(d,
nullptr));
885 as.emplace_back(vt,OUString(
"date"));
887 css::util::DateTimeWithTimezone dttz;
889 values.push_back(dateTimeToText(dttz.DateTimeInTZ, &dttz.Timezone));
890 as.emplace_back(vt, OUString(
"date"));
892 css::util::DateWithTimezone dtz;
894 values.push_back(dateToText(dtz.DateInTZ, &dtz.Timezone));
895 as.emplace_back(vt, OUString(
"date"));
901 css::util::Duration ud;
903 ud.Minutes = ut.Minutes;
904 ud.Seconds = ut.Seconds;
905 ud.NanoSeconds = ut.NanoSeconds;
906 values.push_back(durationToText(ud));
907 as.emplace_back(vt, OUString(
"time"));
909 css::util::Duration ud;
911 values.push_back(durationToText(ud));
912 as.emplace_back(vt, OUString(
"time"));
919 values.push_back(buf.makeStringAndClear());
920 as.emplace_back(vt, OUString(
"float"));
922 SAL_WARN(
"sfx.doc",
"Unsupported property type: " <<
any.getValueTypeName() );
933SfxDocumentMetaData::updateElement(
const OUString& name,
934 std::vector<std::pair<OUString, OUString> >* i_pAttrs)
938 css::uno::Reference<css::xml::dom::XNode> xNode =
939 m_meta.find(name)->second;
941 m_xParent->removeChild(xNode);
945 if (
nullptr != i_pAttrs) {
946 css::uno::Reference<css::xml::dom::XElement> xElem(
947 m_xDoc->createElementNS(getNameSpace(name), name),
948 css::uno::UNO_SET_THROW);
949 xNode.set(xElem, css::uno::UNO_QUERY_THROW);
951 for (
auto const& elem : *i_pAttrs)
953 xElem->setAttributeNS(getNameSpace(elem.first),
954 elem.first, elem.second);
956 m_xParent->appendChild(xNode);
958 m_meta[
name] = xNode;
959 }
catch (
const css::xml::dom::DOMException &) {
961 throw css::lang::WrappedTargetRuntimeException(
962 "SfxDocumentMetaData::updateElement: DOM exception",
963 css::uno::Reference<css::uno::XInterface>(*
this), anyEx);
968void SfxDocumentMetaData::updateUserDefinedAndAttributes()
971 const css::uno::Reference<css::beans::XPropertySet> xPSet(m_xUserDefined,
972 css::uno::UNO_QUERY_THROW);
973 const std::pair<css::uno::Sequence< OUString>, AttrVector>
974 udStringsAttrs( propsToStrings(xPSet) );
975 (void) setMetaList(
"meta:user-defined", udStringsAttrs.first,
976 &udStringsAttrs.second);
979 std::vector<std::pair<OUString, OUString> > attributes;
980 if (!m_TemplateName.isEmpty() || !m_TemplateURL.isEmpty()
981 || isValidDateTime(m_TemplateDate)) {
982 attributes.emplace_back(
"xlink:type", OUString(
"simple"));
983 attributes.emplace_back(
"xlink:actuate", OUString(
"onRequest"));
984 attributes.emplace_back(
"xlink:title", m_TemplateName);
985 attributes.emplace_back(
"xlink:href", m_TemplateURL );
986 if (isValidDateTime(m_TemplateDate)) {
987 attributes.emplace_back(
988 "meta:date", dateTimeToText(m_TemplateDate));
990 updateElement(
"meta:template", &attributes);
992 updateElement(
"meta:template");
996 if (!m_AutoloadURL.isEmpty() || (0 != m_AutoloadSecs)) {
997 attributes.emplace_back(
"xlink:href", m_AutoloadURL );
998 attributes.emplace_back(
"meta:delay",
999 durationToText(m_AutoloadSecs));
1000 updateElement(
"meta:auto-reload", &attributes);
1002 updateElement(
"meta:auto-reload");
1006 if (!m_DefaultTarget.isEmpty()) {
1007 attributes.emplace_back(
1008 "office:target-frame-name",
1011 const char* show = m_DefaultTarget ==
"_blank" ?
"new" :
"replace";
1012 attributes.emplace_back(
1014 OUString::createFromAscii(show));
1015 updateElement(
"meta:hyperlink-behaviour", &attributes);
1017 updateElement(
"meta:hyperlink-behaviour");
1023css::uno::Reference<css::xml::dom::XDocument>
1024SfxDocumentMetaData::createDOM() const
1026 css::uno::Reference<css::xml::dom::XDocumentBuilder> xBuilder( css::xml::dom::DocumentBuilder::create(m_xContext) );
1027 css::uno::Reference<css::xml::dom::XDocument> xDoc = xBuilder->newDocument();
1029 throw css::uno::RuntimeException(
1030 "SfxDocumentMetaData::createDOM: cannot create new document",
1031 *
const_cast<SfxDocumentMetaData*
>(
this));
1036SfxDocumentMetaData::checkInit() const
1038 if (!m_isInitialized) {
1039 throw css::uno::RuntimeException(
1040 "SfxDocumentMetaData::checkInit: not initialized",
1041 *
const_cast<SfxDocumentMetaData*
>(
this));
1043 assert(m_xDoc.is() && m_xParent.is());
1046void extractTagAndNamespaceUri(std::u16string_view aChildNodeName,
1047 std::u16string_view& rTagName, std::u16string_view& rNamespaceURI)
1049 size_t idx = aChildNodeName.find(
':');
1050 assert(idx != std::u16string_view::npos);
1051 std::u16string_view aPrefix = aChildNodeName.substr(0, idx);
1052 rTagName = aChildNodeName.substr(idx + 1);
1053 if (aPrefix == u
"dc")
1054 rNamespaceURI = s_nsDC;
1055 else if (aPrefix == u
"meta")
1056 rNamespaceURI = s_nsODFMeta;
1057 else if (aPrefix == u
"office")
1058 rNamespaceURI = s_nsODF;
1064css::uno::Reference<css::xml::dom::XElement> getChildNodeByName(
1065 const css::uno::Reference<css::xml::dom::XNode>& xNode,
1066 std::u16string_view aChildNodeName)
1068 css::uno::Reference< css::xml::dom::XNodeList > xList = xNode->getChildNodes();
1071 std::u16string_view aTagName, aNamespaceURI;
1072 extractTagAndNamespaceUri(aChildNodeName, aTagName, aNamespaceURI);
1074 const sal_Int32
nLength(xList->getLength());
1077 const css::uno::Reference< css::xml::dom::XElement > xChild(xList->item(a), css::uno::UNO_QUERY);
1078 if (xChild && xChild->getNodeName() == aTagName && aNamespaceURI == xChild->getNamespaceURI())
1085std::vector<css::uno::Reference<css::xml::dom::XNode> > getChildNodeListByName(
1086 const css::uno::Reference<css::xml::dom::XNode>& xNode,
1087 std::u16string_view aChildNodeName)
1089 css::uno::Reference< css::xml::dom::XNodeList > xList = xNode->getChildNodes();
1092 std::u16string_view aTagName, aNamespaceURI;
1093 extractTagAndNamespaceUri(aChildNodeName, aTagName, aNamespaceURI);
1094 std::vector<css::uno::Reference<css::xml::dom::XNode>> aList;
1095 const sal_Int32
nLength(xList->getLength());
1098 const css::uno::Reference< css::xml::dom::XElement > xChild(xList->item(a), css::uno::UNO_QUERY);
1099 if (xChild && xChild->getNodeName() == aTagName && aNamespaceURI == xChild->getNamespaceURI())
1100 aList.push_back(xChild);
1107 const css::uno::Reference<css::xml::dom::XDocument>& i_xDoc)
1110 throw css::uno::RuntimeException(
"SfxDocumentMetaData::init: no DOM tree given", *
this);
1112 m_isInitialized =
false;
1119 css::uno::Reference<css::xml::dom::XNode> xDocNode(
1120 m_xDoc, css::uno::UNO_QUERY_THROW);
1123 css::uno::Reference<css::xml::dom::XNode> xChild = getChildNodeByName(xDocNode, u
"office:document-meta");
1125 m_xParent = getChildNodeByName(xChild, u
"office:meta");
1126 }
catch (
const css::uno::Exception &) {
1129 if (!m_xParent.is()) {
1132 css::uno::Reference<css::xml::dom::XElement> xRElem;
1133 css::uno::Reference<css::xml::dom::XNode> xNode(
1134 i_xDoc->getFirstChild());
1135 while (xNode.is()) {
1136 if (css::xml::dom::NodeType_ELEMENT_NODE ==xNode->getNodeType())
1138 if ( xNode->getNamespaceURI() == s_nsODF && xNode->getLocalName() ==
"document-meta" )
1140 xRElem.set(xNode, css::uno::UNO_QUERY_THROW);
1145 SAL_INFO(
"sfx.doc",
"SfxDocumentMetaData::init(): "
1146 "deleting unexpected root element: "
1147 << xNode->getLocalName());
1148 i_xDoc->removeChild(xNode);
1149 xNode = i_xDoc->getFirstChild();
1152 xNode = xNode->getNextSibling();
1156 static constexpr OUStringLiteral sOfficeDocumentMeta =
u"office:document-meta";
1157 xRElem = i_xDoc->createElementNS(
1158 s_nsODF, sOfficeDocumentMeta);
1159 css::uno::Reference<css::xml::dom::XNode> xRNode(xRElem,
1160 css::uno::UNO_QUERY_THROW);
1161 i_xDoc->appendChild(xRNode);
1163 static constexpr OUStringLiteral sOfficeVersion =
u"office:version";
1164 xRElem->setAttributeNS(s_nsODF, sOfficeVersion,
"1.0");
1166 static constexpr OUStringLiteral sOfficeMeta =
u"office:meta";
1167 css::uno::Reference<css::xml::dom::XNode> xParent (
1168 i_xDoc->createElementNS(s_nsODF, sOfficeMeta),
1169 css::uno::UNO_QUERY_THROW);
1170 xRElem->appendChild(xParent);
1171 m_xParent = xParent;
1172 }
catch (
const css::xml::dom::DOMException &) {
1174 throw css::lang::WrappedTargetRuntimeException(
1175 "SfxDocumentMetaData::init: DOM exception",
1176 css::uno::Reference<css::uno::XInterface>(*
this), anyEx);
1182 for (
const char **pName = s_stdMeta; *
pName !=
nullptr; ++
pName) {
1183 OUString
name = OUString::createFromAscii(*pName);
1190 css::uno::Reference<css::xml::dom::XNode> xNode =
1191 getChildNodeByName(m_xParent, name);
1194 m_meta[
name] = xNode;
1198 for (
const auto & name : s_stdMetaList) {
1199 std::vector<css::uno::Reference<css::xml::dom::XNode> > nodes =
1200 getChildNodeListByName(m_xParent, OUString(name));
1201 m_metaList[
name] = nodes;
1205 static constexpr OUStringLiteral sMetaTemplate =
u"meta:template";
1206 static constexpr OUStringLiteral sMetaAutoReload =
u"meta:auto-reload";
1207 static constexpr OUStringLiteral sMetaHyperlinkBehaviour =
u"meta:hyperlink-behaviour";
1208 m_TemplateName = getMetaAttr(sMetaTemplate,
"xlink:title");
1209 m_TemplateURL = getMetaAttr(sMetaTemplate,
"xlink:href");
1211 textToDateTimeDefault(getMetaAttr(sMetaTemplate,
"meta:date"));
1212 m_AutoloadURL = getMetaAttr(sMetaAutoReload,
"xlink:href");
1214 textToDuration(getMetaAttr(sMetaAutoReload,
"meta:delay"));
1216 getMetaAttr(sMetaHyperlinkBehaviour,
"office:target-frame-name");
1219 std::vector<css::uno::Reference<css::xml::dom::XNode> > & vec =
1220 m_metaList[OUString(
"meta:user-defined")];
1221 m_xUserDefined.clear();
1224 createUserDefined();
1228 for (
auto const& elem : vec)
1230 css::uno::Reference<css::xml::dom::XElement> xElem(elem,
1231 css::uno::UNO_QUERY_THROW);
1233 OUString
name = xElem->getAttributeNS(s_nsODFMeta,
"name");
1234 OUString
type = xElem->getAttributeNS(s_nsODFMeta,
"value-type");
1235 OUString
text = getNodeText(elem);
1236 if ( type ==
"float" ) {
1241 SAL_WARN(
"sfx.doc",
"Invalid float: " << text);
1244 }
else if ( type ==
"date" ) {
1247 css::util::DateTime dt;
1248 std::optional<sal_Int16> nTimeZone;
1249 if (textToDateOrDateTime(d, dt, isDateTime, nTimeZone, text)) {
1252 any <<= css::util::DateTimeWithTimezone(dt,
1259 any <<= css::util::DateWithTimezone(d, *nTimeZone);
1265 SAL_WARN(
"sfx.doc",
"Invalid date: " << text);
1268 }
else if ( type ==
"time" ) {
1269 css::util::Duration ud;
1270 if (textToDuration(ud, text)) {
1273 SAL_WARN(
"sfx.doc",
"Invalid time: " << text);
1276 }
else if ( type ==
"boolean" ) {
1281 SAL_WARN(
"sfx.doc",
"Invalid boolean: " << text);
1288 m_xUserDefined->addProperty(name,
1289 css::beans::PropertyAttribute::REMOVABLE, any);
1290 }
catch (
const css::beans::PropertyExistException &) {
1291 SAL_WARN(
"sfx.doc",
"Duplicate: " << name);
1293 }
catch (
const css::beans::IllegalTypeException &) {
1294 SAL_INFO(
"sfx.doc",
"SfxDocumentMetaData: illegal type: " << name);
1295 }
catch (
const css::lang::IllegalArgumentException &) {
1296 SAL_INFO(
"sfx.doc",
"SfxDocumentMetaData: illegal arg: " << name);
1300 m_isModified =
false;
1301 m_isInitialized =
true;
1305SfxDocumentMetaData::SfxDocumentMetaData(
1306 css::uno::Reference< css::uno::XComponentContext >
const & context)
1308 , SfxDocumentMetaData_Base(
m_aMutex)
1311 , m_isInitialized(false)
1312 , m_isModified(false)
1315 assert(context.is());
1316 assert(context->getServiceManager().is());
1322SfxDocumentMetaData::getImplementationName()
1324 return "SfxDocumentMetaData";
1328SfxDocumentMetaData::supportsService(OUString
const & serviceName)
1333css::uno::Sequence< OUString > SAL_CALL
1334SfxDocumentMetaData::getSupportedServiceNames()
1336 css::uno::Sequence< OUString > s {
"com.sun.star.document.DocumentProperties" };
1342void SAL_CALL SfxDocumentMetaData::dispose()
1344 ::osl::MutexGuard g(m_aMutex);
1345 if (!m_isInitialized) {
1348 WeakComponentImplHelperBase::dispose();
1349 m_NotifyListeners.disposeAndClear(css::lang::EventObject(
1351 m_isInitialized =
false;
1356 m_xUserDefined.clear();
1362SfxDocumentMetaData::getAuthor()
1364 ::osl::MutexGuard g(m_aMutex);
1365 return getMetaText(
"meta:initial-creator");
1368void SAL_CALL SfxDocumentMetaData::setAuthor(
const OUString & the_value)
1370 setMetaTextAndNotify(
"meta:initial-creator", the_value);
1375SfxDocumentMetaData::getGenerator()
1377 ::osl::MutexGuard g(m_aMutex);
1378 return getMetaText(
"meta:generator");
1382SfxDocumentMetaData::setGenerator(
const OUString & the_value)
1384 setMetaTextAndNotify(
"meta:generator", the_value);
1387css::util::DateTime SAL_CALL
1388SfxDocumentMetaData::getCreationDate()
1390 ::osl::MutexGuard g(m_aMutex);
1391 return textToDateTimeDefault(getMetaText(
"meta:creation-date"));
1395SfxDocumentMetaData::setCreationDate(
const css::util::DateTime & the_value)
1397 setMetaTextAndNotify(
"meta:creation-date", dateTimeToText(the_value));
1401SfxDocumentMetaData::getTitle()
1403 ::osl::MutexGuard g(m_aMutex);
1404 return getMetaText(
"dc:title");
1407void SAL_CALL SfxDocumentMetaData::setTitle(
const OUString & the_value)
1409 setMetaTextAndNotify(
"dc:title", the_value);
1413SfxDocumentMetaData::getSubject()
1415 ::osl::MutexGuard g(m_aMutex);
1416 return getMetaText(
"dc:subject");
1420SfxDocumentMetaData::setSubject(
const OUString & the_value)
1422 setMetaTextAndNotify(
"dc:subject", the_value);
1426SfxDocumentMetaData::getDescription()
1428 ::osl::MutexGuard g(m_aMutex);
1429 return getMetaText(
"dc:description");
1433SfxDocumentMetaData::setDescription(
const OUString & the_value)
1435 setMetaTextAndNotify(
"dc:description", the_value);
1438css::uno::Sequence< OUString >
1439SAL_CALL SfxDocumentMetaData::getKeywords()
1441 ::osl::MutexGuard g(m_aMutex);
1442 return getMetaList(
"meta:keyword");
1446SfxDocumentMetaData::setKeywords(
1447 const css::uno::Sequence< OUString > & the_value)
1449 ::osl::ClearableMutexGuard g(m_aMutex);
1450 if (setMetaList(
"meta:keyword", the_value,
nullptr)) {
1456css::lang::Locale SAL_CALL
1457 SfxDocumentMetaData::getLanguage()
1459 ::osl::MutexGuard g(m_aMutex);
1465SfxDocumentMetaData::setLanguage(
const css::lang::Locale & the_value)
1468 setMetaTextAndNotify(
"dc:language", text);
1472SfxDocumentMetaData::getModifiedBy()
1474 ::osl::MutexGuard g(m_aMutex);
1475 return getMetaText(
"dc:creator");
1479SfxDocumentMetaData::setModifiedBy(
const OUString & the_value)
1481 setMetaTextAndNotify(
"dc:creator", the_value);
1484css::util::DateTime SAL_CALL
1485SfxDocumentMetaData::getModificationDate()
1487 ::osl::MutexGuard g(m_aMutex);
1488 return textToDateTimeDefault(getMetaText(
"dc:date"));
1492SfxDocumentMetaData::setModificationDate(
const css::util::DateTime & the_value)
1494 setMetaTextAndNotify(
"dc:date", dateTimeToText(the_value));
1498SfxDocumentMetaData::getPrintedBy()
1500 ::osl::MutexGuard g(m_aMutex);
1501 return getMetaText(
"meta:printed-by");
1505SfxDocumentMetaData::setPrintedBy(
const OUString & the_value)
1507 setMetaTextAndNotify(
"meta:printed-by", the_value);
1510css::util::DateTime SAL_CALL
1511SfxDocumentMetaData::getPrintDate()
1513 ::osl::MutexGuard g(m_aMutex);
1514 return textToDateTimeDefault(getMetaText(
"meta:print-date"));
1518SfxDocumentMetaData::setPrintDate(
const css::util::DateTime & the_value)
1520 setMetaTextAndNotify(
"meta:print-date", dateTimeToText(the_value));
1524SfxDocumentMetaData::getTemplateName()
1526 ::osl::MutexGuard g(m_aMutex);
1528 return m_TemplateName;
1532SfxDocumentMetaData::setTemplateName(
const OUString & the_value)
1534 ::osl::ClearableMutexGuard g(m_aMutex);
1536 if (m_TemplateName != the_value) {
1537 m_TemplateName = the_value;
1544SfxDocumentMetaData::getTemplateURL()
1546 ::osl::MutexGuard g(m_aMutex);
1548 return m_TemplateURL;
1552SfxDocumentMetaData::setTemplateURL(
const OUString & the_value)
1554 ::osl::ClearableMutexGuard g(m_aMutex);
1556 if (m_TemplateURL != the_value) {
1557 m_TemplateURL = the_value;
1563css::util::DateTime SAL_CALL
1564SfxDocumentMetaData::getTemplateDate()
1566 ::osl::MutexGuard g(m_aMutex);
1568 return m_TemplateDate;
1572SfxDocumentMetaData::setTemplateDate(
const css::util::DateTime & the_value)
1574 ::osl::ClearableMutexGuard g(m_aMutex);
1576 if (m_TemplateDate != the_value) {
1577 m_TemplateDate = the_value;
1584SfxDocumentMetaData::getAutoloadURL()
1586 ::osl::MutexGuard g(m_aMutex);
1588 return m_AutoloadURL;
1592SfxDocumentMetaData::setAutoloadURL(
const OUString & the_value)
1594 ::osl::ClearableMutexGuard g(m_aMutex);
1596 if (m_AutoloadURL != the_value) {
1597 m_AutoloadURL = the_value;
1604SfxDocumentMetaData::getAutoloadSecs()
1606 ::osl::MutexGuard g(m_aMutex);
1608 return m_AutoloadSecs;
1612SfxDocumentMetaData::setAutoloadSecs(::sal_Int32 the_value)
1615 throw css::lang::IllegalArgumentException(
1616 "SfxDocumentMetaData::setAutoloadSecs: argument is negative",
1618 ::osl::ClearableMutexGuard g(m_aMutex);
1620 if (m_AutoloadSecs != the_value) {
1621 m_AutoloadSecs = the_value;
1628SfxDocumentMetaData::getDefaultTarget()
1630 ::osl::MutexGuard g(m_aMutex);
1632 return m_DefaultTarget;
1636SfxDocumentMetaData::setDefaultTarget(
const OUString & the_value)
1638 ::osl::ClearableMutexGuard g(m_aMutex);
1640 if (m_DefaultTarget != the_value) {
1641 m_DefaultTarget = the_value;
1647css::uno::Sequence< css::beans::NamedValue > SAL_CALL
1648SfxDocumentMetaData::getDocumentStatistics()
1650 ::osl::MutexGuard g(m_aMutex);
1652 ::std::vector<css::beans::NamedValue> stats;
1653 for (
size_t i = 0; s_stdStats[
i] !=
nullptr; ++
i) {
1654 OUString
text = getMetaAttr(
"meta:document-statistic", s_stdStatAttrs[i]);
1655 if (
text.isEmpty())
continue;
1656 css::beans::NamedValue stat;
1657 stat.Name = OUString::createFromAscii(s_stdStats[i]);
1662 SAL_WARN(
"sfx.doc",
"Invalid number: " << text);
1666 stats.push_back(stat);
1669 return ::comphelper::containerToSequence(stats);
1673SfxDocumentMetaData::setDocumentStatistics(
1674 const css::uno::Sequence< css::beans::NamedValue > & the_value)
1677 osl::MutexGuard g(m_aMutex);
1679 std::vector<std::pair<OUString, OUString> > attributes;
1680 for (
const auto& rValue : the_value) {
1681 const OUString
name = rValue.Name;
1683 for (
size_t j = 0; s_stdStats[j] !=
nullptr; ++j) {
1684 if (
name.equalsAscii(s_stdStats[j])) {
1685 const css::uno::Any
any = rValue.Value;
1688 attributes.emplace_back(s_stdStatAttrs[j],
1689 OUString::number(val));
1692 SAL_WARN(
"sfx.doc",
"Invalid statistic: " << name);
1698 updateElement(
"meta:document-statistic", &attributes);
1704SfxDocumentMetaData::getEditingCycles()
1706 ::osl::MutexGuard g(m_aMutex);
1707 OUString
text = getMetaText(
"meta:editing-cycles");
1710 0, std::numeric_limits<sal_Int16>::max())) {
1711 return static_cast<sal_Int16
>(ret);
1718SfxDocumentMetaData::setEditingCycles(::sal_Int16 the_value)
1721 throw css::lang::IllegalArgumentException(
1722 "SfxDocumentMetaData::setEditingCycles: argument is negative",
1724 setMetaTextAndNotify(
"meta:editing-cycles", OUString::number(the_value));
1728SfxDocumentMetaData::getEditingDuration()
1730 ::osl::MutexGuard g(m_aMutex);
1731 return textToDuration(getMetaText(
"meta:editing-duration"));
1735SfxDocumentMetaData::setEditingDuration(::sal_Int32 the_value)
1738 throw css::lang::IllegalArgumentException(
1739 "SfxDocumentMetaData::setEditingDuration: argument is negative",
1741 setMetaTextAndNotify(
"meta:editing-duration", durationToText(the_value));
1745SfxDocumentMetaData::resetUserData(
const OUString & the_value)
1747 ::osl::ClearableMutexGuard g(m_aMutex);
1749 bool bModified(
false );
1750 bModified |= setMetaText(
"meta:initial-creator", the_value);
1753 bModified |= setMetaText(
"meta:creation-date", dateTimeToText(uDT));
1754 bModified |= setMetaText(
"dc:creator", OUString());
1755 bModified |= setMetaText(
"meta:printed-by", OUString());
1756 bModified |= setMetaText(
"dc:date", dateTimeToText(css::util::DateTime()));
1757 bModified |= setMetaText(
"meta:print-date",
1758 dateTimeToText(css::util::DateTime()));
1759 bModified |= setMetaText(
"meta:editing-duration", durationToText(0));
1760 bModified |= setMetaText(
"meta:editing-cycles",
1770css::uno::Reference< css::beans::XPropertyContainer > SAL_CALL
1771SfxDocumentMetaData::getUserDefinedProperties()
1773 ::osl::MutexGuard g(m_aMutex);
1775 createUserDefined();
1776 return m_xUserDefined;
1781SfxDocumentMetaData::loadFromStorage(
1782 const css::uno::Reference< css::embed::XStorage > & xStorage,
1783 const css::uno::Sequence< css::beans::PropertyValue > & Medium)
1786 throw css::lang::IllegalArgumentException(
"SfxDocumentMetaData::loadFromStorage: argument is null", *
this, 0);
1787 ::osl::MutexGuard g(m_aMutex);
1790 css::uno::Reference<css::io::XStream>
xStream(
1791 xStorage->openStreamElement(
1793 css::embed::ElementModes::READ) );
1794 if (!
xStream.is())
throw css::uno::RuntimeException();
1795 css::uno::Reference<css::io::XInputStream> xInStream =
1797 if (!xInStream.is())
throw css::uno::RuntimeException();
1800 css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
1802 css::xml::sax::InputSource input;
1803 input.aInputStream = xInStream;
1808 const char *pServiceName = bOasis
1809 ?
"com.sun.star.document.XMLOasisMetaImporter"
1810 :
"com.sun.star.document.XMLMetaImporter";
1813 css::uno::Reference<css::beans::XPropertySet> xPropArg =
1814 getURLProperties(Medium);
1816 xPropArg->getPropertyValue(
"BaseURI")
1817 >>= input.sSystemId;
1818 input.sSystemId += OUString::Concat(
"/") +
s_meta;
1819 }
catch (
const css::uno::Exception &) {
1820 input.sSystemId =
s_meta;
1822 css::uno::Sequence< css::uno::Any >
args{ css::uno::Any(xPropArg) };
1825 css::uno::Reference<XInterface> xFilter =
1826 xMsf->createInstanceWithArgumentsAndContext(
1827 OUString::createFromAscii(pServiceName), args, m_xContext);
1829 css::uno::Reference<css::xml::sax::XFastParser> xFastParser(xFilter, css::uno::UNO_QUERY);
1830 css::uno::Reference<css::document::XImporter> xImp(xFilter, css::uno::UNO_QUERY_THROW);
1831 xImp->setTargetDocument(css::uno::Reference<css::lang::XComponent>(
this));
1834 xFastParser->parseStream(input);
1837 css::uno::Reference<css::xml::sax::XDocumentHandler> xDocHandler(xFilter, css::uno::UNO_QUERY_THROW);
1838 css::uno::Reference<css::xml::sax::XParser> xParser = css::xml::sax::Parser::create(m_xContext);
1839 xParser->setDocumentHandler(xDocHandler);
1840 xParser->parseStream(input);
1842 }
catch (
const css::xml::sax::SAXException &) {
1843 throw css::io::WrongFormatException(
1844 "SfxDocumentMetaData::loadFromStorage:"
1845 " XML parsing exception", *
this);
1852SfxDocumentMetaData::storeToStorage(
1853 const css::uno::Reference< css::embed::XStorage > & xStorage,
1854 const css::uno::Sequence< css::beans::PropertyValue > & Medium)
1857 throw css::lang::IllegalArgumentException(
1858 "SfxDocumentMetaData::storeToStorage: argument is null", *
this, 0);
1859 ::osl::MutexGuard g(m_aMutex);
1866 css::uno::Reference<css::io::XStream>
xStream =
1867 xStorage->openStreamElement(s_meta,
1868 css::embed::ElementModes::WRITE
1869 | css::embed::ElementModes::TRUNCATE);
1870 if (!
xStream.is())
throw css::uno::RuntimeException();
1871 css::uno::Reference< css::beans::XPropertySet > xStreamProps(xStream,
1872 css::uno::UNO_QUERY_THROW);
1873 xStreamProps->setPropertyValue(
1875 css::uno::Any(OUString(
"text/xml")));
1876 xStreamProps->setPropertyValue(
1878 css::uno::Any(
false));
1879 xStreamProps->setPropertyValue(
1880 "UseCommonStoragePasswordEncryption",
1881 css::uno::Any(
false));
1882 css::uno::Reference<css::io::XOutputStream> xOutStream =
1884 if (!xOutStream.is())
throw css::uno::RuntimeException();
1885 css::uno::Reference<css::lang::XMultiComponentFactory> xMsf (
1887 css::uno::Reference<css::xml::sax::XWriter> xSaxWriter(
1888 css::xml::sax::Writer::create(m_xContext));
1889 xSaxWriter->setOutputStream(xOutStream);
1894 const char *pServiceName = bOasis
1895 ?
"com.sun.star.document.XMLOasisMetaExporter"
1896 :
"com.sun.star.document.XMLMetaExporter";
1899 css::uno::Reference<css::beans::XPropertySet> xPropArg =
1900 getURLProperties(Medium);
1901 css::uno::Sequence< css::uno::Any >
args{ css::uno::Any(xSaxWriter), css::uno::Any(xPropArg) };
1903 css::uno::Reference<css::document::XExporter> xExp(
1904 xMsf->createInstanceWithArgumentsAndContext(
1905 OUString::createFromAscii(pServiceName), args, m_xContext),
1906 css::uno::UNO_QUERY_THROW);
1907 xExp->setSourceDocument(css::uno::Reference<css::lang::XComponent>(
this));
1908 css::uno::Reference<css::document::XFilter> xFilter(xExp,
1909 css::uno::UNO_QUERY_THROW);
1910 if (!xFilter->filter(css::uno::Sequence< css::beans::PropertyValue >())) {
1911 throw css::io::IOException(
1912 "SfxDocumentMetaData::storeToStorage: cannot filter", *
this);
1914 css::uno::Reference<css::embed::XTransactedObject> xTransaction(
1915 xStorage, css::uno::UNO_QUERY);
1916 if (xTransaction.is()) {
1917 xTransaction->commit();
1922SfxDocumentMetaData::loadFromMedium(
const OUString & URL,
1923 const css::uno::Sequence< css::beans::PropertyValue > & Medium)
1925 css::uno::Reference<css::io::XInputStream> xIn;
1928 if (!
URL.isEmpty()) {
1932 if (
md.addInputStream()) {
1935 css::uno::Reference<css::embed::XStorage> xStorage;
1942 URL, css::embed::ElementModes::READ, m_xContext);
1944 }
catch (
const css::uno::RuntimeException &) {
1946 }
catch (
const css::io::IOException &) {
1948 }
catch (
const css::uno::Exception &) {
1950 throw css::lang::WrappedTargetException(
1951 "SfxDocumentMetaData::loadFromMedium: exception",
1952 css::uno::Reference<css::uno::XInterface>(*
this),
1955 if (!xStorage.is()) {
1956 throw css::uno::RuntimeException(
1957 "SfxDocumentMetaData::loadFromMedium: cannot get Storage",
1960 loadFromStorage(xStorage,
md.getAsConstPropertyValueList());
1964SfxDocumentMetaData::storeToMedium(
const OUString & URL,
1965 const css::uno::Sequence< css::beans::PropertyValue > & Medium)
1968 if (!
URL.isEmpty()) {
1971 SfxMedium aMedium(
md.getAsConstPropertyValueList());
1972 css::uno::Reference<css::embed::XStorage> xStorage
1973 = aMedium.GetOutputStorage();
1976 if (!xStorage.is()) {
1977 throw css::uno::RuntimeException(
1978 "SfxDocumentMetaData::storeToMedium: cannot get Storage",
1982 utl::MediaDescriptor::const_iterator iter
1984 if (iter !=
md.end()) {
1985 css::uno::Reference< css::beans::XPropertySet > xProps(xStorage,
1986 css::uno::UNO_QUERY_THROW);
1987 xProps->setPropertyValue(
1991 storeToStorage(xStorage,
md.getAsConstPropertyValueList());
1994 const bool bOk = aMedium.Commit();
1997 ErrCode nError = aMedium.GetError();
1998 if ( nError == ERRCODE_NONE ) {
2002 throw css::task::ErrorCodeIOException(
2003 "SfxDocumentMetaData::storeToMedium <" + URL +
"> Commit failed: " + nError.
toString(),
2004 css::uno::Reference< css::uno::XInterface >(), sal_uInt32(nError));
2010void SAL_CALL SfxDocumentMetaData::initialize(
const css::uno::Sequence< css::uno::Any > & aArguments)
2017 ::osl::MutexGuard g(m_aMutex);
2018 css::uno::Reference<css::xml::dom::XDocument> xDoc;
2020 for (sal_Int32 i = 0;
i <
aArguments.getLength(); ++
i) {
2022 if (!(any >>= xDoc)) {
2023 throw css::lang::IllegalArgumentException(
2024 "SfxDocumentMetaData::initialize: argument must be XDocument",
2025 *
this,
static_cast<sal_Int16
>(i));
2028 throw css::lang::IllegalArgumentException(
2029 "SfxDocumentMetaData::initialize: argument is null",
2030 *
this,
static_cast<sal_Int16
>(i));
2043css::uno::Reference<css::util::XCloneable> SAL_CALL
2044SfxDocumentMetaData::createClone()
2046 ::osl::MutexGuard g(m_aMutex);
2052 css::uno::Reference<css::xml::dom::XDocument> xDoc = createDOM();
2054 updateUserDefinedAndAttributes();
2056 css::uno::Reference<css::xml::dom::XNode> xRoot(
2057 m_xDoc->getDocumentElement(), css::uno::UNO_QUERY_THROW);
2058 css::uno::Reference<css::xml::dom::XNode> xRootNew(
2059 xDoc->importNode(xRoot,
true));
2060 xDoc->appendChild(xRootNew);
2062 }
catch (
const css::uno::RuntimeException &) {
2064 }
catch (
const css::uno::Exception &) {
2066 throw css::lang::WrappedTargetRuntimeException(
2067 "SfxDocumentMetaData::createClone: exception",
2068 css::uno::Reference<css::uno::XInterface>(*
this), anyEx);
2070 return css::uno::Reference<css::util::XCloneable> (pNew);
2074sal_Bool SAL_CALL SfxDocumentMetaData::isModified( )
2076 ::osl::MutexGuard g(m_aMutex);
2078 css::uno::Reference<css::util::XModifiable> xMB(m_xUserDefined,
2079 css::uno::UNO_QUERY);
2080 return m_isModified || (xMB.is() && xMB->isModified());
2083void SAL_CALL SfxDocumentMetaData::setModified(
sal_Bool bModified )
2085 css::uno::Reference<css::util::XModifiable> xMB;
2087 ::osl::MutexGuard g(m_aMutex);
2089 m_isModified = bModified;
2090 if ( !bModified && m_xUserDefined.is() )
2092 xMB.set(m_xUserDefined, css::uno::UNO_QUERY);
2094 "SfxDocumentMetaData::setModified: PropertyBag not Modifiable?");
2099 css::uno::Reference<css::uno::XInterface> xThis(*
this);
2100 css::lang::EventObject event(xThis);
2101 m_NotifyListeners.notifyEach(&css::util::XModifyListener::modified,
2103 }
catch (
const css::uno::RuntimeException &) {
2105 }
catch (
const css::uno::Exception &) {
2111 xMB->setModified(
false);
2117void SAL_CALL SfxDocumentMetaData::addModifyListener(
2118 const css::uno::Reference< css::util::XModifyListener > & xListener)
2120 ::osl::MutexGuard g(m_aMutex);
2122 m_NotifyListeners.addInterface(xListener);
2123 css::uno::Reference<css::util::XModifyBroadcaster> xMB(m_xUserDefined,
2124 css::uno::UNO_QUERY);
2126 xMB->addModifyListener(xListener);
2130void SAL_CALL SfxDocumentMetaData::removeModifyListener(
2131 const css::uno::Reference< css::util::XModifyListener > & xListener)
2133 ::osl::MutexGuard g(m_aMutex);
2135 m_NotifyListeners.removeInterface(xListener);
2136 css::uno::Reference<css::util::XModifyBroadcaster> xMB(m_xUserDefined,
2137 css::uno::UNO_QUERY);
2139 xMB->removeModifyListener(xListener);
2144void SAL_CALL SfxDocumentMetaData::serialize(
2145 const css::uno::Reference<css::xml::sax::XDocumentHandler>& i_xHandler,
2146 const css::uno::Sequence< css::beans::StringPair >& i_rNamespaces)
2148 ::osl::MutexGuard g(m_aMutex);
2150 updateUserDefinedAndAttributes();
2151 css::uno::Reference<css::xml::sax::XSAXSerializable> xSAXable(m_xDoc,
2152 css::uno::UNO_QUERY_THROW);
2153 xSAXable->serialize(i_xHandler, i_rNamespaces);
2156void SfxDocumentMetaData::createUserDefined()
2160 if ( m_xUserDefined.is() )
2163 css::uno::Sequence<css::uno::Type> types{
2181 css::beans::PropertyBag::createWithTypes( m_xContext, types,
true,
false ),
2182 css::uno::UNO_QUERY_THROW);
2184 const css::uno::Reference<css::util::XModifyBroadcaster> xMB(
2185 m_xUserDefined, css::uno::UNO_QUERY);
2188 const std::vector<css::uno::Reference<css::util::XModifyListener> >
2189 listeners(m_NotifyListeners.getElements());
2190 for (
const auto& l : listeners) {
2191 xMB->addModifyListener(l);
2198extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
2200 css::uno::XComponentContext *context,
2201 css::uno::Sequence<css::uno::Any>
const &)
2203 return cppu::acquire(
new CompatWriterDocPropsImpl(context));
2206extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
2208 css::uno::XComponentContext *context,
2209 css::uno::Sequence<css::uno::Any>
const &)
2211 return cppu::acquire(
new SfxDocumentMetaData(context));
Reference< XComponentContext > m_xContext
css::util::DateTime GetUNODateTime() const
COMPHELPER_DLLPUBLIC OUString toString() const
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
static OUString convertToBcp47(LanguageType nLangID)
sal_Int32 GetVersion() const
static css::uno::Reference< css::embed::XStorage > GetStorageFromInputStream(const css::uno::Reference< css::io::XInputStream > &xStream, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
static css::uno::Reference< css::embed::XStorage > GetStorageFromURL(const OUString &aURL, sal_Int32 nStorageMode, const css::uno::Reference< css::uno::XComponentContext > &rxContext=css::uno::Reference< css::uno::XComponentContext >())
css::uno::Type const & get()
static void convertDateTime(OUStringBuffer &rBuffer, const css::util::DateTime &rDateTime, sal_Int16 const *pTimeZoneOffset, bool bAddTimeIf0AM=false)
static void convertDouble(OUStringBuffer &rBuffer, double fNumber, bool bWriteUnits, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
static void convertDuration(OUStringBuffer &rBuffer, const double fTime)
static bool parseDateTime(css::util::DateTime &rDateTime, std::u16string_view rString)
static bool parseDateOrDateTime(css::util::Date *pDate, css::util::DateTime &rDateTime, bool &rbDateTime, std::optional< sal_Int16 > *pTimeZoneOffset, std::u16string_view rString)
static void convertDate(OUStringBuffer &rBuffer, const css::util::Date &rDate, sal_Int16 const *pTimeZoneOffset)
static bool convertNumber(sal_Int32 &rValue, std::u16string_view aString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32)
static bool convertBool(bool &rBool, std::u16string_view rString)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define ERRCODE_IO_GENERAL
Sequence< OUString > aServiceNames
Sequence< PropertyValue > aArguments
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
bool isValidDate(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
bool isAssignableFrom(const Type &_rAssignable, const Type &_rFrom)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Any SAL_CALL getCaughtException()
std::u16string_view getTitle(std::u16string_view aPath)
constexpr sal_Int64 md(U i, U)
static void init(struct DocumentMetadataAccess_Impl &i_rImpl)
init Impl struct
std::vector< char * > values