summaryrefslogtreecommitdiff
path: root/xmloff/source/text/XMLPropertyBackpatcher.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xmloff/source/text/XMLPropertyBackpatcher.cxx')
-rw-r--r--xmloff/source/text/XMLPropertyBackpatcher.cxx312
1 files changed, 312 insertions, 0 deletions
diff --git a/xmloff/source/text/XMLPropertyBackpatcher.cxx b/xmloff/source/text/XMLPropertyBackpatcher.cxx
new file mode 100644
index 000000000000..364096ad8185
--- /dev/null
+++ b/xmloff/source/text/XMLPropertyBackpatcher.cxx
@@ -0,0 +1,312 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_xmloff.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Reference.h>
+
+#include <rtl/ustring.hxx>
+#include <tools/debug.hxx>
+#include "XMLPropertyBackpatcher.hxx"
+#include <xmloff/txtimp.hxx> // XMLTextImportHelper partially implemented here
+
+
+using ::rtl::OUString;
+using ::std::vector;
+using ::std::map;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::beans::XPropertySet;
+
+
+template<class A>
+XMLPropertyBackpatcher<A>::XMLPropertyBackpatcher(
+ const ::rtl::OUString& sPropName)
+: sPropertyName(sPropName)
+, bDefaultHandling(sal_False)
+, bPreserveProperty(sal_False)
+, sPreservePropertyName()
+{
+}
+
+template<class A>
+XMLPropertyBackpatcher<A>::XMLPropertyBackpatcher(
+ const OUString& sPropName,
+ const OUString& sPreserveName,
+ sal_Bool bDefault,
+ A aDef)
+: sPropertyName(sPropName)
+, bDefaultHandling(bDefault)
+, bPreserveProperty(sPreserveName.getLength()>0)
+, sPreservePropertyName(sPreserveName)
+, aDefault(aDef)
+{
+}
+
+template<class A>
+XMLPropertyBackpatcher<A>::XMLPropertyBackpatcher(
+ const sal_Char* pPropName)
+: bDefaultHandling(sal_False)
+, bPreserveProperty(sal_False)
+{
+ DBG_ASSERT(pPropName != NULL, "need property name");
+ sPropertyName = OUString::createFromAscii(pPropName);
+}
+
+template<class A>
+XMLPropertyBackpatcher<A>::XMLPropertyBackpatcher(
+ const sal_Char* pPropName,
+ const sal_Char* pPreservePropName,
+ sal_Bool bDefault,
+ A aDef)
+: bDefaultHandling(bDefault)
+, bPreserveProperty(pPreservePropName != NULL)
+, aDefault(aDef)
+{
+ DBG_ASSERT(pPropName != NULL, "need property name");
+ sPropertyName = OUString::createFromAscii(pPropName);
+ if (pPreservePropName != NULL)
+ {
+ sPreservePropertyName = OUString::createFromAscii(pPreservePropName);
+ }
+}
+
+template<class A>
+XMLPropertyBackpatcher<A>::~XMLPropertyBackpatcher()
+{
+ SetDefault();
+}
+
+
+template<class A>
+void XMLPropertyBackpatcher<A>::ResolveId(
+ const OUString& sName,
+ A aValue)
+{
+ // insert ID into ID map
+ aIDMap[sName] = aValue;
+
+ // backpatch old references, if backpatch list exists
+ if (aBackpatchListMap.count(sName))
+ {
+ // aah, we have a backpatch list!
+ BackpatchListType* pList =
+ (BackpatchListType*)aBackpatchListMap[sName];
+
+ // a) remove list from list map
+ aBackpatchListMap.erase(sName);
+
+ // b) for every item, set SequenceNumber
+ // (and preserve Property, if appropriate)
+ Any aAny;
+ aAny <<= aValue;
+ if (bPreserveProperty)
+ {
+ // preserve version
+ for(BackpatchListType::iterator aIter = pList->begin();
+ aIter != pList->end();
+ aIter++)
+ {
+ Reference<XPropertySet> xProp = (*aIter);
+ Any aPres = xProp->getPropertyValue(sPreservePropertyName);
+ xProp->setPropertyValue(sPropertyName, aAny);
+ xProp->setPropertyValue(sPreservePropertyName, aPres);
+ }
+ }
+ else
+ {
+ // without preserve
+ for(BackpatchListType::iterator aIter = pList->begin();
+ aIter != pList->end();
+ aIter++)
+ {
+ (*aIter)->setPropertyValue(sPropertyName, aAny);
+ }
+ }
+
+ // c) delete list
+ delete pList;
+ }
+ // else: no backpatch list -> then we're finished
+}
+
+template<class A>
+void XMLPropertyBackpatcher<A>::SetProperty(
+ const Reference<XPropertySet> & xPropSet,
+ const OUString& sName)
+{
+ Reference<XPropertySet> xNonConstPropSet(xPropSet);
+ SetProperty(xNonConstPropSet, sName);
+}
+
+template<class A>
+void XMLPropertyBackpatcher<A>::SetProperty(
+ Reference<XPropertySet> & xPropSet,
+ const OUString& sName)
+{
+ if (aIDMap.count(sName))
+ {
+ // we know this ID -> set property
+ Any aAny;
+ aAny <<= aIDMap[sName];
+ xPropSet->setPropertyValue(sPropertyName, aAny);
+ }
+ else
+ {
+ // ID unknown -> into backpatch list for later fixup
+ if (! aBackpatchListMap.count(sName))
+ {
+ // create backpatch list for this name
+ BackpatchListType* pTmp = new BackpatchListType() ;
+ aBackpatchListMap[sName] = (void*)pTmp;
+ }
+
+ // insert footnote
+ ((BackpatchListType*)aBackpatchListMap[sName])->push_back(xPropSet);
+ }
+}
+
+template<class A>
+void XMLPropertyBackpatcher<A>::SetDefault()
+{
+ if (bDefaultHandling)
+ {
+ // not implemented yet
+ }
+}
+
+// force instantiation of templates
+template class XMLPropertyBackpatcher<sal_Int16>;
+template class XMLPropertyBackpatcher<OUString>;
+
+struct SAL_DLLPRIVATE XMLTextImportHelper::BackpatcherImpl
+{
+ /// backpatcher for references to footnotes and endnotes
+ ::std::auto_ptr< XMLPropertyBackpatcher<sal_Int16> >
+ m_pFootnoteBackpatcher;
+
+ /// backpatchers for references to sequences
+ ::std::auto_ptr< XMLPropertyBackpatcher<sal_Int16> >
+ m_pSequenceIdBackpatcher;
+
+ ::std::auto_ptr< XMLPropertyBackpatcher< ::rtl::OUString> >
+ m_pSequenceNameBackpatcher;
+
+};
+
+::boost::shared_ptr<XMLTextImportHelper::BackpatcherImpl>
+XMLTextImportHelper::MakeBackpatcherImpl()
+{
+ // n.b.: the shared_ptr stores the dtor!
+ return ::boost::shared_ptr<BackpatcherImpl>(new BackpatcherImpl);
+}
+
+static ::rtl::OUString const& GetSequenceNumber()
+{
+ static ::rtl::OUString s_SequenceNumber(
+ RTL_CONSTASCII_USTRINGPARAM("SequenceNumber"));
+ return s_SequenceNumber;
+}
+
+//
+// XMLTextImportHelper
+//
+// Code from XMLTextImportHelper using the XMLPropertyBackpatcher is
+// implemented here. The reason is that in the unxsols2 environment,
+// all templates are instatiated as file local (switch
+// -instances=static), and thus are not accessible from the outside.
+//
+// The previous solution was to force additional instantiation of
+// XMLPropertyBackpatcher in txtimp.cxx. This solution combines all
+// usage of the XMLPropertyBackpatcher in XMLPropertyBackpatcher.cxx
+// instead.
+//
+
+XMLPropertyBackpatcher<sal_Int16>& XMLTextImportHelper::GetFootnoteBP()
+{
+ if (!m_pBackpatcherImpl->m_pFootnoteBackpatcher.get())
+ {
+ m_pBackpatcherImpl->m_pFootnoteBackpatcher.reset(
+ new XMLPropertyBackpatcher<sal_Int16>(GetSequenceNumber()));
+ }
+ return *m_pBackpatcherImpl->m_pFootnoteBackpatcher;
+}
+
+XMLPropertyBackpatcher<sal_Int16>& XMLTextImportHelper::GetSequenceIdBP()
+{
+ if (!m_pBackpatcherImpl->m_pSequenceIdBackpatcher.get())
+ {
+ m_pBackpatcherImpl->m_pSequenceIdBackpatcher.reset(
+ new XMLPropertyBackpatcher<sal_Int16>(GetSequenceNumber()));
+ }
+ return *m_pBackpatcherImpl->m_pSequenceIdBackpatcher;
+}
+
+XMLPropertyBackpatcher<OUString>& XMLTextImportHelper::GetSequenceNameBP()
+{
+ static ::rtl::OUString s_SourceName(
+ RTL_CONSTASCII_USTRINGPARAM("SourceName"));
+ if (!m_pBackpatcherImpl->m_pSequenceNameBackpatcher.get())
+ {
+ m_pBackpatcherImpl->m_pSequenceNameBackpatcher.reset(
+ new XMLPropertyBackpatcher<OUString>(s_SourceName));
+ }
+ return *m_pBackpatcherImpl->m_pSequenceNameBackpatcher;
+}
+
+void XMLTextImportHelper::InsertFootnoteID(
+ const OUString& sXMLId,
+ sal_Int16 nAPIId)
+{
+ GetFootnoteBP().ResolveId(sXMLId, nAPIId);
+}
+
+void XMLTextImportHelper::ProcessFootnoteReference(
+ const OUString& sXMLId,
+ const Reference<XPropertySet> & xPropSet)
+{
+ GetFootnoteBP().SetProperty(xPropSet, sXMLId);
+}
+
+void XMLTextImportHelper::InsertSequenceID(
+ const OUString& sXMLId,
+ const OUString& sName,
+ sal_Int16 nAPIId)
+{
+ GetSequenceIdBP().ResolveId(sXMLId, nAPIId);
+ GetSequenceNameBP().ResolveId(sXMLId, sName);
+}
+
+void XMLTextImportHelper::ProcessSequenceReference(
+ const OUString& sXMLId,
+ const Reference<XPropertySet> & xPropSet)
+{
+ GetSequenceIdBP().SetProperty(xPropSet, sXMLId);
+ GetSequenceNameBP().SetProperty(xPropSet, sXMLId);
+}
+