LibreOffice Module desktop (master)  1
dp_configuration.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  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 //TODO: Large parts of this file were copied from dp_component.cxx; those parts
21 // should be consolidated.
22 
23 #include <config_extensions.h>
24 
25 #include <dp_backend.h>
26 #if HAVE_FEATURE_EXTENSIONS
27 #include <dp_persmap.h>
28 #endif
29 #include <dp_services.hxx>
30 #include <dp_ucb.h>
31 #include <rtl/string.hxx>
32 #include <rtl/strbuf.hxx>
33 #include <rtl/ustrbuf.hxx>
34 #include <cppuhelper/exc_hlp.hxx>
35 #include <ucbhelper/content.hxx>
36 #include <unotools/ucbhelper.hxx>
38 #include <xmlscript/xml_helper.hxx>
39 #include <comphelper/lok.hxx>
40 #include <svl/inettype.hxx>
41 #include <com/sun/star/configuration/Update.hpp>
42 #include <com/sun/star/lang/IllegalArgumentException.hpp>
43 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
44 #include <deque>
45 #include <memory>
46 #include <utility>
47 
49 
50 using namespace ::dp_misc;
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::ucb;
54 
56 namespace {
57 
58 class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
59 {
60  class PackageImpl : public ::dp_registry::backend::Package
61  {
62  BackendImpl * getMyBackend() const ;
63 
64  const bool m_isSchema;
65 
66  // Package
67  virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
68  ::osl::ResettableMutexGuard & guard,
69  ::rtl::Reference<AbortChannel> const & abortChannel,
70  Reference<XCommandEnvironment> const & xCmdEnv ) override;
71  virtual void processPackage_(
72  ::osl::ResettableMutexGuard & guard,
73  bool registerPackage,
74  bool startup,
75  ::rtl::Reference<AbortChannel> const & abortChannel,
76  Reference<XCommandEnvironment> const & xCmdEnv ) override;
77 
78  public:
79  PackageImpl(
80  ::rtl::Reference<PackageRegistryBackend> const & myBackend,
81  OUString const & url, OUString const & name,
82  Reference<deployment::XPackageTypeInfo> const & xPackageType,
83  bool isSchema, bool bRemoved, OUString const & identifier)
84  : Package( myBackend, url, name, name /* display-name */,
85  xPackageType, bRemoved, identifier),
86  m_isSchema( isSchema )
87  {}
88  };
89  friend class PackageImpl;
90 
91  std::deque<OUString> m_xcs_files;
92  std::deque<OUString> m_xcu_files;
93  std::deque<OUString> & getFiles( bool xcs ) {
94  return xcs ? m_xcs_files : m_xcu_files;
95  }
96 
99  std::unique_ptr<ConfigurationBackendDb> m_backendDb;
100 
101  // PackageRegistryBackend
102  virtual Reference<deployment::XPackage> bindPackage_(
103  OUString const & url, OUString const & mediaType, bool bRemoved,
104  OUString const & identifier,
105  Reference<XCommandEnvironment> const & xCmdEnv ) override;
106 
107 #if HAVE_FEATURE_EXTENSIONS
108  // for backwards compatibility - nil if no (compatible) back-compat db present
109  std::unique_ptr<PersistentMap> m_registeredPackages;
110 #endif
111 
112  virtual void SAL_CALL disposing() override;
113 
114  const Reference<deployment::XPackageTypeInfo> m_xConfDataTypeInfo;
115  const Reference<deployment::XPackageTypeInfo> m_xConfSchemaTypeInfo;
116  Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
117 
118  void configmgrini_verify_init(
119  Reference<XCommandEnvironment> const & xCmdEnv );
120  void configmgrini_flush( Reference<XCommandEnvironment> const & xCmdEnv );
121 
122  /* The parameter isURL is false in the case of adding the conf:ini-entry
123  value from the backend db. This entry already contains the path as it
124  is used in the configmgr.ini.
125  */
126  void addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url,
127  Reference<XCommandEnvironment> const & xCmdEnv );
128 #if HAVE_FEATURE_EXTENSIONS
129  bool removeFromConfigmgrIni( bool isSchema, OUString const & url,
130  Reference<XCommandEnvironment> const & xCmdEnv );
131 #endif
132  void addDataToDb(OUString const & url, ConfigurationBackendDb::Data const & data);
133  ::std::optional<ConfigurationBackendDb::Data> readDataFromDb(OUString const & url);
134  void revokeEntryFromDb(OUString const & url);
135  bool hasActiveEntry(OUString const & url);
136  bool activateEntry(OUString const & url);
137 
138 public:
139  BackendImpl( Sequence<Any> const & args,
140  Reference<XComponentContext> const & xComponentContext );
141 
142  // XPackageRegistry
143  virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
144  getSupportedPackageTypes() override;
145  virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType) override;
146 
148 };
149 
150 
151 void BackendImpl::disposing()
152 {
153  try {
154  configmgrini_flush( Reference<XCommandEnvironment>() );
155 
157  }
158  catch (const RuntimeException &) {
159  throw;
160  }
161  catch (const Exception &) {
162  Any exc( ::cppu::getCaughtException() );
163  throw lang::WrappedTargetRuntimeException(
164  "caught unexpected exception while disposing...",
165  static_cast<OWeakObject *>(this), exc );
166  }
167 }
168 
169 
170 BackendImpl::BackendImpl(
171  Sequence<Any> const & args,
172  Reference<XComponentContext> const & xComponentContext )
173  : PackageRegistryBackend( args, xComponentContext ),
174  m_configmgrini_inited( false ),
175  m_configmgrini_modified( false ),
176  m_xConfDataTypeInfo( new Package::TypeInfo(
177  "application/vnd.sun.star.configuration-data",
178  "*.xcu",
179  DpResId(RID_STR_CONF_DATA)
180  ) ),
181  m_xConfSchemaTypeInfo( new Package::TypeInfo(
182  "application/vnd.sun.star.configuration-schema",
183  "*.xcs",
184  DpResId(RID_STR_CONF_SCHEMA)
185  ) ),
186  m_typeInfos( 2 )
187 {
190 
191  const Reference<XCommandEnvironment> xCmdEnv;
192 
193  if (transientMode())
194  {
195  // TODO
196  }
197  else
198  {
199  OUString dbFile = makeURL(getCachePath(), "backenddb.xml");
200  m_backendDb.reset(
201  new ConfigurationBackendDb(getComponentContext(), dbFile));
202  //clean up data folders which are no longer used.
203  //This must not be done in the same process where the help files
204  //are still registers. Only after revoking and restarting OOo the folders
205  //can be removed. This works now, because the extension manager is a singleton
206  //and the backends are only create once per process.
207  std::vector<OUString> folders = m_backendDb->getAllDataUrls();
208  deleteUnusedFolders(folders);
209 
210  configmgrini_verify_init( xCmdEnv );
211 
212 #if HAVE_FEATURE_EXTENSIONS
213  std::unique_ptr<PersistentMap> pMap;
214  OUString aCompatURL( makeURL( getCachePath(), "registered_packages.pmap" ) );
215 
216  // Don't create it if it doesn't exist already
217  if ( ::utl::UCBContentHelper::Exists( expandUnoRcUrl( aCompatURL ) ) )
218  {
219  try
220  {
221  pMap.reset( new PersistentMap( aCompatURL ) );
222  }
223  catch (const Exception &e)
224  {
225  OUString aStr = "Exception loading legacy package database: '" +
226  e.Message +
227  "' - ignoring file, please remove it.\n";
228  dp_misc::writeConsole( aStr.getStr() );
229  }
230  }
231  m_registeredPackages = std::move(pMap);
232 #endif
233  }
234 }
235 
236 void BackendImpl::addDataToDb(
237  OUString const & url, ConfigurationBackendDb::Data const & data)
238 {
239  if (m_backendDb)
240  m_backendDb->addEntry(url, data);
241 }
242 
243 ::std::optional<ConfigurationBackendDb::Data> BackendImpl::readDataFromDb(
244  OUString const & url)
245 {
246  ::std::optional<ConfigurationBackendDb::Data> data;
247  if (m_backendDb)
248  data = m_backendDb->getEntry(url);
249  return data;
250 }
251 
252 void BackendImpl::revokeEntryFromDb(OUString const & url)
253 {
254  if (m_backendDb)
255  m_backendDb->revokeEntry(url);
256 }
257 
258 bool BackendImpl::hasActiveEntry(OUString const & url)
259 {
260  if (m_backendDb)
261  return m_backendDb->hasActiveEntry(url);
262  return false;
263 }
264 
265 bool BackendImpl::activateEntry(OUString const & url)
266 {
267  if (m_backendDb)
268  return m_backendDb->activateEntry(url);
269  return false;
270 }
271 
272 
273 // XPackageRegistry
274 
275 Sequence< Reference<deployment::XPackageTypeInfo> >
276 BackendImpl::getSupportedPackageTypes()
277 {
278  return m_typeInfos;
279 }
280 void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
281 {
282  if (m_backendDb)
283  m_backendDb->removeEntry(url);
284 }
285 
286 // PackageRegistryBackend
287 
288 Reference<deployment::XPackage> BackendImpl::bindPackage_(
289  OUString const & url, OUString const & mediaType_,
290  bool bRemoved, OUString const & identifier,
291  Reference<XCommandEnvironment> const & xCmdEnv )
292 {
293  OUString mediaType( mediaType_ );
294  if (mediaType.isEmpty())
295  {
296  // detect media-type:
297  ::ucbhelper::Content ucbContent;
298  if (create_ucb_content( &ucbContent, url, xCmdEnv ))
299  {
300  const OUString title( StrTitle::getTitle( ucbContent ) );
301  if (title.endsWithIgnoreAsciiCase( ".xcu" )) {
302  mediaType = "application/vnd.sun.star.configuration-data";
303  }
304  if (title.endsWithIgnoreAsciiCase( ".xcs" )) {
305  mediaType = "application/vnd.sun.star.configuration-schema";
306  }
307  }
308  if (mediaType.isEmpty())
309  throw lang::IllegalArgumentException(
310  StrCannotDetectMediaType() + url,
311  static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
312  }
313 
314  OUString type, subType;
316  if (INetContentTypes::parse( mediaType, type, subType, &params ))
317  {
318  if (type.equalsIgnoreAsciiCase("application"))
319  {
320  OUString name;
321  if (!bRemoved)
322  {
323  ::ucbhelper::Content ucbContent( url, xCmdEnv, m_xComponentContext );
324  name = StrTitle::getTitle( ucbContent );
325  }
326 
327  if (subType.equalsIgnoreAsciiCase( "vnd.sun.star.configuration-data"))
328  {
329  return new PackageImpl(
330  this, url, name, m_xConfDataTypeInfo, false /* data file */,
331  bRemoved, identifier);
332  }
333  else if (subType.equalsIgnoreAsciiCase( "vnd.sun.star.configuration-schema")) {
334  return new PackageImpl(
335  this, url, name, m_xConfSchemaTypeInfo, true /* schema file */,
336  bRemoved, identifier);
337  }
338  }
339  }
340  throw lang::IllegalArgumentException(
341  StrUnsupportedMediaType() + mediaType,
342  static_cast<OWeakObject *>(this),
343  static_cast<sal_Int16>(-1) );
344 }
345 
346 
347 void BackendImpl::configmgrini_verify_init(
348  Reference<XCommandEnvironment> const & xCmdEnv )
349 {
350  if (transientMode())
351  return;
352  const ::osl::MutexGuard guard( getMutex() );
354  return;
355 
356  // common rc:
357  ::ucbhelper::Content ucb_content;
358  if (create_ucb_content(
359  &ucb_content,
360  makeURL( getCachePath(), "configmgr.ini" ),
361  xCmdEnv, false /* no throw */ ))
362  {
363  OUString line;
364  if (readLine( &line, "SCHEMA=", ucb_content,
365  RTL_TEXTENCODING_UTF8 ))
366  {
367  sal_Int32 index = RTL_CONSTASCII_LENGTH("SCHEMA=");
368  do {
369  OUString token( line.getToken( 0, ' ', index ).trim() );
370  if (!token.isEmpty()) {
371  //The file may not exist anymore if a shared or bundled
372  //extension was removed, but it can still be in the configmgrini.
373  //After running XExtensionManager::synchronize, the configmgrini is
374  //cleaned up
375  m_xcs_files.push_back( token );
376  }
377  }
378  while (index >= 0);
379  }
380  if (readLine( &line, "DATA=", ucb_content,
381  RTL_TEXTENCODING_UTF8 )) {
382  sal_Int32 index = RTL_CONSTASCII_LENGTH("DATA=");
383  do {
384  OUString token( line.getToken( 0, ' ', index ).trim() );
385  if (!token.isEmpty())
386  {
387  if (token[ 0 ] == '?')
388  token = token.copy( 1 );
389  //The file may not exist anymore if a shared or bundled
390  //extension was removed, but it can still be in the configmgrini.
391  //After running XExtensionManager::synchronize, the configmgrini is
392  //cleaned up
393  m_xcu_files.push_back( token );
394  }
395  }
396  while (index >= 0);
397  }
398  }
399  m_configmgrini_modified = false;
400  m_configmgrini_inited = true;
401 }
402 
403 
404 void BackendImpl::configmgrini_flush(
405  Reference<XCommandEnvironment> const & xCmdEnv )
406 {
407  if (transientMode())
408  return;
410  return;
411 
412  OStringBuffer buf;
413  if (! m_xcs_files.empty())
414  {
415  auto iPos( m_xcs_files.cbegin() );
416  auto const iEnd( m_xcs_files.cend() );
417  buf.append( "SCHEMA=" );
418  while (iPos != iEnd) {
419  // encoded ASCII file-urls:
420  const OString item(
421  OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
422  buf.append( item );
423  ++iPos;
424  if (iPos != iEnd)
425  buf.append( ' ' );
426  }
427  buf.append(LF);
428  }
429  if (! m_xcu_files.empty())
430  {
431  auto iPos( m_xcu_files.cbegin() );
432  auto const iEnd( m_xcu_files.cend() );
433  buf.append( "DATA=" );
434  while (iPos != iEnd) {
435  // encoded ASCII file-urls:
436  const OString item(
437  OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
438  buf.append( item );
439  ++iPos;
440  if (iPos != iEnd)
441  buf.append( ' ' );
442  }
443  buf.append(LF);
444  }
445 
446  // write configmgr.ini:
447  const Reference<io::XInputStream> xData(
449  reinterpret_cast<sal_Int8 const *>(buf.getStr()),
450  buf.getLength() ) );
451  ::ucbhelper::Content ucb_content(
452  makeURL( getCachePath(), "configmgr.ini" ), xCmdEnv, m_xComponentContext );
453  ucb_content.writeStream( xData, true /* replace existing */ );
454 
455  m_configmgrini_modified = false;
456 }
457 
458 
459 void BackendImpl::addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url_,
460  Reference<XCommandEnvironment> const & xCmdEnv )
461 {
462  const OUString rcterm( isURL ? dp_misc::makeRcTerm(url_) : url_ );
463  const ::osl::MutexGuard guard( getMutex() );
464  configmgrini_verify_init( xCmdEnv );
465  std::deque<OUString> & rSet = getFiles(isSchema);
466  if (std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
467  rSet.push_front( rcterm ); // prepend to list, thus overriding
468  // write immediately:
470  configmgrini_flush( xCmdEnv );
471  }
472 }
473 
474 #if HAVE_FEATURE_EXTENSIONS
475 bool BackendImpl::removeFromConfigmgrIni(
476  bool isSchema, OUString const & url_,
477  Reference<XCommandEnvironment> const & xCmdEnv )
478 {
479  const OUString rcterm( dp_misc::makeRcTerm(url_) );
480  const ::osl::MutexGuard guard( getMutex() );
481  configmgrini_verify_init( xCmdEnv );
482  std::deque<OUString> & rSet = getFiles(isSchema);
483  auto i(std::find(rSet.begin(), rSet.end(), rcterm));
484  if (i == rSet.end() && !isSchema)
485  {
486  //in case the xcu contained %origin% then the configmr.ini contains the
487  //url to the file in the user installation (e.g. $BUNDLED_EXTENSIONS_USER)
488  //However, m_url (getURL()) contains the URL for the file in the actual
489  //extension installation.
490  ::std::optional<ConfigurationBackendDb::Data> data = readDataFromDb(url_);
491  if (data)
492  i = std::find(rSet.begin(), rSet.end(), data->iniEntry);
493  }
494  if (i == rSet.end()) {
495  return false;
496  }
497  rSet.erase(i);
498  // write immediately:
500  configmgrini_flush( xCmdEnv );
501  return true;
502 }
503 #endif
504 
505 // Package
506 
507 
508 BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
509 {
510  BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
511  if (nullptr == pBackend)
512  {
513  //May throw a DisposedException
514  check();
515  //We should never get here...
516  throw RuntimeException(
517  "Failed to get the BackendImpl",
518  static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
519  }
520  return pBackend;
521 }
522 
523 beans::Optional< beans::Ambiguous<sal_Bool> >
524 BackendImpl::PackageImpl::isRegistered_(
525  ::osl::ResettableMutexGuard &,
528 {
529  BackendImpl * that = getMyBackend();
530 
531  bool bReg = false;
532  if (that->hasActiveEntry(getURL()))
533  bReg = true;
534 
535 #if HAVE_FEATURE_EXTENSIONS
536  const OUString url(getURL());
537  if (!bReg && that->m_registeredPackages)
538  {
539  // fallback for user extension registered in berkeley DB
540  bReg = that->m_registeredPackages->has(
541  OUStringToOString( url, RTL_TEXTENCODING_UTF8 ));
542  }
543 #endif
544  return beans::Optional< beans::Ambiguous<sal_Bool> >(
545  true, beans::Ambiguous<sal_Bool>( bReg, false ) );
546 }
547 
548 
549 OUString encodeForXml( OUString const & text )
550 {
551  // encode conforming xml:
552  sal_Int32 len = text.getLength();
553  OUStringBuffer buf;
554  for ( sal_Int32 pos = 0; pos < len; ++pos )
555  {
556  sal_Unicode c = text[ pos ];
557  switch (c) {
558  case '<':
559  buf.append( "&lt;" );
560  break;
561  case '>':
562  buf.append( "&gt;" );
563  break;
564  case '&':
565  buf.append( "&amp;" );
566  break;
567  case '\'':
568  buf.append( "&apos;" );
569  break;
570  case '\"':
571  buf.append( "&quot;" );
572  break;
573  default:
574  buf.append( c );
575  break;
576  }
577  }
578  return buf.makeStringAndClear();
579 }
580 
581 
582 OUString replaceOrigin(
583  OUString const & url, OUString const & destFolder, Reference< XCommandEnvironment > const & xCmdEnv, Reference< XComponentContext > const & xContext, bool & out_replaced)
584 {
585  // looking for %origin%:
586  ::ucbhelper::Content ucb_content( url, xCmdEnv, xContext );
587  std::vector<sal_Int8> bytes( readFile( ucb_content ) );
588  std::vector<sal_Int8> filtered( bytes.size() * 2 );
589  bool use_filtered = false;
590  OString origin;
591  char const * pBytes = reinterpret_cast<char const *>(
592  bytes.data());
593  std::size_t nBytes = bytes.size();
594  size_t write_pos = 0;
595  while (nBytes > 0)
596  {
597  sal_Int32 index = rtl_str_indexOfChar_WithLength( pBytes, nBytes, '%' );
598  if (index < 0) {
599  if (! use_filtered) // opt
600  break;
601  index = nBytes;
602  }
603 
604  if ((write_pos + index) > filtered.size())
605  filtered.resize( (filtered.size() + index) * 2 );
606  memcpy( filtered.data() + write_pos, pBytes, index );
607  write_pos += index;
608  pBytes += index;
609  nBytes -= index;
610  if (nBytes == 0)
611  break;
612 
613  // consume %:
614  ++pBytes;
615  --nBytes;
616  char const * pAdd = "%";
617  sal_Int32 nAdd = 1;
618  if (nBytes > 1 && pBytes[ 0 ] == '%')
619  {
620  // %% => %
621  ++pBytes;
622  --nBytes;
623  use_filtered = true;
624  }
625  else if (rtl_str_shortenedCompare_WithLength(
626  pBytes, nBytes,
627  "origin%",
628  RTL_CONSTASCII_LENGTH("origin%"),
629  RTL_CONSTASCII_LENGTH("origin%")) == 0)
630  {
631  if (origin.isEmpty()) {
632  // encode only once
633  origin = OUStringToOString(
634  encodeForXml( url.copy( 0, url.lastIndexOf( '/' ) ) ),
635  // xxx todo: encode always for UTF-8? => lookup doc-header?
636  RTL_TEXTENCODING_UTF8 );
637  }
638  pAdd = origin.getStr();
639  nAdd = origin.getLength();
640  pBytes += RTL_CONSTASCII_LENGTH("origin%");
641  nBytes -= RTL_CONSTASCII_LENGTH("origin%");
642  use_filtered = true;
643  }
644  if ((write_pos + nAdd) > filtered.size())
645  filtered.resize( (filtered.size() + nAdd) * 2 );
646  memcpy( filtered.data() + write_pos, pAdd, nAdd );
647  write_pos += nAdd;
648  }
649  if (!use_filtered)
650  return url;
651  if (write_pos < filtered.size())
652  filtered.resize( write_pos );
653  OUString newUrl(url);
654  if (!destFolder.isEmpty())
655  {
656  //get the file name of the xcu and add it to the url of the temporary folder
657  sal_Int32 i = url.lastIndexOf('/');
658  newUrl = destFolder + url.copy(i);
659  }
660 
661  ucbhelper::Content(newUrl, xCmdEnv, xContext).writeStream(
662  xmlscript::createInputStream(filtered), true);
663  out_replaced = true;
664  return newUrl;
665 }
666 
667 
668 void BackendImpl::PackageImpl::processPackage_(
669  ::osl::ResettableMutexGuard &,
670  bool doRegisterPackage,
671  bool startup,
673  Reference<XCommandEnvironment> const & xCmdEnv )
674 {
675  BackendImpl * that = getMyBackend();
676  OUString url( getURL() );
677 
678  if (doRegisterPackage)
679  {
680  if (getMyBackend()->activateEntry(getURL()))
681  {
682  ::std::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
683  OSL_ASSERT(data);
684  that->addToConfigmgrIni( m_isSchema, false, data->iniEntry, xCmdEnv );
685  }
686  else
687  {
688  ConfigurationBackendDb::Data data;
689  if (!m_isSchema)
690  {
691  const OUString sModFolder = that->createFolder(xCmdEnv);
692  bool out_replaced = false;
693  url = replaceOrigin(url, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
694  if (out_replaced)
695  data.dataUrl = sModFolder;
696  else
697  deleteTempFolder(sModFolder);
698  }
699  //No need for live-deployment for bundled extension, because OOo
700  //restarts after installation
701  if ((that->m_eContext != Context::Bundled && !startup)
703  {
704  if (m_isSchema)
705  {
706  css::configuration::Update::get(
707  that->m_xComponentContext)->insertExtensionXcsFile(
708  that->m_eContext == Context::Shared, expandUnoRcUrl(url));
709  }
710  else
711  {
712  css::configuration::Update::get(
713  that->m_xComponentContext)->insertExtensionXcuFile(
714  that->m_eContext == Context::Shared, expandUnoRcUrl(url));
715  }
716  }
717  that->addToConfigmgrIni( m_isSchema, true, url, xCmdEnv );
718  data.iniEntry = dp_misc::makeRcTerm(url);
719  that->addDataToDb(getURL(), data);
720  }
721  }
722  else // revoke
723  {
724 #if HAVE_FEATURE_EXTENSIONS
725  if (!that->removeFromConfigmgrIni(m_isSchema, url, xCmdEnv) &&
726  that->m_registeredPackages) {
727  // Obsolete package database handling - should be removed for LibreOffice 4.0
729  that->m_registeredPackages->getEntries());
730  for (auto const& entry : entries)
731  {
732  //If the xcu file was installed before the configmgr was changed
733  //to use the configmgr.ini, one needed to rebuild to whole directory
734  //structure containing the xcu, xcs files from all extensions. Now,
735  //we just add all other xcu/xcs files to the configmgr.ini instead of
736  //rebuilding the directory structure.
737  OUString url2(
738  OStringToOUString(entry.first, RTL_TEXTENCODING_UTF8));
739  if (url2 != url) {
740  bool schema = entry.second.equalsIgnoreAsciiCase(
741  "vnd.sun.star.configuration-schema");
742  OUString url_replaced(url2);
743  ConfigurationBackendDb::Data data;
744  if (!schema)
745  {
746  const OUString sModFolder = that->createFolder(xCmdEnv);
747  bool out_replaced = false;
748  url_replaced = replaceOrigin(
749  url2, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
750  if (out_replaced)
751  data.dataUrl = sModFolder;
752  else
753  deleteTempFolder(sModFolder);
754  }
755  that->addToConfigmgrIni(schema, true, url_replaced, xCmdEnv);
756  data.iniEntry = dp_misc::makeRcTerm(url_replaced);
757  that->addDataToDb(url2, data);
758  }
759  that->m_registeredPackages->erase(entry.first);
760  }
761  try
762  {
764  makeURL( that->getCachePath(), "registry" ),
765  xCmdEnv, that->getComponentContext() ).executeCommand(
766  "delete", Any( true /* delete physically */ ) );
767  }
768  catch(const Exception&)
769  {
770  OSL_ASSERT(false);
771  }
772  }
773 #endif
774  ::std::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
775  //If an xcu file was life deployed then always a data entry is written.
776  //If the xcu file was already in the configmr.ini then there is also
777  //a data entry
778  if (!m_isSchema && data)
779  {
780  css::configuration::Update::get(
781  that->m_xComponentContext)->removeExtensionXcuFile(expandUnoRcTerm(data->iniEntry));
782  }
783  that->revokeEntryFromDb(url);
784  }
785 }
786 
787 } // anon namespace
788 
789 namespace sdecl = comphelper::service_decl;
792  serviceBI,
793  "com.sun.star.comp.deployment.configuration.PackageRegistryBackend",
795 
796 } // namespace dp_registry
797 
798 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
tuple line
UNOTOOLS_DLLPUBLIC bool Exists(OUString const &url)
bool m_configmgrini_inited
virtual void SAL_CALL disposing() override
Definition: dp_backend.cxx:114
bool m_configmgrini_modified
std::vector< sal_uInt8 > bytes
OUString expandUnoRcTerm(OUString const &term_)
Definition: dp_misc.cxx:292
sdecl::class_< BackendImpl, sdecl::with_args< true > > serviceBI
::cppu::ImplementationEntry const entries[]
const bool m_isSchema
OUString makeURL(OUString const &baseURL, OUString const &relPath_)
appends a relative path to a url.
Definition: dp_misc.cxx:251
const Reference< deployment::XPackageTypeInfo > m_xConfSchemaTypeInfo
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC std::vector< sal_Int8 > readFile(::ucbhelper::Content &ucb_content)
Definition: dp_ucb.cxx:189
static bool parse(OUString const &rMediaType, OUString &rType, OUString &rSubType, INetContentTypeParameterList *pParameters=nullptr)
sal_uInt16 sal_Unicode
Sequence< Reference< deployment::XPackageTypeInfo > > m_typeInfos
Any SAL_CALL getCaughtException()
std::unordered_map< OString, OString > t_string2string_map
Definition: dp_persmap.h:31
size_t pos
def check(model)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool readLine(OUString *res, OUString const &startingWith,::ucbhelper::Content &ucb_content, rtl_TextEncoding textenc)
Definition: dp_ucb.cxx:202
void writeConsole(OUString const &sText)
writes the argument string to the console.
Definition: dp_misc.cxx:465
Reference< XComponentContext > const m_xComponentContext
const Reference< deployment::XPackageTypeInfo > m_xConfDataTypeInfo
Reference< io::XInputStream > createInputStream(std::vector< sal_Int8 > const &rInData)
int i
std::unique_ptr< ConfigurationBackendDb > m_backendDb
tuple index
OUString makeRcTerm(OUString const &url)
Definition: dp_misc.cxx:299
Reference< XComponentContext > getComponentContext(Reference< XMultiServiceFactory > const &factory)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool create_ucb_content(::ucbhelper::Content *ucb_content, OUString const &url, css::uno::Reference< css::ucb::XCommandEnvironment > const &xCmdEnv, bool throw_exc=true)
OUString expandUnoRcUrl(OUString const &url)
Definition: dp_misc.cxx:315
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
#define BACKEND_SERVICE_NAME
Definition: dp_backend.h:41
static uno::Reference< css::uno::XComponentContext > xContext
Definition: init.cxx:2105
std::deque< OUString > m_xcs_files
const char LF
Definition: dp_misc.h:33
const char * name
std::unordered_map< OString, INetContentTypeParameter > INetContentTypeParameterList
std::deque< OUString > m_xcu_files
ResultType type
OUString DpResId(const char *pId)
Definition: dp_shared.hxx:37
sdecl::ServiceDecl const serviceDecl(serviceBI,"com.sun.star.comp.deployment.configuration.PackageRegistryBackend", BACKEND_SERVICE_NAME)
void writeStream(const css::uno::Reference< css::io::XInputStream > &rStream, bool bReplaceExisting)
aStr
::osl::Mutex & getMutex()