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