Make comphelper/configuration.hxx work for localized properties
See aebf5bf223
"fdo#52232 ConfigurationSet wrapper
unusable for localized properties" for a discussion of the problems with the
original design.
1 Redesigned configmgr's localized property access to understand ['*<locale>']
paths that select the best existing value match for the requested <locale>.
Adapted ConfigurationWrapper::getLocalizedPropertyValue accordingly.
2 Redesigned ConfigurationChanges to fix the locale at instantiation time.
That takes care of ConfigurationWrapper::setLocalizedPropertyValue,
ConfigurationWrapper::getGroupReadWrite, and
ConfigurationWrapper::getSetReadWrite. (This required an additional constructor
parameter for the ReadWriteAccess service, to specify a locale at instantiation
time.)
3 Redesigned ReadOnlyAccess to be a service that fixes the locale at
instantiation time. That allows to take care of
ConfigurationWrapper::getGroupReadOnly and ConfigurationWrapper::getSetReadOnly.
Change-Id: I2ae7342b278b6f4222a0189a1deb2a53e204059f
This commit is contained in:
@@ -148,8 +148,6 @@ public:
|
||||
boost::shared_ptr< ConfigurationChanges > createChanges() const;
|
||||
|
||||
private:
|
||||
rtl::OUString extendLocalizedPath(rtl::OUString const & path) const;
|
||||
|
||||
com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
|
||||
context_;
|
||||
|
||||
|
@@ -64,6 +64,51 @@ struct TheConfigurationWrapper:
|
||||
TheConfigurationWrapper >
|
||||
{};
|
||||
|
||||
OUString getDefaultLocale(
|
||||
css::uno::Reference< css::uno::XComponentContext > const & context)
|
||||
{
|
||||
css::lang::Locale locale(
|
||||
css::uno::Reference< css::lang::XLocalizable >(
|
||||
css::configuration::theDefaultProvider::get(context),
|
||||
css::uno::UNO_QUERY_THROW)->
|
||||
getLocale());
|
||||
OUStringBuffer buf;
|
||||
SAL_WARN_IF(
|
||||
locale.Language.indexOf('-') != -1, "comphelper",
|
||||
"Locale language \"" << locale.Language << "\" contains \"-\"");
|
||||
buf.append(locale.Language);
|
||||
SAL_WARN_IF(
|
||||
locale.Country.isEmpty() && !locale.Variant.isEmpty(), "comphelper",
|
||||
"Locale has empty country but non-empty variant \"" << locale.Variant
|
||||
<< '"');
|
||||
if (!locale.Country.isEmpty()) {
|
||||
buf.append('-');
|
||||
SAL_WARN_IF(
|
||||
locale.Country.indexOf('-') != -1, "comphelper",
|
||||
"Locale language \"" << locale.Country << "\" contains \"-\"");
|
||||
buf.append(locale.Country);
|
||||
if (!locale.Variant.isEmpty()) {
|
||||
buf.append('-');
|
||||
buf.append(locale.Variant);
|
||||
}
|
||||
}
|
||||
return buf.makeStringAndClear();
|
||||
}
|
||||
|
||||
OUString extendLocalizedPath(OUString const & path, OUString const & locale) {
|
||||
rtl::OUStringBuffer buf(path);
|
||||
buf.append("/['*");
|
||||
SAL_WARN_IF(
|
||||
locale.match("*"), "comphelper",
|
||||
"Locale \"" << locale << "\" starts with \"-\"");
|
||||
assert(locale.indexOf('&') == -1);
|
||||
assert(locale.indexOf('"') == -1);
|
||||
assert(locale.indexOf('\'') == -1);
|
||||
buf.append(locale);
|
||||
buf.append("']");
|
||||
return buf.makeStringAndClear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boost::shared_ptr< comphelper::ConfigurationChanges >
|
||||
@@ -82,7 +127,9 @@ void comphelper::ConfigurationChanges::commit() const {
|
||||
|
||||
comphelper::ConfigurationChanges::ConfigurationChanges(
|
||||
css::uno::Reference< css::uno::XComponentContext > const & context):
|
||||
access_(css::configuration::ReadWriteAccess::create(context))
|
||||
access_(
|
||||
css::configuration::ReadWriteAccess::create(
|
||||
context, getDefaultLocale(context)))
|
||||
{}
|
||||
|
||||
void comphelper::ConfigurationChanges::setPropertyValue(
|
||||
@@ -114,7 +161,8 @@ comphelper::detail::ConfigurationWrapper::get(
|
||||
|
||||
comphelper::detail::ConfigurationWrapper::ConfigurationWrapper(
|
||||
css::uno::Reference< css::uno::XComponentContext > const & context):
|
||||
context_(context), access_(css::configuration::ReadOnlyAccess::get(context))
|
||||
context_(context),
|
||||
access_(css::configuration::ReadOnlyAccess::create(context, "*"))
|
||||
{}
|
||||
|
||||
comphelper::detail::ConfigurationWrapper::~ConfigurationWrapper() {}
|
||||
@@ -137,7 +185,8 @@ css::uno::Any
|
||||
comphelper::detail::ConfigurationWrapper::getLocalizedPropertyValue(
|
||||
rtl::OUString const & path) const
|
||||
{
|
||||
return access_->getByHierarchicalName(extendLocalizedPath(path));
|
||||
return access_->getByHierarchicalName(
|
||||
extendLocalizedPath(path, getDefaultLocale(context_)));
|
||||
}
|
||||
|
||||
void comphelper::detail::ConfigurationWrapper::setLocalizedPropertyValue(
|
||||
@@ -145,7 +194,7 @@ void comphelper::detail::ConfigurationWrapper::setLocalizedPropertyValue(
|
||||
rtl::OUString const & path, com::sun::star::uno::Any const & value) const
|
||||
{
|
||||
assert(batch.get() != 0);
|
||||
batch->setPropertyValue(extendLocalizedPath(path), value);
|
||||
batch->setPropertyValue(path, value);
|
||||
}
|
||||
|
||||
css::uno::Reference< css::container::XHierarchicalNameAccess >
|
||||
@@ -153,7 +202,10 @@ comphelper::detail::ConfigurationWrapper::getGroupReadOnly(
|
||||
rtl::OUString const & path) const
|
||||
{
|
||||
return css::uno::Reference< css::container::XHierarchicalNameAccess >(
|
||||
access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
|
||||
(css::configuration::ReadOnlyAccess::create(
|
||||
context_, getDefaultLocale(context_))->
|
||||
getByHierarchicalName(path)),
|
||||
css::uno::UNO_QUERY_THROW);
|
||||
}
|
||||
|
||||
css::uno::Reference< css::container::XHierarchicalNameReplace >
|
||||
@@ -170,7 +222,10 @@ comphelper::detail::ConfigurationWrapper::getSetReadOnly(
|
||||
rtl::OUString const & path) const
|
||||
{
|
||||
return css::uno::Reference< css::container::XNameAccess >(
|
||||
access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
|
||||
(css::configuration::ReadOnlyAccess::create(
|
||||
context_, getDefaultLocale(context_))->
|
||||
getByHierarchicalName(path)),
|
||||
css::uno::UNO_QUERY_THROW);
|
||||
}
|
||||
|
||||
css::uno::Reference< css::container::XNameContainer >
|
||||
@@ -188,46 +243,4 @@ comphelper::detail::ConfigurationWrapper::createChanges() const {
|
||||
new ConfigurationChanges(context_));
|
||||
}
|
||||
|
||||
rtl::OUString comphelper::detail::ConfigurationWrapper::extendLocalizedPath(
|
||||
rtl::OUString const & path) const
|
||||
{
|
||||
rtl::OUStringBuffer buf(path);
|
||||
buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("/['"));
|
||||
css::lang::Locale locale(
|
||||
css::uno::Reference< css::lang::XLocalizable >(
|
||||
css::configuration::theDefaultProvider::get(context_),
|
||||
css::uno::UNO_QUERY_THROW)->
|
||||
getLocale());
|
||||
SAL_WARN_IF(
|
||||
locale.Language.indexOf('-') != -1, "comphelper",
|
||||
"Locale language \"" << locale.Language << "\" contains \"-\"");
|
||||
assert(locale.Language.indexOf('&') == -1);
|
||||
assert(locale.Language.indexOf('"') == -1);
|
||||
assert(locale.Language.indexOf('\'') == -1);
|
||||
buf.append(locale.Language);
|
||||
SAL_WARN_IF(
|
||||
locale.Country.isEmpty() && !locale.Variant.isEmpty(), "comphelper",
|
||||
"Locale has empty country but non-empty variant \"" << locale.Variant
|
||||
<< '"');
|
||||
if (!locale.Country.isEmpty()) {
|
||||
buf.append('-');
|
||||
SAL_WARN_IF(
|
||||
locale.Country.indexOf('-') != -1, "comphelper",
|
||||
"Locale language \"" << locale.Country << "\" contains \"-\"");
|
||||
assert(locale.Country.indexOf('&') == -1);
|
||||
assert(locale.Country.indexOf('"') == -1);
|
||||
assert(locale.Country.indexOf('\'') == -1);
|
||||
buf.append(locale.Country);
|
||||
if (!locale.Variant.isEmpty()) {
|
||||
buf.append('-');
|
||||
assert(locale.Variant.indexOf('&') == -1);
|
||||
assert(locale.Variant.indexOf('"') == -1);
|
||||
assert(locale.Variant.indexOf('\'') == -1);
|
||||
buf.append(locale.Variant);
|
||||
}
|
||||
}
|
||||
buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("']"));
|
||||
return buf.makeStringAndClear();
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
@@ -1484,6 +1484,81 @@ rtl::Reference< Node > Access::getParentNode() {
|
||||
}
|
||||
|
||||
rtl::Reference< ChildAccess > Access::getChild(rtl::OUString const & name) {
|
||||
if (getNode()->kind() == Node::KIND_LOCALIZED_PROPERTY && name.match("*")) {
|
||||
OUString locale(name.copy(1));
|
||||
if (locale.match("*")) {
|
||||
SAL_WARN(
|
||||
"configmgr",
|
||||
("access best-matching localized property value via"
|
||||
" \"*<locale>\" with <locale> \"")
|
||||
<< locale << "\" recursively starting with \"*\"");
|
||||
return getChild(locale);
|
||||
}
|
||||
SAL_WARN_IF(
|
||||
locale.isEmpty(), "configmgr",
|
||||
("access best-matching localized property value via \"*<locale>\""
|
||||
" with empty <locale>; falling back to defaults"));
|
||||
if (!locale.isEmpty()) {
|
||||
// Find best match using an adaption of RFC 4647 lookup matching
|
||||
// rules, removing "-" or "_" delimited segments from the end:
|
||||
for (;;) {
|
||||
rtl::Reference< ChildAccess > child(getChild(locale));
|
||||
if (child.is()) {
|
||||
return child;
|
||||
}
|
||||
sal_Int32 i = locale.getLength() - 1;
|
||||
while (i > 0 && locale[i] != '-' && locale[i] != '_') {
|
||||
--i;
|
||||
}
|
||||
if (i <= 0) {
|
||||
break;
|
||||
}
|
||||
locale = locale.copy(0, i);
|
||||
}
|
||||
// As a workaround for broken xcu data that does not use shortest
|
||||
// xml:lang attributes, look for the first entry with the same first
|
||||
// segment as the requested language tag before falling back to
|
||||
// defaults (see fdo#33638):
|
||||
assert(
|
||||
!locale.isEmpty() && locale.indexOf('-') == -1 &&
|
||||
locale.indexOf('_') == -1);
|
||||
std::vector< rtl::Reference< ChildAccess > > children(
|
||||
getAllChildren());
|
||||
for (std::vector< rtl::Reference< ChildAccess > >::iterator i(
|
||||
children.begin());
|
||||
i != children.end(); ++i)
|
||||
{
|
||||
OUString name2((*i)->getNameInternal());
|
||||
if (name2.match(locale) &&
|
||||
(name2.getLength() == locale.getLength() ||
|
||||
name2[locale.getLength()] == '-' ||
|
||||
name2[locale.getLength()] == '_'))
|
||||
{
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Defaults are the "en-US" locale, the "en" locale, the empty string
|
||||
// locale, the first child (if any), or a null ChildAccess, in that
|
||||
// order:
|
||||
rtl::Reference< ChildAccess > child(getChild("en-US"));
|
||||
if (child.is()) {
|
||||
return child;
|
||||
}
|
||||
child = getChild("en");
|
||||
if (child.is()) {
|
||||
return child;
|
||||
}
|
||||
child = getChild(OUString());
|
||||
if (child.is()) {
|
||||
return child;
|
||||
}
|
||||
std::vector< rtl::Reference< ChildAccess > > children(getAllChildren());
|
||||
if (!children.empty()) {
|
||||
return children.front();
|
||||
}
|
||||
return rtl::Reference< ChildAccess >();
|
||||
}
|
||||
ModifiedChildren::iterator i(modifiedChildren_.find(name));
|
||||
return i == modifiedChildren_.end()
|
||||
? getUnmodifiedChild(name) : getModifiedChild(i);
|
||||
|
@@ -259,17 +259,6 @@ void ChildAccess::setProperty(
|
||||
localModifications->add(getRelativePath());
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
rtl::OUString lcl_StripSegment(const rtl::OUString &rLocale)
|
||||
{
|
||||
sal_Int32 i = !rLocale.isEmpty() ? rLocale.getLength() - 1 : 0;
|
||||
while (i > 0 && rLocale[i] != '-' && rLocale[i] != '_')
|
||||
--i;
|
||||
return rLocale.copy(0, i);
|
||||
}
|
||||
}
|
||||
|
||||
css::uno::Any ChildAccess::asValue() {
|
||||
if (changedValue_.get() != 0) {
|
||||
return *changedValue_;
|
||||
@@ -280,66 +269,11 @@ css::uno::Any ChildAccess::asValue() {
|
||||
getComponents());
|
||||
case Node::KIND_LOCALIZED_PROPERTY:
|
||||
{
|
||||
rtl::OUString sLocale(getRootAccess()->getLocale());
|
||||
if (!Components::allLocales(sLocale))
|
||||
{
|
||||
rtl::Reference< ChildAccess > child;
|
||||
// Find best match using an adaption of RFC 4647 lookup matching
|
||||
// rules, removing "-" or "_" delimited segments from the end
|
||||
while (1)
|
||||
{
|
||||
child = getChild(sLocale);
|
||||
if (child.is())
|
||||
break;
|
||||
rtl::OUString sTmpLocale = lcl_StripSegment(sLocale);
|
||||
if (sTmpLocale.isEmpty())
|
||||
break;
|
||||
sLocale = sTmpLocale;
|
||||
}
|
||||
|
||||
//Resolves: fdo#33638 Look for the first entry with the same
|
||||
//first segment as the requested language tag, before falling
|
||||
//back to en-US, etc.
|
||||
typedef std::vector< rtl::Reference< ChildAccess > > ChildVector;
|
||||
if (!child.is())
|
||||
{
|
||||
const ChildVector &rAllChildren = getAllChildren();
|
||||
for (ChildVector::const_iterator aI = rAllChildren.begin(),
|
||||
aEnd = rAllChildren.end(); aI != aEnd; ++aI)
|
||||
{
|
||||
rtl::OUString sLanguage = lcl_StripSegment((*aI)->getNameInternal());
|
||||
if (sLocale == sLanguage)
|
||||
{
|
||||
child = *aI;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// defaults are the "en-US" locale, the "en" locale, the empty
|
||||
// string locale, the first child (if any), or a nil value (even
|
||||
// though it may be illegal for the given property), in that
|
||||
// order:
|
||||
if (!child.is())
|
||||
{
|
||||
child = getChild(
|
||||
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US")));
|
||||
if (!child.is())
|
||||
{
|
||||
child = getChild(
|
||||
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")));
|
||||
if (!child.is())
|
||||
{
|
||||
child = getChild(rtl::OUString());
|
||||
if (!child.is())
|
||||
{
|
||||
ChildVector all(getAllChildren());
|
||||
if (!all.empty())
|
||||
child = all.front();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
OUString locale(getRootAccess()->getLocale());
|
||||
if (!Components::allLocales(locale)) {
|
||||
rtl::Reference< ChildAccess > child(getChild("*" + locale));
|
||||
// As a last resort, return a nil value even though it may be
|
||||
// illegal for the given property:
|
||||
return child.is() ? child->asValue() : css::uno::Any();
|
||||
}
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@
|
||||
<singleton name="com.sun.star.configuration.theDefaultProvider"/>
|
||||
</implementation>
|
||||
<implementation name="com.sun.star.comp.configuration.ReadOnlyAccess">
|
||||
<singleton name="com.sun.star.configuration.ReadOnlyAccess"/>
|
||||
<service name="com.sun.star.configuration.ReadOnlyAccess"/>
|
||||
</implementation>
|
||||
<implementation name="com.sun.star.comp.configuration.ReadWriteAccess">
|
||||
<service name="com.sun.star.configuration.ReadWriteAccess"/>
|
||||
|
@@ -30,15 +30,21 @@
|
||||
#include "sal/config.h"
|
||||
|
||||
#include "boost/noncopyable.hpp"
|
||||
#include "cppuhelper/implbase2.hxx"
|
||||
#include "com/sun/star/lang/XServiceInfo.hpp"
|
||||
#include "com/sun/star/container/NoSuchElementException.hpp"
|
||||
#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
|
||||
#include "com/sun/star/lang/IllegalArgumentException.hpp"
|
||||
#include "com/sun/star/lang/NotInitializedException.hpp"
|
||||
#include "com/sun/star/lang/XInitialization.hpp"
|
||||
#include "com/sun/star/lang/XServiceInfo.hpp"
|
||||
#include "com/sun/star/uno/Any.hxx"
|
||||
#include "com/sun/star/uno/Exception.hpp"
|
||||
#include "com/sun/star/uno/Reference.hxx"
|
||||
#include "com/sun/star/uno/RuntimeException.hpp"
|
||||
#include "com/sun/star/uno/Sequence.hxx"
|
||||
#include "com/sun/star/uno/XComponentContext.hpp"
|
||||
#include "com/sun/star/uno/XInterface.hpp"
|
||||
#include "cppuhelper/implbase3.hxx"
|
||||
#include "cppuhelper/weak.hxx"
|
||||
#include "osl/mutex.hxx"
|
||||
#include "rtl/ref.hxx"
|
||||
#include "rtl/ustring.h"
|
||||
@@ -57,12 +63,15 @@ namespace {
|
||||
namespace css = com::sun::star;
|
||||
|
||||
class Service:
|
||||
public cppu::WeakImplHelper2<
|
||||
css::lang::XServiceInfo, css::container::XHierarchicalNameAccess >,
|
||||
public cppu::WeakImplHelper3<
|
||||
css::lang::XServiceInfo, css::lang::XInitialization,
|
||||
css::container::XHierarchicalNameAccess >,
|
||||
private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
Service(css::uno::Reference< css::uno::XComponentContext > const & context);
|
||||
explicit Service(
|
||||
css::uno::Reference< css::uno::XComponentContext > const & context):
|
||||
context_(context) {}
|
||||
|
||||
private:
|
||||
virtual ~Service() {}
|
||||
@@ -79,30 +88,57 @@ private:
|
||||
getSupportedServiceNames() throw (css::uno::RuntimeException)
|
||||
{ return read_only_access::getSupportedServiceNames(); }
|
||||
|
||||
virtual void SAL_CALL initialize(
|
||||
css::uno::Sequence< css::uno::Any > const & aArguments)
|
||||
throw (css::uno::Exception, css::uno::RuntimeException);
|
||||
|
||||
virtual css::uno::Any SAL_CALL getByHierarchicalName(
|
||||
rtl::OUString const & aName)
|
||||
throw (
|
||||
css::container::NoSuchElementException, css::uno::RuntimeException)
|
||||
{ return root_->getByHierarchicalName(aName); }
|
||||
{ return getRoot()->getByHierarchicalName(aName); }
|
||||
|
||||
virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName)
|
||||
throw (css::uno::RuntimeException)
|
||||
{ return root_->hasByHierarchicalName(aName); }
|
||||
{ return getRoot()->hasByHierarchicalName(aName); }
|
||||
|
||||
rtl::Reference< RootAccess > getRoot();
|
||||
|
||||
css::uno::Reference< css::uno::XComponentContext > context_;
|
||||
|
||||
osl::Mutex mutex_;
|
||||
rtl::Reference< RootAccess > root_;
|
||||
};
|
||||
|
||||
Service::Service(
|
||||
css::uno::Reference< css::uno::XComponentContext > const & context)
|
||||
void Service::initialize(css::uno::Sequence< css::uno::Any > const & aArguments)
|
||||
throw (css::uno::Exception, css::uno::RuntimeException)
|
||||
{
|
||||
osl::MutexGuard guard(*lock());
|
||||
Components & components = Components::getSingleton(context);
|
||||
root_ = new RootAccess(
|
||||
components, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")),
|
||||
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), false);
|
||||
OUString locale;
|
||||
if (aArguments.getLength() != 1 || !(aArguments[0] >>= locale)) {
|
||||
throw css::lang::IllegalArgumentException(
|
||||
"not exactly one string argument",
|
||||
static_cast< cppu::OWeakObject * >(this), -1);
|
||||
}
|
||||
osl::MutexGuard g1(mutex_);
|
||||
if (root_.is()) {
|
||||
throw css::uno::RuntimeException(
|
||||
"already initialized", static_cast< cppu::OWeakObject * >(this));
|
||||
}
|
||||
osl::MutexGuard g2(*lock());
|
||||
Components & components = Components::getSingleton(context_);
|
||||
root_ = new RootAccess(components, "/", locale, false);
|
||||
components.addRootAccess(root_);
|
||||
}
|
||||
|
||||
rtl::Reference< RootAccess > Service::getRoot() {
|
||||
osl::MutexGuard g(mutex_);
|
||||
if (!root_.is()) {
|
||||
throw css::lang::NotInitializedException(
|
||||
"not initialized", static_cast< cppu::OWeakObject * >(this));
|
||||
}
|
||||
return root_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
css::uno::Reference< css::uno::XInterface > create(
|
||||
|
@@ -30,18 +30,24 @@
|
||||
#include "sal/config.h"
|
||||
|
||||
#include "boost/noncopyable.hpp"
|
||||
#include "cppuhelper/implbase2.hxx"
|
||||
#include "com/sun/star/lang/IllegalArgumentException.hpp"
|
||||
#include "com/sun/star/lang/WrappedTargetException.hpp"
|
||||
#include "com/sun/star/lang/XServiceInfo.hpp"
|
||||
#include "com/sun/star/container/NoSuchElementException.hpp"
|
||||
#include "com/sun/star/configuration/XReadWriteAccess.hpp"
|
||||
#include "com/sun/star/container/NoSuchElementException.hpp"
|
||||
#include "com/sun/star/lang/IllegalArgumentException.hpp"
|
||||
#include "com/sun/star/lang/NotInitializedException.hpp"
|
||||
#include "com/sun/star/lang/WrappedTargetException.hpp"
|
||||
#include "com/sun/star/lang/XInitialization.hpp"
|
||||
#include "com/sun/star/lang/XServiceInfo.hpp"
|
||||
#include "com/sun/star/uno/Any.hxx"
|
||||
#include "com/sun/star/uno/Exception.hpp"
|
||||
#include "com/sun/star/uno/Reference.hxx"
|
||||
#include "com/sun/star/uno/RuntimeException.hpp"
|
||||
#include "com/sun/star/uno/Sequence.hxx"
|
||||
#include "com/sun/star/uno/XComponentContext.hpp"
|
||||
#include "com/sun/star/uno/XInterface.hpp"
|
||||
#include "com/sun/star/util/ChangesSet.hpp"
|
||||
#include "cppuhelper/implbase3.hxx"
|
||||
#include "cppuhelper/weak.hxx"
|
||||
#include "osl/mutex.hxx"
|
||||
#include "rtl/ref.hxx"
|
||||
#include "rtl/ustring.h"
|
||||
#include "rtl/ustring.hxx"
|
||||
@@ -59,12 +65,15 @@ namespace {
|
||||
namespace css = com::sun::star;
|
||||
|
||||
class Service:
|
||||
public cppu::WeakImplHelper2<
|
||||
css::lang::XServiceInfo, css::configuration::XReadWriteAccess >,
|
||||
public cppu::WeakImplHelper3<
|
||||
css::lang::XServiceInfo, css::lang::XInitialization,
|
||||
css::configuration::XReadWriteAccess >,
|
||||
private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
Service(css::uno::Reference< css::uno::XComponentContext > const & context);
|
||||
explicit Service(
|
||||
css::uno::Reference< css::uno::XComponentContext > const & context):
|
||||
context_(context) {}
|
||||
|
||||
private:
|
||||
virtual ~Service() {}
|
||||
@@ -81,15 +90,19 @@ private:
|
||||
getSupportedServiceNames() throw (css::uno::RuntimeException)
|
||||
{ return read_write_access::getSupportedServiceNames(); }
|
||||
|
||||
virtual void SAL_CALL initialize(
|
||||
css::uno::Sequence< css::uno::Any > const & aArguments)
|
||||
throw (css::uno::Exception, css::uno::RuntimeException);
|
||||
|
||||
virtual css::uno::Any SAL_CALL getByHierarchicalName(
|
||||
rtl::OUString const & aName)
|
||||
throw (
|
||||
css::container::NoSuchElementException, css::uno::RuntimeException)
|
||||
{ return root_->getByHierarchicalName(aName); }
|
||||
{ return getRoot()->getByHierarchicalName(aName); }
|
||||
|
||||
virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName)
|
||||
throw (css::uno::RuntimeException)
|
||||
{ return root_->hasByHierarchicalName(aName); }
|
||||
{ return getRoot()->hasByHierarchicalName(aName); }
|
||||
|
||||
virtual void SAL_CALL replaceByHierarchicalName(
|
||||
rtl::OUString const & aName, css::uno::Any const & aElement)
|
||||
@@ -97,34 +110,57 @@ private:
|
||||
css::lang::IllegalArgumentException,
|
||||
css::container::NoSuchElementException,
|
||||
css::lang::WrappedTargetException, css::uno::RuntimeException)
|
||||
{ root_->replaceByHierarchicalName(aName, aElement); }
|
||||
{ getRoot()->replaceByHierarchicalName(aName, aElement); }
|
||||
|
||||
virtual void SAL_CALL commitChanges()
|
||||
throw (css::lang::WrappedTargetException, css::uno::RuntimeException)
|
||||
{ root_->commitChanges(); }
|
||||
{ getRoot()->commitChanges(); }
|
||||
|
||||
virtual sal_Bool SAL_CALL hasPendingChanges()
|
||||
throw (css::uno::RuntimeException)
|
||||
{ return root_->hasPendingChanges(); }
|
||||
{ return getRoot()->hasPendingChanges(); }
|
||||
|
||||
virtual css::util::ChangesSet SAL_CALL getPendingChanges()
|
||||
throw (css::uno::RuntimeException)
|
||||
{ return root_->getPendingChanges(); }
|
||||
{ return getRoot()->getPendingChanges(); }
|
||||
|
||||
rtl::Reference< RootAccess > getRoot();
|
||||
|
||||
css::uno::Reference< css::uno::XComponentContext > context_;
|
||||
|
||||
osl::Mutex mutex_;
|
||||
rtl::Reference< RootAccess > root_;
|
||||
};
|
||||
|
||||
Service::Service(
|
||||
css::uno::Reference< css::uno::XComponentContext > const & context)
|
||||
void Service::initialize(css::uno::Sequence< css::uno::Any > const & aArguments)
|
||||
throw (css::uno::Exception, css::uno::RuntimeException)
|
||||
{
|
||||
osl::MutexGuard guard(*lock());
|
||||
Components & components = Components::getSingleton(context);
|
||||
root_ = new RootAccess(
|
||||
components, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")),
|
||||
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), true);
|
||||
OUString locale;
|
||||
if (aArguments.getLength() != 1 || !(aArguments[0] >>= locale)) {
|
||||
throw css::lang::IllegalArgumentException(
|
||||
"not exactly one string argument",
|
||||
static_cast< cppu::OWeakObject * >(this), -1);
|
||||
}
|
||||
osl::MutexGuard g1(mutex_);
|
||||
if (root_.is()) {
|
||||
throw css::uno::RuntimeException(
|
||||
"already initialized", static_cast< cppu::OWeakObject * >(this));
|
||||
}
|
||||
osl::MutexGuard g2(*lock());
|
||||
Components & components = Components::getSingleton(context_);
|
||||
root_ = new RootAccess(components, "/", locale, true);
|
||||
components.addRootAccess(root_);
|
||||
}
|
||||
|
||||
rtl::Reference< RootAccess > Service::getRoot() {
|
||||
osl::MutexGuard g(mutex_);
|
||||
if (!root_.is()) {
|
||||
throw css::lang::NotInitializedException(
|
||||
"not initialized", static_cast< cppu::OWeakObject * >(this));
|
||||
}
|
||||
return root_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
css::uno::Reference< css::uno::XInterface > create(
|
||||
|
@@ -34,13 +34,20 @@
|
||||
|
||||
module com { module sun { module star { module configuration {
|
||||
|
||||
/* Provides easy read-only access to the complete configuration.
|
||||
/** Provides easy read-only access to the complete configuration.
|
||||
|
||||
<p>This singleton is still unpublished and unstable.</p>
|
||||
<p>This service is still unpublished and unstable.</p>
|
||||
|
||||
@since LibreOffice 3.6
|
||||
@since LibreOffice 3.7
|
||||
*/
|
||||
singleton ReadOnlyAccess: com::sun::star::container::XHierarchicalNameAccess;
|
||||
service ReadOnlyAccess: com::sun::star::container::XHierarchicalNameAccess {
|
||||
/** Service constructor.
|
||||
|
||||
@param locale a string representation of the locale to use for localized
|
||||
properties; use <code>*</code> for all-locale access
|
||||
*/
|
||||
create([in] string locale);
|
||||
};
|
||||
|
||||
}; }; }; };
|
||||
|
||||
|
@@ -34,13 +34,20 @@
|
||||
|
||||
module com { module sun { module star { module configuration {
|
||||
|
||||
/* Provides easy read/write access to the complete configuration.
|
||||
/** Provides easy read/write access to the complete configuration.
|
||||
|
||||
<p>This service is still unpublished and unstable.</p>
|
||||
<p>This service is still unpublished and unstable.</p>
|
||||
|
||||
@since LibreOffice 3.6
|
||||
@since LibreOffice 3.7
|
||||
*/
|
||||
service ReadWriteAccess: com::sun::star::configuration::XReadWriteAccess;
|
||||
service ReadWriteAccess: com::sun::star::configuration::XReadWriteAccess {
|
||||
/** Service constructor.
|
||||
|
||||
@param locale a string representation of the locale to use for localized
|
||||
properties; use <code>*</code> for all-locale access
|
||||
*/
|
||||
create([in] string locale);
|
||||
};
|
||||
|
||||
}; }; }; };
|
||||
|
||||
|
Reference in New Issue
Block a user