VikasMahato

Untitled

Jun 16th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.10 KB | None | 0 0
  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 "xmldataprovider.hxx"
  11. #include <datatransformation.hxx>
  12. #include <salhelper/thread.hxx>
  13.  
  14. #include <comphelper/string.hxx>
  15. #include <orcusfiltersimpl.hxx>
  16.  
  17. #include <orcusxml.hxx>
  18. #include <filter.hxx>
  19. #include <document.hxx>
  20.  
  21. #include <svtools/treelistbox.hxx>
  22. #include <svtools/treelistentry.hxx>
  23. #include <ucbhelper/content.hxx>
  24. #include <o3tl/make_unique.hxx>
  25. #include <orcus/spreadsheet/import_interface.hpp>
  26. #include <orcus/xml_structure_tree.hpp>
  27. #include <orcus/xml_namespace.hpp>
  28. #include <orcus/orcus_xml.hpp>
  29. #include <orcus/global.hpp>
  30. #include <orcus/sax_parser_base.hpp>
  31.  
  32. #include <orcus/stream.hpp>
  33. #include <orcusfiltersimpl.hxx>
  34. #include <com/sun/star/ucb/XCommandEnvironment.hpp>
  35. #include <comphelper/processfactory.hxx>
  36.  
  37. #include <iostream>
  38. #include <string>
  39. #include <sstream>
  40. #include <vector>
  41.  
  42. #include <orcusfilters.hxx>
  43.  
  44. using namespace com::sun::star;
  45.  
  46. namespace sc {
  47.  
  48. class SetNamespaceAlias
  49. {
  50.     orcus::orcus_xml& mrFilter;
  51.     orcus::xmlns_repository& mrNsRepo;
  52.  
  53. public:
  54.     SetNamespaceAlias(orcus::orcus_xml& filter, orcus::xmlns_repository& repo)
  55.         : mrFilter(filter)
  56.         , mrNsRepo(repo)
  57.     {
  58.     }
  59.  
  60.     void operator()(size_t index)
  61.     {
  62.         orcus::xmlns_id_t nsid = mrNsRepo.get_identifier(index);
  63.         if (nsid == orcus::XMLNS_UNKNOWN_ID)
  64.             return;
  65.  
  66.         std::string alias = mrNsRepo.get_short_name(index);
  67.         mrFilter.set_namespace_alias(alias.c_str(), nsid);
  68.     }
  69. };
  70.  
  71. class InsertFieldPath
  72. {
  73.     orcus::orcus_xml& mrFilter;
  74.  
  75. public:
  76.     explicit InsertFieldPath(orcus::orcus_xml& rFilter)
  77.         : mrFilter(rFilter)
  78.     {
  79.     }
  80.     void operator()(const OString& rPath) { mrFilter.append_field_link(rPath.getStr()); }
  81. };
  82.  
  83. class XMLFetchThread : public salhelper::Thread
  84. {
  85.     ScDocument& mrDocument;
  86.     OUString maURL;
  87.     OUString maTreePath;
  88.     std::unique_ptr<ScOrcusXMLContext> mpXMLContext;
  89.     const std::vector<std::shared_ptr<sc::DataTransformation>> maDataTransformations;
  90.     std::function<void()> maImportFinishedHdl;
  91.  
  92. public:
  93.     XMLFetchThread(ScDocument& rDoc, const OUString&, const OUString& rTreePath, std::function<void()> aImportFinishedHdl,
  94.             const std::vector<std::shared_ptr<sc::DataTransformation>>& rTransformations);
  95.     void removeDuplicates(std::vector<size_t>& rArray);
  96.     virtual void execute() override;
  97. };
  98.  
  99. XMLFetchThread::XMLFetchThread(ScDocument& rDoc, const OUString& rURL, const OUString& rTreePath, std::function<void()> aImportFinishedHdl,
  100.         const std::vector<std::shared_ptr<sc::DataTransformation>>& rTransformations):
  101.     salhelper::Thread("XML Fetch Thread"),
  102.     mrDocument(rDoc),
  103.     maURL(rURL),
  104.     maTreePath(rTreePath),
  105.     maDataTransformations(rTransformations),
  106.     maImportFinishedHdl(aImportFinishedHdl)
  107. {
  108. }
  109.  
  110. void XMLFetchThread::removeDuplicates(std::vector<size_t>& rArray)
  111. {
  112.     std::sort(rArray.begin(), rArray.end());
  113.     std::vector<size_t>::iterator it = std::unique(rArray.begin(), rArray.end());
  114.     rArray.erase(it, rArray.end());
  115. }
  116.  
  117. void XMLFetchThread::execute()
  118. {
  119.     OStringBuffer aBuffer(64000);
  120.     std::unique_ptr<SvStream> pStream = DataProvider::FetchStreamFromURL(maURL, aBuffer);
  121.  
  122.     if (aBuffer.isEmpty())
  123.         return;
  124.  
  125.     ScOrcusFilters* pOrcus = ScFormatFilter::Get().GetOrcusFilters();  
  126.     if (!pOrcus)
  127.         return;
  128.  
  129.     mpXMLContext.reset(pOrcus->createXMLContext(mrDocument, maURL));
  130.     if (!mpXMLContext)
  131.         return;
  132.  
  133.     // Begin import.
  134.       ScOrcusImportXMLParam aParam;
  135. /*
  136.       // Convert single cell links.
  137.       {
  138.           std::set<const SvTreeListEntry*>::const_iterator it = maCellLinks.begin(), itEnd = maCellLinks.end();
  139.  
  140.           for (; it != itEnd; ++it)
  141.           {
  142.               const SvTreeListEntry& rEntry = **it;
  143.               OUString aPath = getXPath(*mpLbTree, rEntry, aParam.maNamespaces);
  144.               const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rEntry);
  145.  
  146.               aParam.maCellLinks.emplace_back(
  147.                       pUserData->maLinkedPos, OUStringToOString(aPath, RTL_TEXTENCODING_UTF8));
  148.           }
  149.       }
  150.  
  151.       // Convert range links. For now, an element with range link takes all its
  152.       // child elements as its fields.
  153.       {
  154.           std::set<const SvTreeListEntry*>::const_iterator it = maRangeLinks.begin(), itEnd = maRangeLinks.end();
  155.           for (; it != itEnd; ++it)
  156.           {
  157.               const SvTreeListEntry& rEntry = **it;
  158.               const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rEntry);
  159.  
  160.               ScOrcusImportXMLParam::RangeLink aRangeLink;
  161.               aRangeLink.maPos = pUserData->maLinkedPos;
  162.  
  163.               // Go through all its child elements.
  164.               getFieldLinks(aRangeLink, aParam.maNamespaces, *mpLbTree, rEntry);
  165.  
  166.               aParam.maRangeLinks.push_back(aRangeLink);
  167.           }
  168.       }
  169. */
  170.       // Remove duplicate namespace IDs.
  171.     //  removeDuplicates(aParam.maNamespaces);
  172.  
  173.       // Now do the import.
  174.       mpXMLContext->importXML(aParam);
  175.  
  176.  
  177.     for (auto& itr : maDataTransformations)
  178.     {
  179.         itr->Transform(mrDocument);
  180.     }
  181.  
  182.     SolarMutexGuard aGuard;
  183.     maImportFinishedHdl();
  184. }
  185.  
  186. XMLDataProvider::XMLDataProvider(ScDocument* pDoc, sc::ExternalDataSource& rDataSource):
  187.     DataProvider(rDataSource),
  188.     mpDocument(pDoc)
  189. {
  190. }
  191.  
  192. XMLDataProvider::~XMLDataProvider()
  193. {
  194.     if (mxXMLFetchThread.is())
  195.     {
  196.         SolarMutexReleaser aReleaser;
  197.         mxXMLFetchThread->join();
  198.     }
  199. }
  200.  
  201. void XMLDataProvider::Import()
  202. {
  203.     // already importing data
  204.     if (mpDoc)
  205.         return;
  206.  
  207.     mpDoc.reset(new ScDocument(SCDOCMODE_CLIP));
  208.     mpDoc->ResetClip(mpDocument, SCTAB(0));
  209.     mxXMLFetchThread = new XMLFetchThread(*mpDoc, mrDataSource.getURL(), mrDataSource.getTreePath(),
  210.             std::bind(&XMLDataProvider::ImportFinished, this), mrDataSource.getDataTransformation());
  211.     mxXMLFetchThread->launch();
  212.  
  213.     if (mbDeterministic)
  214.     {
  215.         SolarMutexReleaser aReleaser;
  216.         mxXMLFetchThread->join();
  217.     }
  218. }
  219.  
  220. std::map<OUString, OUString> XMLDataProvider::getDataSourcesForURL(const OUString& /*rURL*/)
  221. {
  222.     std::map<OUString, OUString> aMap;
  223.  
  224.     OStringBuffer aBuffer(64000);
  225.     std::unique_ptr<SvStream> pStream
  226.         = DataProvider::FetchStreamFromURL(mrDataSource.getURL(), aBuffer);
  227.  
  228.     if (aBuffer.isEmpty())
  229.         return std::map<OUString, OUString>();
  230.  
  231.     return aMap;
  232. }
  233.  
  234. void XMLDataProvider::ImportFinished()
  235. {
  236.     mrDataSource.getDBManager()->WriteToDoc(*mpDoc);
  237.     mxXMLFetchThread.clear();
  238.     mpDoc.reset();
  239. }
  240.  
  241. const OUString& XMLDataProvider::GetURL() const
  242. {
  243.     return mrDataSource.getURL();
  244. }
  245.  
  246. }
  247.  
  248. /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Add Comment
Please, Sign In to add comment