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 <rtl/strbuf.hxx>
15 #include <sal/log.hxx>
16 #include <unotools/charclass.hxx>
17 #include <tools/stream.hxx>
19 
20 #include "htmldataprovider.hxx"
21 #include "xmldataprovider.hxx"
22 #include "sqldataprovider.hxx"
23 #include <datamapper.hxx>
24 #include <dbdata.hxx>
25 #include <docsh.hxx>
26 
27 using namespace com::sun::star;
28 
29 namespace sc {
30 
31 std::unique_ptr<SvStream> DataProvider::FetchStreamFromURL(const OUString& rURL, OStringBuffer& rBuffer)
32 {
33  try
34  {
35  uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess = ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() );
36 
37  uno::Reference< io::XInputStream > xStream = xFileAccess->openFileRead( rURL );
38 
39  const sal_Int32 BUF_LEN = 8000;
40  uno::Sequence< sal_Int8 > buffer( BUF_LEN );
41 
42  sal_Int32 nRead = 0;
43  while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN )
44  {
45  rBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
46  }
47 
48  if ( nRead > 0 )
49  {
50  rBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
51  }
52 
53  xStream->closeInput();
54 
55  SvStream* pStream = new SvMemoryStream(const_cast<char*>(rBuffer.getStr()), rBuffer.getLength(), StreamMode::READ);
56  return std::unique_ptr<SvStream>(pStream);
57  }
58  catch(...)
59  {
60  rBuffer.setLength(0);
61  return nullptr;
62  }
63 }
64 
65 ExternalDataSource::ExternalDataSource(const OUString& rURL,
66  const OUString& rProvider, ScDocument* pDoc)
67  : maURL(rURL)
68  , maProvider(rProvider)
69  , mpDoc(pDoc)
70 {
71 }
72 
73 void ExternalDataSource::setID(const OUString& rID)
74 {
75  maID = rID;
76 }
77 
79 {
80  maParam = rParam;
81 }
82 
83 
84 
85 void ExternalDataSource::setURL(const OUString& rURL)
86 {
87  maURL = rURL;
88 }
89 
90 void ExternalDataSource::setProvider(const OUString& rProvider)
91 {
92  maProvider = rProvider;
93  mpDataProvider.reset();
94 }
95 
96 const OUString& ExternalDataSource::getURL() const
97 {
98  return maURL;
99 }
100 
101 const OUString& ExternalDataSource::getProvider() const
102 {
103  return maProvider;
104 }
105 
106 const OUString& ExternalDataSource::getID() const
107 {
108  return maID;
109 }
110 
112 {
113  return maParam;
114 }
115 
117 {
118  if (mpDBDataManager)
119  {
120  ScDBData* pDBData = mpDBDataManager->getDBData();
121  if (pDBData)
122  return pDBData->GetName();
123  }
124  return OUString();
125 }
126 
127 void ExternalDataSource::setDBData(const OUString& rDBName)
128 {
129  if (!mpDBDataManager)
130  {
131  mpDBDataManager = std::make_shared<ScDBDataManager>(rDBName, mpDoc);
132  }
133  else
134  {
135  mpDBDataManager->SetDatabase(rDBName);
136  }
137 }
138 
140 {
141  return 0;
142 }
143 
145 {
146  return mpDBDataManager.get();
147 }
148 
149 void ExternalDataSource::refresh(ScDocument* pDoc, bool bDeterministic)
150 {
151  // no DB data available
152  if (!mpDBDataManager)
153  return;
154 
155  // if no data provider exists, try to create one
156  if (!mpDataProvider)
158 
159  // if we still have not been able to create one, we can not refresh the data
160  if (!mpDataProvider)
161  return;
162 
163  if (bDeterministic)
164  mpDataProvider->setDeterministic();
165 
166  mpDataProvider->Import();
167 }
168 
170  const std::shared_ptr<sc::DataTransformation>& mpDataTransformation)
171 {
172  maDataTransformations.push_back(mpDataTransformation);
173 }
174 
175 const std::vector<std::shared_ptr<sc::DataTransformation>>& ExternalDataSource::getDataTransformation() const
176 {
177  return maDataTransformations;
178 }
179 
181  //mpDoc(pDoc)
182 {
183 }
184 
186 {
187 }
188 
190 {
191  maDataSources.push_back(rSource);
192 }
193 
194 const std::vector<sc::ExternalDataSource>& ExternalDataMapper::getDataSources() const
195 {
196  return maDataSources;
197 }
198 
199 std::vector<sc::ExternalDataSource>& ExternalDataMapper::getDataSources()
200 {
201  return maDataSources;
202 }
203 
205  mbDeterministic(false),
206  mrDataSource(rDataSource)
207 {
208 }
209 
211 {
212  mbDeterministic = true;
213 }
214 
216 {
217 }
218 
220 {
221  // first apply all data transformations
222 
223  bool bShrunk = false;
224  SCCOL nStartCol = 0;
225  SCROW nStartRow = 0;
226  SCCOL nEndCol = rDoc.MaxCol();
227  SCROW nEndRow = rDoc.MaxRow();
228  rDoc.ShrinkToUsedDataArea(bShrunk, 0, nStartCol, nStartRow, nEndCol, nEndRow, false, true, true);
229  ScRange aClipRange(nStartCol, nStartRow, 0, nEndCol, nEndRow, 0);
230  rDoc.SetClipArea(aClipRange);
231 
232  ScRange aDestRange;
233  getDBData()->GetArea(aDestRange);
234  SCCOL nColSize = std::min<SCCOL>(aDestRange.aEnd.Col() - aDestRange.aStart.Col(), nEndCol);
235  aDestRange.aEnd.SetCol(aDestRange.aStart.Col() + nColSize);
236 
237  SCROW nRowSize = std::min<SCROW>(aDestRange.aEnd.Row() - aDestRange.aStart.Row(), nEndRow);
238  aDestRange.aEnd.SetRow(aDestRange.aStart.Row() + nRowSize);
239 
240  ScMarkData aMark(mpDoc->GetSheetLimits());
241  aMark.SelectTable(0, true);
242  mpDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::CONTENTS, nullptr, &rDoc);
243  ScDocShell* pDocShell = static_cast<ScDocShell*>(mpDoc->GetDocumentShell());
244  if (pDocShell)
245  pDocShell->PostPaint(aDestRange, PaintPartFlags::All);
246 }
247 
248 ScDBDataManager::ScDBDataManager(const OUString& rDBName, ScDocument* pDoc):
249  maDBName(rDBName),
250  mpDoc(pDoc)
251 {
252 }
253 
255 {
256 }
257 
258 void ScDBDataManager::SetDatabase(const OUString& rDBName)
259 {
260  maDBName = rDBName;
261 }
262 
264 {
266  return pDBData;
267 }
268 
269 bool DataProviderFactory::isInternalDataProvider(const OUString& rProvider)
270 {
271  return rProvider.startsWith("org.libreoffice.calc");
272 }
273 
274 std::shared_ptr<DataProvider> DataProviderFactory::getDataProvider(ScDocument* pDoc,
275  sc::ExternalDataSource& rDataSource)
276 {
277  const OUString& rDataProvider = rDataSource.getProvider();
278  bool bInternal = DataProviderFactory::isInternalDataProvider(rDataProvider);
279  if (bInternal)
280  {
281  if (rDataProvider == "org.libreoffice.calc.csv")
282  return std::make_shared<CSVDataProvider>(pDoc, rDataSource);
283  else if (rDataProvider == "org.libreoffice.calc.html")
284  return std::make_shared<HTMLDataProvider>(pDoc, rDataSource);
285  else if (rDataProvider == "org.libreoffice.calc.xml")
286  return std::make_shared<XMLDataProvider>(pDoc, rDataSource);
287  else if (rDataProvider == "org.libreoffice.calc.sql")
288  return std::make_shared<SQLDataProvider>(pDoc, rDataSource);
289  }
290  else
291  {
292  SAL_WARN("sc", "no external data provider supported yet");
293  return std::shared_ptr<DataProvider>();
294  }
295 
296  return std::shared_ptr<DataProvider>();
297 }
298 
300 {
301  std::vector<OUString> aDataProviders;
302  aDataProviders.emplace_back("org.libreoffice.calc.csv");
303  aDataProviders.emplace_back("org.libreoffice.calc.html");
304  aDataProviders.emplace_back("org.libreoffice.calc.xml");
305  aDataProviders.emplace_back("org.libreoffice.calc.sql");
306 
307  return aDataProviders;
308 }
309 
310 }
311 
312 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
Definition: document.hxx:819
ScAddress aStart
Definition: address.hxx:500
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
SCROW Row() const
Definition: address.hxx:262
static std::vector< OUString > getDataProviders()
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:2800
ScAddress aEnd
Definition: address.hxx:501
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)
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:67
Reference< XInputStream > xStream
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:876
OUString maProvider
The data provider is a unique identifier that will allow to identify and instantiate the required dat...
Definition: datamapper.hxx:55
void SetRow(SCROW nRowP)
Definition: address.hxx:275
void SetCol(SCCOL nColP)
Definition: address.hxx:279
void setID(const OUString &rID)
void WriteToDoc(ScDocument &rDoc)
void SetClipArea(const ScRange &rArea, bool bCut=false)
Definition: document.cxx:3105
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:875
bool ShrinkToUsedDataArea(bool &o_bShrunk, SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow, bool bColumnsOnly, bool bStickyTopRow=false, bool bStickyLeftCol=false, bool bConsiderCellNotes=false, bool bConsiderCellDrawObjects=false) const
Shrink a range to only include used data area.
Definition: document.cxx:1070
const std::vector< ExternalDataSource > & getDataSources() const
static std::shared_ptr< DataProvider > getDataProvider(ScDocument *pDoc, sc::ExternalDataSource &rDataSource)
std::vector< ExternalDataSource > maDataSources
Definition: datamapper.hxx:104
void SelectTable(SCTAB nTab, bool bNew)
Definition: markdata.cxx:172
sal_Int16 SCCOL
Definition: types.hxx:22
OUString getDBName() const
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:877
const OUString & getURL() const
void SetDatabase(const OUString &rDBName)
void refresh(ScDocument *pDoc, bool bDeterministic=false)
const OUString & GetName() const
Definition: dbdata.hxx:122
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:99
void GetArea(SCTAB &rTab, SCCOL &rCol1, SCROW &rRow1, SCCOL &rCol2, SCROW &rRow2) const
Definition: dbdata.cxx:301
std::vector< std::shared_ptr< sc::DataTransformation > > maDataTransformations
Definition: datamapper.hxx:70
const OUString & getProvider() const
SCCOL Col() const
Definition: address.hxx:267
ScDBData * findByUpperName(const OUString &rName)
Definition: dbdata.cxx:1145
ScDBDataManager * getDBManager()
sal_Int32 SCROW
Definition: types.hxx:18
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:63
ExternalDataMapper(ScDocument *pDoc)
void setURL(const OUString &rURL)
virtual ~DataProvider()
OUString maURL
The URL for the external data provider.
Definition: datamapper.hxx:40
static SC_DLLPUBLIC const CharClass * getCharClassPtr()
Definition: global.cxx:1018
static double getUpdateFrequency()
Reference< XComponentContext > getProcessComponentContext()
NamedDBs & getNamedDBs()
Definition: dbdata.hxx:315
void setXMLImportParam(const ScOrcusImportXMLParam &rParam)
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1061
#define SAL_WARN(area, stream)
static bool isInternalDataProvider(const OUString &rProvider)
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:68
ScOrcusImportXMLParam maParam
Definition: datamapper.hxx:65