From c34e9439e89c9af3d12e4d82591b565935357eda Mon Sep 17 00:00:00 2001 From: Justin Luth Date: Thu, 11 Dec 2014 21:51:03 +0300 Subject: [PATCH] fdo#69609 import registrymodification.xcu from presets folder ToDo1: either find out how to use PATH_SEPARATOR variable, or get confirmation that "/" is the correct way to do it and that functions will handle platform differences. Ensure that I am using the necessary file functions. ToDo2: find out if there is a variable for registrymodifications.xcu ToDo3: add more exclusions to prune user-specific settings from the generic profile. ToDo4: verify that I have all the required #includes to compile as a single module, proper programming styles etc. - Change-Id: I28bc81a26587409f87ad5b1c97cc0f0ef4410eab --- desktop/source/app/userinstall.cxx | 200 +++++++++++++++++++++++++++++++++++-- desktop/source/app/userinstall.hxx | 27 +++++ 2 files changed, 218 insertions(+), 9 deletions(-) diff --git a/desktop/source/app/userinstall.cxx b/desktop/source/app/userinstall.cxx index ef0b0a1..804c0de 100644 --- a/desktop/source/app/userinstall.cxx +++ b/desktop/source/app/userinstall.cxx @@ -33,6 +33,14 @@ #include #include "userinstall.hxx" +#include +#include + + +using namespace com::sun::star; //configuration::Update +using namespace com::sun::star::lang; //XMultiServiceFactory +using namespace com::sun::star::container; //XNameAccess + namespace desktop { namespace userinstall { @@ -130,10 +138,24 @@ Status create(OUString const & uri) { return ERROR_OTHER; } #endif + + //haven't found a SYSTEM-VARIABLE for the name registrymodifications.xcu + //don't know how to use PATH_SEPARATOR + OUString presetsXCUFilePath = baseUri + "/" + LIBO_SHARE_PRESETS_FOLDER + "/" + "registrymodifications.xcu"; + osl::File presetsXCUFile(presetsXCUFilePath); + ::osl::FileBase::RC nPresetError = presetsXCUFile.open(osl_File_OpenFlag_Read); + if ( nPresetError == ::osl::FileBase::E_None ) + { + RegistryModificationsImpl aImpl; + aImpl.importRegistryModifications (presetsXCUFilePath); + } + presetsXCUFile.close(); + boost::shared_ptr batch( comphelper::ConfigurationChanges::create()); officecfg::Setup::Office::ooSetupInstCompleted::set(true, batch); batch->commit(); + return CREATED; } @@ -150,19 +172,179 @@ bool isCreated() { Status finalize() { OUString uri; - switch (utl::Bootstrap::locateUserInstallation(uri)) { - case utl::Bootstrap::PATH_EXISTS: - if (isCreated()) { - return EXISTED; + switch (utl::Bootstrap::locateUserInstallation(uri)) + { + case utl::Bootstrap::PATH_EXISTS: + if (isCreated()) + { + return EXISTED; + } + // fall through + case utl::Bootstrap::PATH_VALID: + return create(uri); + default: + return ERROR_OTHER; + } +} + +bool getComponent(OUString const & path, OUString * component) { + OSL_ASSERT(component != 0); + if (path.isEmpty() || path[0] != '/') { + OSL_TRACE( + ("configuration migration in/exclude path %s ignored (does not" + " start with slash)"), + OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr()); + return false; + } + sal_Int32 i = path.indexOf('/', 1); + *component = i < 0 ? path.copy(1) : path.copy(1, i - 1); + return true; +} + +uno::Sequence< OUString > setToSeq(std::set< OUString > const & set) { + std::set< OUString >::size_type n = set.size(); + if (n > SAL_MAX_INT32) { + throw std::bad_alloc(); + } + uno::Sequence< OUString > seq(static_cast< sal_Int32 >(n)); + sal_Int32 i = 0; + for (std::set< OUString >::const_iterator j(set.begin()); + j != set.end(); ++j) + { + seq[i++] = *j; + } + return seq; +} + + +RegistryModificationsImpl::RegistryModificationsImpl() +{ +} + +RegistryModificationsImpl::~RegistryModificationsImpl() +{ +} + + +bool RegistryModificationsImpl::importRegistryModifications (OUString& url) { + Components comps = readMigrationSteps(readAvailableMigrations()); + + comps["org.openoffice.Office.Common"].excludedPaths.insert("/org.openoffice.Office.Common/History"); + comps["org.openoffice.Office.Histories"].excludedPaths.insert("/org.openoffice.Office.Histories"); + comps["org.openoffice.Office.Recovery"].excludedPaths.insert("/org.openoffice.Office.Recovery"); + comps["org.openoffice.UserProfile"].excludedPaths.insert("/org.openoffice.Office.UserProfile/Data"); + + for (Components::const_iterator i(comps.begin()); i != comps.end(); ++i) + { + if (!i->second.includedPaths.empty()) + { + configuration::Update::get(comphelper::getProcessComponentContext()) + ->insertModificationXcuFile(url, + setToSeq(i->second.includedPaths), + setToSeq(i->second.excludedPaths)); } - // fall through - case utl::Bootstrap::PATH_VALID: - return create(uri); - default: - return ERROR_OTHER; } + return CREATED; } +OUString RegistryModificationsImpl::readAvailableMigrations() +{ + OUString preferredVersion; + sal_Int32 preferredPriority = 0; + + uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW); + uno::Sequence< OUString > seqSupportedVersions = aMigrationAccess->getElementNames(); + + for (sal_Int32 i=0; i xMigrationData( aMigrationAccess->getByName(seqSupportedVersions[i]), uno::UNO_QUERY_THROW ); + xMigrationData->getByName( "Priority" ) >>= nPriority; + if (nPriority > preferredPriority) + { + preferredVersion = seqSupportedVersions[i]; + preferredPriority = nPriority; + } + } + return preferredVersion; +} + +uno::Reference< XNameAccess > RegistryModificationsImpl::getConfigAccess(const sal_Char* pPath, bool bUpdate) +{ + uno::Reference< XNameAccess > xNameAccess; + try + { + OUString sAccessSrvc; + if (bUpdate) + sAccessSrvc = "com.sun.star.configuration.ConfigurationUpdateAccess"; + else + sAccessSrvc = "com.sun.star.configuration.ConfigurationAccess"; + + OUString sConfigURL = OUString::createFromAscii(pPath); + + uno::Reference< XMultiServiceFactory > theConfigProvider( + configuration::theDefaultProvider::get( + comphelper::getProcessComponentContext())); + + // access the provider + uno::Sequence< uno::Any > theArgs(1); + theArgs[ 0 ] <<= sConfigURL; + xNameAccess = uno::Reference< XNameAccess > ( + theConfigProvider->createInstanceWithArguments( + sAccessSrvc, theArgs ), uno::UNO_QUERY_THROW ); + } + catch (const com::sun::star::uno::Exception& e) + { + SAL_WARN( + "desktop.migration", "ignoring Exception \"" << e.Message << "\""); + } + return xNameAccess; +} + +Components RegistryModificationsImpl::readMigrationSteps(const OUString& rMigrationName) +{ + Components comps; + + // get migration access + uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW); + uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(rMigrationName), uno::UNO_QUERY_THROW ); + + // get migration description from from org.openoffice.Setup/Migration + // and build vector of migration steps + OUString aMigrationSteps( "MigrationSteps" ); + uno::Reference< XNameAccess > theNameAccess(xMigrationData->getByName(aMigrationSteps), uno::UNO_QUERY_THROW); + uno::Sequence< OUString > seqMigrations = theNameAccess->getElementNames(); + uno::Reference< XNameAccess > tmpAccess; + uno::Sequence< OUString > tmpSeq; + for (sal_Int32 i = 0; i < seqMigrations.getLength(); i++) + { + // get current migration step + theNameAccess->getByName(seqMigrations[i]) >>= tmpAccess; + + // included nodes... + if (tmpAccess->getByName("IncludedNodes") >>= tmpSeq) + { + for (sal_Int32 j=0; jgetByName("ExcludedNodes") >>= tmpSeq) + { + for (sal_Int32 j=0; j +#include +#include //std:map + namespace desktop { namespace userinstall { @@ -32,8 +35,32 @@ enum Status { ERROR_OTHER }; +struct componentParts { + std::set< OUString > includedPaths; + std::set< OUString > excludedPaths; +}; + +typedef std::map< OUString, componentParts > Components; + + Status finalize(); + +class RegistryModificationsImpl +{ +private: + // functions to control the migration process + OUString readAvailableMigrations(); + Components readMigrationSteps(const OUString& rMigrationName); + + css::uno::Reference< css::container::XNameAccess > getConfigAccess(const sal_Char* path, bool rw=false); + +public: + RegistryModificationsImpl(); + ~RegistryModificationsImpl(); + bool importRegistryModifications( OUString& baseUri); +}; + } } #endif -- 1.9.1