1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: providerimpl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_configmgr.hxx"
35 #include "providerimpl.hxx"
36 #include "options.hxx"
37 #include "apifactoryimpl.hxx"
38 #include "apitreeimplobj.hxx"
39 #include "apitreeaccess.hxx"
40 #include "roottree.hxx"
42 #include "noderef.hxx"
43 #include "objectregistry.hxx"
44 #include "bootstrap.hxx"
45 #include "cachefactory.hxx"
46 #include "provider.hxx"
47 #include "treemanager.hxx"
49 #include <osl/interlck.h>
50 #include <com/sun/star/beans/PropertyValue.hpp>
51 #include <com/sun/star/lang/DisposedException.hpp>
52 #include <com/sun/star/lang/Locale.hpp>
53 #include <rtl/ustrbuf.hxx>
54 #include <rtl/logfile.hxx>
56 #define RTL_LOGFILE_OU2A(rtlOUString) (::rtl::OUStringToOString((rtlOUString), RTL_TEXTENCODING_ASCII_US).getStr())
60 namespace css
= ::com::sun::star
;
61 namespace uno
= css::uno
;
62 namespace beans
= css::beans
;
67 class ApiProviderInstances
69 rtl::Reference
<ObjectRegistry
> m_aObjectRegistry
;
70 ReadOnlyObjectFactory m_aReaderFactory
;
71 UpdateObjectFactory m_aWriterFactory
;
72 ApiProvider m_aReaderProvider
;
73 ApiProvider m_aWriterProvider
;
75 ApiProviderInstances(OProviderImpl
& rProviderImpl
)
76 : m_aObjectRegistry(new ObjectRegistry())
77 , m_aReaderFactory(m_aReaderProvider
,m_aObjectRegistry
)
78 , m_aWriterFactory(m_aWriterProvider
,m_aObjectRegistry
)
79 , m_aReaderProvider(m_aReaderFactory
,rProviderImpl
)
80 , m_aWriterProvider(m_aWriterFactory
,rProviderImpl
)
84 ~ApiProviderInstances()
87 ApiProvider
& getReaderProvider() { return m_aReaderProvider
; }
88 ApiProvider
& getWriterProvider() { return m_aWriterProvider
; }
89 Factory
& getReaderFactory() { return m_aReaderFactory
; }
90 Factory
& getWriterFactory() { return m_aWriterFactory
; }
94 //=============================================================================
96 //=============================================================================
98 //=============================================================================
99 //-----------------------------------------------------------------------------
100 OProviderImpl::OProviderImpl(OProvider
* _pProvider
, uno::Reference
< uno::XComponentContext
> const & _xContext
)
101 :m_pProvider(_pProvider
)
104 ,m_pNewProviders(NULL
)
105 ,m_aTreeManagerMutex()
106 ,m_pTreeManager(NULL
)
108 OSL_ENSURE(_xContext
.is(), "OProviderImpl : NULL context !");
110 uno::Reference
< lang::XMultiComponentFactory
> xFactory
= _xContext
->getServiceManager();
111 OSL_ENSURE(xFactory
.is(), "OProviderImpl : missing service factory !");
113 m_xTypeConverter
= m_xTypeConverter
.query(
114 xFactory
->createInstanceWithContext( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Converter" )),
117 OSL_ENSURE(m_xTypeConverter
.is(), "Module::Module : could not create an instance of the type converter !");
119 //-----------------------------------------------------------------------------
120 rtl::Reference
< TreeManager
> OProviderImpl::maybeGetTreeManager() const SAL_THROW(())
122 osl::MutexGuard
aGuard(m_aTreeManagerMutex
);
123 rtl::Reference
< TreeManager
> xResult(m_pTreeManager
);
126 //-----------------------------------------------------------------------------
127 rtl::Reference
< TreeManager
> OProviderImpl::getTreeManager() const SAL_THROW((com::sun::star::uno::RuntimeException
))
129 osl::MutexGuard
aGuard(m_aTreeManagerMutex
);
130 if (m_pTreeManager
== NULL
)
132 rtl::OUString sMsg
= rtl::OUString::createFromAscii("OProviderImpl: No cache available - provider was already disposed.");
133 throw com::sun::star::lang::DisposedException(sMsg
,static_cast<lang::XMultiServiceFactory
*>(m_pProvider
));
135 rtl::Reference
< TreeManager
> xResult(m_pTreeManager
);
138 //-----------------------------------------------------------------------------
139 void OProviderImpl::setTreeManager(TreeManager
* pTreeManager
) SAL_THROW((com::sun::star::uno::RuntimeException
))
141 osl::MutexGuard
aGuard(m_aTreeManagerMutex
);
143 OSL_PRECOND(m_pTreeManager
== NULL
, "OProviderImpl: TreeManager is already set");
144 OSL_PRECOND(pTreeManager
!= NULL
, "OProviderImpl: Trying to set a NULL TreeManager");
146 if (pTreeManager
== NULL
)
148 rtl::OUString sMsg
= rtl::OUString::createFromAscii("OProviderImpl: No cache available - cache creation failed.");
149 throw com::sun::star::uno::RuntimeException(sMsg
,NULL
);
152 (m_pTreeManager
= pTreeManager
) -> acquire();
154 //-----------------------------------------------------------------------------
155 void OProviderImpl::clearTreeManager() SAL_THROW(())
157 osl::ClearableMutexGuard
aGuard(m_aTreeManagerMutex
);
158 if (TreeManager
* pTM
= m_pTreeManager
)
160 m_pTreeManager
= NULL
;
164 //-----------------------------------------------------------------------------
165 bool OProviderImpl::initSession(const ContextReader
& _rSettings
)
167 bool bNeedProfile
= false;
168 rtl::Reference
< TreeManager
> xNewTreeManager
;
169 if (_rSettings
.isUnoBackend())
171 this->implInitFromSettings(_rSettings
,bNeedProfile
);
173 xNewTreeManager
= CacheFactory::instance().createCacheManager(_rSettings
.getBaseContext());
177 throw com::sun::star::uno::RuntimeException(rtl::OUString::createFromAscii("OProviderImpl: Only UNO Backends Supported"),NULL
);
180 setTreeManager( xNewTreeManager
.get() );
181 OSL_ASSERT( xNewTreeManager
.get() );
183 // put out of line to get rid of the order dependency (and to have a acquired configuration)
184 m_pNewProviders
= new configapi::ApiProviderInstances(*this);
186 // now complete our state from the user's profile, if necessary
190 static ::rtl::OUString
ssUserProfile(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup"));
191 configuration::AbsolutePath aProfileModule
= configuration::AbsolutePath::makeModulePath(ssUserProfile
);
193 sharable::Node
* profileTree
= xNewTreeManager
->requestSubtree(aProfileModule
, m_aDefaultOptions
);
194 if (profileTree
!= 0)
196 implInitFromProfile(profileTree
);
198 // should we clean this up ?
199 // xNewTreeManager->releaseSubtree(aProfileModule, xTempOptions);
202 catch (uno::Exception
& e
)
204 // could not read profile
206 CFG_TRACE_ERROR_NI("Provider bootstrapping: Caught an exception trying to get 'Setup' data: %s", OUSTRING2ASCII(e
.Message
));
211 //-----------------------------------------------------------------------------
213 // these can be overridden. default does nothing
214 void OProviderImpl::initFromSettings(const ContextReader
& , bool& )
217 //-----------------------------------------------------------------------------
218 void OProviderImpl::initFromProfile(sharable::Node
*)
221 //-----------------------------------------------------------------------------
222 // these implement the base class behavior
223 void OProviderImpl::implInitFromSettings(const ContextReader
& _rSettings
, bool& rNeedProfile
)
225 bool bIntrinsicNeedProfile
= true;
227 if (_rSettings
.hasLocale())
229 bIntrinsicNeedProfile
= false;
230 rtl::OUString sDefaultLocale
= _rSettings
.getLocale();
231 m_aDefaultOptions
.setIsoLocale(sDefaultLocale
);
233 else if (_rSettings
.isAdminService())
235 bIntrinsicNeedProfile
= false;
236 m_aDefaultOptions
.setAllLocales();
239 OSL_ASSERT(!m_aDefaultOptions
.hasLocale());
241 if (_rSettings
.hasAsyncSetting())
243 m_aDefaultOptions
.enableAsync( !!_rSettings
.getAsyncSetting() );
247 // call the template method
248 this->initFromSettings(_rSettings
, rNeedProfile
);
250 if (bIntrinsicNeedProfile
)
251 rNeedProfile
= true; // to get locale
253 //-----------------------------------------------------------------------------
254 void OProviderImpl::implInitFromProfile(sharable::Node
* profile
)
256 OSL_ASSERT(profile
!= 0);
258 sharable::GroupNode
* profileNode
= sharable::GroupNode::from(profile
);
260 OSL_ASSERT(profileNode
!= 0);
262 // read the default locale for the user
263 if (!m_aDefaultOptions
.hasLocale())
265 static rtl::OUString
ssSubGroup(RTL_CONSTASCII_USTRINGPARAM("L10N"));
266 static rtl::OUString
ssLocale(RTL_CONSTASCII_USTRINGPARAM("ooLocale"));
268 sharable::GroupNode
* l10nNode
= sharable::GroupNode::from(profileNode
->getChild(ssSubGroup
));
271 sharable::ValueNode
* value
= sharable::ValueNode::from(l10nNode
->getChild(ssLocale
));
275 rtl::OUString sDefaultLocale
;
276 if (value
->getValue() >>= sDefaultLocale
)
278 m_aDefaultOptions
.setIsoLocale(sDefaultLocale
);
281 OSL_ENSURE(false, "Could not extract locale parameter into string");
286 // call the template method
287 this->initFromProfile(profile
);
289 // last fallback, if there is no locale - even in ooLocale
290 m_aDefaultOptions
.ensureLocaleSet();
293 //-----------------------------------------------------------------------------
294 void OProviderImpl::setDefaultLocale( com::sun::star::lang::Locale
const & aLocale
)
296 m_aDefaultOptions
.setLocale( aLocale
);
297 // ensure that the locale is never cleared to 'empty'
298 m_aDefaultOptions
.ensureLocaleSet();
301 //-----------------------------------------------------------------------------
302 OProviderImpl::~OProviderImpl()
304 UnoApiLock aLock
; // hmm...
307 delete m_pNewProviders
;
310 // --------------------------------- disposing ---------------------------------
311 void SAL_CALL
OProviderImpl::dispose() throw()
315 rtl::Reference
< TreeManager
> xTM
= maybeGetTreeManager();
322 catch (uno::Exception
& e
)
325 CFG_TRACE_ERROR("Disposing the TreeManager or closing the session caused an exception: %s", OUSTRING2ASCII(e
.Message
));
330 //-----------------------------------------------------------------------------
331 // access to the raw notifications
332 TreeManager
* OProviderImpl::getNotifier() SAL_THROW(())
334 rtl::Reference
< TreeManager
> xTM
= maybeGetTreeManager();
338 // DefaultProvider access
339 //-----------------------------------------------------------------------------
340 rtl::Reference
< TreeManager
> OProviderImpl::getDefaultProvider() const SAL_THROW((com::sun::star::uno::RuntimeException
))
342 return getTreeManager().get();
345 //-----------------------------------------------------------------------------
346 sharable::Node
* OProviderImpl::requestSubtree( configuration::AbsolutePath
const& aSubtreePath
,
347 RequestOptions
const & _aOptions
348 ) SAL_THROW((com::sun::star::uno::Exception
))
350 rtl::Reference
< TreeManager
> xTreeManager
= getTreeManager();
352 sharable::Node
* tree
= 0;
355 tree
= xTreeManager
->requestSubtree(aSubtreePath
, _aOptions
);
357 catch(uno::Exception
&e
)
359 ::rtl::OUString sMessage
= getErrorMessage(aSubtreePath
, _aOptions
);
360 // append the error message given by the tree provider
361 sMessage
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\n\nThe backend returned the following error:\n"));
362 sMessage
+= e
.Message
;
364 throw lang::WrappedTargetException(sMessage
, getProviderInstance(), uno::makeAny(e
));
369 ::rtl::OUString sMessage
= getErrorMessage(aSubtreePath
, _aOptions
);
371 sMessage
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\n\nNo backend error message available\n"));
373 throw uno::Exception(sMessage
, getProviderInstance());
379 //-----------------------------------------------------------------------------
380 void OProviderImpl::updateTree(TreeChangeList
& aChanges
) SAL_THROW((com::sun::star::uno::Exception
))
382 getTreeManager()->updateTree(aChanges
);
385 //-----------------------------------------------------------------------------
386 void OProviderImpl::releaseSubtree( configuration::AbsolutePath
const& aSubtreePath
, RequestOptions
const& _aOptions
) SAL_THROW(())
388 rtl::Reference
< TreeManager
> xTM
= maybeGetTreeManager();
390 xTM
->releaseSubtree(aSubtreePath
, _aOptions
);
393 //-----------------------------------------------------------------------------
394 void OProviderImpl::saveAndNotifyUpdate(TreeChangeList
const& aChanges
) SAL_THROW((com::sun::star::uno::Exception
))
396 getTreeManager()->saveAndNotifyUpdate(aChanges
);
399 //-----------------------------------------------------------------------------
400 void OProviderImpl::fetchSubtree(configuration::AbsolutePath
const& aSubtreePath
, RequestOptions
const& _aOptions
) SAL_THROW(())
402 rtl::Reference
< TreeManager
> xTM
= maybeGetTreeManager();
404 xTM
->fetchSubtree(aSubtreePath
, _aOptions
);
407 //-----------------------------------------------------------------------------
408 sal_Bool
OProviderImpl::fetchDefaultData(configuration::AbsolutePath
const& aSubtreePath
, RequestOptions
const& _aOptions
) SAL_THROW((com::sun::star::uno::Exception
))
410 return getTreeManager()->fetchDefaultData(aSubtreePath
, _aOptions
);
412 //-----------------------------------------------------------------------------------
413 void OProviderImpl::refreshAll()SAL_THROW((com::sun::star::uno::Exception
))
415 m_pTreeManager
->refreshAll();
417 //-----------------------------------------------------------------------------------
418 void OProviderImpl::flushAll()SAL_THROW(())
420 m_pTreeManager
->flushAll();
422 //-----------------------------------------------------------------------------------
423 void OProviderImpl::enableAsync(const sal_Bool
& bEnableAsync
) SAL_THROW(())
425 m_pTreeManager
->enableAsync(bEnableAsync
);
427 //-----------------------------------------------------------------------------
428 uno::XInterface
* OProviderImpl::getProviderInstance()
430 return static_cast<com::sun::star::lang::XMultiServiceFactory
*>(m_pProvider
);
433 //-----------------------------------------------------------------------------------
434 rtl::OUString
OProviderImpl::getErrorMessage(configuration::AbsolutePath
const& _rAccessor
, RequestOptions
const& _aOptions
)
436 rtl::OUString
const sAccessor
= _rAccessor
.toString();
438 CFG_TRACE_ERROR("config provider: the cache manager could not provide the tree (neither from the cache nor from the session)");
439 ::rtl::OUString sMessage
;
440 ::rtl::OUString
sEntity(_aOptions
.getEntity());
441 ::rtl::OUString
sLocale(_aOptions
.getLocale());
442 CFG_TRACE_INFO_NI("config provider: the entity we tried this for is \"%s\", the locale \"%s\", the path \"%s\"", OUSTRING2ASCII(sEntity
), OUSTRING2ASCII(sLocale
), OUSTRING2ASCII(sAccessor
));
443 sMessage
+= sAccessor
;
445 if (sEntity
.getLength())
447 sMessage
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" (and for entity "));
449 sMessage
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
452 if (sLocale
.getLength())
454 sMessage
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" (and for locale "));
456 sMessage
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
459 sMessage
+= ::rtl::OUString::createFromAscii(" could not be created. Unable to retrieve the node from the configuration server.");
463 // actual factory methods
464 //-----------------------------------------------------------------------------------
465 configapi::NodeElement
* OProviderImpl::buildReadAccess(rtl::OUString
const& _rAccessor
, RequestOptions
const& _aOptions
, sal_Int32 nMinLevels
) SAL_THROW((com::sun::star::uno::Exception
))
467 CFG_TRACE_INFO("config provider: requesting the tree from the cache manager");
469 OSL_ASSERT(sal_Int16(nMinLevels
) == nMinLevels
);
471 RTL_LOGFILE_CONTEXT_AUTHOR(aLog
, "configmgr::OProviderImpl", "jb99855", "configmgr::OProviderImpl::buildReadAccess()");
472 RTL_LOGFILE_CONTEXT_TRACE1(aLog
, "request path: %s", RTL_LOGFILE_OU2A(_rAccessor
) );
476 configuration::AbsolutePath aAccessorPath
= configuration::AbsolutePath::parse(_rAccessor
);
478 sharable::Node
* tree
= requestSubtree(aAccessorPath
,_aOptions
);
480 RTL_LOGFILE_CONTEXT_TRACE(aLog
, "data loaded" );
482 unsigned int nDepth
= (nMinLevels
== treeop::ALL_LEVELS
) ? configuration::C_TreeDepthAll
: (unsigned int)(nMinLevels
);
484 RTL_LOGFILE_CONTEXT_AUTHOR(aLog2
, "configmgr::OProviderImpl", "jb99855", "configmgr: createReadOnlyTree()");
486 rtl::Reference
< configuration::Tree
> aRootTree( configuration::createReadOnlyTree(
487 aAccessorPath
, tree
, nDepth
,
488 configuration::TemplateProvider( getTreeManager(), _aOptions
)
491 return m_pNewProviders
->getReaderFactory().makeAccessRoot(aRootTree
, _aOptions
);
493 catch (configuration::Exception
& e
)
495 configapi::ExceptionMapper
ec(e
);
496 ec
.setContext(this->getProviderInstance());
498 throw lang::WrappedTargetException(ec
.message(), ec
.context(), uno::Any());
503 //-----------------------------------------------------------------------------------
504 configapi::NodeElement
* OProviderImpl::buildUpdateAccess(rtl::OUString
const& _rAccessor
, RequestOptions
const& _aOptions
,
505 sal_Int32 nMinLevels
) SAL_THROW((com::sun::star::uno::Exception
))
507 CFG_TRACE_INFO("config provider: requesting the tree from the cache manager");
508 OSL_ASSERT(sal_Int16(nMinLevels
) == nMinLevels
);
510 RTL_LOGFILE_CONTEXT_AUTHOR(aLog
, "configmgr::OProviderImpl", "jb99855", "configmgr: buildUpdateAccess()");
511 RTL_LOGFILE_CONTEXT_TRACE1(aLog
, "request path: %s", RTL_LOGFILE_OU2A(_rAccessor
) );
515 configuration::AbsolutePath aAccessorPath
= configuration::AbsolutePath::parse(_rAccessor
);
517 sharable::Node
* tree
= requestSubtree(aAccessorPath
, _aOptions
);
519 RTL_LOGFILE_CONTEXT_TRACE(aLog
, "data loaded" );
521 unsigned int nDepth
= (nMinLevels
== treeop::ALL_LEVELS
) ? configuration::C_TreeDepthAll
: (unsigned int)(nMinLevels
);
523 RTL_LOGFILE_CONTEXT_AUTHOR(aLog2
, "configmgr::OProviderImpl", "jb99855", "createUpdatableTree()");
525 rtl::Reference
< configuration::Tree
> aRootTree( configuration::createUpdatableTree(
526 aAccessorPath
, tree
, nDepth
,
527 configuration::TemplateProvider( getTreeManager(), _aOptions
)
531 return m_pNewProviders
->getWriterFactory().makeAccessRoot(aRootTree
, _aOptions
);
533 catch (configuration::Exception
& e
)
535 configapi::ExceptionMapper
ec(e
);
536 ec
.setContext(this->getProviderInstance());
538 throw lang::WrappedTargetException(ec
.message(), ec
.context(), uno::Any());
542 //=============================================================================
543 //= OProvider::FactoryArguments
544 //=============================================================================
546 sal_Char
const * const OProviderImpl::FactoryArguments::asciiArgumentNames
[] =
548 "nodepath", // ARG_NODEPATH, // requested node path
549 "depth", // ARG_DEPTH, // depth of the tree
550 "user", // ARG_USER_DEPRECATED, // name of the user - only for admin
551 "locale", // ARG_LOCALE, // desired locale
552 "nocache", // ARG_NOCACHE_OBSOLETE, // cache disabling
553 "lazywrite", // ARG_ASYNC_DEPRECATED, // lasy write data
554 "enableasync", // ARG_ASYNC, // lasy write data
555 "entity", // ARG_ENTITY, // name of the entity to be manipulated - only for admin
556 "reload", //ARG_REFRESH // refresh component
560 OProviderImpl::FactoryArguments::Argument
561 OProviderImpl::FactoryArguments::lookupArgument(const rtl::OUString
& rName
)
564 rtl::OUString
sCheck( rName
.toAsciiLowerCase() );
566 sal_Char
const * const * const pFirst
= asciiArgumentNames
;
567 sal_Char
const * const * const pLast
= pFirst
+ _arg_count
;
569 sal_Char
const * const * it
= pFirst
;
571 for(; it
!= pLast
; ++it
)
573 if (0 == sCheck
.compareToAscii(*it
))
579 OSL_ASSERT( Argument(pLast
-pFirst
) == ARG_NOT_FOUND
);
580 return static_cast<Argument
>(it
- pFirst
);
583 //-----------------------------------------------------------------------------------
584 bool OProviderImpl::FactoryArguments::extractOneArgument(
585 rtl::OUString
const& aName
, uno::Any
const& aValue
,
586 rtl::OUString
& /* [out] */ _rNodeAccessor
,
587 sal_Int32
& /* [out] */ _nLevels
,
588 RequestOptions
& /* [in/out] */ _rOptions
)
591 switch ( lookupArgument(aName
) )
595 rtl::OUString sStringVal
;
596 if (aValue
>>= sStringVal
)
597 _rNodeAccessor
= sStringVal
;
605 sal_Int32 nIntVal
= 0;
606 if (aValue
>>= nIntVal
)
614 case ARG_USER_DEPRECATED
:
616 rtl::OUString sStringVal
;
617 if (aValue
>>= sStringVal
)
618 _rOptions
.setEntity(sStringVal
);
626 rtl::OUString sStringVal
;
627 if (aValue
>>= sStringVal
)
629 _rOptions
.setIsoLocale(sStringVal
);
633 lang::Locale aLocale
;
634 if (aValue
>>= aLocale
)
636 _rOptions
.setLocale(aLocale
);
643 case ARG_NOCACHE_OBSOLETE
:
646 if (aValue
>>= bBoolVal
)
647 OSL_ENSURE(false,"ConfigurationProvider: Parameter \"nocache\" is obsolete and has no effect");
654 case ARG_ASYNC_DEPRECATED
:
656 sal_Bool bBoolVal
= sal_False
;
657 if (aValue
>>= bBoolVal
)
658 _rOptions
.enableAsync(!!bBoolVal
);
665 sal_Bool bBoolVal
= sal_False
;
666 if (aValue
>>= bBoolVal
)
667 _rOptions
.forceRefresh(!!bBoolVal
);
675 rtl::OString
sMessage(RTL_CONSTASCII_STRINGPARAM("Unknown argument \""));
676 sMessage
+= rtl::OUStringToOString(aName
, RTL_TEXTENCODING_ASCII_US
);
677 sMessage
+= rtl::OString(RTL_CONSTASCII_STRINGPARAM("\" !\n- Parameter will be ignored -\n"));
678 CFG_TRACE_WARNING( "provider: %s", sMessage
.getStr() );
680 OSL_ENSURE(false, sMessage
.getStr());
686 CFG_TRACE_ERROR( "Known argument is not handled" );
687 OSL_ENSURE(false, "Known argument is not handled");
693 //-----------------------------------------------------------------------------------
695 void failInvalidArg(uno::Any
const & aArg
, sal_Int32 _nArg
= -1)
696 SAL_THROW((lang::IllegalArgumentException
))
698 OSL_ENSURE( sal_Int16(_nArg
) == _nArg
, "Argument number out of range. Raising imprecise exception.");
700 rtl::OUStringBuffer sMessage
;
701 sMessage
.appendAscii("Configuration Provider: An argument");
702 sMessage
.appendAscii(" has the wrong type.");
703 sMessage
.appendAscii("\n- Expected a NamedValue or PropertyValue");
704 sMessage
.appendAscii("\n- Found type ").append( aArg
.getValueType().getTypeName() );
706 throw lang::IllegalArgumentException( sMessage
.makeStringAndClear(),
707 uno::Reference
<uno::XInterface
>(),
711 //-----------------------------------------------------------------------------------
713 void failInvalidArgValue(rtl::OUString
const & aName
, uno::Any
const & aValue
, sal_Int32 _nArg
= -1)
714 SAL_THROW((lang::IllegalArgumentException
))
716 OSL_ENSURE( sal_Int16(_nArg
) == _nArg
, "Argument number out of range. Raising imprecise exception.");
718 rtl::OUStringBuffer sMessage
;
719 sMessage
.appendAscii("Configuration Provider: The argument ").append(aName
);
720 sMessage
.appendAscii(" has the wrong type.");
721 sMessage
.appendAscii("\n- Found type ").append( aValue
.getValueType().getTypeName() );
723 throw lang::IllegalArgumentException( sMessage
.makeStringAndClear(),
724 uno::Reference
<uno::XInterface
>(),
728 //-----------------------------------------------------------------------------------
730 bool extractLegacyArguments( const uno::Sequence
<uno::Any
>& _rArgs
,
731 rtl::OUString
& /* [out] */ _rNodeAccessor
,
732 sal_Int32
& /* [out] */ _nLevels
)
733 SAL_THROW((lang::IllegalArgumentException
))
735 OSL_ASSERT( _rArgs
.getLength() != 0 );
737 // compatibility : formerly, you could specify the node path as first arg and the (optional) depth
739 if (! (_rArgs
[0] >>= _rNodeAccessor
) )
742 switch (_rArgs
.getLength() )
745 // valid single argument
749 // valid second argument
750 if (_rArgs
[1] >>= _nLevels
)
756 if (_rArgs
[1] >>= _nLevels
)
758 // valid second argument, but too many arguments altogether
759 throw lang::IllegalArgumentException(
760 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
761 "Configuration Provider: Too many arguments. "
762 "Additional arguments are not supported when passing the node path as string (deprecated convention).")),
763 uno::Reference
<uno::XInterface
>(),
771 // here we have an invalid second argument
773 if (_rArgs
[1].getValueTypeClass() != uno::TypeClass_STRUCT
)
775 // completely invalid second argument
776 failInvalidArgValue(rtl::OUString::createFromAscii("<depth>"),_rArgs
[1],1);
779 // Assume PropertyValue or NamedValue,
780 // which should be handled consistently by caller
784 //-----------------------------------------------------------------------------------
785 void OProviderImpl::FactoryArguments::extractArgs( const uno::Sequence
<uno::Any
>& _rArgs
,
786 rtl::OUString
& /* [out] */ _rNodeAccessor
,
787 sal_Int32
& /* [out] */ _nLevels
,
788 RequestOptions
& /* [in/out] */ _aOptions
)
789 SAL_THROW((lang::IllegalArgumentException
))
793 _nLevels
= treeop::ALL_LEVELS
; // setting a fallback
795 // the args have to be a sequence of property or named values
796 beans::NamedValue aNV
;
797 beans::PropertyValue aPV
;
798 for (sal_Int32 i
=0; i
<_rArgs
.getLength(); ++i
)
800 if (_rArgs
[i
] >>= aPV
)
802 if ( !extractOneArgument(aPV
.Name
,aPV
.Value
,_rNodeAccessor
,_nLevels
,_aOptions
) )
803 failInvalidArgValue(aPV
.Name
,aPV
.Value
,i
);
805 else if (_rArgs
[i
] >>= aNV
)
807 if ( !extractOneArgument(aNV
.Name
,aNV
.Value
,_rNodeAccessor
,_nLevels
,_aOptions
) )
808 failInvalidArgValue(aNV
.Name
,aNV
.Value
,i
);
812 if (i
== 0)// try compatibility format
813 if ( extractLegacyArguments(_rArgs
,_rNodeAccessor
,_nLevels
))
816 failInvalidArg(_rArgs
[i
],i
);
821 if (_rNodeAccessor
.getLength() == 0)
823 rtl::OUString
sMessage(RTL_CONSTASCII_USTRINGPARAM("Configuration Provider: Missing argument: no nodepath was provided"));
824 throw lang::IllegalArgumentException(sMessage
,uno::Reference
<uno::XInterface
>(),0);
828 //--------------------------------------------------------------------------
829 uno::Reference
<uno::XInterface
> OProviderImpl::createReadAccess( uno::Sequence
<uno::Any
> const& aArgs
)
830 SAL_THROW((com::sun::star::uno::Exception
))
832 CFG_TRACE_INFO("config provider: going to create a read access instance");
838 RequestOptions aOptions
= getDefaultOptions();
840 OProviderImpl::FactoryArguments::extractArgs(aArgs
, sPath
, nLevels
, aOptions
);
842 CFG_TRACE_INFO_NI("config provider: node accessor extracted from the args is %s", OUSTRING2ASCII(sPath
));
843 CFG_TRACE_INFO_NI("config provider: level depth extracted from the args is %i", nLevels
);
845 // create the access object
846 uno::Reference
< uno::XInterface
> xReturn
;
848 configapi::NodeElement
* pElement
= buildReadAccess(sPath
, aOptions
, nLevels
);
851 xReturn
= pElement
->getUnoInstance();
853 // acquired once by buildReadAccess
860 //-----------------------------------------------------------------------------------
861 uno::Reference
<uno::XInterface
> OProviderImpl::createUpdateAccess( uno::Sequence
<uno::Any
> const& aArgs
)
862 SAL_THROW((com::sun::star::uno::Exception
))
864 CFG_TRACE_INFO("config provider: going to create an update access instance");
870 RequestOptions aOptions
= getDefaultOptions();
872 OProviderImpl::FactoryArguments::extractArgs(aArgs
, sPath
, nLevels
, aOptions
);
874 CFG_TRACE_INFO_NI("config provider: node accessor extracted from the args is %s", OUSTRING2ASCII(sPath
));
875 CFG_TRACE_INFO_NI("config provider: level depth extracted from the args is %i", nLevels
);
877 // create the access object
878 uno::Reference
< uno::XInterface
> xReturn
;
880 configapi::NodeElement
* pElement
= buildUpdateAccess(sPath
, aOptions
, nLevels
);
883 xReturn
= pElement
->getUnoInstance();
885 // acquired once by buildReadAccess
891 //-----------------------------------------------------------------------------------
894 } // namespace configmgr