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>
17 #include <unotools/charclass.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 
28 using namespace com::sun::star;
29 
30 namespace sc {
31 
32 std::unique_ptr<SvStream> DataProvider::FetchStreamFromURL(const OUString& rURL, OStringBuffer& rBuffer)
33 {
34  try
35  {
36  uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess = ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() );
37 
38  uno::Reference< io::XInputStream > xStream = xFileAccess->openFileRead( rURL );
39 
40  const sal_Int32 BUF_LEN = 8000;
41  uno::Sequence< sal_Int8 > buffer( BUF_LEN );
42 
43  sal_Int32 nRead = 0;
44  while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN )
45  {
46  rBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
47  }
48 
49  if ( nRead > 0 )
50  {
51  rBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
52  }
53 
54  xStream->closeInput();
55 
56  SvStream* pStream = new SvMemoryStream(const_cast<char*>(rBuffer.getStr()), rBuffer.getLength(), StreamMode::READ);
57  return std::unique_ptr<SvStream>(pStream);
58  }
59  catch(...)
60  {
61  rBuffer.setLength(0);
62  return nullptr;
63  }
64 }
65 
66 ExternalDataSource::ExternalDataSource(const OUString& rURL,
67  const OUString& rProvider, ScDocument* pDoc)
68  : maURL(rURL)
69  , maProvider(rProvider)
70  , mpDoc(pDoc)
71 {
72 }
73 
74 void ExternalDataSource::setID(const OUString& rID)
75 {
76  maID = rID;
77 }
78 
80 {
81  maParam = rParam;
82 }
83 
84 
85 
86 void ExternalDataSource::setURL(const OUString& rURL)
87 {
88  maURL = rURL;
89 }
90 
91 void ExternalDataSource::setProvider(const OUString& rProvider)
92 {
93  maProvider = rProvider;
94  mpDataProvider.reset();
95 }
96 
97 const OUString& ExternalDataSource::getURL() const
98 {
99  return maURL;
100 }
101 
102 const OUString& ExternalDataSource::getProvider() const
103 {
104  return maProvider;
105 }
106 
107 const OUString& ExternalDataSource::getID() const
108 {
109  return maID;
110 }
111 
113 {
114  return maParam;
115 }
116 
118 {
119  if (mpDBDataManager)
120  {
121  ScDBData* pDBData = mpDBDataManager->getDBData();
122  if (pDBData)
123  return pDBData->GetName();
124  }
125  return OUString();
126 }
127 
128 void ExternalDataSource::setDBData(const OUString& rDBName)
129 {
130  if (!mpDBDataManager)
131  {
132  mpDBDataManager = std::make_shared<ScDBDataManager>(rDBName, mpDoc);
133  }
134  else
135  {
136  mpDBDataManager->SetDatabase(rDBName);
137  }
138 }
139 
141 {
142  return 0;
143 }
144 
146 {
147  return mpDBDataManager.get();
148 }
149 
150 void ExternalDataSource::refresh(ScDocument* pDoc, bool bDeterministic)
151 {
152  // no DB data available
153  if (!mpDBDataManager)
154  return;
155 
156  // if no data provider exists, try to create one
157  if (!mpDataProvider)
159 
160  // if we still have not been able to create one, we can not refresh the data
161  if (!mpDataProvider)
162  return;
163 
164  if (bDeterministic)
165  mpDataProvider->setDeterministic();
166 
167  mpDataProvider->Import();
168 }
169 
171  const std::shared_ptr<sc::DataTransformation>& mpDataTransformation)
172 {
173  maDataTransformations.push_back(mpDataTransformation);
174 }
175 
176 const std::vector<std::shared_ptr<sc::DataTransformation>>& ExternalDataSource::getDataTransformation() const
177 {
178  return maDataTransformations;
179 }
180 
182  //mrDoc(rDoc)
183 {
184 }
185 
187 {
188 }
189 
191 {
192  maDataSources.push_back(rSource);
193 }
194 
195 const std::vector<sc::ExternalDataSource>& ExternalDataMapper::getDataSources() const
196 {
197  return maDataSources;
198 }
199 
200 std::vector<sc::ExternalDataSource>& ExternalDataMapper::getDataSources()
201 {
202  return maDataSources;
203 }
204 
206  mbDeterministic(false),
207  mrDataSource(rDataSource)
208 {
209 }
210 
212 {
213  mbDeterministic = true;
214 }
215 
217 {
218 }
219 
221 {
222  // first apply all data transformations
223 
224  bool bShrunk = false;
225  SCCOL nStartCol = 0;
226  SCROW nStartRow = 0;
227  SCCOL nEndCol = rDoc.MaxCol();
228  SCROW nEndRow = rDoc.MaxRow();
229  rDoc.ShrinkToUsedDataArea(bShrunk, 0, nStartCol, nStartRow, nEndCol, nEndRow, false, true, true);
230  ScRange aClipRange(nStartCol, nStartRow, 0, nEndCol, nEndRow, 0);
231  rDoc.SetClipArea(aClipRange);
232 
233  ScRange aDestRange;
234  getDBData()->GetArea(aDestRange);
235  SCCOL nColSize = std::min<SCCOL>(aDestRange.aEnd.Col() - aDestRange.aStart.Col(), nEndCol);
236  aDestRange.aEnd.SetCol(aDestRange.aStart.Col() + nColSize);
237 
238  SCROW nRowSize = std::min<SCROW>(aDestRange.aEnd.Row() - aDestRange.aStart.Row(), nEndRow);
239  aDestRange.aEnd.SetRow(aDestRange.aStart.Row() + nRowSize);
240 
241  ScMarkData aMark(mpDoc->GetSheetLimits());
242  aMark.SelectTable(0, true);
243  mpDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::CONTENTS, nullptr, &rDoc);
244  ScDocShell* pDocShell = static_cast<ScDocShell*>(mpDoc->GetDocumentShell());
245  if (pDocShell)
246  pDocShell->PostPaint(aDestRange, PaintPartFlags::All);
247 }
248 
249 ScDBDataManager::ScDBDataManager(const OUString& rDBName, ScDocument* pDoc):
250  maDBName(rDBName),
251  mpDoc(pDoc)
252 {
253 }
254 
256 {
257 }
258 
259 void ScDBDataManager::SetDatabase(const OUString& rDBName)
260 {
261  maDBName = rDBName;
262 }
263 
265 {
267  return pDBData;
268 }
269 
270 bool DataProviderFactory::isInternalDataProvider(std::u16string_view rProvider)
271 {
272  return o3tl::starts_with(rProvider, u"org.libreoffice.calc");
273 }
274 
275 std::shared_ptr<DataProvider> DataProviderFactory::getDataProvider(ScDocument* pDoc,
276  sc::ExternalDataSource& rDataSource)
277 {
278  const OUString& rDataProvider = rDataSource.getProvider();
279  bool bInternal = DataProviderFactory::isInternalDataProvider(rDataProvider);
280  if (bInternal)
281  {
282  if (rDataProvider == "org.libreoffice.calc.csv")
283  return std::make_shared<CSVDataProvider>(pDoc, rDataSource);
284  else if (rDataProvider == "org.libreoffice.calc.html")
285  return std::make_shared<HTMLDataProvider>(pDoc, rDataSource);
286  else if (rDataProvider == "org.libreoffice.calc.xml")
287  return std::make_shared<XMLDataProvider>(pDoc, rDataSource);
288  else if (rDataProvider == "org.libreoffice.calc.sql")
289  return std::make_shared<SQLDataProvider>(pDoc, rDataSource);
290  }
291  else
292  {
293  SAL_WARN("sc", "no external data provider supported yet");
294  return std::shared_ptr<DataProvider>();
295  }
296 
297  return std::shared_ptr<DataProvider>();
298 }
299 
301 {
302  std::vector<OUString> aDataProviders;
303  aDataProviders.emplace_back("org.libreoffice.calc.csv");
304  aDataProviders.emplace_back("org.libreoffice.calc.html");
305  aDataProviders.emplace_back("org.libreoffice.calc.xml");
306  aDataProviders.emplace_back("org.libreoffice.calc.sql");
307 
308  return aDataProviders;
309 }
310 
311 }
312 
313 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
Definition: document.hxx:814
ScAddress aStart
Definition: address.hxx:499
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:42
static bool isInternalDataProvider(std::u16string_view rProvider)
SCROW Row() const
Definition: address.hxx:261
static std::vector< OUString > getDataProviders()
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 bSkipAttrForEmpty=false, const ScRangeList *pDestRanges=nullptr)
If pDestRanges is given it overrides rDestRange, rDestRange in this case is the overall encompassing ...
Definition: document.cxx:2816
ScAddress aEnd
Definition: address.hxx:500
ScDBDataManager(const OUString &rDBName, ScDocument *pDoc)
bool mbDeterministic
If true make the threaded import deterministic for the tests.
void AddDataTransformation(const std::shared_ptr< sc::DataTransformation > &mpDataTransformation)
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
void setProvider(const OUString &rProvider)
This class handles the copying of the data from the imported temporary document to the actual documen...
std::shared_ptr< DataProvider > mpDataProvider
Definition: datamapper.hxx:65
Reference< XInputStream > xStream
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:872
OUString maProvider
The data provider is a unique identifier that will allow to identify and instantiate the required dat...
Definition: datamapper.hxx:53
void SetRow(SCROW nRowP)
Definition: address.hxx:274
void SetCol(SCCOL nColP)
Definition: address.hxx:278
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:1063
void setID(const OUString &rID)
void WriteToDoc(ScDocument &rDoc)
void SetClipArea(const ScRange &rArea, bool bCut=false)
Definition: document.cxx:3134
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:871
const std::vector< ExternalDataSource > & getDataSources() const
static std::shared_ptr< DataProvider > getDataProvider(ScDocument *pDoc, sc::ExternalDataSource &rDataSource)
std::vector< ExternalDataSource > maDataSources
Definition: datamapper.hxx:100
void SelectTable(SCTAB nTab, bool bNew)
Definition: markdata.cxx:171
sal_Int16 SCCOL
Definition: types.hxx:21
OUString getDBName() const
static SC_DLLPUBLIC const CharClass & getCharClass()
Definition: global.cxx:1016
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:873
const OUString & getURL() const
void SetDatabase(const OUString &rDBName)
void refresh(ScDocument *pDoc, bool bDeterministic=false)
float u
const OUString & GetName() const
Definition: dbdata.hxx:121
ExternalDataMapper(ScDocument &rDoc)
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:101
void GetArea(SCTAB &rTab, SCCOL &rCol1, SCROW &rRow1, SCCOL &rCol2, SCROW &rRow2) const
Definition: dbdata.cxx:300
std::vector< std::shared_ptr< sc::DataTransformation > > maDataTransformations
Definition: datamapper.hxx:68
const OUString & getProvider() const
SCCOL Col() const
Definition: address.hxx:266
ScDBData * findByUpperName(const OUString &rName)
Definition: dbdata.cxx:1142
ScDBDataManager * getDBManager()
sal_Int32 SCROW
Definition: types.hxx:17
const ScOrcusImportXMLParam & getXMLImportParam() const
void insertDataSource(const ExternalDataSource &rSource)
DataProvider(sc::ExternalDataSource &rDataSource)
OUString maID
The ID allows the same data provider to support different data streams.
Definition: datamapper.hxx:61
void setURL(const OUString &rURL)
virtual ~DataProvider()
OUString maURL
The URL for the external data provider.
Definition: datamapper.hxx:38
static double getUpdateFrequency()
Reference< XComponentContext > getProcessComponentContext()
NamedDBs & getNamedDBs()
Definition: dbdata.hxx:315
void setXMLImportParam(const ScOrcusImportXMLParam &rParam)
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1057
#define SAL_WARN(area, stream)
ScDBData * getDBData()
const std::vector< std::shared_ptr< sc::DataTransformation > > & getDataTransformation() const
const OUString & getID() const
void setDBData(const OUString &rDBName)
std::shared_ptr< ScDBDataManager > mpDBDataManager
Definition: datamapper.hxx:66
ScOrcusImportXMLParam maParam
Definition: datamapper.hxx:63