diff options
Diffstat (limited to 'sc/source/ui/dataprovider/dataprovider.cxx')
-rw-r--r-- | sc/source/ui/dataprovider/dataprovider.cxx | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/sc/source/ui/dataprovider/dataprovider.cxx b/sc/source/ui/dataprovider/dataprovider.cxx new file mode 100644 index 000000000..72f674a7b --- /dev/null +++ b/sc/source/ui/dataprovider/dataprovider.cxx @@ -0,0 +1,313 @@ +/* -*- 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 <dataprovider.hxx> +#include <com/sun/star/ucb/XSimpleFileAccess3.hpp> +#include <com/sun/star/ucb/SimpleFileAccess.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <o3tl/string_view.hxx> +#include <rtl/strbuf.hxx> +#include <sal/log.hxx> +#include <unotools/charclass.hxx> +#include <tools/stream.hxx> +#include <comphelper/processfactory.hxx> + +#include "htmldataprovider.hxx" +#include "xmldataprovider.hxx" +#include "sqldataprovider.hxx" +#include <datamapper.hxx> +#include <dbdata.hxx> +#include <docsh.hxx> + +using namespace com::sun::star; + +namespace sc { + +std::unique_ptr<SvStream> DataProvider::FetchStreamFromURL(const OUString& rURL, OStringBuffer& rBuffer) +{ + try + { + uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess = ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ); + + uno::Reference< io::XInputStream > xStream = xFileAccess->openFileRead( rURL ); + + const sal_Int32 BUF_LEN = 8000; + uno::Sequence< sal_Int8 > buffer( BUF_LEN ); + + sal_Int32 nRead = 0; + while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN ) + { + rBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead ); + } + + if ( nRead > 0 ) + { + rBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead ); + } + + xStream->closeInput(); + + SvStream* pStream = new SvMemoryStream(const_cast<char*>(rBuffer.getStr()), rBuffer.getLength(), StreamMode::READ); + return std::unique_ptr<SvStream>(pStream); + } + catch(...) + { + rBuffer.setLength(0); + return nullptr; + } +} + +ExternalDataSource::ExternalDataSource(const OUString& rURL, + const OUString& rProvider, ScDocument* pDoc) + : maURL(rURL) + , maProvider(rProvider) + , mpDoc(pDoc) +{ +} + +void ExternalDataSource::setID(const OUString& rID) +{ + maID = rID; +} + +void ExternalDataSource::setXMLImportParam(const ScOrcusImportXMLParam& rParam) +{ + maParam = rParam; +} + + + +void ExternalDataSource::setURL(const OUString& rURL) +{ + maURL = rURL; +} + +void ExternalDataSource::setProvider(const OUString& rProvider) +{ + maProvider = rProvider; + mpDataProvider.reset(); +} + +const OUString& ExternalDataSource::getURL() const +{ + return maURL; +} + +const OUString& ExternalDataSource::getProvider() const +{ + return maProvider; +} + +const OUString& ExternalDataSource::getID() const +{ + return maID; +} + +const ScOrcusImportXMLParam& ExternalDataSource::getXMLImportParam() const +{ + return maParam; +} + +OUString ExternalDataSource::getDBName() const +{ + if (mpDBDataManager) + { + ScDBData* pDBData = mpDBDataManager->getDBData(); + if (pDBData) + return pDBData->GetName(); + } + return OUString(); +} + +void ExternalDataSource::setDBData(const OUString& rDBName) +{ + if (!mpDBDataManager) + { + mpDBDataManager = std::make_shared<ScDBDataManager>(rDBName, mpDoc); + } + else + { + mpDBDataManager->SetDatabase(rDBName); + } +} + +double ExternalDataSource::getUpdateFrequency() +{ + return 0; +} + +ScDBDataManager* ExternalDataSource::getDBManager() +{ + return mpDBDataManager.get(); +} + +void ExternalDataSource::refresh(ScDocument* pDoc, bool bDeterministic) +{ + // no DB data available + if (!mpDBDataManager) + return; + + // if no data provider exists, try to create one + if (!mpDataProvider) + mpDataProvider = DataProviderFactory::getDataProvider(pDoc, *this); + + // if we still have not been able to create one, we can not refresh the data + if (!mpDataProvider) + return; + + if (bDeterministic) + mpDataProvider->setDeterministic(); + + mpDataProvider->Import(); +} + +void ExternalDataSource::AddDataTransformation( + const std::shared_ptr<sc::DataTransformation>& mpDataTransformation) +{ + maDataTransformations.push_back(mpDataTransformation); +} + +const std::vector<std::shared_ptr<sc::DataTransformation>>& ExternalDataSource::getDataTransformation() const +{ + return maDataTransformations; +} + +ExternalDataMapper::ExternalDataMapper(ScDocument& /*rDoc*/) + //mrDoc(rDoc) +{ +} + +ExternalDataMapper::~ExternalDataMapper() +{ +} + +void ExternalDataMapper::insertDataSource(const sc::ExternalDataSource& rSource) +{ + maDataSources.push_back(rSource); +} + +const std::vector<sc::ExternalDataSource>& ExternalDataMapper::getDataSources() const +{ + return maDataSources; +} + +std::vector<sc::ExternalDataSource>& ExternalDataMapper::getDataSources() +{ + return maDataSources; +} + +DataProvider::DataProvider(sc::ExternalDataSource& rDataSource): + mbDeterministic(false), + mrDataSource(rDataSource) +{ +} + +void DataProvider::setDeterministic() +{ + mbDeterministic = true; +} + +DataProvider::~DataProvider() +{ +} + +void ScDBDataManager::WriteToDoc(ScDocument& rDoc) +{ + // first apply all data transformations + + bool bShrunk = false; + SCCOL nStartCol = 0; + SCROW nStartRow = 0; + SCCOL nEndCol = rDoc.MaxCol(); + SCROW nEndRow = rDoc.MaxRow(); + rDoc.ShrinkToUsedDataArea(bShrunk, 0, nStartCol, nStartRow, nEndCol, nEndRow, false, true, true); + ScRange aClipRange(nStartCol, nStartRow, 0, nEndCol, nEndRow, 0); + rDoc.SetClipArea(aClipRange); + + ScRange aDestRange; + getDBData()->GetArea(aDestRange); + SCCOL nColSize = std::min<SCCOL>(aDestRange.aEnd.Col() - aDestRange.aStart.Col(), nEndCol); + aDestRange.aEnd.SetCol(aDestRange.aStart.Col() + nColSize); + + SCROW nRowSize = std::min<SCROW>(aDestRange.aEnd.Row() - aDestRange.aStart.Row(), nEndRow); + aDestRange.aEnd.SetRow(aDestRange.aStart.Row() + nRowSize); + + ScMarkData aMark(mpDoc->GetSheetLimits()); + aMark.SelectTable(0, true); + mpDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::CONTENTS, nullptr, &rDoc); + ScDocShell* pDocShell = static_cast<ScDocShell*>(mpDoc->GetDocumentShell()); + if (pDocShell) + pDocShell->PostPaint(aDestRange, PaintPartFlags::All); +} + +ScDBDataManager::ScDBDataManager(const OUString& rDBName, ScDocument* pDoc): + maDBName(rDBName), + mpDoc(pDoc) +{ +} + +ScDBDataManager::~ScDBDataManager() +{ +} + +void ScDBDataManager::SetDatabase(const OUString& rDBName) +{ + maDBName = rDBName; +} + +ScDBData* ScDBDataManager::getDBData() +{ + ScDBData* pDBData = mpDoc->GetDBCollection()->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(maDBName)); + return pDBData; +} + +bool DataProviderFactory::isInternalDataProvider(std::u16string_view rProvider) +{ + return o3tl::starts_with(rProvider, u"org.libreoffice.calc"); +} + +std::shared_ptr<DataProvider> DataProviderFactory::getDataProvider(ScDocument* pDoc, + sc::ExternalDataSource& rDataSource) +{ + const OUString& rDataProvider = rDataSource.getProvider(); + bool bInternal = DataProviderFactory::isInternalDataProvider(rDataProvider); + if (bInternal) + { + if (rDataProvider == "org.libreoffice.calc.csv") + return std::make_shared<CSVDataProvider>(pDoc, rDataSource); + else if (rDataProvider == "org.libreoffice.calc.html") + return std::make_shared<HTMLDataProvider>(pDoc, rDataSource); + else if (rDataProvider == "org.libreoffice.calc.xml") + return std::make_shared<XMLDataProvider>(pDoc, rDataSource); + else if (rDataProvider == "org.libreoffice.calc.sql") + return std::make_shared<SQLDataProvider>(pDoc, rDataSource); + } + else + { + SAL_WARN("sc", "no external data provider supported yet"); + return std::shared_ptr<DataProvider>(); + } + + return std::shared_ptr<DataProvider>(); +} + +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"); + aDataProviders.emplace_back("org.libreoffice.calc.sql"); + + return aDataProviders; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |