LibreOffice Module sc (master) 1
dataprovider.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include <dataprovider.hxx>
11#include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
12#include <com/sun/star/ucb/SimpleFileAccess.hpp>
13#include <com/sun/star/io/XInputStream.hpp>
14#include <o3tl/string_view.hxx>
15#include <rtl/strbuf.hxx>
16#include <sal/log.hxx>
18#include <tools/stream.hxx>
20
21#include "htmldataprovider.hxx"
22#include "xmldataprovider.hxx"
23#include "sqldataprovider.hxx"
24#include <datamapper.hxx>
25#include <dbdata.hxx>
26#include <docsh.hxx>
27#include <utility>
28
29using namespace com::sun::star;
30
31namespace sc {
32
33std::unique_ptr<SvStream> DataProvider::FetchStreamFromURL(const OUString& rURL, OStringBuffer& rBuffer)
34{
35 try
36 {
37 uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess = ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() );
38
39 uno::Reference< io::XInputStream > xStream = xFileAccess->openFileRead( rURL );
40
41 const sal_Int32 BUF_LEN = 8000;
42 uno::Sequence< sal_Int8 > buffer( BUF_LEN );
43
44 sal_Int32 nRead = 0;
45 while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN )
46 {
47 rBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
48 }
49
50 if ( nRead > 0 )
51 {
52 rBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
53 }
54
55 xStream->closeInput();
56
57 SvStream* pStream = new SvMemoryStream(const_cast<char*>(rBuffer.getStr()), rBuffer.getLength(), StreamMode::READ);
58 return std::unique_ptr<SvStream>(pStream);
59 }
60 catch(...)
61 {
62 rBuffer.setLength(0);
63 return nullptr;
64 }
65}
66
68 OUString aProvider, ScDocument* pDoc)
69 : maURL(std::move(aURL))
70 , maProvider(std::move(aProvider))
71 , mpDoc(pDoc)
72{
73}
74
75void ExternalDataSource::setID(const OUString& rID)
76{
77 maID = rID;
78}
79
81{
82 maParam = rParam;
83}
84
85
86
87void ExternalDataSource::setURL(const OUString& rURL)
88{
89 maURL = rURL;
90}
91
92void ExternalDataSource::setProvider(const OUString& rProvider)
93{
94 maProvider = rProvider;
95 mpDataProvider.reset();
96}
97
98const OUString& ExternalDataSource::getURL() const
99{
100 return maURL;
101}
102
103const OUString& ExternalDataSource::getProvider() const
104{
105 return maProvider;
106}
107
108const OUString& ExternalDataSource::getID() const
109{
110 return maID;
111}
112
114{
115 return maParam;
116}
117
119{
120 if (mpDBDataManager)
121 {
122 ScDBData* pDBData = mpDBDataManager->getDBData();
123 if (pDBData)
124 return pDBData->GetName();
125 }
126 return OUString();
127}
128
129void ExternalDataSource::setDBData(const OUString& rDBName)
130{
131 if (!mpDBDataManager)
132 {
133 mpDBDataManager = std::make_shared<ScDBDataManager>(rDBName, mpDoc);
134 }
135 else
136 {
137 mpDBDataManager->SetDatabase(rDBName);
138 }
139}
140
142{
143 return 0;
144}
145
147{
148 return mpDBDataManager.get();
149}
150
151void ExternalDataSource::refresh(ScDocument* pDoc, bool bDeterministic)
152{
153 // no DB data available
154 if (!mpDBDataManager)
155 return;
156
157 // if no data provider exists, try to create one
158 if (!mpDataProvider)
160
161 // if we still have not been able to create one, we can not refresh the data
162 if (!mpDataProvider)
163 return;
164
165 if (bDeterministic)
166 mpDataProvider->setDeterministic();
167
168 mpDataProvider->Import();
169}
170
172 const std::shared_ptr<sc::DataTransformation>& mpDataTransformation)
173{
174 maDataTransformations.push_back(mpDataTransformation);
175}
176
177const std::vector<std::shared_ptr<sc::DataTransformation>>& ExternalDataSource::getDataTransformation() const
178{
180}
181
183 //mrDoc(rDoc)
184{
185}
186
188{
189}
190
192{
193 maDataSources.push_back(rSource);
194}
195
196const std::vector<sc::ExternalDataSource>& ExternalDataMapper::getDataSources() const
197{
198 return maDataSources;
199}
200
201std::vector<sc::ExternalDataSource>& ExternalDataMapper::getDataSources()
202{
203 return maDataSources;
204}
205
207 mbDeterministic(false),
208 mrDataSource(rDataSource)
209{
210}
211
213{
214 mbDeterministic = true;
215}
216
218{
219}
220
222{
223 // first apply all data transformations
224
225 bool bShrunk = false;
226 SCCOL nStartCol = 0;
227 SCROW nStartRow = 0;
228 SCCOL nEndCol = rDoc.MaxCol();
229 SCROW nEndRow = rDoc.MaxRow();
230 rDoc.ShrinkToUsedDataArea(bShrunk, 0, nStartCol, nStartRow, nEndCol, nEndRow, false, true, true);
231 ScRange aClipRange(nStartCol, nStartRow, 0, nEndCol, nEndRow, 0);
232 rDoc.SetClipArea(aClipRange);
233
234 ScRange aDestRange;
235 getDBData()->GetArea(aDestRange);
236 SCCOL nColSize = std::min<SCCOL>(aDestRange.aEnd.Col() - aDestRange.aStart.Col(), nEndCol);
237 aDestRange.aEnd.SetCol(aDestRange.aStart.Col() + nColSize);
238
239 SCROW nRowSize = std::min<SCROW>(aDestRange.aEnd.Row() - aDestRange.aStart.Row(), nEndRow);
240 aDestRange.aEnd.SetRow(aDestRange.aStart.Row() + nRowSize);
241
243 aMark.SelectTable(0, true);
244 mpDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::CONTENTS, nullptr, &rDoc);
245 ScDocShell* pDocShell = static_cast<ScDocShell*>(mpDoc->GetDocumentShell());
246 if (pDocShell)
247 pDocShell->PostPaint(aDestRange, PaintPartFlags::All);
248}
249
251 maDBName(std::move(aDBName)),
252 mpDoc(pDoc)
253{
254}
255
257{
258}
259
260void ScDBDataManager::SetDatabase(const OUString& rDBName)
261{
262 maDBName = rDBName;
263}
264
266{
268 return pDBData;
269}
270
271bool DataProviderFactory::isInternalDataProvider(std::u16string_view rProvider)
272{
273 return o3tl::starts_with(rProvider, u"org.libreoffice.calc");
274}
275
276std::shared_ptr<DataProvider> DataProviderFactory::getDataProvider(ScDocument* pDoc,
277 sc::ExternalDataSource& rDataSource)
278{
279 const OUString& rDataProvider = rDataSource.getProvider();
280 bool bInternal = DataProviderFactory::isInternalDataProvider(rDataProvider);
281 if (bInternal)
282 {
283 if (rDataProvider == "org.libreoffice.calc.csv")
284 return std::make_shared<CSVDataProvider>(pDoc, rDataSource);
285 else if (rDataProvider == "org.libreoffice.calc.html")
286 return std::make_shared<HTMLDataProvider>(pDoc, rDataSource);
287 else if (rDataProvider == "org.libreoffice.calc.xml")
288 return std::make_shared<XMLDataProvider>(pDoc, rDataSource);
289 else if (rDataProvider == "org.libreoffice.calc.sql")
290 return std::make_shared<SQLDataProvider>(pDoc, rDataSource);
291 }
292 else
293 {
294 SAL_WARN("sc", "no external data provider supported yet");
295 return std::shared_ptr<DataProvider>();
296 }
297
298 return std::shared_ptr<DataProvider>();
299}
300
302{
303 std::vector<OUString> aDataProviders;
304 aDataProviders.emplace_back("org.libreoffice.calc.csv");
305 aDataProviders.emplace_back("org.libreoffice.calc.html");
306 aDataProviders.emplace_back("org.libreoffice.calc.xml");
307 aDataProviders.emplace_back("org.libreoffice.calc.sql");
308
309 return aDataProviders;
310}
311
312}
313
314/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XInputStream > xStream
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
SCCOL Col() const
Definition: address.hxx:279
ScDBData * findByUpperName(const OUString &rName)
Definition: dbdata.cxx:1221
NamedDBs & getNamedDBs()
Definition: dbdata.hxx:324
const OUString & GetName() const
Definition: dbdata.hxx:127
void GetArea(SCTAB &rTab, SCCOL &rCol1, SCROW &rRow1, SCCOL &rCol2, SCROW &rRow2) const
Definition: dbdata.cxx:298
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:101
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:898
SC_DLLPUBLIC void CopyFromClip(const ScRange &rDestRange, const ScMarkData &rMark, InsertDeleteFlags nInsFlag, ScDocument *pRefUndoDoc, ScDocument *pClipDoc, bool bResetCut=true, bool bAsLink=false, bool bIncludeFiltered=true, bool bSkipEmptyCells=false, const ScRangeList *pDestRanges=nullptr)
Paste data from a clipboard document into this document.
Definition: document.cxx:2814
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:892
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
void SetClipArea(const ScRange &rArea, bool bCut=false)
Definition: document.cxx:3132
bool ShrinkToUsedDataArea(bool &o_bShrunk, SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow, bool bColumnsOnly, bool bStickyTopRow=false, bool bStickyLeftCol=false, ScDataAreaExtras *pDataAreaExtras=nullptr) const
Shrink a range to only include used data area.
Definition: document.cxx:1049
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
Definition: document.hxx:827
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1083
static SC_DLLPUBLIC const CharClass & getCharClass()
Definition: global.cxx:1064
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
void SelectTable(SCTAB nTab, bool bNew)
Definition: markdata.cxx:157
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
static std::vector< OUString > getDataProviders()
static std::shared_ptr< DataProvider > getDataProvider(ScDocument *pDoc, sc::ExternalDataSource &rDataSource)
static bool isInternalDataProvider(std::u16string_view rProvider)
virtual ~DataProvider()
static std::unique_ptr< SvStream > FetchStreamFromURL(const OUString &, OStringBuffer &rBuffer)
bool mbDeterministic
If true make the threaded import deterministic for the tests.
DataProvider(sc::ExternalDataSource &rDataSource)
void insertDataSource(const ExternalDataSource &rSource)
std::vector< ExternalDataSource > maDataSources
Definition: datamapper.hxx:100
const std::vector< ExternalDataSource > & getDataSources() const
ExternalDataMapper(ScDocument &rDoc)
const ScOrcusImportXMLParam & getXMLImportParam() const
std::shared_ptr< DataProvider > mpDataProvider
Definition: datamapper.hxx:65
const OUString & getProvider() const
void setXMLImportParam(const ScOrcusImportXMLParam &rParam)
void setID(const OUString &rID)
static double getUpdateFrequency()
std::vector< std::shared_ptr< sc::DataTransformation > > maDataTransformations
Definition: datamapper.hxx:68
void setProvider(const OUString &rProvider)
void refresh(ScDocument *pDoc, bool bDeterministic=false)
const OUString & getID() const
const std::vector< std::shared_ptr< sc::DataTransformation > > & getDataTransformation() const
ScOrcusImportXMLParam maParam
Definition: datamapper.hxx:63
void setURL(const OUString &rURL)
OUString maURL
The URL for the external data provider.
Definition: datamapper.hxx:38
OUString maID
The ID allows the same data provider to support different data streams.
Definition: datamapper.hxx:61
OUString getDBName() const
void setDBData(const OUString &rDBName)
std::shared_ptr< ScDBDataManager > mpDBDataManager
Definition: datamapper.hxx:66
void AddDataTransformation(const std::shared_ptr< sc::DataTransformation > &mpDataTransformation)
ExternalDataSource(OUString aURL, OUString aProvider, ScDocument *pDoc)
OUString maProvider
The data provider is a unique identifier that will allow to identify and instantiate the required dat...
Definition: datamapper.hxx:53
const OUString & getURL() const
ScDBDataManager * getDBManager()
This class handles the copying of the data from the imported temporary document to the actual documen...
void WriteToDoc(ScDocument &rDoc)
ScDBData * getDBData()
void SetDatabase(const OUString &rDBName)
ScDBDataManager(OUString aDBName, ScDocument *pDoc)
URL aURL
float u
#define SAL_WARN(area, stream)
Reference< XComponentContext > getProcessComponentContext()
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
CAUTION! The following defines must be in the same namespace as the respective type.
Definition: broadcast.cxx:15
const URL maURL
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17