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