summaryrefslogtreecommitdiff
path: root/configmgr
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2015-08-28 13:49:56 +0200
committerStephan Bergmann <sbergman@redhat.com>2015-09-01 15:06:44 +0200
commit12f92e6d9ea8bf05bda6d3c42f9b6f0aba000cb0 (patch)
tree6d60a95bfe2eded30cc1e7af536a2c4db495cd9e /configmgr
parentaefb3d973c8248b8c60149850f0835e4a8abd85d (diff)
Support modification write-back to other than registrymodifications.xcu
...to eventually support writing to dconf (see TODO). Even when writing somewhere else, it may still be useful to read from the current "user:" location, so a new convention was introduced to CONFIGURATION_LAYERS types that support write-back: - A leading "!" indicates that the layer is indeed used for write-back (probably in addition to reading from it). For backwards compatibility (when users use own settings of CONFIGURATION_LAYERS, instead of depending on the value in the shipped fundamental ini-file), no prefix on the "user:" is now interpreted the same as a "!" prefix. - A leading "*" indicates that the layer is not used for write-back (but only for reading from it). Change-Id: I399cc7bfe927db50586834f9630c184aaa2153f2
Diffstat (limited to 'configmgr')
-rw-r--r--configmgr/source/components.cxx61
-rw-r--r--configmgr/source/components.hxx5
2 files changed, 48 insertions, 18 deletions
diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx
index b3c8acb71c92..d6f7144f58df 100644
--- a/configmgr/source/components.cxx
+++ b/configmgr/source/components.cxx
@@ -279,12 +279,21 @@ void Components::addModification(Path const & path) {
void Components::writeModifications() {
- if (!(data_.modifications.empty() || modificationFileUrl_.isEmpty()
- || writeThread_.is()))
- {
- writeThread_ = new WriteThread(
- &writeThread_, *this, modificationFileUrl_, data_);
- writeThread_->launch();
+ if (!data_.modifications.empty()) {
+ switch (modificationTarget_) {
+ case ModificationTarget::None:
+ break;
+ case ModificationTarget::File:
+ if (!writeThread_.is()) {
+ writeThread_ = new WriteThread(
+ &writeThread_, *this, modificationFileUrl_, data_);
+ writeThread_->launch();
+ }
+ break;
+ case ModificationTarget::Dconf:
+ //TODO
+ break;
+ }
}
}
@@ -455,7 +464,8 @@ css::beans::Optional< css::uno::Any > Components::getExternalValue(
Components::Components(
css::uno::Reference< css::uno::XComponentContext > const & context):
- context_(context), sharedExtensionLayer_(-1), userExtensionLayer_(-1)
+ context_(context), sharedExtensionLayer_(-1), userExtensionLayer_(-1),
+ modificationTarget_(ModificationTarget::None)
{
assert(context.is());
lock_ = lock();
@@ -468,9 +478,10 @@ Components::Components(
if (i == conf.getLength()) {
break;
}
- if (!modificationFileUrl_.isEmpty()) {
+ if (modificationTarget_ != ModificationTarget::None) {
throw css::uno::RuntimeException(
- "CONFIGURATION_LAYERS: \"user\" followed by further layers");
+ "CONFIGURATION_LAYERS: modification target layer followed by"
+ " further layers");
}
sal_Int32 c = i;
for (;; ++c) {
@@ -522,11 +533,15 @@ Components::Components(
++layer; //TODO: overflow
#if ENABLE_DCONF
} else if (type == "dconf") {
- if (!url.isEmpty()) {
+ if (url == "!") {
+ modificationTarget_ = ModificationTarget::Dconf;
+ } else if (url == "*") {
+ readDconfLayer(data_, layer);
+ } else {
throw css::uno::RuntimeException(
- "CONFIGURATION_LAYERS: non-empty \"dconf\" URL");
+ "CONFIGURATION_LAYERS: unknown \"dconf\" kind \"" + url
+ + "\"");
}
- readDconfLayer(data_, layer);
++layer; //TODO: overflow
#endif
#if defined WNT
@@ -549,12 +564,24 @@ Components::Components(
++layer; //TODO: overflow
#endif
} else if (type == "user") {
+ bool write;
+ if (url.startsWith("!", &url)) {
+ write = true;
+ } else if (url.startsWith("*", &url)) {
+ write = false;
+ } else {
+ write = true; // for backwards compatibility
+ }
if (url.isEmpty()) {
throw css::uno::RuntimeException(
"CONFIGURATION_LAYERS: empty \"user\" URL");
}
- modificationFileUrl_ = url;
- parseModificationLayer(url);
+ if (write) {
+ modificationTarget_ = ModificationTarget::File;
+ modificationFileUrl_ = url;
+ }
+ parseModificationLayer(write ? Data::NO_LAYER : layer, url);
+ ++layer; //TODO: overflow
} else {
throw css::uno::RuntimeException(
"CONFIGURATION_LAYERS: unknown layer type \"" + type + "\"");
@@ -789,9 +816,9 @@ void Components::parseResLayer(int layer, OUString const & url) {
parseFiles(layer, ".xcu", &parseXcuFile, resUrl, false);
}
-void Components::parseModificationLayer(OUString const & url) {
+void Components::parseModificationLayer(int layer, OUString const & url) {
try {
- parseFileLeniently(&parseXcuFile, url, Data::NO_LAYER, 0, 0, 0);
+ parseFileLeniently(&parseXcuFile, url, layer, 0, 0, 0);
} catch (css::container::NoSuchElementException &) {
SAL_INFO(
"configmgr", "user registrymodifications.xcu does not (yet) exist");
@@ -799,7 +826,7 @@ void Components::parseModificationLayer(OUString const & url) {
// longer relevant, probably OOo 4; also see hack for xsi namespace in
// xmlreader::XmlReader::registerNamespaceIri):
parseFiles(
- Data::NO_LAYER, ".xcu", &parseXcuFile,
+ layer, ".xcu", &parseXcuFile,
expand(
"${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap")
":UserInstallation}/user/registry/data"),
diff --git a/configmgr/source/components.hxx b/configmgr/source/components.hxx
index 25d0d6e05cfc..43e682e7757e 100644
--- a/configmgr/source/components.hxx
+++ b/configmgr/source/components.hxx
@@ -139,7 +139,7 @@ private:
void parseResLayer(int layer, OUString const & url);
- void parseModificationLayer(OUString const & url);
+ void parseModificationLayer(int layer, OUString const & url);
int getExtensionLayer(bool shared);
@@ -153,6 +153,8 @@ private:
class WriteThread;
+ enum class ModificationTarget { None, File, Dconf };
+
css::uno::Reference< css::uno::XComponentContext >
context_;
Data data_;
@@ -161,6 +163,7 @@ private:
rtl::Reference< WriteThread > writeThread_;
int sharedExtensionLayer_;
int userExtensionLayer_;
+ ModificationTarget modificationTarget_;
OUString modificationFileUrl_;
std::shared_ptr<osl::Mutex> lock_;
};