[Libreoffice-commits] core.git: sc/inc sc/Library_sc.mk sc/qa sc/source
Vikas Mahato
vikasmahato0 at gmail.com
Sun Jul 8 21:33:05 UTC 2018
sc/Library_sc.mk | 1
sc/inc/datamapper.hxx | 6 +
sc/qa/unit/data/dataprovider/xml/test1.xml | 19 +++
sc/qa/unit/dataproviders_test.cxx | 44 ++++++++
sc/source/ui/dataprovider/dataprovider.cxx | 16 +++
sc/source/ui/dataprovider/xmldataprovider.cxx | 128 ++++++++++++++++++++++++++
sc/source/ui/dataprovider/xmldataprovider.hxx | 41 ++++++++
7 files changed, 255 insertions(+)
New commits:
commit e300efd3a029672e24114914355c5c690fb725d5
Author: Vikas Mahato <vikasmahato0 at gmail.com>
Date: Sun Jun 24 20:53:01 2018 +0530
Added XML data provider
Change-Id: Ib5727912977eb79cdf1f84bf874919beafc693eb
Reviewed-on: https://gerrit.libreoffice.org/56356
Tested-by: Jenkins
Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 2f4f06b6ea25..5425d681caab 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -399,6 +399,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/ui/dataprovider/dataprovider \
sc/source/ui/dataprovider/datatransformation \
sc/source/ui/dataprovider/htmldataprovider \
+ sc/source/ui/dataprovider/xmldataprovider \
sc/source/ui/dbgui/asciiopt \
sc/source/ui/dbgui/consdlg \
sc/source/ui/dbgui/csvcontrol \
diff --git a/sc/inc/datamapper.hxx b/sc/inc/datamapper.hxx
index 1d7e710051c0..9c59a7461b82 100644
--- a/sc/inc/datamapper.hxx
+++ b/sc/inc/datamapper.hxx
@@ -16,6 +16,8 @@
#include <rtl/ustring.hxx>
+#include "orcusxml.hxx"
+
class ScDocument;
class ScDBData;
@@ -62,6 +64,8 @@ private:
*/
OUString maID;
+ ScOrcusImportXMLParam maParam;
+
double mnUpdateFrequency;
std::shared_ptr<DataProvider> mpDataProvider;
@@ -83,10 +87,12 @@ public:
void setID(const OUString& rID);
void setURL(const OUString& rURL);
void setProvider(const OUString& rProvider);
+ void setXMLImportParam(const ScOrcusImportXMLParam& rParam);
const OUString& getURL() const;
const OUString& getProvider() const;
const OUString& getID() const;
+ const ScOrcusImportXMLParam& getXMLImportParam() const;
double getUpdateFrequency() const;
OUString getDBName() const;
void setDBData(const OUString& rDBName);
diff --git a/sc/qa/unit/data/dataprovider/xml/test1.xml b/sc/qa/unit/data/dataprovider/xml/test1.xml
new file mode 100644
index 000000000000..03ba28288825
--- /dev/null
+++ b/sc/qa/unit/data/dataprovider/xml/test1.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<bookstore>
+ <book>
+ <title>1</title>
+ <author>test1</author>
+ </book>
+ <book>
+ <title>2</title>
+ <author>test2</author>
+ </book>
+ <book>
+ <title>3</title>
+ <author>test3</author>
+ </book>
+ <book>
+ <title>4</title>
+ <author>test4</author>
+ </book>
+</bookstore>
\ No newline at end of file
diff --git a/sc/qa/unit/dataproviders_test.cxx b/sc/qa/unit/dataproviders_test.cxx
index 1960fa59eecf..aef3ec6abb05 100644
--- a/sc/qa/unit/dataproviders_test.cxx
+++ b/sc/qa/unit/dataproviders_test.cxx
@@ -14,6 +14,7 @@
#include <address.hxx>
#include <dataprovider.hxx>
#include <vcl/scheduler.hxx>
+#include <orcusxml.hxx>
#include <memory>
@@ -29,11 +30,13 @@ public:
void testCSVImport();
void testDataLargerThanDB();
void testHTMLImport();
+ void testXMLImport();
CPPUNIT_TEST_SUITE(ScDataProvidersTest);
CPPUNIT_TEST(testCSVImport);
CPPUNIT_TEST(testDataLargerThanDB);
CPPUNIT_TEST(testHTMLImport);
+ CPPUNIT_TEST(testXMLImport);
CPPUNIT_TEST_SUITE_END();
private:
@@ -137,6 +140,47 @@ void ScDataProvidersTest::testHTMLImport()
}
}
+void ScDataProvidersTest::testXMLImport()
+{
+ ScDBData* pDBData = new ScDBData("testDB", 0, 0, 0, 10, 10);
+ bool bInserted = m_pDoc->GetDBCollection()->getNamedDBs().insert(pDBData);
+ CPPUNIT_ASSERT(bInserted);
+
+ OUString aFileURL;
+ ScOrcusImportXMLParam aParam;
+
+ ScOrcusImportXMLParam::RangeLink aRangeLink;
+ aRangeLink.maPos = ScAddress(0,0,0);
+ aRangeLink.maFieldPaths.push_back("/bookstore/book/title");
+ aRangeLink.maFieldPaths.push_back("/bookstore/book/author");
+ aParam.maRangeLinks.push_back(aRangeLink);
+
+ createFileURL("test1.", "xml", aFileURL);
+ sc::ExternalDataSource aDataSource(aFileURL, "org.libreoffice.calc.xml", m_pDoc);
+ aDataSource.setDBData("testDB");
+ aDataSource.setXMLImportParam(aParam);
+
+
+ m_pDoc->GetExternalDataMapper().insertDataSource(aDataSource);
+ auto& rDataSources = m_pDoc->GetExternalDataMapper().getDataSources();
+ CPPUNIT_ASSERT(!rDataSources.empty());
+
+ rDataSources[0].refresh(m_pDoc, true);
+ Scheduler::ProcessEventsToIdle();
+
+ CPPUNIT_ASSERT_EQUAL(OUString("title"), m_pDoc->GetString(0, 0, 0));
+ CPPUNIT_ASSERT_EQUAL(OUString("author"), m_pDoc->GetString(1, 0, 0));
+ CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(0, 1, 0));
+ CPPUNIT_ASSERT_EQUAL(OUString("test1"), m_pDoc->GetString(1, 1, 0));
+ CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(0, 2, 0));
+ CPPUNIT_ASSERT_EQUAL(OUString("test2"), m_pDoc->GetString(1, 2, 0));
+ CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(0, 3, 0));
+ CPPUNIT_ASSERT_EQUAL(OUString("test3"), m_pDoc->GetString(1, 3, 0));
+ CPPUNIT_ASSERT_EQUAL(4.0, m_pDoc->GetValue(0, 4, 0));
+ CPPUNIT_ASSERT_EQUAL(OUString("test4"), m_pDoc->GetString(1, 4, 0));
+}
+
+
ScDataProvidersTest::ScDataProvidersTest() :
ScBootstrapFixture( "sc/qa/unit/data/dataprovider" ),
m_pDoc(nullptr)
diff --git a/sc/source/ui/dataprovider/dataprovider.cxx b/sc/source/ui/dataprovider/dataprovider.cxx
index 22a3be99475e..01aa0c80331a 100644
--- a/sc/source/ui/dataprovider/dataprovider.cxx
+++ b/sc/source/ui/dataprovider/dataprovider.cxx
@@ -15,6 +15,7 @@
#include <rtl/strbuf.hxx>
#include "htmldataprovider.hxx"
+#include "xmldataprovider.hxx"
#include <datatransformation.hxx>
using namespace com::sun::star;
@@ -74,6 +75,13 @@ void ExternalDataSource::setID(const OUString& rID)
maID = rID;
}
+void ExternalDataSource::setXMLImportParam(const ScOrcusImportXMLParam& rParam)
+{
+ maParam = rParam;
+}
+
+
+
void ExternalDataSource::setURL(const OUString& rURL)
{
maURL = rURL;
@@ -100,6 +108,11 @@ const OUString& ExternalDataSource::getID() const
return maID;
}
+const ScOrcusImportXMLParam& ExternalDataSource::getXMLImportParam() const
+{
+ return maParam;
+}
+
OUString ExternalDataSource::getDBName() const
{
if (mpDBDataManager)
@@ -274,6 +287,8 @@ std::shared_ptr<DataProvider> DataProviderFactory::getDataProvider(ScDocument* p
return std::shared_ptr<DataProvider>(new CSVDataProvider(pDoc, rDataSource));
else if (rDataProvider == "org.libreoffice.calc.html")
return std::shared_ptr<DataProvider>(new HTMLDataProvider(pDoc, rDataSource));
+ else if (rDataProvider == "org.libreoffice.calc.xml")
+ return std::shared_ptr<DataProvider>(new XMLDataProvider(pDoc, rDataSource));
}
else
{
@@ -289,6 +304,7 @@ std::vector<OUString> DataProviderFactory::getDataProviders()
std::vector<OUString> aDataProviders;
aDataProviders.emplace_back("org.libreoffice.calc.csv");
aDataProviders.emplace_back("org.libreoffice.calc.html");
+ aDataProviders.emplace_back("org.libreoffice.calc.xml");
return aDataProviders;
}
diff --git a/sc/source/ui/dataprovider/xmldataprovider.cxx b/sc/source/ui/dataprovider/xmldataprovider.cxx
new file mode 100644
index 000000000000..43fb36cf79b1
--- /dev/null
+++ b/sc/source/ui/dataprovider/xmldataprovider.cxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "xmldataprovider.hxx"
+#include <datatransformation.hxx>
+#include <salhelper/thread.hxx>
+#include <comphelper/string.hxx>
+#include <filter.hxx>
+#include <document.hxx>
+#include <orcusfilters.hxx>
+
+using namespace com::sun::star;
+
+namespace sc
+{
+class XMLFetchThread : public salhelper::Thread
+{
+ ScDocument& mrDocument;
+ OUString maURL;
+ OUString maID;
+ ScOrcusImportXMLParam maParam;
+ std::unique_ptr<ScOrcusXMLContext> mpXMLContext;
+ const std::vector<std::shared_ptr<sc::DataTransformation>> maDataTransformations;
+ std::function<void()> maImportFinishedHdl;
+
+public:
+ XMLFetchThread(ScDocument& rDoc, const OUString&, const ScOrcusImportXMLParam& rParam,
+ const OUString& rID, std::function<void()> aImportFinishedHdl,
+ const std::vector<std::shared_ptr<sc::DataTransformation>>& rTransformations);
+ virtual void execute() override;
+};
+
+XMLFetchThread::XMLFetchThread(
+ ScDocument& rDoc, const OUString& rURL, const ScOrcusImportXMLParam& rParam,
+ const OUString& rID, std::function<void()> aImportFinishedHdl,
+ const std::vector<std::shared_ptr<sc::DataTransformation>>& rTransformations)
+ : salhelper::Thread("XML Fetch Thread")
+ , mrDocument(rDoc)
+ , maURL(rURL)
+ , maID(rID)
+ , maParam(rParam)
+ , maDataTransformations(rTransformations)
+ , maImportFinishedHdl(aImportFinishedHdl)
+{
+}
+
+void XMLFetchThread::execute()
+{
+ ScOrcusFilters* pOrcus = ScFormatFilter::Get().GetOrcusFilters();
+ if (!pOrcus)
+ return;
+
+ mpXMLContext.reset(pOrcus->createXMLContext(mrDocument, maURL));
+ if (!mpXMLContext)
+ return;
+
+ if (!maID.isEmpty())
+ {
+ ScOrcusImportXMLParam::RangeLink aRangeLink;
+ aRangeLink.maPos = ScAddress(0, 0, 0);
+ aRangeLink.maFieldPaths.push_back(OUStringToOString(maID, RTL_TEXTENCODING_UTF8));
+ maParam.maRangeLinks.clear();
+ maParam.maRangeLinks.push_back(aRangeLink);
+ }
+ // Do the import.
+ mpXMLContext->importXML(maParam);
+
+ for (auto& itr : maDataTransformations)
+ {
+ itr->Transform(mrDocument);
+ }
+
+ SolarMutexGuard aGuard;
+ maImportFinishedHdl();
+}
+
+XMLDataProvider::XMLDataProvider(ScDocument* pDoc, sc::ExternalDataSource& rDataSource)
+ : DataProvider(rDataSource)
+ , mpDocument(pDoc)
+{
+}
+
+XMLDataProvider::~XMLDataProvider()
+{
+ if (mxXMLFetchThread.is())
+ {
+ SolarMutexReleaser aReleaser;
+ mxXMLFetchThread->join();
+ }
+}
+
+void XMLDataProvider::Import()
+{
+ // already importing data
+ if (mpDoc)
+ return;
+
+ mpDoc.reset(new ScDocument(SCDOCMODE_CLIP));
+ mpDoc->ResetClip(mpDocument, SCTAB(0));
+ mxXMLFetchThread = new XMLFetchThread(
+ *mpDoc, mrDataSource.getURL(), mrDataSource.getXMLImportParam(), mrDataSource.getID(),
+ std::bind(&XMLDataProvider::ImportFinished, this), mrDataSource.getDataTransformation());
+ mxXMLFetchThread->launch();
+
+ if (mbDeterministic)
+ {
+ SolarMutexReleaser aReleaser;
+ mxXMLFetchThread->join();
+ }
+}
+
+void XMLDataProvider::ImportFinished()
+{
+ mrDataSource.getDBManager()->WriteToDoc(*mpDoc);
+ mxXMLFetchThread.clear();
+ mpDoc.reset();
+}
+
+const OUString& XMLDataProvider::GetURL() const { return mrDataSource.getURL(); }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/dataprovider/xmldataprovider.hxx b/sc/source/ui/dataprovider/xmldataprovider.hxx
new file mode 100644
index 000000000000..286d6aa120c2
--- /dev/null
+++ b/sc/source/ui/dataprovider/xmldataprovider.hxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_UI_DATAPROVIDER_XMLDATAPROVIDER_HXX
+#define INCLUDED_SC_SOURCE_UI_DATAPROVIDER_XMLDATAPROVIDER_HXX
+
+#include <dataprovider.hxx>
+
+namespace sc
+{
+class XMLFetchThread;
+class DataTransformation;
+
+class XMLDataProvider : public DataProvider
+{
+private:
+ ScDocument* mpDocument;
+ rtl::Reference<XMLFetchThread> mxXMLFetchThread;
+ ScDocumentUniquePtr mpDoc;
+
+public:
+ XMLDataProvider(ScDocument* pDoc, sc::ExternalDataSource& rDataSource);
+ virtual ~XMLDataProvider() override;
+
+ virtual void Import() override;
+
+ virtual const OUString& GetURL() const override;
+
+ void ImportFinished();
+};
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list