update dev300-m58
[ooovba.git] / configmgr / source / api2 / provider.cxx
blob37043d57055826fa603bfdf57743c325cbb35c6f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: provider.cxx,v $
10 * $Revision: 1.19 $
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"
34 #include "apiserviceinfo.hxx"
35 #include "confapifactory.hxx"
36 #include "configpath.hxx"
37 #include "datalock.hxx"
38 #include "provider.hxx"
39 #include "providerimpl.hxx"
40 #include "tracer.hxx"
41 #include "bootstrap.hxx"
42 #include "wrapexception.hxx"
43 #include <osl/mutex.hxx>
44 #include <rtl/ustrbuf.hxx>
45 #ifndef __SGI_STL_ALGORITHM
46 #include <algorithm>
47 #endif
48 #include <comphelper/sequence.hxx>
49 #include <cppuhelper/typeprovider.hxx>
50 #include <com/sun/star/beans/PropertyValue.hpp>
51 #include <cppuhelper/typeprovider.hxx>
52 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
53 #include <com/sun/star/lang/XEventListener.hpp>
55 namespace configmgr
57 namespace css = ::com::sun::star;
58 namespace uno = css::uno;
59 namespace lang = css::lang;
60 namespace beans = css::beans;
62 namespace
64 //------------------------------------------------------------------------
65 sal_Char const * const aConfigProviderServices[] =
67 "com.sun.star.configuration.ConfigurationProvider",
70 sal_Char const * const aAdminProviderServices[] =
72 "com.sun.star.configuration.AdministrationProvider",
75 //------------------------------------------------------------------------
77 ServiceImplementationInfo const aConfigProviderInfo =
79 "com.sun.star.comp.configuration.ConfigurationProvider",
80 aConfigProviderServices,
83 ServiceImplementationInfo const aAdminProviderInfo =
85 "com.sun.star.comp.configuration.AdministrationProvider",
86 aAdminProviderServices,
87 aConfigProviderServices
89 //------------------------------------------------------------------------
91 sal_Char const * const
92 aDefaultProviderServiceAndImplName = A_DefaultProviderServiceAndImplName;
94 //------------------------------------------------------------------------
96 sal_Char const * const aDefaultProviderServices[] =
98 aDefaultProviderServiceAndImplName,
101 //------------------------------------------------------------------------
103 ServiceRegistrationInfo const aDefaultProviderInfo =
105 aDefaultProviderServiceAndImplName,
106 aDefaultProviderServices
108 SingletonRegistrationInfo const aDefaultProviderSingletonInfo =
110 A_DefaultProviderSingletonName,
111 aDefaultProviderServiceAndImplName,
112 aDefaultProviderServiceAndImplName,
115 //------------------------------------------------------------------------
116 typedef uno::Reference< uno::XInterface > (OProviderImpl::*CreatorFunc)(const uno::Sequence< uno::Any >& aArguments);
117 struct ServiceCreationInfo
119 ServiceRegistrationInfo const* info;
120 CreatorFunc create;
123 static sal_Int32 getCreateServiceDataCount()
125 return 2;
128 static const ServiceCreationInfo* getCreateServiceData()
130 static ServiceCreationInfo const createServiceData[] =
132 { &configapi::aCreateReadAccessSI, &OProviderImpl::createReadAccess },
133 { &configapi::aCreateUpdateAccessSI, &OProviderImpl::createUpdateAccess },
135 OSL_ENSURE(sizeof(createServiceData)/sizeof(createServiceData[0]) == getCreateServiceDataCount(),
136 "getCreateServiceData : inconsistent data !");
137 return createServiceData;
139 //------------------------------------------------------------------------
142 static ServiceCreationInfo const* findCreationInfo( const rtl::OUString& aServiceSpecifier )
144 for (int i= 0; i<getCreateServiceDataCount(); ++i)
146 ServiceCreationInfo const& rCreationInfo = getCreateServiceData()[i];
148 ServiceRegistrationInfo const* pInfo = rCreationInfo.info;
149 if (!pInfo)
150 continue;
152 if (sal_Char const * pImplName = pInfo->implementationName)
154 if (0 == aServiceSpecifier.compareToAscii(pImplName))
155 return &rCreationInfo;
158 if (sal_Char const * const* pNames = pInfo->registeredServiceNames)
160 while(*pNames)
162 if (0 == aServiceSpecifier.compareToAscii(*pNames))
163 return &rCreationInfo;
165 ++pNames;
169 // not found
170 return 0;
173 //#define ID_PREFETCH 1
174 static const int ID_PREFETCH=1;
175 static const int ID_ENABLEASYNC=2;
177 static inline
178 rtl::OUString getPrefetchPropName() { return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PrefetchNodes") ); }
179 static inline
180 rtl::OUString getEnableAsyncPropName() { return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("EnableAsync") ); }
181 //=============================================================================
182 //= OProvider
183 //=============================================================================
184 // service info export
185 const ServiceRegistrationInfo* getConfigurationProviderServiceInfo()
187 return getRegistrationInfo(&aConfigProviderInfo);
190 const ServiceRegistrationInfo* getAdminProviderServiceInfo()
192 return getRegistrationInfo(&aAdminProviderInfo);
195 const ServiceRegistrationInfo* getDefaultProviderServiceInfo()
197 return &aDefaultProviderInfo;
200 const SingletonRegistrationInfo* getDefaultProviderSingletonInfo()
202 return &aDefaultProviderSingletonInfo;
205 //-----------------------------------------------------------------------------
206 uno::Reference<uno::XInterface> SAL_CALL
207 getDefaultConfigProviderSingleton( uno::Reference< uno::XComponentContext > const& xContext )
209 OSL_ENSURE( xContext.is(), "ERROR: NULL context has no singletons" );
211 UnoContextTunnel aTunnel;
212 aTunnel.passthru( xContext );
214 uno::Reference<uno::XInterface> xResult;
216 if (xContext.is())
219 rtl::OUString aSingletonName = SINGLETON(A_DefaultProviderSingletonName);
220 uno::Any aResult = xContext->getValueByName(aSingletonName);
221 aResult >>= xResult;
223 catch (uno::Exception & )
225 // to do: really use the tunneled failure when that is set properly
226 if ( aTunnel.recoverFailure(true).hasValue() )
228 // have a failure, but can't recover it
229 // -> try to regenerate
230 instantiateDefaultProvider(xContext);
232 OSL_ENSURE(false, "Cannot recreate configuration backend instantiation failure - using generic error");
234 // cannot recover any failure
235 throw;
238 return xResult;
240 // ------------------------------------------------------------------------
241 // ----------------------------------------------------------------------------
242 #define TUNNEL_ALL_EXCEPTIONS() \
243 WRAP_CONFIGBACKEND_CREATION_EXCEPTIONS1( UnoContextTunnel::tunnelFailure, true)
245 // ----------------------------------------------------------------------------
246 // ------------------------------------------------------------------------
248 uno::Reference< uno::XInterface > SAL_CALL instantiateDefaultProvider( uno::Reference< uno::XComponentContext > const & xTargetContext )
250 uno::Reference< uno::XComponentContext > xContext = UnoContextTunnel::recoverContext(xTargetContext);
252 ServiceImplementationInfo const * pProviderInfo =
253 ContextReader::testAdminService(xContext,true) ? &aAdminProviderInfo : &aConfigProviderInfo;
255 OProvider* pNewProvider = new OProvider(xContext,pProviderInfo);
256 uno::Reference< lang::XMultiServiceFactory > aRet( pNewProvider );
260 pNewProvider->connect();
262 TUNNEL_ALL_EXCEPTIONS()
264 return uno::Reference< uno::XInterface >( aRet, uno::UNO_QUERY );
267 // -----------------------------------------------------------------------------
268 class OProviderDisposingListener : public cppu::WeakImplHelper1<lang::XEventListener>
270 OProvider* m_pProvider;
272 public:
273 OProviderDisposingListener(OProvider* pProvider)
274 :m_pProvider(pProvider){}
276 virtual void SAL_CALL disposing(com::sun::star::lang::EventObject const& rEvt) throw()
278 CFG_TRACE_INFO("Service Manager or context disposed, disposing the provider");
279 if (OProvider* pProvider = m_pProvider)
281 m_pProvider = NULL;
282 pProvider->disposing(rEvt);
287 //=============================================================================
288 //= OProvider
289 //=============================================================================
290 //-----------------------------------------------------------------------------
291 OProvider::OProvider(uno::Reference< uno::XComponentContext > const & xContext, ServiceImplementationInfo const* pInfo)
292 :ServiceComponentImpl(pInfo)
293 ,OPropertyContainer(ServiceComponentImpl::rBHelper)
294 ,m_xContext(xContext)
295 ,m_pImpl(NULL)
296 ,m_bEnableAsync(false)
298 OSL_ENSURE(m_xContext.is(), "Creating a provider without a context");
299 attachToContext();
300 registerProperty(getPrefetchPropName(), ID_PREFETCH, 0,&m_aPrefetchNodes, ::getCppuType(&m_aPrefetchNodes));
301 registerProperty(getEnableAsyncPropName(), ID_ENABLEASYNC, 0, &m_bEnableAsync, ::getBooleanCppuType());
304 //-----------------------------------------------------------------------------
305 OProvider::~OProvider()
307 delete m_pImpl;
308 discardContext(releaseContext());
311 //-----------------------------------------------------------------------------
312 void OProvider::connect() throw (uno::Exception)
314 OSL_ENSURE( m_pImpl == NULL, "Error: Configuration Provider already is connected");
316 std::auto_ptr<OProviderImpl> pNewImpl( new OProviderImpl(this, m_xContext) );
318 implConnect(*pNewImpl,ContextReader(m_xContext));
320 m_pImpl = pNewImpl.release();
321 if (m_pImpl)
323 sal_Bool isEnabled = m_pImpl->getDefaultOptions().isAsyncEnabled();
324 this->setPropertyValue( getEnableAsyncPropName(), uno::makeAny(isEnabled) );
328 //-----------------------------------------------------------------------------
329 void OProvider::attachToContext()
331 UnoApiLock aLock;
332 ::osl::MutexGuard aGuard(ServiceComponentImpl::rBHelper.rMutex);
333 OSL_ASSERT(!m_xDisposeListener.is());
334 if (m_xContext.is())
336 uno::Reference< lang::XComponent > xContextComp(m_xContext, uno::UNO_QUERY);
337 uno::Reference< lang::XComponent > xServiceMgrComp(m_xContext->getServiceManager(), uno::UNO_QUERY);
339 m_xDisposeListener = new OProviderDisposingListener(this);
341 if (xContextComp.is()) xContextComp ->addEventListener(m_xDisposeListener);
342 if (xServiceMgrComp.is()) xServiceMgrComp->addEventListener(m_xDisposeListener);
344 OSL_ENSURE(xServiceMgrComp.is() || xContextComp.is(),
345 "Provider cannot detect shutdown -> no XComponent found");
349 //-----------------------------------------------------------------------------
350 uno::Reference< lang::XComponent > OProvider::releaseContext()
352 UnoApiLock aLock;
353 ::osl::MutexGuard aGuard(ServiceComponentImpl::rBHelper.rMutex);
355 uno::Reference< lang::XComponent > xContextComp(m_xContext, uno::UNO_QUERY);
356 if (m_xDisposeListener.is() && m_xContext.is())
358 uno::Reference< lang::XComponent > xServiceMgrComp(m_xContext->getServiceManager(), uno::UNO_QUERY);
360 if (xContextComp.is())
362 try { xContextComp ->removeEventListener(m_xDisposeListener); }
363 catch (uno::Exception & ) {}
366 if (xServiceMgrComp.is())
368 try { xServiceMgrComp->removeEventListener(m_xDisposeListener); }
369 catch (uno::Exception & ) {}
372 m_xDisposeListener = NULL;
373 m_xContext = NULL;
375 return xContextComp;
377 //-----------------------------------------------------------------------------
379 void OProvider::discardContext(uno::Reference< lang::XComponent > const & xContext)
381 UnoApiLock aLock;
382 if (xContext.is())
384 uno::Reference< uno::XComponentContext > xCC(xContext,uno::UNO_QUERY);
385 OSL_ASSERT(xCC.is());
387 if (BootstrapContext::isWrapper(xCC))
389 try { xContext->dispose(); }
390 catch (uno::Exception & ) {}
394 //-----------------------------------------------------------------------------
395 // XTypeProvider
396 //-----------------------------------------------------------------------------
397 uno::Sequence< uno::Type > SAL_CALL OProvider::getTypes( ) throw(uno::RuntimeException)
399 cppu::OTypeCollection aCollection(::getCppuType( (const uno::Reference< beans::XPropertySet > *)0 ),
400 ::getCppuType( (const uno::Reference< beans::XFastPropertySet > *)0 ),
401 ::getCppuType( (const uno::Reference< beans::XMultiPropertySet > *)0 ),
402 ::comphelper::concatSequences(ServiceComponentImpl::getTypes(), cppu::ImplHelper4< lang::XMultiServiceFactory, lang::XLocalizable, util::XRefreshable, util::XFlushable >::getTypes()));
403 return aCollection.getTypes();
406 // XPropertySet
407 //-----------------------------------------------------------------------------
408 uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OProvider::getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException)
410 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
413 //-----------------------------------------------------------------------------
414 uno::Reference< uno::XInterface > SAL_CALL OProvider::createInstance( const rtl::OUString& aServiceSpecifier )
415 throw(uno::Exception, uno::RuntimeException)
417 UnoApiLock aLock;
418 // same as creating with empty sequence of arguments
419 return this->createInstanceWithArguments( aServiceSpecifier, uno::Sequence< uno::Any >() );
422 //-----------------------------------------------------------------------------
423 uno::Reference< uno::XInterface > SAL_CALL
424 OProvider::createInstanceWithArguments( const rtl::OUString& aServiceSpecifier, const uno::Sequence< uno::Any >& aArguments )
425 throw(uno::Exception, uno::RuntimeException)
427 UnoApiLock aLock;
429 OSL_ENSURE(m_pImpl, "OProvider: no implementation available");
431 if (ServiceCreationInfo const* pInfo = findCreationInfo(aServiceSpecifier))
433 // it's a known service name - try to create without args
434 if (CreatorFunc create = pInfo->create)
436 return (m_pImpl->*create)(aArguments);
440 rtl::OUStringBuffer sMsg;
441 sMsg.appendAscii("ConfigurationProvider: Cannot create view - ");
442 sMsg.append( aServiceSpecifier ) .appendAscii(" is not a valid configuration access service. ");
444 throw lang::ServiceNotRegisteredException(sMsg.makeStringAndClear(),*this);
447 //-----------------------------------------------------------------------------
448 uno::Sequence< rtl::OUString > SAL_CALL OProvider::getAvailableServiceNames( )
449 throw(uno::RuntimeException)
451 UnoApiLock aLock;
453 sal_Int32 nCount = 0;
455 for (int i= 0; i< getCreateServiceDataCount(); ++i)
456 nCount += countServices(getCreateServiceData()[i].info);
459 uno::Sequence< rtl::OUString > aNames(nCount);
460 if (nCount > 0)
462 sal_Int32 n = 0;
463 for (int i= 0; i<getCreateServiceDataCount(); ++i)
465 ServiceRegistrationInfo const* pInfo = getCreateServiceData()[i].info;
466 sal_Char const * const* pNames = pInfo ? pInfo->registeredServiceNames : 0;
468 if (pNames)
470 while(*pNames)
472 aNames[n] = rtl::OUString::createFromAscii(*pNames);
473 ++n;
474 ++pNames;
480 return aNames;
483 // XLocalizable
484 //-----------------------------------------------------------------------------
485 void SAL_CALL OProvider::setLocale( const lang::Locale& eLocale )
486 throw (uno::RuntimeException)
488 UnoApiLock aLock;
490 OSL_ENSURE(m_pImpl, "OProvider: no implementation available");
492 m_pImpl->setDefaultLocale( eLocale );
495 //-----------------------------------------------------------------------------
496 lang::Locale SAL_CALL OProvider::getLocale()
497 throw (uno::RuntimeException)
499 UnoApiLock aLock;
501 OSL_ENSURE(m_pImpl, "OProvider: no implementation available");
503 return m_pImpl->getDefaultOptions().getUnoLocale();
506 //XRefreshable
507 //-----------------------------------------------------------------------------
508 void SAL_CALL OProvider::refresh()
509 throw (uno::RuntimeException)
511 UnoApiLock aLock;
513 OSL_ENSURE(m_pImpl, "OProvider: no implementation available");
517 m_pImpl->refreshAll();
519 catch (uno::RuntimeException& ) { throw; }
520 catch (uno::Exception& e)
522 // FIXME: use getCaughtException()
523 throw lang::WrappedTargetRuntimeException(e.Message, *this, uno::makeAny(e));
525 //Broadcast the changes
526 uno::Reference< css::util::XRefreshListener > const * const pRefresh = 0;
527 cppu::OInterfaceContainerHelper * aInterfaceContainer=
528 getBroadcastHelper().getContainer (::getCppuType(pRefresh));
530 if(aInterfaceContainer)
532 lang::EventObject aEventObject(*this);
534 cppu::OInterfaceIteratorHelper aIterator(*aInterfaceContainer);
535 while(aIterator.hasMoreElements())
537 uno::Reference< uno::XInterface > xIface = aIterator.next();
538 uno::Reference< util::XRefreshListener > xRefresh (xIface, uno::UNO_QUERY);
539 if (xRefresh.is())
541 xRefresh->refreshed(aEventObject);
546 //-----------------------------------------------------------------------------
547 void SAL_CALL OProvider::addRefreshListener(
548 const uno::Reference< util::XRefreshListener >& aListener )
549 throw (uno::RuntimeException)
551 UnoApiLock aLock;
552 getBroadcastHelper().addListener(::getCppuType(&aListener), aListener);
554 //-----------------------------------------------------------------------------
555 void SAL_CALL OProvider::removeRefreshListener(
556 const uno::Reference< util::XRefreshListener >& aListener )
557 throw (uno::RuntimeException)
559 UnoApiLock aLock;
560 getBroadcastHelper().removeListener(::getCppuType(&aListener), aListener);
562 //XFlushable
563 //-----------------------------------------------------------------------------
564 void SAL_CALL OProvider::flush( )
565 throw (uno::RuntimeException)
567 UnoApiLock aLock;
568 OSL_ENSURE(m_pImpl, "OProvider: no implementation available");
569 m_pImpl->flushAll();
571 //Broadcast the changes
572 uno::Reference< css::util::XFlushListener > const * const pFlush = 0;
573 cppu::OInterfaceContainerHelper * aInterfaceContainer=
574 getBroadcastHelper().getContainer(::getCppuType(pFlush));
576 if(aInterfaceContainer)
578 lang::EventObject aEventObject(*this);
580 cppu::OInterfaceIteratorHelper aIterator(*aInterfaceContainer);
581 while(aIterator.hasMoreElements())
583 uno::Reference< uno::XInterface > xIface = aIterator.next();
584 uno::Reference< util::XFlushListener > xFlush (xIface, uno::UNO_QUERY);
585 if (xFlush.is())
587 xFlush->flushed(aEventObject);
592 //-----------------------------------------------------------------------------
593 void SAL_CALL OProvider::addFlushListener(
594 const uno::Reference< util::XFlushListener >& aListener )
595 throw (uno::RuntimeException)
597 UnoApiLock aLock;
598 getBroadcastHelper().addListener(::getCppuType(&aListener), aListener);
600 //-----------------------------------------------------------------------------
601 void SAL_CALL OProvider::removeFlushListener(
602 const uno::Reference< util::XFlushListener >& aListener )
603 throw (uno::RuntimeException)
605 UnoApiLock aLock;
606 getBroadcastHelper().removeListener(::getCppuType(&aListener), aListener);
609 // XInterface
610 //-----------------------------------------------------------------------------
611 uno::Any SAL_CALL OProvider::queryInterface(uno::Type const& rType) throw(uno::RuntimeException)
613 UnoApiLock aLock;
614 uno::Any aRet( ServiceComponentImpl::queryInterface(rType) );
615 if ( !aRet.hasValue() )
616 aRet = cppu::ImplHelper4< lang::XMultiServiceFactory, lang::XLocalizable, util::XRefreshable, util::XFlushable >::queryInterface(rType);
617 if ( !aRet.hasValue() )
618 aRet = queryPropertyInterface(rType);
619 return aRet;
622 //-----------------------------------------------------------------------------
623 void OProvider::implConnect(OProviderImpl& _rFreshProviderImpl, const ContextReader& _rSettings) throw(uno::Exception)
625 UnoApiLock aLock;
626 if (!_rFreshProviderImpl.initSession(_rSettings))
627 throw uno::Exception(::rtl::OUString::createFromAscii("Could not connect to the configuration. Please check your settings."), static_cast< ::cppu::OWeakObject* >(this) );
630 //-----------------------------------------------------------------------------
631 void SAL_CALL OProvider::disposing(com::sun::star::lang::EventObject const& /*rEvt*/) throw()
633 UnoApiLock aLock;
634 releaseContext();
635 this->dispose();
638 //-----------------------------------------------------------------------------
639 void SAL_CALL OProvider::disposing()
641 UnoApiLock aLock;
643 if (m_pImpl)
644 m_pImpl->dispose();
646 uno::Reference< lang::XComponent > xComp = releaseContext();
648 ServiceComponentImpl::disposing();
649 OPropertyContainer::disposing();
651 discardContext( xComp );
654 // OPropertyArrayUsageHelper
655 // -------------------------------------------------------------------------
656 ::cppu::IPropertyArrayHelper* OProvider::createArrayHelper( ) const
658 UnoApiLock aLock;
659 uno::Sequence< beans::Property > aProps;
660 describeProperties(aProps);
661 return new ::cppu::OPropertyArrayHelper(aProps);
663 // -------------------------------------------------------------------------
664 ::cppu::IPropertyArrayHelper & OProvider::getInfoHelper()
666 UnoApiLock aLock;
667 return *getArrayHelper();
670 void SAL_CALL OProvider::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue)
671 throw (::com::sun::star::uno::Exception)
673 UnoApiLock aLock;
675 OPropertyContainer::setFastPropertyValue_NoBroadcast( nHandle, rValue );
677 switch(nHandle)
679 case ID_PREFETCH:
681 uno::Sequence< rtl::OUString > aNodeList;
682 rValue >>= aNodeList;
684 RequestOptions const aOptions = m_pImpl->getDefaultOptions();
686 for (sal_Int32 i = 0; i < aNodeList.getLength(); i++)
688 configuration::AbsolutePath aModulePath = configuration::AbsolutePath::makeModulePath(aNodeList[i]);
689 m_pImpl->fetchSubtree(aModulePath , aOptions);
691 }break;
693 case ID_ENABLEASYNC:
695 //Forward to TreeManager
696 sal_Bool bAsync;
697 if (rValue >>= bAsync)
699 m_pImpl->enableAsync(bAsync);
700 if (!bAsync)
701 this->flush();
703 else
704 OSL_ENSURE(false, "Unexpected type of new property value");
706 break;
707 default:
709 OSL_ENSURE(false, "OProvider::setFastPropertyValue_NoBroadcast -unknown property");
714 } // namespace configmgr