diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2011-12-13 12:37:00 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2011-12-13 12:50:34 +0100 |
commit | bcdea3b379637a98e5bbc304078149ca6c2b6e03 (patch) | |
tree | a3803df980a54ab1a03c740c3114a54ca7d12f27 /unotools | |
parent | ddf1cf333174777e7923aa0d6126daf2c8645fed (diff) |
Simplified, type-safe C++ configuration access.
* New offapi com.sun.star.configuration entities to access the complete
configuration read-only or read/write...
* ...configmgr adapted to support those new services/singletons...
* ...new unotools/configuration.hxx is the type-safe C++ plumbing on top of
that...
* ...officecfg now generates C++ headers to access all the properties and sets
given in the .xcs files...
* ...and svl's asiancfg.cxx exemplarily makes use of the new
officecfg/Office/Common.hxx to access the configuration.
* There is still TODOs: For one, see those listed in
officecfg/registry/cppheader.xsl. For another, at least a notification
mechanism for the new read-only configuration access and the C++ wrapper is
missing.
Diffstat (limited to 'unotools')
-rw-r--r-- | unotools/Library_utl.mk | 1 | ||||
-rw-r--r-- | unotools/Package_inc.mk | 1 | ||||
-rw-r--r-- | unotools/inc/unotools/configuration.hxx | 270 | ||||
-rw-r--r-- | unotools/source/config/configuration.cxx | 207 |
4 files changed, 479 insertions, 0 deletions
diff --git a/unotools/Library_utl.mk b/unotools/Library_utl.mk index e9f252d53792..01571459d571 100644 --- a/unotools/Library_utl.mk +++ b/unotools/Library_utl.mk @@ -81,6 +81,7 @@ $(eval $(call gb_Library_add_exception_objects,utl,\ unotools/source/config/configmgr \ unotools/source/config/confignode \ unotools/source/config/configpathes \ + unotools/source/config/configuration \ unotools/source/config/configvaluecontainer \ unotools/source/config/defaultoptions \ unotools/source/config/docinfohelper \ diff --git a/unotools/Package_inc.mk b/unotools/Package_inc.mk index 58d91273506b..615e762d8518 100644 --- a/unotools/Package_inc.mk +++ b/unotools/Package_inc.mk @@ -45,6 +45,7 @@ $(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/configitem.hxx,unoto $(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/configmgr.hxx,unotools/configmgr.hxx)) $(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/confignode.hxx,unotools/confignode.hxx)) $(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/configpathes.hxx,unotools/configpathes.hxx)) +$(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/configuration.hxx,unotools/configuration.hxx)) $(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/configvaluecontainer.hxx,unotools/configvaluecontainer.hxx)) $(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/datetime.hxx,unotools/datetime.hxx)) $(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/defaultoptions.hxx,unotools/defaultoptions.hxx)) diff --git a/unotools/inc/unotools/configuration.hxx b/unotools/inc/unotools/configuration.hxx new file mode 100644 index 000000000000..c9969c8a024f --- /dev/null +++ b/unotools/inc/unotools/configuration.hxx @@ -0,0 +1,270 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License or as specified alternatively below. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * Major Contributor(s): + * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com> + * (initial developer) + * + * All Rights Reserved. + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ + +#ifndef INCLUDED_UNOTOOLS_CONFIGURATION_HXX +#define INCLUDED_UNOTOOLS_CONFIGURATION_HXX + +#include "sal/config.h" + +#include "boost/noncopyable.hpp" +#include "boost/shared_ptr.hpp" +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Reference.hxx" +#include "sal/types.h" +#include "unotools/unotoolsdllapi.h" + +namespace com { namespace sun { namespace star { + namespace configuration { class XReadWriteAccess; } + namespace container { + class XHierarchicalNameAccess; + class XNameAccess; + class XNameContainer; + } + namespace uno { class XComponentContext; } +} } } +namespace rtl { class OUString; } + +namespace unotools { + +namespace detail { class ConfigurationWrapper; } + +/// A batch of configuration changes that is committed as a whole. +/// +/// Client code needs to call commit explicitly; otherwise the changes are lost +/// when the instance is destroyed. +/// +/// This is the only class from this header file that client code should use +/// directly. +class UNOTOOLS_DLLPUBLIC ConfigurationChanges: private boost::noncopyable { +public: + static boost::shared_ptr< ConfigurationChanges > create( + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > + const & context); + + ~ConfigurationChanges(); + + void commit() const; + +private: + SAL_DLLPRIVATE ConfigurationChanges( + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > + const & context); + + SAL_DLLPRIVATE void setPropertyValue( + rtl::OUString const & path, com::sun::star::uno::Any const & value) + const; + + SAL_DLLPRIVATE + com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > + getSet(rtl::OUString const & path) const; + + com::sun::star::uno::Reference< + com::sun::star::configuration::XReadWriteAccess > access_; + + friend class detail::ConfigurationWrapper; +}; + +namespace detail { + +/// @internal +class UNOTOOLS_DLLPUBLIC ConfigurationWrapper: private boost::noncopyable { +public: + static ConfigurationWrapper const & get( + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > + const & context); + + SAL_DLLPRIVATE explicit ConfigurationWrapper( + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > + const & context); + + SAL_DLLPRIVATE ~ConfigurationWrapper(); + + com::sun::star::uno::Any getPropertyValue(rtl::OUString const & path) const; + + void setPropertyValue( + boost::shared_ptr< ConfigurationChanges > const & batch, + rtl::OUString const & path, com::sun::star::uno::Any const & value) + const; + + com::sun::star::uno::Any getLocalizedPropertyValue( + rtl::OUString const & path) const; + + void setLocalizedPropertyValue( + boost::shared_ptr< ConfigurationChanges > const & batch, + rtl::OUString const & path, com::sun::star::uno::Any const & value) + const; + + com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > + getSetReadOnly(rtl::OUString const & path) const; + + com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > + getSetReadWrite( + boost::shared_ptr< ConfigurationChanges > const & batch, + rtl::OUString const & path) const; + + 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_; + + com::sun::star::uno::Reference< + com::sun::star::container::XHierarchicalNameAccess > access_; +}; + +} + +/// A type-safe wrapper around a (non-localized) configuration property. +/// +/// Automatically generated headers for the various configuration properties +/// derive from this template and make available its member functions to access +/// each given configuration property. +template< typename T, typename U > struct ConfigurationProperty: + private boost::noncopyable +{ + /// Get the value of the given (non-localized) configuration property. + /// + /// For nillable properties, U is of type boost::optional<U'>. + static U get( + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > + const & context) + { + // Folding this into one statement causes a bogus error at least with + // Red Hat GCC 4.6.2-1: + com::sun::star::uno::Any a( + detail::ConfigurationWrapper::get(context).getPropertyValue( + T::path())); + return a.get< U >(); + } + + /// Set the value of the given (non-localized) configuration property, via a + /// given changes batch. + /// + /// For nillable properties, U is of type boost::optional<U'>. + static void set( + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > + const & context, + boost::shared_ptr< ConfigurationChanges > const & batch, + U const & value) + { + detail::ConfigurationWrapper::get(context).setPropertyValue( + batch, T::path(), com::sun::star::uno::makeAny(value)); + } + +private: + ConfigurationProperty(); // not defined + ~ConfigurationProperty(); // not defined +}; + +/// A type-safe wrapper around a localized configuration property. +/// +/// Automatically generated headers for the various localized configuration +/// properties derive from this template and make available its member functions +/// to access each given localized configuration property. +template< typename T, typename U > struct ConfigurationLocalizedProperty: + private boost::noncopyable +{ + /// Get the value of the given localized configuration property, for the + /// locale currently set at the + /// com.sun.star.configuration.theDefaultProvider. + /// + /// For nillable properties, U is of type boost::optional<U'>. + static U get( + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > + const & context) + { + // Folding this into one statement causes a bogus error at least with + // Red Hat GCC 4.6.2-1: + com::sun::star::uno::Any a( + detail::ConfigurationWrapper::get(context). + getLocalizedPropertyValue(T::path())); + return a.get< U >(); + } + + /// Set the value of the given localized configuration property, for the + /// locale currently set at the + /// com.sun.star.configuration.theDefaultProvider, via a given changes + /// batch. + /// + /// For nillable properties, U is of type boost::optional<U'>. + static void set( + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > + const & context, + boost::shared_ptr< ConfigurationChanges > const & batch, + U const & value) + { + detail::ConfigurationWrapper::get(context).setLocalizedPropertyValue( + batch, T::path(), com::sun::star::uno::makeAny(value)); + } + +private: + ConfigurationLocalizedProperty(); // not defined + ~ConfigurationLocalizedProperty(); // not defined +}; + +/// A type-safe wrapper around a configuration set. +/// +/// Automatically generated headers for the various configuration sets derive +/// from this template and make available its member functions to access each +/// given configuration set. +template< typename T > struct ConfigurationSet: private boost::noncopyable { + /// Get read-only access to the given configuration set. + static + com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > + get(com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > + const & context) + { + return detail::ConfigurationWrapper::get(context).getSetReadOnly( + T::path()); + } + + /// Get read/write access to the given configuration set, storing any + /// modifications via the given changes batch. + static + com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > + get(com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > + const & context, + boost::shared_ptr< ConfigurationChanges > const & batch) + { + return detail::ConfigurationWrapper::get(context).getSetReadWrite( + batch, T::path()); + } + +private: + ConfigurationSet(); // not defined + ~ConfigurationSet(); // not defined +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unotools/source/config/configuration.cxx b/unotools/source/config/configuration.cxx new file mode 100644 index 000000000000..a4b30ed360fa --- /dev/null +++ b/unotools/source/config/configuration.cxx @@ -0,0 +1,207 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License or as specified alternatively below. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * Major Contributor(s): + * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com> + * (initial developer) + * + * All Rights Reserved. + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ + +#include "sal/config.h" + +#include <cassert> + +#include "boost/shared_ptr.hpp" +#include "com/sun/star/configuration/ReadOnlyAccess.hpp" +#include "com/sun/star/configuration/ReadWriteAccess.hpp" +#include "com/sun/star/configuration/XReadWriteAccess.hpp" +#include "com/sun/star/configuration/theDefaultProvider.hpp" +#include "com/sun/star/container/XHierarchicalNameAccess.hpp" +#include "com/sun/star/container/XNameAccess.hpp" +#include "com/sun/star/container/XNameContainer.hpp" +#include "com/sun/star/lang/Locale.hpp" +#include "com/sun/star/lang/XLocalizable.hpp" +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "rtl/instance.hxx" +#include "rtl/oustringostreaminserter.hxx" +#include "rtl/ustrbuf.hxx" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "sal/log.hxx" +#include "unotools/configuration.hxx" + +namespace { + +namespace css = com::sun::star; + +struct TheConfigurationWrapper: + public rtl::StaticWithArg< + unotools::detail::ConfigurationWrapper, + css::uno::Reference< css::uno::XComponentContext >, + TheConfigurationWrapper > +{}; + +} + +boost::shared_ptr< unotools::ConfigurationChanges > +unotools::ConfigurationChanges::create( + css::uno::Reference< css::uno::XComponentContext > const & context) +{ + return TheConfigurationWrapper::get(context).createChanges(); +} + + +unotools::ConfigurationChanges::~ConfigurationChanges() {} + +void unotools::ConfigurationChanges::commit() const { + access_->commitChanges(); +} + +unotools::ConfigurationChanges::ConfigurationChanges( + css::uno::Reference< css::uno::XComponentContext > const & context): + access_(css::configuration::ReadWriteAccess::create(context)) +{} + +void unotools::ConfigurationChanges::setPropertyValue( + rtl::OUString const & path, css::uno::Any const & value) const +{ + access_->replaceByHierarchicalName(path, value); +} + +css::uno::Reference< css::container::XNameContainer > +unotools::ConfigurationChanges::getSet(rtl::OUString const & path) const +{ + return css::uno::Reference< css::container::XNameContainer >( + access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW); +} + +unotools::detail::ConfigurationWrapper const & +unotools::detail::ConfigurationWrapper::get( + css::uno::Reference< css::uno::XComponentContext > const & context) +{ + return TheConfigurationWrapper::get(context); +} + +unotools::detail::ConfigurationWrapper::ConfigurationWrapper( + css::uno::Reference< css::uno::XComponentContext > const & context): + context_(context), access_(css::configuration::ReadOnlyAccess::get(context)) +{} + +unotools::detail::ConfigurationWrapper::~ConfigurationWrapper() {} + +css::uno::Any unotools::detail::ConfigurationWrapper::getPropertyValue( + rtl::OUString const & path) const +{ + return access_->getByHierarchicalName(path); +} + +void unotools::detail::ConfigurationWrapper::setPropertyValue( + boost::shared_ptr< ConfigurationChanges > const & batch, + rtl::OUString const & path, com::sun::star::uno::Any const & value) const +{ + assert(batch.get() != 0); + batch->setPropertyValue(path, value); +} + +css::uno::Any unotools::detail::ConfigurationWrapper::getLocalizedPropertyValue( + rtl::OUString const & path) const +{ + return access_->getByHierarchicalName(extendLocalizedPath(path)); +} + +void unotools::detail::ConfigurationWrapper::setLocalizedPropertyValue( + boost::shared_ptr< ConfigurationChanges > const & batch, + rtl::OUString const & path, com::sun::star::uno::Any const & value) const +{ + assert(batch.get() != 0); + batch->setPropertyValue(extendLocalizedPath(path), value); +} + +css::uno::Reference< css::container::XNameAccess > +unotools::detail::ConfigurationWrapper::getSetReadOnly( + rtl::OUString const & path) const +{ + return css::uno::Reference< css::container::XNameAccess >( + access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW); +} + +css::uno::Reference< css::container::XNameContainer > +unotools::detail::ConfigurationWrapper::getSetReadWrite( + boost::shared_ptr< ConfigurationChanges > const & batch, + rtl::OUString const & path) const +{ + assert(batch.get() != 0); + return batch->getSet(path); +} + +boost::shared_ptr< unotools::ConfigurationChanges > +unotools::detail::ConfigurationWrapper::createChanges() const { + return boost::shared_ptr< ConfigurationChanges >( + new ConfigurationChanges(context_)); +} + +rtl::OUString unotools::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, "unotools", + "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(), "unotools", + "Locale has empty country but non-empty variant \"" << locale.Variant + << '"'); + if (!locale.Country.isEmpty()) { + buf.append('-'); + SAL_WARN_IF( + locale.Country.indexOf('-') == -1, "unotools", + "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: */ |