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;
|
boost::shared_ptr< ConfigurationChanges > createChanges() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rtl::OUString extendLocalizedPath(rtl::OUString const & path) const;
|
|
||||||
|
|
||||||
com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
|
com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
|
||||||
context_;
|
context_;
|
||||||
|
|
||||||
|
@@ -64,6 +64,51 @@ struct TheConfigurationWrapper:
|
|||||||
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 >
|
boost::shared_ptr< comphelper::ConfigurationChanges >
|
||||||
@@ -82,7 +127,9 @@ void comphelper::ConfigurationChanges::commit() const {
|
|||||||
|
|
||||||
comphelper::ConfigurationChanges::ConfigurationChanges(
|
comphelper::ConfigurationChanges::ConfigurationChanges(
|
||||||
css::uno::Reference< css::uno::XComponentContext > const & context):
|
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(
|
void comphelper::ConfigurationChanges::setPropertyValue(
|
||||||
@@ -114,7 +161,8 @@ comphelper::detail::ConfigurationWrapper::get(
|
|||||||
|
|
||||||
comphelper::detail::ConfigurationWrapper::ConfigurationWrapper(
|
comphelper::detail::ConfigurationWrapper::ConfigurationWrapper(
|
||||||
css::uno::Reference< css::uno::XComponentContext > const & context):
|
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() {}
|
comphelper::detail::ConfigurationWrapper::~ConfigurationWrapper() {}
|
||||||
@@ -137,7 +185,8 @@ css::uno::Any
|
|||||||
comphelper::detail::ConfigurationWrapper::getLocalizedPropertyValue(
|
comphelper::detail::ConfigurationWrapper::getLocalizedPropertyValue(
|
||||||
rtl::OUString const & path) const
|
rtl::OUString const & path) const
|
||||||
{
|
{
|
||||||
return access_->getByHierarchicalName(extendLocalizedPath(path));
|
return access_->getByHierarchicalName(
|
||||||
|
extendLocalizedPath(path, getDefaultLocale(context_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void comphelper::detail::ConfigurationWrapper::setLocalizedPropertyValue(
|
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
|
rtl::OUString const & path, com::sun::star::uno::Any const & value) const
|
||||||
{
|
{
|
||||||
assert(batch.get() != 0);
|
assert(batch.get() != 0);
|
||||||
batch->setPropertyValue(extendLocalizedPath(path), value);
|
batch->setPropertyValue(path, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
css::uno::Reference< css::container::XHierarchicalNameAccess >
|
css::uno::Reference< css::container::XHierarchicalNameAccess >
|
||||||
@@ -153,7 +202,10 @@ comphelper::detail::ConfigurationWrapper::getGroupReadOnly(
|
|||||||
rtl::OUString const & path) const
|
rtl::OUString const & path) const
|
||||||
{
|
{
|
||||||
return css::uno::Reference< css::container::XHierarchicalNameAccess >(
|
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 >
|
css::uno::Reference< css::container::XHierarchicalNameReplace >
|
||||||
@@ -170,7 +222,10 @@ comphelper::detail::ConfigurationWrapper::getSetReadOnly(
|
|||||||
rtl::OUString const & path) const
|
rtl::OUString const & path) const
|
||||||
{
|
{
|
||||||
return css::uno::Reference< css::container::XNameAccess >(
|
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 >
|
css::uno::Reference< css::container::XNameContainer >
|
||||||
@@ -188,46 +243,4 @@ comphelper::detail::ConfigurationWrapper::createChanges() const {
|
|||||||
new ConfigurationChanges(context_));
|
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: */
|
/* 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) {
|
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));
|
ModifiedChildren::iterator i(modifiedChildren_.find(name));
|
||||||
return i == modifiedChildren_.end()
|
return i == modifiedChildren_.end()
|
||||||
? getUnmodifiedChild(name) : getModifiedChild(i);
|
? getUnmodifiedChild(name) : getModifiedChild(i);
|
||||||
|
@@ -259,17 +259,6 @@ void ChildAccess::setProperty(
|
|||||||
localModifications->add(getRelativePath());
|
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() {
|
css::uno::Any ChildAccess::asValue() {
|
||||||
if (changedValue_.get() != 0) {
|
if (changedValue_.get() != 0) {
|
||||||
return *changedValue_;
|
return *changedValue_;
|
||||||
@@ -280,66 +269,11 @@ css::uno::Any ChildAccess::asValue() {
|
|||||||
getComponents());
|
getComponents());
|
||||||
case Node::KIND_LOCALIZED_PROPERTY:
|
case Node::KIND_LOCALIZED_PROPERTY:
|
||||||
{
|
{
|
||||||
rtl::OUString sLocale(getRootAccess()->getLocale());
|
OUString locale(getRootAccess()->getLocale());
|
||||||
if (!Components::allLocales(sLocale))
|
if (!Components::allLocales(locale)) {
|
||||||
{
|
rtl::Reference< ChildAccess > child(getChild("*" + locale));
|
||||||
rtl::Reference< ChildAccess > child;
|
// As a last resort, return a nil value even though it may be
|
||||||
// Find best match using an adaption of RFC 4647 lookup matching
|
// illegal for the given property:
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return child.is() ? child->asValue() : css::uno::Any();
|
return child.is() ? child->asValue() : css::uno::Any();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
<singleton name="com.sun.star.configuration.theDefaultProvider"/>
|
<singleton name="com.sun.star.configuration.theDefaultProvider"/>
|
||||||
</implementation>
|
</implementation>
|
||||||
<implementation name="com.sun.star.comp.configuration.ReadOnlyAccess">
|
<implementation name="com.sun.star.comp.configuration.ReadOnlyAccess">
|
||||||
<singleton name="com.sun.star.configuration.ReadOnlyAccess"/>
|
<service name="com.sun.star.configuration.ReadOnlyAccess"/>
|
||||||
</implementation>
|
</implementation>
|
||||||
<implementation name="com.sun.star.comp.configuration.ReadWriteAccess">
|
<implementation name="com.sun.star.comp.configuration.ReadWriteAccess">
|
||||||
<service name="com.sun.star.configuration.ReadWriteAccess"/>
|
<service name="com.sun.star.configuration.ReadWriteAccess"/>
|
||||||
|
@@ -30,15 +30,21 @@
|
|||||||
#include "sal/config.h"
|
#include "sal/config.h"
|
||||||
|
|
||||||
#include "boost/noncopyable.hpp"
|
#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/NoSuchElementException.hpp"
|
||||||
#include "com/sun/star/container/XHierarchicalNameAccess.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/Reference.hxx"
|
||||||
#include "com/sun/star/uno/RuntimeException.hpp"
|
#include "com/sun/star/uno/RuntimeException.hpp"
|
||||||
#include "com/sun/star/uno/Sequence.hxx"
|
#include "com/sun/star/uno/Sequence.hxx"
|
||||||
#include "com/sun/star/uno/XComponentContext.hpp"
|
#include "com/sun/star/uno/XComponentContext.hpp"
|
||||||
#include "com/sun/star/uno/XInterface.hpp"
|
#include "com/sun/star/uno/XInterface.hpp"
|
||||||
|
#include "cppuhelper/implbase3.hxx"
|
||||||
|
#include "cppuhelper/weak.hxx"
|
||||||
#include "osl/mutex.hxx"
|
#include "osl/mutex.hxx"
|
||||||
#include "rtl/ref.hxx"
|
#include "rtl/ref.hxx"
|
||||||
#include "rtl/ustring.h"
|
#include "rtl/ustring.h"
|
||||||
@@ -57,12 +63,15 @@ namespace {
|
|||||||
namespace css = com::sun::star;
|
namespace css = com::sun::star;
|
||||||
|
|
||||||
class Service:
|
class Service:
|
||||||
public cppu::WeakImplHelper2<
|
public cppu::WeakImplHelper3<
|
||||||
css::lang::XServiceInfo, css::container::XHierarchicalNameAccess >,
|
css::lang::XServiceInfo, css::lang::XInitialization,
|
||||||
|
css::container::XHierarchicalNameAccess >,
|
||||||
private boost::noncopyable
|
private boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Service(css::uno::Reference< css::uno::XComponentContext > const & context);
|
explicit Service(
|
||||||
|
css::uno::Reference< css::uno::XComponentContext > const & context):
|
||||||
|
context_(context) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ~Service() {}
|
virtual ~Service() {}
|
||||||
@@ -79,30 +88,57 @@ private:
|
|||||||
getSupportedServiceNames() throw (css::uno::RuntimeException)
|
getSupportedServiceNames() throw (css::uno::RuntimeException)
|
||||||
{ return read_only_access::getSupportedServiceNames(); }
|
{ 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(
|
virtual css::uno::Any SAL_CALL getByHierarchicalName(
|
||||||
rtl::OUString const & aName)
|
rtl::OUString const & aName)
|
||||||
throw (
|
throw (
|
||||||
css::container::NoSuchElementException, css::uno::RuntimeException)
|
css::container::NoSuchElementException, css::uno::RuntimeException)
|
||||||
{ return root_->getByHierarchicalName(aName); }
|
{ return getRoot()->getByHierarchicalName(aName); }
|
||||||
|
|
||||||
virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName)
|
virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName)
|
||||||
throw (css::uno::RuntimeException)
|
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_;
|
rtl::Reference< RootAccess > root_;
|
||||||
};
|
};
|
||||||
|
|
||||||
Service::Service(
|
void Service::initialize(css::uno::Sequence< css::uno::Any > const & aArguments)
|
||||||
css::uno::Reference< css::uno::XComponentContext > const & context)
|
throw (css::uno::Exception, css::uno::RuntimeException)
|
||||||
{
|
{
|
||||||
osl::MutexGuard guard(*lock());
|
OUString locale;
|
||||||
Components & components = Components::getSingleton(context);
|
if (aArguments.getLength() != 1 || !(aArguments[0] >>= locale)) {
|
||||||
root_ = new RootAccess(
|
throw css::lang::IllegalArgumentException(
|
||||||
components, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")),
|
"not exactly one string argument",
|
||||||
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), false);
|
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_);
|
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(
|
css::uno::Reference< css::uno::XInterface > create(
|
||||||
|
@@ -30,18 +30,24 @@
|
|||||||
#include "sal/config.h"
|
#include "sal/config.h"
|
||||||
|
|
||||||
#include "boost/noncopyable.hpp"
|
#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/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/Reference.hxx"
|
||||||
#include "com/sun/star/uno/RuntimeException.hpp"
|
#include "com/sun/star/uno/RuntimeException.hpp"
|
||||||
#include "com/sun/star/uno/Sequence.hxx"
|
#include "com/sun/star/uno/Sequence.hxx"
|
||||||
#include "com/sun/star/uno/XComponentContext.hpp"
|
#include "com/sun/star/uno/XComponentContext.hpp"
|
||||||
#include "com/sun/star/uno/XInterface.hpp"
|
#include "com/sun/star/uno/XInterface.hpp"
|
||||||
#include "com/sun/star/util/ChangesSet.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/ref.hxx"
|
||||||
#include "rtl/ustring.h"
|
#include "rtl/ustring.h"
|
||||||
#include "rtl/ustring.hxx"
|
#include "rtl/ustring.hxx"
|
||||||
@@ -59,12 +65,15 @@ namespace {
|
|||||||
namespace css = com::sun::star;
|
namespace css = com::sun::star;
|
||||||
|
|
||||||
class Service:
|
class Service:
|
||||||
public cppu::WeakImplHelper2<
|
public cppu::WeakImplHelper3<
|
||||||
css::lang::XServiceInfo, css::configuration::XReadWriteAccess >,
|
css::lang::XServiceInfo, css::lang::XInitialization,
|
||||||
|
css::configuration::XReadWriteAccess >,
|
||||||
private boost::noncopyable
|
private boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Service(css::uno::Reference< css::uno::XComponentContext > const & context);
|
explicit Service(
|
||||||
|
css::uno::Reference< css::uno::XComponentContext > const & context):
|
||||||
|
context_(context) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ~Service() {}
|
virtual ~Service() {}
|
||||||
@@ -81,15 +90,19 @@ private:
|
|||||||
getSupportedServiceNames() throw (css::uno::RuntimeException)
|
getSupportedServiceNames() throw (css::uno::RuntimeException)
|
||||||
{ return read_write_access::getSupportedServiceNames(); }
|
{ 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(
|
virtual css::uno::Any SAL_CALL getByHierarchicalName(
|
||||||
rtl::OUString const & aName)
|
rtl::OUString const & aName)
|
||||||
throw (
|
throw (
|
||||||
css::container::NoSuchElementException, css::uno::RuntimeException)
|
css::container::NoSuchElementException, css::uno::RuntimeException)
|
||||||
{ return root_->getByHierarchicalName(aName); }
|
{ return getRoot()->getByHierarchicalName(aName); }
|
||||||
|
|
||||||
virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName)
|
virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName)
|
||||||
throw (css::uno::RuntimeException)
|
throw (css::uno::RuntimeException)
|
||||||
{ return root_->hasByHierarchicalName(aName); }
|
{ return getRoot()->hasByHierarchicalName(aName); }
|
||||||
|
|
||||||
virtual void SAL_CALL replaceByHierarchicalName(
|
virtual void SAL_CALL replaceByHierarchicalName(
|
||||||
rtl::OUString const & aName, css::uno::Any const & aElement)
|
rtl::OUString const & aName, css::uno::Any const & aElement)
|
||||||
@@ -97,34 +110,57 @@ private:
|
|||||||
css::lang::IllegalArgumentException,
|
css::lang::IllegalArgumentException,
|
||||||
css::container::NoSuchElementException,
|
css::container::NoSuchElementException,
|
||||||
css::lang::WrappedTargetException, css::uno::RuntimeException)
|
css::lang::WrappedTargetException, css::uno::RuntimeException)
|
||||||
{ root_->replaceByHierarchicalName(aName, aElement); }
|
{ getRoot()->replaceByHierarchicalName(aName, aElement); }
|
||||||
|
|
||||||
virtual void SAL_CALL commitChanges()
|
virtual void SAL_CALL commitChanges()
|
||||||
throw (css::lang::WrappedTargetException, css::uno::RuntimeException)
|
throw (css::lang::WrappedTargetException, css::uno::RuntimeException)
|
||||||
{ root_->commitChanges(); }
|
{ getRoot()->commitChanges(); }
|
||||||
|
|
||||||
virtual sal_Bool SAL_CALL hasPendingChanges()
|
virtual sal_Bool SAL_CALL hasPendingChanges()
|
||||||
throw (css::uno::RuntimeException)
|
throw (css::uno::RuntimeException)
|
||||||
{ return root_->hasPendingChanges(); }
|
{ return getRoot()->hasPendingChanges(); }
|
||||||
|
|
||||||
virtual css::util::ChangesSet SAL_CALL getPendingChanges()
|
virtual css::util::ChangesSet SAL_CALL getPendingChanges()
|
||||||
throw (css::uno::RuntimeException)
|
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_;
|
rtl::Reference< RootAccess > root_;
|
||||||
};
|
};
|
||||||
|
|
||||||
Service::Service(
|
void Service::initialize(css::uno::Sequence< css::uno::Any > const & aArguments)
|
||||||
css::uno::Reference< css::uno::XComponentContext > const & context)
|
throw (css::uno::Exception, css::uno::RuntimeException)
|
||||||
{
|
{
|
||||||
osl::MutexGuard guard(*lock());
|
OUString locale;
|
||||||
Components & components = Components::getSingleton(context);
|
if (aArguments.getLength() != 1 || !(aArguments[0] >>= locale)) {
|
||||||
root_ = new RootAccess(
|
throw css::lang::IllegalArgumentException(
|
||||||
components, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")),
|
"not exactly one string argument",
|
||||||
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), true);
|
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_);
|
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(
|
css::uno::Reference< css::uno::XInterface > create(
|
||||||
|
@@ -34,13 +34,20 @@
|
|||||||
|
|
||||||
module com { module sun { module star { module configuration {
|
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 {
|
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