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: multistratumbackend.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"
34 #include "multistratumbackend.hxx"
36 #ifndef CONFIGMGR_API_FACTORY_HXX_
37 #include "confapifactory.hxx"
38 #endif // CONFIGMGR_API_FACTORY_HXX_
39 #include "serviceinfohelper.hxx"
40 #include "backendstratalistener.hxx"
42 #ifndef _CONFIGMGR_BOOTSTRAP_HXX
43 #include "bootstrap.hxx"
45 #include "simpleinteractionrequest.hxx"
46 #include "configinteractionhandler.hxx"
47 #include <com/sun/star/configuration/backend/XMultiLayerStratum.hpp>
48 #include <com/sun/star/configuration/backend/XSingleLayerStratum.hpp>
49 #include <com/sun/star/configuration/backend/StratumCreationException.hpp>
50 #include <com/sun/star/task/XInteractionHandler.hpp>
51 #include <com/sun/star/lang/DisposedException.hpp>
52 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
53 #include <rtl/ustrbuf.hxx>
55 #include <cppuhelper/exc_hlp.hxx>
59 //==============================================================================
60 #define OU2A(rtlOUString) (::rtl::OUStringToOString((rtlOUString), RTL_TEXTENCODING_ASCII_US).getStr())
61 //==============================================================================
65 namespace css
= com::sun::star
;
69 namespace configmgr
{ namespace backend
{
71 //==============================================================================
72 static const rtl::OUString
kSchemaServiceParam(
73 RTL_CONSTASCII_USTRINGPARAM( CONTEXT_ITEM_PREFIX_
"SchemaSupplier"));
75 static const rtl::OUString
kStrataServiceParam(
76 RTL_CONSTASCII_USTRINGPARAM( CONTEXT_ITEM_PREFIX_
"Strata"));
78 static const rtl::OUString
kEntity(
79 RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_
"EntityLayer")) ;
81 static const rtl::OUString
kAdminModeFlag(
82 RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_ADMINFLAG
)) ;
84 static const rtl::OUString
kThisOwnerEntity(
85 RTL_CONSTASCII_USTRINGPARAM("<ThisOwnerEntity>")) ;
87 //------------------------------------------------------------------------------
88 bool checkOptionalArg(rtl::OUString
& aArg
)
90 if (aArg
.getLength() && aArg
[0] == sal_Unicode('?'))
100 //------------------------------------------------------------------------------
101 void parseStrataInfo(const rtl::OUString aServiceList
,
102 std::vector
< std::pair
<rtl::OUString
, rtl::OUString
> >& aServiceInfoList
,
103 const uno::Reference
<uno::XInterface
>& pContext
)
105 sal_Int32 nNextToken
=0;
106 sal_Int32 nLength
= aServiceList
.getLength();
110 rtl::OUString aServiceName
=aServiceList
.getToken(0, ':',nNextToken
);
111 if((nNextToken
==-1)||(aServiceName
.getLength()==0))
113 throw backenduno::BackendSetupException(
114 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
115 "Malformed Strata Service specified")),
116 pContext
, uno::Any()) ;
118 rtl::OUString aServiceData
= aServiceList
.getToken(0, ';',nNextToken
);
120 std::pair
<rtl::OUString
, rtl::OUString
> aServiceInfo(aServiceName
,aServiceData
);
121 aServiceInfoList
.push_back(aServiceInfo
);
123 while (nNextToken
>= 0 && nNextToken
< nLength
) ;
125 //------------------------------------------------------------------------------
126 MultiStratumBackend::MultiStratumBackend(
127 const uno::Reference
<uno::XComponentContext
>& xContext
)
128 : cppu::WeakComponentImplHelper7
< backenduno::XBackend
, backenduno::XBackendEntities
, backenduno::XVersionedSchemaSupplier
, backenduno::XBackendChangesNotifier
, backenduno::XBackendChangesListener
, lang::XInitialization
, lang::XServiceInfo
>(mMutex
), mFactory(xContext
->getServiceManager(),uno::UNO_QUERY_THROW
)
133 //------------------------------------------------------------------------------
135 MultiStratumBackend::~MultiStratumBackend()
138 //------------------------------------------------------------------------------
139 bool MultiStratumBackend::checkOkState()
141 if (!mSchemaSupplier
.is())
143 if(rBHelper
.bDisposed
)
145 throw lang::DisposedException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
146 "MultiStratumBackend: Backends already disposed")),*this);
150 throw uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
151 "MultiStratumBackend: Object was never Initialised")),*this);
156 //------------------------------------------------------------------------------
158 void SAL_CALL
MultiStratumBackend::initialize(
159 const uno::Sequence
<uno::Any
>& aParameters
)
160 throw (uno::RuntimeException
, uno::Exception
,
161 css::configuration::InvalidBootstrapFileException
,
162 backenduno::BackendSetupException
) {
164 if (aParameters
.getLength() == 0) {
165 throw lang::IllegalArgumentException(
166 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
167 "No parameters provided to MultiStratumBackend")),
171 uno::Reference
<uno::XComponentContext
> context
;
173 for (sal_Int32 i
= 0 ; i
< aParameters
.getLength() ; ++ i
) {
174 if (aParameters
[i
] >>= context
) { break ; }
180 //Initialize Backends
181 initializeSchemaSupplier (context
);
182 initializeBackendStrata(context
);
184 sal_Bool bAdminMode
= false;
185 context
->getValueByName(kAdminModeFlag
) >>= bAdminMode
;
190 rtl::OUString sDefaultEntity
;
191 if ( (context
->getValueByName(kEntity
) >>= sDefaultEntity
) && sDefaultEntity
.getLength() )
193 for (sal_uInt32 i
= 0; i
< mBackendStrata
.size(); i
++)
195 uno::Reference
< backenduno::XBackendEntities
> xEntities( mBackendStrata
[i
], uno::UNO_QUERY
);
196 if (xEntities
.is()&& xEntities
->supportsEntity(sDefaultEntity
))
198 mBackendStrata
.resize(i
+1);
199 mOwnerEntity
= sDefaultEntity
;
206 mBackendStrata
.resize(1);
210 if(mOwnerEntity
.getLength()==0)
212 uno::Reference
< backenduno::XBackendEntities
> xEntities(
213 mBackendStrata
[mBackendStrata
.size()-1], uno::UNO_QUERY
);
216 mOwnerEntity
= xEntities
->getOwnerEntity();
220 mOwnerEntity
= kThisOwnerEntity
;
223 mStrataListener
= new BackendStrataListener(*this);
226 catch(uno::Exception
& )
228 mSchemaSupplier
.clear();
229 mBackendStrata
.clear() ;
235 //------------------------------------------------------------------------------
236 void MultiStratumBackend::initializeSchemaSupplier(const uno::Reference
<uno::XComponentContext
>& aContext
)
239 rtl::OUString aServiceName
;
241 aContext
->getValueByName(kSchemaServiceParam
) >>= aServiceName
;
242 uno::Sequence
< uno::Any
> aInitArgs( 1 );
243 aInitArgs
[0] <<= aContext
;
244 mSchemaSupplier
= uno::Reference
<backenduno::XSchemaSupplier
>::query(mFactory
->createInstanceWithArguments(aServiceName
,aInitArgs
)) ;
245 if (!mSchemaSupplier
.is())
247 throw backenduno::BackendSetupException(
248 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
249 "MultiStratumBackend: Could not create Schema Supplier service")),
254 //------------------------------------------------------------------------------
256 bool approveRecovery(const backenduno::StratumCreationException
& aError
)
258 sal_uInt32
const k_supported_choices
= apihelper::CONTINUATION_APPROVE
; //| apihelper::CONTINUATION_DISAPPROVE;
260 sal_uInt32 chosen
= apihelper::CONTINUATION_UNKNOWN
;
262 apihelper::ConfigurationInteractionHandler handler
;
264 uno::Reference
< css::task::XInteractionHandler
> h(handler
.get());
266 rtl::Reference
< apihelper::SimpleInteractionRequest
> req(
267 new apihelper::SimpleInteractionRequest(
268 uno::makeAny(aError
), k_supported_choices
));
269 h
->handle(req
.get());
270 chosen
= req
->getResponse();
272 } catch (uno::Exception
& e
) {
273 OSL_TRACE("Warning - Configuration: Interaction handler failed: [%s]\n", OU2A(e
.Message
));
278 case apihelper::CONTINUATION_APPROVE
: return true;
279 case apihelper::CONTINUATION_DISAPPROVE
: return false;
280 case apihelper::CONTINUATION_UNKNOWN
: break;
282 default: OSL_ENSURE(false,"Unsolicited continuation chosen"); break;
284 // no choice available - default: disapprove
287 //------------------------------------------------------------------------------
288 void MultiStratumBackend::initializeBackendStrata(const uno::Reference
<uno::XComponentContext
>& aContext
)
291 rtl::OUString sStrata
;
293 aContext
->getValueByName(kStrataServiceParam
) >>= sStrata
;
294 if(sStrata
.getLength()==0)
296 throw backenduno::BackendSetupException(
297 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
298 "MultiStratumBackend: No Strata Services Specified")),
303 //need to parse the Strata to extract service names and data location
304 std::vector
< std::pair
<rtl::OUString
, rtl::OUString
> > aServiceInfoList
;
305 parseStrataInfo(sStrata
,aServiceInfoList
,*this);
307 for (std::vector
< std::pair
<rtl::OUString
, rtl::OUString
> >::const_iterator it
= aServiceInfoList
.begin(); it
!= aServiceInfoList
.end(); ++it
)
309 uno::Sequence
< uno::Any
> aInitArgs( 1 );
310 rtl::OUString sServiceName
= it
->first
;
311 const rtl::OUString
& sServiceData
= it
->second
;
312 aInitArgs
[0] <<= sServiceData
;
313 uno::Reference
<uno::XInterface
> xBackend
;
314 bool bOptional
= checkOptionalArg(sServiceName
);
318 xBackend
= mFactory
->createInstanceWithArguments(sServiceName
,aInitArgs
);
320 catch (uno::Exception
& exception
)
324 static const sal_Char sErrContext
[] = "MultiStratumBackend: Could not create Backend Stratum Service: ";
325 rtl::OUString
const sContext(RTL_CONSTASCII_USTRINGPARAM(sErrContext
));
326 rtl::OUString
const sMessage
= sContext
.concat(exception
.Message
);
328 backenduno::StratumCreationException
error(sMessage
,*this,
329 ::cppu::getCaughtException(),
330 sServiceName
,sServiceData
);
331 if (!approveRecovery(error
))
338 mBackendStrata
.push_back(xBackend
) ;
342 //---------------------------------------------------------------------------------------------
344 rtl::OUString SAL_CALL
345 MultiStratumBackend::getOwnerEntity( )
346 throw (uno::RuntimeException
)
353 return rtl::OUString();
355 //------------------------------------------------------------------------------
357 rtl::OUString SAL_CALL
358 MultiStratumBackend::getAdminEntity()
359 throw (uno::RuntimeException
)
361 osl::MutexGuard
aGuard(mMutex
);
364 uno::Reference
< backenduno::XBackendEntities
> xEntities( mBackendStrata
[0], uno::UNO_QUERY
);
367 return xEntities
->getAdminEntity();
371 return rtl::OUString();
374 return rtl::OUString();
376 //------------------------------------------------------------------------------
379 MultiStratumBackend::supportsEntity( const rtl::OUString
& aEntity
)
380 throw (backenduno::BackendAccessException
, uno::RuntimeException
)
383 osl::MutexGuard
aGuard(mMutex
);
386 for (std::vector
< uno::Reference
<uno::XInterface
> >::const_iterator it
= mBackendStrata
.begin(); it
!= mBackendStrata
.end(); ++it
)
388 uno::Reference
< backenduno::XBackendEntities
> xEntities( *it
, uno::UNO_QUERY
);
391 if( xEntities
->supportsEntity(aEntity
))
399 //------------------------------------------------------------------------------
402 MultiStratumBackend::isEqualEntity( const rtl::OUString
& aEntity
, const rtl::OUString
& aOtherEntity
)
403 throw (backenduno::BackendAccessException
,
404 lang::IllegalArgumentException
,
405 uno::RuntimeException
)
407 osl::MutexGuard
aGuard(mMutex
);
408 if (aEntity
.getLength() == 0)
410 rtl::OUString
const sMsg(RTL_CONSTASCII_USTRINGPARAM(
411 "LocalSingleBackend - Invalid empty entity."));
413 throw lang::IllegalArgumentException(sMsg
, *this, 1);
415 if (aOtherEntity
.getLength() == 0)
417 rtl::OUString
const sMsg(RTL_CONSTASCII_USTRINGPARAM(
418 "LocalSingleBackend - Invalid empty entity."));
420 throw lang::IllegalArgumentException(sMsg
, *this, 2);
424 if (aEntity
.equals(aOtherEntity
))
431 for (std::vector
< uno::Reference
<uno::XInterface
> >::const_iterator it
= mBackendStrata
.begin(); it
!= mBackendStrata
.end(); ++it
)
433 uno::Reference
< backenduno::XBackendEntities
> xEntities( *it
, uno::UNO_QUERY
);
436 if( xEntities
->supportsEntity(aEntity
))
437 return xEntities
->isEqualEntity(aEntity
,aOtherEntity
);
444 //------------------------------------------------------------------------------
446 rtl::OUString SAL_CALL
447 MultiStratumBackend::getSchemaVersion(const rtl::OUString
& aComponent
)
448 throw (backenduno::BackendAccessException
,
449 lang::IllegalArgumentException
,
450 uno::RuntimeException
)
452 osl::MutexGuard
aGuard(mMutex
);
456 uno::Reference
<backenduno::XVersionedSchemaSupplier
> xVersionSupplier(mSchemaSupplier
,uno::UNO_QUERY
);
457 if (xVersionSupplier
.is())
458 return xVersionSupplier
->getSchemaVersion(aComponent
) ;
460 return rtl::OUString();
462 //------------------------------------------------------------------------------
464 uno::Reference
<backenduno::XSchema
> SAL_CALL
465 MultiStratumBackend::getComponentSchema(const rtl::OUString
& aComponent
)
466 throw (backenduno::BackendAccessException
,
467 lang::IllegalArgumentException
,
468 uno::RuntimeException
)
470 osl::MutexGuard
aGuard(mMutex
);
474 return mSchemaSupplier
->getComponentSchema(aComponent
) ;
478 //------------------------------------------------------------------------------
480 uno::Sequence
<uno::Reference
<backenduno::XLayer
> > SAL_CALL
481 MultiStratumBackend::listOwnLayers(const rtl::OUString
& aComponent
)
482 throw (backenduno::BackendAccessException
,
483 lang::IllegalArgumentException
,
484 uno::RuntimeException
)
488 return listLayers(aComponent
, mOwnerEntity
) ;
490 return uno::Sequence
<uno::Reference
<backenduno::XLayer
> >() ;
492 //------------------------------------------------------------------------------
494 uno::Reference
<backenduno::XUpdateHandler
> SAL_CALL
495 MultiStratumBackend::getOwnUpdateHandler(const rtl::OUString
& aComponent
)
496 throw (backenduno::BackendAccessException
,
497 lang::NoSupportException
,
498 lang::IllegalArgumentException
,
499 uno::RuntimeException
)
503 return getUpdateHandler(aComponent
, mOwnerEntity
) ;
507 //------------------------------------------------------------------------------
509 uno::Sequence
<uno::Reference
<backenduno::XLayer
> > SAL_CALL
510 MultiStratumBackend::listLayers(const rtl::OUString
& aComponent
,
511 const rtl::OUString
& aEntity
)
512 throw (backenduno::BackendAccessException
,
513 lang::IllegalArgumentException
,
514 uno::RuntimeException
)
517 osl::MutexGuard
aGuard(mMutex
);
520 sal_Int32 nNumSupportedLayers
= mBackendStrata
.size();
521 if(aEntity
!= mOwnerEntity
)
523 nNumSupportedLayers
= findSupportingStratum(aEntity
);
525 return searchSupportingStrata(nNumSupportedLayers
,aEntity
,aComponent
);
527 return uno::Sequence
<uno::Reference
<backenduno::XLayer
> >();
529 //------------------------------------------------------------------------------
530 sal_Int32
MultiStratumBackend::findSupportingStratum(const rtl::OUString
& aEntity
)
532 sal_Int32 nNumLayers
= mBackendStrata
.size();
533 for (std::vector
< uno::Reference
<uno::XInterface
> >::reverse_iterator it
= mBackendStrata
.rbegin(); it
!= mBackendStrata
.rend(); ++it
)
535 uno::Reference
< backenduno::XBackendEntities
> xEntities( *it
, uno::UNO_QUERY
);
538 if( xEntities
->supportsEntity(aEntity
))
545 rtl::OUStringBuffer sMsg
;
546 sMsg
.appendAscii("\n MultiStratumBackend: No Backend supports Entity: \"");
547 sMsg
.append(aEntity
);
548 throw lang::IllegalArgumentException(sMsg
.makeStringAndClear(),
551 //------------------------------------------------------------------------------
552 uno::Sequence
<uno::Reference
<backenduno::XLayer
> >
553 MultiStratumBackend::searchSupportingStrata(sal_Int32 nNumLayers
,
554 rtl::OUString aEntity
,
555 const rtl::OUString
& aComponent
)
557 uno::Sequence
<uno::Reference
<backenduno::XLayer
> > aLayers
;
558 std::vector
<uno::Reference
<backenduno::XLayer
> > aBackendLayers
;
559 for (sal_Int32 i
= 0 ; i
< nNumLayers
; ++ i
)
561 uno::Sequence
<uno::Reference
<backenduno::XLayer
> > aMultiLayers
;
562 uno::Reference
< backenduno::XBackendEntities
> xEntities(mBackendStrata
[i
], uno::UNO_QUERY
);
564 uno::Reference
<backenduno::XBackend
> xBackend(mBackendStrata
[i
], uno::UNO_QUERY
) ;
569 if( !xEntities
->supportsEntity(aEntity
))
571 aEntity
= xEntities
->getOwnerEntity();
573 aMultiLayers
= xBackend
->listLayers(aComponent
, aEntity
) ;
577 aMultiLayers
= xBackend
->listOwnLayers(aComponent
);
582 uno::Reference
<backenduno::XMultiLayerStratum
> xMultiLayerStratum(
583 mBackendStrata
[i
], uno::UNO_QUERY
) ;
585 if (xMultiLayerStratum
.is())
589 if( !xEntities
->supportsEntity(aEntity
))
591 aEntity
= xEntities
->getOwnerEntity();
593 aMultiLayers
= xMultiLayerStratum
->getLayers(
594 xMultiLayerStratum
->listLayerIds(aComponent
, aEntity
),
600 throw backenduno::BackendSetupException(
601 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
602 "MultiStratumBackend: XMultiLayerStratum must support XBackendEntities")),
609 uno::Reference
<backenduno::XSingleLayerStratum
> xSingleLayerStratum(
610 mBackendStrata
[i
], uno::UNO_REF_QUERY_THROW
) ;
611 if (xSingleLayerStratum
.is())
613 uno::Reference
<backenduno::XLayer
> xLayer
= xSingleLayerStratum
->getLayer( aComponent
, rtl::OUString());
614 //Could be an empty layer
617 aBackendLayers
.push_back(xLayer
);
622 // There might be non-existent layers in the list if there's no
623 // actual data associated to a given layer id. Hence we have to
624 // compress the list.
625 for (sal_Int32 j
= 0 ; j
< aMultiLayers
.getLength() ; ++j
)
627 if (aMultiLayers
[j
].is())
629 aBackendLayers
.push_back( aMultiLayers
[j
]);
633 aLayers
.realloc(aBackendLayers
.size());
634 for (sal_uInt32 k
=0; k
< aBackendLayers
.size();k
++)
636 aLayers
[k
] = aBackendLayers
[k
];
640 //------------------------------------------------------------------------------
641 uno::Reference
<backenduno::XUpdateHandler
> SAL_CALL
642 MultiStratumBackend::getUpdateHandler(const rtl::OUString
& aComponent
,
643 const rtl::OUString
& aEntity
)
644 throw (backenduno::BackendAccessException
,
645 lang::NoSupportException
,
646 lang::IllegalArgumentException
,
647 uno::RuntimeException
)
649 osl::MutexGuard
aGuard(mMutex
);
654 sal_Int32 nNumSupportedLayers
= mBackendStrata
.size();
655 rtl::OUString aUsedEntity
;
657 if(aEntity
!= mOwnerEntity
)
659 nNumSupportedLayers
= findSupportingStratum(aEntity
);
660 aUsedEntity
= aEntity
;
664 uno::Reference
< backenduno::XBackendEntities
> xEntities( mBackendStrata
[mBackendStrata
.size()-1], uno::UNO_QUERY
);
667 aUsedEntity
= xEntities
->getOwnerEntity();
670 sal_Int32 nStrataIndex
= nNumSupportedLayers
-1;
672 uno::Reference
<backenduno::XBackend
> xBackend(
673 mBackendStrata
[nStrataIndex
], uno::UNO_QUERY
) ;
674 uno::Reference
< uno::XInterface
> xHandler
;
677 if (aUsedEntity
.getLength()==0)
679 xHandler
= xBackend
->getOwnUpdateHandler(aComponent
) ;
680 return uno::Reference
<backenduno::XUpdateHandler
>(xHandler
,uno::UNO_REF_QUERY_THROW
);
684 xHandler
= xBackend
->getUpdateHandler(aComponent
, aUsedEntity
) ;
685 return uno::Reference
<backenduno::XUpdateHandler
>(xHandler
,uno::UNO_REF_QUERY_THROW
);
691 uno::Sequence
<uno::Any
> arguments(1) ;
693 uno::Reference
< backenduno::XMultiLayerStratum
> xMultiLayerStratum
694 (mBackendStrata
[nStrataIndex
], uno::UNO_QUERY
);
695 if(xMultiLayerStratum
.is())
697 arguments
[0] <<= xMultiLayerStratum
->getUpdatableLayer(
698 xMultiLayerStratum
->getUpdateLayerId(aComponent
,aUsedEntity
));
702 uno::Reference
< backenduno::XSingleLayerStratum
> xSingleLayerStratum(
703 mBackendStrata
[nStrataIndex
], uno::UNO_REF_QUERY_THROW
);
705 arguments
[0] <<= xSingleLayerStratum
->getUpdatableLayer(aComponent
);
713 const rtl::OUString
kUpdateMerger(RTL_CONSTASCII_USTRINGPARAM(
714 "com.sun.star.configuration.backend.LayerUpdateMerger")) ;
719 throw lang::DisposedException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
720 "MultiStratumBackend: Service Factory already dispoed")),*this);
723 xHandler
= mFactory
->createInstanceWithArguments(kUpdateMerger
, arguments
);
725 catch (uno::RuntimeException
& )
727 catch (uno::Exception
& e
)
729 const rtl::OUString
sMessage(RTL_CONSTASCII_USTRINGPARAM(
730 "Configuration MultiStratumBackend: Cannot create UpdateMerger - error message: ")) ;
731 throw uno::RuntimeException(sMessage
.concat(e
.Message
),*this);
734 return uno::Reference
<backenduno::XUpdateHandler
>(xHandler
, uno::UNO_REF_QUERY_THROW
) ;
739 // ---------------------------------------------------------------------------
741 void SAL_CALL
MultiStratumBackend::disposing()
743 osl::MutexGuard
aGuard(mMutex
);
748 if (mSchemaSupplier
.is())
750 uno::Reference
< lang::XComponent
> xComp( mSchemaSupplier
, uno::UNO_QUERY
);
755 if (mSchemaSupplier
.is())
757 mSchemaSupplier
.clear();
760 if (!mBackendStrata
.empty())
762 for (std::vector
< uno::Reference
<uno::XInterface
> >::const_iterator it
= mBackendStrata
.begin(); it
!= mBackendStrata
.end(); ++it
)
764 uno::Reference
< lang::XComponent
> xComp( *it
, uno::UNO_QUERY
);
771 catch(uno::Exception
&){}
774 mBackendStrata
.clear();
779 //------------------------------------------------------------------------------
781 static const sal_Char
* const kBackendService
= "com.sun.star.configuration.backend.Backend" ;
783 static const sal_Char
* const kImplementation
=
784 "com.sun.star.comp.configuration.backend.MultiStratumBackend" ;
786 static sal_Char
const * const kServiceNames
[] =
791 static const ServiceImplementationInfo kServiceInfo
=
798 const ServiceRegistrationInfo
*getMultiStratumBackendServiceInfo()
800 return getRegistrationInfo(&kServiceInfo
) ;
803 uno::Reference
<uno::XInterface
> SAL_CALL
804 instantiateMultiStratumBackend(const uno::Reference
< uno::XComponentContext
>& xContext
)
806 return *new MultiStratumBackend(xContext
) ;
808 //------------------------------------------------------------------------------
810 static const rtl::OUString
kImplementationName(
811 RTL_CONSTASCII_USTRINGPARAM(kImplementation
)) ;
812 //------------------------------------------------------------------------------
814 rtl::OUString SAL_CALL
815 MultiStratumBackend::getImplementationName(void)
816 throw (uno::RuntimeException
)
818 return ServiceInfoHelper(&kServiceInfo
).getImplementationName() ;
820 //------------------------------------------------------------------------------
823 MultiStratumBackend::supportsService(const rtl::OUString
& aServiceName
)
824 throw (uno::RuntimeException
)
826 return ServiceInfoHelper(&kServiceInfo
).supportsService(aServiceName
) ;
828 //------------------------------------------------------------------------------
829 uno::Sequence
<rtl::OUString
> SAL_CALL
830 MultiStratumBackend::getSupportedServiceNames(void)
831 throw (uno::RuntimeException
)
833 return ServiceInfoHelper(&kServiceInfo
).getSupportedServiceNames() ;
835 //------------------------------------------------------------------------------
836 void SAL_CALL
MultiStratumBackend::addChangesListener( const uno::Reference
<backenduno::XBackendChangesListener
>& xListener
,
837 const rtl::OUString
& aComponent
)
838 throw (::com::sun::star::uno::RuntimeException
)
840 osl::MutexGuard
aGuard(mMutex
);
844 mListenerList
.insert( ListenerList::value_type(aComponent
, xListener
));
845 //Now register with lower layers
846 for (sal_uInt32 i
= 0 ; i
< mBackendStrata
.size() ; ++ i
)
848 uno::Reference
<backenduno::XBackendChangesNotifier
> xBackend(mBackendStrata
[i
], uno::UNO_QUERY
) ;
851 xBackend
->addChangesListener(mStrataListener
, aComponent
);
856 //------------------------------------------------------------------------------
857 void SAL_CALL
MultiStratumBackend::removeChangesListener( const uno::Reference
<backenduno::XBackendChangesListener
>& /*xListner*/,
858 const rtl::OUString
& aComponent
)
859 throw (::com::sun::star::uno::RuntimeException
)
861 osl::MutexGuard
aGuard(mMutex
);
864 sal_Int32 nCount
= mListenerList
.count(aComponent
);
867 OSL_TRACE("MultiStratumBackend: removeListener: no listener registered for component %s"
868 , aComponent
.getStr());
872 ListenerList::iterator aIter
;
873 aIter
= mListenerList
.find(aComponent
);
874 mListenerList
.erase(aIter
);
877 //Deregister Listener from strata backend if they support notification
878 for (sal_uInt32 i
= 0 ; i
< mBackendStrata
.size(); ++ i
)
880 uno::Reference
<backenduno::XBackendChangesNotifier
> xBackend(mBackendStrata
[i
], uno::UNO_QUERY
) ;
883 xBackend
->removeChangesListener(mStrataListener
, aComponent
);
890 //------------------------------------------------------------------------------
891 void MultiStratumBackend::componentDataChanged(const backenduno::ComponentChangeEvent
& aEvent
)
892 throw (::com::sun::star::uno::RuntimeException
)
896 notifyListeners( aEvent
);
899 catch (uno::RuntimeException
& ) { throw; }
900 catch (uno::Exception
& e
)
902 throw lang::WrappedTargetRuntimeException(e
.Message
, *this, uno::makeAny(e
));
905 //------------------------------------------------------------------------------
906 void MultiStratumBackend::disposing( lang::EventObject
const & /*rSource*/ )
907 throw (::com::sun::star::uno::RuntimeException
)
909 //------------------------------------------------------------------------------
910 void MultiStratumBackend::notifyListeners(const backenduno::ComponentChangeEvent
& aEvent
)const
912 //fire off notification to all registered listeners for specific Component
913 ListenerList::const_iterator aIter
;
914 rtl::OUString aComponentName
= aEvent
.Component
;
915 if (mListenerList
.empty())
917 OSL_TRACE("MultiStratumBackend: notifyListeners: no listeners registered for component %s",
918 aComponentName
.getStr());
922 aIter
= mListenerList
.begin();
924 if (aIter
->first
== aComponentName
)
926 aIter
->second
->componentDataChanged(aEvent
);
929 }while (aIter
!= mListenerList
.end());
932 //------------------------------------------------------------------------------
933 } } // configmgr.backend