update credits
[LibreOffice.git] / desktop / source / deployment / registry / configuration / dp_configuration.cxx
blob9254a7c9ef6f9a502e4b3d9d3ff29a8b73536ccc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 //TODO: Large parts of this file were copied from dp_component.cxx; those parts
21 // should be consolidated.
23 #include <config_features.h>
25 #include "dp_configuration.hrc"
26 #include "dp_backend.h"
27 #if HAVE_FEATURE_EXTENSIONS
28 #include "dp_persmap.h"
29 #endif
30 #include "dp_ucb.h"
31 #include "rtl/string.hxx"
32 #include "rtl/ustrbuf.hxx"
33 #include "rtl/uri.hxx"
34 #include "osl/file.hxx"
35 #include "cppuhelper/exc_hlp.hxx"
36 #include "ucbhelper/content.hxx"
37 #include "unotools/ucbhelper.hxx"
38 #include "comphelper/anytostring.hxx"
39 #include "comphelper/servicedecl.hxx"
40 #include "xmlscript/xml_helper.hxx"
41 #include "svl/inettype.hxx"
42 #include "com/sun/star/configuration/Update.hpp"
43 #include "com/sun/star/ucb/NameClash.hpp"
44 #include "com/sun/star/io/XActiveDataSink.hpp"
45 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
46 #include "com/sun/star/util/XRefreshable.hpp"
47 #include <list>
48 #include <memory>
50 #include "dp_configurationbackenddb.hxx"
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;
57 namespace dp_registry {
58 namespace backend {
59 namespace configuration {
60 namespace {
62 typedef ::std::list<OUString> t_stringlist;
64 //==============================================================================
65 class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
67 class PackageImpl : public ::dp_registry::backend::Package
69 BackendImpl * getMyBackend() const ;
71 const bool m_isSchema;
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 );
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 );
85 public:
86 inline 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 )
96 friend class PackageImpl;
98 t_stringlist m_xcs_files;
99 t_stringlist m_xcu_files;
100 t_stringlist & getFiles( bool xcs ) {
101 return xcs ? m_xcs_files : m_xcu_files;
104 bool m_configmgrini_inited;
105 bool m_configmgrini_modified;
106 std::auto_ptr<ConfigurationBackendDb> m_backendDb;
108 // PackageRegistryBackend
109 virtual Reference<deployment::XPackage> bindPackage_(
110 OUString const & url, OUString const & mediaType, sal_Bool bRemoved,
111 OUString const & identifier,
112 Reference<XCommandEnvironment> const & xCmdEnv );
114 #if HAVE_FEATURE_EXTENSIONS
115 // for backwards compatibility - nil if no (compatible) back-compat db present
116 ::std::auto_ptr<PersistentMap> m_registeredPackages;
117 #endif
119 virtual void SAL_CALL disposing();
121 const Reference<deployment::XPackageTypeInfo> m_xConfDataTypeInfo;
122 const Reference<deployment::XPackageTypeInfo> m_xConfSchemaTypeInfo;
123 Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
125 void configmgrini_verify_init(
126 Reference<XCommandEnvironment> const & xCmdEnv );
127 void configmgrini_flush( Reference<XCommandEnvironment> const & xCmdEnv );
129 /* The paramter 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.
133 bool addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url,
134 Reference<XCommandEnvironment> const & xCmdEnv );
135 bool removeFromConfigmgrIni( bool isSchema, OUString const & url,
136 Reference<XCommandEnvironment> const & xCmdEnv );
138 void addDataToDb(OUString const & url, ConfigurationBackendDb::Data const & data);
139 ::boost::optional<ConfigurationBackendDb::Data> readDataFromDb(OUString const & url);
140 void revokeEntryFromDb(OUString const & url);
141 bool hasActiveEntry(OUString const & url);
142 bool activateEntry(OUString const & url);
144 public:
145 BackendImpl( Sequence<Any> const & args,
146 Reference<XComponentContext> const & xComponentContext );
148 // XPackageRegistry
149 virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
150 getSupportedPackageTypes() throw (RuntimeException);
151 virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
152 throw (deployment::DeploymentException,
153 uno::RuntimeException);
155 using PackageRegistryBackend::disposing;
158 //______________________________________________________________________________
159 void BackendImpl::disposing()
161 try {
162 configmgrini_flush( Reference<XCommandEnvironment>() );
164 PackageRegistryBackend::disposing();
166 catch (const RuntimeException &) {
167 throw;
169 catch (const Exception &) {
170 Any exc( ::cppu::getCaughtException() );
171 throw lang::WrappedTargetRuntimeException(
172 "caught unexpected exception while disposing...",
173 static_cast<OWeakObject *>(this), exc );
177 //______________________________________________________________________________
178 BackendImpl::BackendImpl(
179 Sequence<Any> const & args,
180 Reference<XComponentContext> const & xComponentContext )
181 : PackageRegistryBackend( args, xComponentContext ),
182 m_configmgrini_inited( false ),
183 m_configmgrini_modified( false ),
184 m_xConfDataTypeInfo( new Package::TypeInfo(
185 "application/vnd.sun.star.configuration-data",
186 "*.xcu",
187 getResourceString(RID_STR_CONF_DATA),
188 RID_IMG_CONF_XML ) ),
189 m_xConfSchemaTypeInfo( new Package::TypeInfo(
190 "application/vnd.sun.star.configuration-schema",
191 "*.xcs",
192 getResourceString(RID_STR_CONF_SCHEMA),
193 RID_IMG_CONF_XML ) ),
194 m_typeInfos( 2 )
196 m_typeInfos[ 0 ] = m_xConfDataTypeInfo;
197 m_typeInfos[ 1 ] = m_xConfSchemaTypeInfo;
199 const Reference<XCommandEnvironment> xCmdEnv;
201 if (transientMode())
203 // TODO
205 else
207 OUString dbFile = makeURL(getCachePath(), "backenddb.xml");
208 m_backendDb.reset(
209 new ConfigurationBackendDb(getComponentContext(), dbFile));
210 //clean up data folders which are no longer used.
211 //This must not be done in the same process where the help files
212 //are still registers. Only after revoking and restarting OOo the folders
213 //can be removed. This works now, because the extension manager is a singleton
214 //and the backends are only create once per process.
215 ::std::list<OUString> folders = m_backendDb->getAllDataUrls();
216 deleteUnusedFolders(OUString(), folders);
218 configmgrini_verify_init( xCmdEnv );
220 #if HAVE_FEATURE_EXTENSIONS
221 SAL_WNODEPRECATED_DECLARATIONS_PUSH
222 ::std::auto_ptr<PersistentMap> pMap;
223 SAL_WNODEPRECATED_DECLARATIONS_POP
224 OUString aCompatURL( makeURL( getCachePath(), "registered_packages.pmap" ) );
226 // Don't create it if it doesn't exist already
227 if ( ::utl::UCBContentHelper::Exists( expandUnoRcUrl( aCompatURL ) ) )
231 SAL_WNODEPRECATED_DECLARATIONS_PUSH
232 pMap = ::std::auto_ptr<PersistentMap>( new PersistentMap( aCompatURL, false ) );
233 SAL_WNODEPRECATED_DECLARATIONS_POP
235 catch (const Exception &e)
237 OUStringBuffer aStr( "Exception loading legacy package database: '" );
238 aStr.append( e.Message );
239 aStr.append( "' - ignoring file, please remove it.\n" );
240 dp_misc::writeConsole( aStr.getStr() );
243 m_registeredPackages = pMap;
244 #endif
248 void BackendImpl::addDataToDb(
249 OUString const & url, ConfigurationBackendDb::Data const & data)
251 if (m_backendDb.get())
252 m_backendDb->addEntry(url, data);
255 ::boost::optional<ConfigurationBackendDb::Data> BackendImpl::readDataFromDb(
256 OUString const & url)
258 ::boost::optional<ConfigurationBackendDb::Data> data;
259 if (m_backendDb.get())
260 data = m_backendDb->getEntry(url);
261 return data;
264 void BackendImpl::revokeEntryFromDb(OUString const & url)
266 if (m_backendDb.get())
267 m_backendDb->revokeEntry(url);
270 bool BackendImpl::hasActiveEntry(OUString const & url)
272 if (m_backendDb.get())
273 return m_backendDb->hasActiveEntry(url);
274 return false;
277 bool BackendImpl::activateEntry(OUString const & url)
279 if (m_backendDb.get())
280 return m_backendDb->activateEntry(url);
281 return false;
286 // XPackageRegistry
287 //______________________________________________________________________________
288 Sequence< Reference<deployment::XPackageTypeInfo> >
289 BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
291 return m_typeInfos;
293 void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
294 throw (deployment::DeploymentException,
295 uno::RuntimeException)
297 if (m_backendDb.get())
298 m_backendDb->removeEntry(url);
301 // PackageRegistryBackend
302 //______________________________________________________________________________
303 Reference<deployment::XPackage> BackendImpl::bindPackage_(
304 OUString const & url, OUString const & mediaType_,
305 sal_Bool bRemoved, OUString const & identifier,
306 Reference<XCommandEnvironment> const & xCmdEnv )
308 OUString mediaType( mediaType_ );
309 if (mediaType.isEmpty())
311 // detect media-type:
312 ::ucbhelper::Content ucbContent;
313 if (create_ucb_content( &ucbContent, url, xCmdEnv ))
315 const OUString title( StrTitle::getTitle( ucbContent ) );
316 if (title.endsWithIgnoreAsciiCase( ".xcu" )) {
317 mediaType = OUString("application/vnd.sun.star.configuration-data");
319 if (title.endsWithIgnoreAsciiCase( ".xcs" )) {
320 mediaType = OUString("application/vnd.sun.star.configuration-schema");
323 if (mediaType.isEmpty())
324 throw lang::IllegalArgumentException(
325 StrCannotDetectMediaType::get() + url,
326 static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
329 OUString type, subType;
330 INetContentTypeParameterList params;
331 if (INetContentTypes::parse( mediaType, type, subType, &params ))
333 if (type.equalsIgnoreAsciiCase("application"))
335 OUString name;
336 if (!bRemoved)
338 ::ucbhelper::Content ucbContent( url, xCmdEnv, m_xComponentContext );
339 name = StrTitle::getTitle( ucbContent );
342 ::ucbhelper::Content ucbContent( url, xCmdEnv, m_xComponentContext );
343 if (subType.equalsIgnoreAsciiCase( "vnd.sun.star.configuration-data"))
345 return new PackageImpl(
346 this, url, name, m_xConfDataTypeInfo, false /* data file */,
347 bRemoved, identifier);
349 else if (subType.equalsIgnoreAsciiCase( "vnd.sun.star.configuration-schema")) {
350 return new PackageImpl(
351 this, url, name, m_xConfSchemaTypeInfo, true /* schema file */,
352 bRemoved, identifier);
356 throw lang::IllegalArgumentException(
357 StrUnsupportedMediaType::get() + mediaType,
358 static_cast<OWeakObject *>(this),
359 static_cast<sal_Int16>(-1) );
363 //______________________________________________________________________________
364 void BackendImpl::configmgrini_verify_init(
365 Reference<XCommandEnvironment> const & xCmdEnv )
367 if (transientMode())
368 return;
369 const ::osl::MutexGuard guard( getMutex() );
370 if (! m_configmgrini_inited)
372 // common rc:
373 ::ucbhelper::Content ucb_content;
374 if (create_ucb_content(
375 &ucb_content,
376 makeURL( getCachePath(), "configmgr.ini" ),
377 xCmdEnv, false /* no throw */ ))
379 OUString line;
380 if (readLine( &line, "SCHEMA=", ucb_content,
381 RTL_TEXTENCODING_UTF8 ))
383 sal_Int32 index = RTL_CONSTASCII_LENGTH("SCHEMA=");
384 do {
385 OUString token( line.getToken( 0, ' ', index ).trim() );
386 if (!token.isEmpty()) {
387 //The file may not exist anymore if a shared or bundled
388 //extension was removed, but it can still be in the configmgrini.
389 //After running XExtensionManager::synchronize, the configmgrini is
390 //cleaned up
391 m_xcs_files.push_back( token );
394 while (index >= 0);
396 if (readLine( &line, "DATA=", ucb_content,
397 RTL_TEXTENCODING_UTF8 )) {
398 sal_Int32 index = RTL_CONSTASCII_LENGTH("DATA=");
399 do {
400 OUString token( line.getToken( 0, ' ', index ).trim() );
401 if (!token.isEmpty())
403 if (token[ 0 ] == '?')
404 token = token.copy( 1 );
405 //The file may not exist anymore if a shared or bundled
406 //extension was removed, but it can still be in the configmgrini.
407 //After running XExtensionManager::synchronize, the configmgrini is
408 //cleaned up
409 m_xcu_files.push_back( token );
412 while (index >= 0);
415 m_configmgrini_modified = false;
416 m_configmgrini_inited = true;
420 //______________________________________________________________________________
421 void BackendImpl::configmgrini_flush(
422 Reference<XCommandEnvironment> const & xCmdEnv )
424 if (transientMode())
425 return;
426 if (!m_configmgrini_inited || !m_configmgrini_modified)
427 return;
429 OStringBuffer buf;
430 if (! m_xcs_files.empty())
432 t_stringlist::const_iterator iPos( m_xcs_files.begin() );
433 t_stringlist::const_iterator const iEnd( m_xcs_files.end() );
434 buf.append( "SCHEMA=" );
435 while (iPos != iEnd) {
436 // encoded ASCII file-urls:
437 const OString item(
438 OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
439 buf.append( item );
440 ++iPos;
441 if (iPos != iEnd)
442 buf.append( ' ' );
444 buf.append(LF);
446 if (! m_xcu_files.empty())
448 t_stringlist::const_iterator iPos( m_xcu_files.begin() );
449 t_stringlist::const_iterator const iEnd( m_xcu_files.end() );
450 buf.append( "DATA=" );
451 while (iPos != iEnd) {
452 // encoded ASCII file-urls:
453 const OString item(
454 OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
455 buf.append( item );
456 ++iPos;
457 if (iPos != iEnd)
458 buf.append( ' ' );
460 buf.append(LF);
463 // write configmgr.ini:
464 const Reference<io::XInputStream> xData(
465 ::xmlscript::createInputStream(
466 ::rtl::ByteSequence(
467 reinterpret_cast<sal_Int8 const *>(buf.getStr()),
468 buf.getLength() ) ) );
469 ::ucbhelper::Content ucb_content(
470 makeURL( getCachePath(), "configmgr.ini" ), xCmdEnv, m_xComponentContext );
471 ucb_content.writeStream( xData, true /* replace existing */ );
473 m_configmgrini_modified = false;
476 //______________________________________________________________________________
477 bool BackendImpl::addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url_,
478 Reference<XCommandEnvironment> const & xCmdEnv )
480 const OUString rcterm( isURL ? dp_misc::makeRcTerm(url_) : url_ );
481 const ::osl::MutexGuard guard( getMutex() );
482 configmgrini_verify_init( xCmdEnv );
483 t_stringlist & rSet = getFiles(isSchema);
484 if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
485 rSet.push_front( rcterm ); // prepend to list, thus overriding
486 // write immediately:
487 m_configmgrini_modified = true;
488 configmgrini_flush( xCmdEnv );
489 return true;
491 else
492 return false;
495 //______________________________________________________________________________
496 bool BackendImpl::removeFromConfigmgrIni(
497 bool isSchema, OUString const & url_,
498 Reference<XCommandEnvironment> const & xCmdEnv )
500 const OUString rcterm( dp_misc::makeRcTerm(url_) );
501 const ::osl::MutexGuard guard( getMutex() );
502 configmgrini_verify_init( xCmdEnv );
503 t_stringlist & rSet = getFiles(isSchema);
504 t_stringlist::iterator i(std::find(rSet.begin(), rSet.end(), rcterm));
505 if (i == rSet.end() && !isSchema)
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 installatation.
511 ::boost::optional<ConfigurationBackendDb::Data> data = readDataFromDb(url_);
512 if (data)
513 i = std::find(rSet.begin(), rSet.end(), data->iniEntry);
515 if (i == rSet.end()) {
516 return false;
518 rSet.erase(i);
519 // write immediately:
520 m_configmgrini_modified = true;
521 configmgrini_flush( xCmdEnv );
522 return true;
526 // Package
527 //______________________________________________________________________________
529 BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
531 BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
532 if (NULL == pBackend)
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)));
541 return pBackend;
544 beans::Optional< beans::Ambiguous<sal_Bool> >
545 BackendImpl::PackageImpl::isRegistered_(
546 ::osl::ResettableMutexGuard &,
547 ::rtl::Reference<AbortChannel> const &,
548 Reference<XCommandEnvironment> const & )
550 BackendImpl * that = getMyBackend();
551 const OUString url(getURL());
553 bool bReg = false;
554 if (that->hasActiveEntry(getURL()))
555 bReg = true;
557 #if HAVE_FEATURE_EXTENSIONS
558 if (!bReg && that->m_registeredPackages.get())
560 // fallback for user extension registered in berkeley DB
561 bReg = that->m_registeredPackages->has(
562 OUStringToOString( url, RTL_TEXTENCODING_UTF8 ));
564 #endif
565 return beans::Optional< beans::Ambiguous<sal_Bool> >(
566 true, beans::Ambiguous<sal_Bool>( bReg, false ) );
569 //------------------------------------------------------------------------------
570 OUString encodeForXml( OUString const & text )
572 // encode conforming xml:
573 sal_Int32 len = text.getLength();
574 OUStringBuffer buf;
575 for ( sal_Int32 pos = 0; pos < len; ++pos )
577 sal_Unicode c = text[ pos ];
578 switch (c) {
579 case '<':
580 buf.appendAscii( "&lt;" );
581 break;
582 case '>':
583 buf.appendAscii( "&gt;" );
584 break;
585 case '&':
586 buf.appendAscii( "&amp;" );
587 break;
588 case '\'':
589 buf.appendAscii( "&apos;" );
590 break;
591 case '\"':
592 buf.appendAscii( "&quot;" );
593 break;
594 default:
595 buf.append( c );
596 break;
599 return buf.makeStringAndClear();
602 //______________________________________________________________________________
603 OUString replaceOrigin(
604 OUString const & url, OUString const & destFolder, Reference< XCommandEnvironment > const & xCmdEnv, Reference< XComponentContext > const & xContext, bool & out_replaced)
606 // looking for %origin%:
607 ::ucbhelper::Content ucb_content( url, xCmdEnv, xContext );
608 ::rtl::ByteSequence bytes( readFile( ucb_content ) );
609 ::rtl::ByteSequence filtered( bytes.getLength() * 2,
610 ::rtl::BYTESEQ_NODEFAULT );
611 bool use_filtered = false;
612 OString origin;
613 sal_Char const * pBytes = reinterpret_cast<sal_Char const *>(
614 bytes.getConstArray());
615 sal_Size nBytes = bytes.getLength();
616 sal_Int32 write_pos = 0;
617 while (nBytes > 0)
619 sal_Int32 index = rtl_str_indexOfChar_WithLength( pBytes, nBytes, '%' );
620 if (index < 0) {
621 if (! use_filtered) // opt
622 break;
623 index = nBytes;
626 if ((write_pos + index) > filtered.getLength())
627 filtered.realloc( (filtered.getLength() + index) * 2 );
628 memcpy( filtered.getArray() + write_pos, pBytes, index );
629 write_pos += index;
630 pBytes += index;
631 nBytes -= index;
632 if (nBytes == 0)
633 break;
635 // consume %:
636 ++pBytes;
637 --nBytes;
638 sal_Char const * pAdd = "%";
639 sal_Int32 nAdd = 1;
640 if (nBytes > 1 && pBytes[ 0 ] == '%')
642 // %% => %
643 ++pBytes;
644 --nBytes;
645 use_filtered = true;
647 else if (rtl_str_shortenedCompare_WithLength(
648 pBytes, nBytes,
649 "origin%",
650 RTL_CONSTASCII_LENGTH("origin%"),
651 RTL_CONSTASCII_LENGTH("origin%")) == 0)
653 if (origin.isEmpty()) {
654 // encode only once
655 origin = OUStringToOString(
656 encodeForXml( url.copy( 0, url.lastIndexOf( '/' ) ) ),
657 // xxx todo: encode always for UTF-8? => lookup doc-header?
658 RTL_TEXTENCODING_UTF8 );
660 pAdd = origin.getStr();
661 nAdd = origin.getLength();
662 pBytes += RTL_CONSTASCII_LENGTH("origin%");
663 nBytes -= RTL_CONSTASCII_LENGTH("origin%");
664 use_filtered = true;
666 if ((write_pos + nAdd) > filtered.getLength())
667 filtered.realloc( (filtered.getLength() + nAdd) * 2 );
668 memcpy( filtered.getArray() + write_pos, pAdd, nAdd );
669 write_pos += nAdd;
671 if (!use_filtered)
672 return url;
673 if (write_pos < filtered.getLength())
674 filtered.realloc( write_pos );
675 OUString newUrl(url);
676 if (!destFolder.isEmpty())
678 //get the file name of the xcu and add it to the url of the temporary folder
679 sal_Int32 i = url.lastIndexOf('/');
680 newUrl = destFolder + url.copy(i);
683 ucbhelper::Content(newUrl, xCmdEnv, xContext).writeStream(
684 xmlscript::createInputStream(filtered), true);
685 out_replaced = true;
686 return newUrl;
689 //______________________________________________________________________________
690 void BackendImpl::PackageImpl::processPackage_(
691 ::osl::ResettableMutexGuard &,
692 bool doRegisterPackage,
693 bool startup,
694 ::rtl::Reference<AbortChannel> const &,
695 Reference<XCommandEnvironment> const & xCmdEnv )
697 BackendImpl * that = getMyBackend();
698 OUString url( getURL() );
700 if (doRegisterPackage)
702 if (getMyBackend()->activateEntry(getURL()))
704 ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
705 OSL_ASSERT(data);
706 that->addToConfigmgrIni( m_isSchema, false, data->iniEntry, xCmdEnv );
708 else
710 ConfigurationBackendDb::Data data;
711 if (!m_isSchema)
713 const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
714 bool out_replaced = false;
715 url = replaceOrigin(url, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
716 if (out_replaced)
717 data.dataUrl = sModFolder;
718 else
719 deleteTempFolder(sModFolder);
721 //No need for live-deployment for bundled extension, because OOo
722 //restarts after installation
723 if (that->m_eContext != CONTEXT_BUNDLED
724 && !startup)
726 if (m_isSchema)
728 com::sun::star::configuration::Update::get(
729 that->m_xComponentContext)->insertExtensionXcsFile(
730 that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
732 else
734 com::sun::star::configuration::Update::get(
735 that->m_xComponentContext)->insertExtensionXcuFile(
736 that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
739 that->addToConfigmgrIni( m_isSchema, true, url, xCmdEnv );
740 data.iniEntry = dp_misc::makeRcTerm(url);
741 that->addDataToDb(getURL(), data);
744 else // revoke
746 #if HAVE_FEATURE_EXTENSIONS
747 if (!that->removeFromConfigmgrIni(m_isSchema, url, xCmdEnv) &&
748 that->m_registeredPackages.get()) {
749 // Obsolete package database handling - should be removed for LibreOffice 4.0
750 t_string2string_map entries(
751 that->m_registeredPackages->getEntries());
752 for (t_string2string_map::iterator i(entries.begin());
753 i != entries.end(); ++i)
755 //If the xcu file was installed before the configmgr was chaned
756 //to use the configmgr.ini, one needed to rebuild to whole directory
757 //structur containing the xcu, xcs files from all extensions. Now,
758 //we just add all other xcu/xcs files to the configmgr.ini instead of
759 //rebuilding the directory structure.
760 OUString url2(
761 OStringToOUString(i->first, RTL_TEXTENCODING_UTF8));
762 if (url2 != url) {
763 bool schema = i->second.equalsIgnoreAsciiCase(
764 "vnd.sun.star.configuration-schema");
765 OUString url_replaced(url2);
766 ConfigurationBackendDb::Data data;
767 if (!schema)
769 const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
770 bool out_replaced = false;
771 url_replaced = replaceOrigin(
772 url2, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
773 if (out_replaced)
774 data.dataUrl = sModFolder;
775 else
776 deleteTempFolder(sModFolder);
778 that->addToConfigmgrIni(schema, true, url_replaced, xCmdEnv);
779 data.iniEntry = dp_misc::makeRcTerm(url_replaced);
780 that->addDataToDb(url2, data);
782 that->m_registeredPackages->erase(i->first);
786 ::ucbhelper::Content(
787 makeURL( that->getCachePath(), "registry" ),
788 xCmdEnv, that->getComponentContext() ).executeCommand(
789 "delete", Any( true /* delete physically */ ) );
791 catch(const Exception&)
793 OSL_ASSERT(0);
796 #endif
797 ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
798 //If an xcu file was life deployed then always a data entry is written.
799 //If the xcu file was already in the configmr.ini then there is also
800 //a data entry
801 if (!m_isSchema && data)
803 com::sun::star::configuration::Update::get(
804 that->m_xComponentContext)->removeExtensionXcuFile(expandUnoRcTerm(data->iniEntry));
806 that->revokeEntryFromDb(url);
810 } // anon namespace
812 namespace sdecl = comphelper::service_decl;
813 sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
814 extern sdecl::ServiceDecl const serviceDecl(
815 serviceBI,
816 "com.sun.star.comp.deployment.configuration.PackageRegistryBackend",
817 BACKEND_SERVICE_NAME );
819 } // namespace configuration
820 } // namespace backend
821 } // namespace dp_registry
823 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */