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