merge the formfield patch from ooo-build
[ooovba.git] / configmgr / source / backend / multistratumbackend.cxx
blob3bc3169a320dd5abb0ef6e18a9b7ad3f438fa064
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: multistratumbackend.cxx,v $
10 * $Revision: 1.13 $
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"
44 #endif
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>
57 #include <stdio.h>
59 //==============================================================================
60 #define OU2A(rtlOUString) (::rtl::OUStringToOString((rtlOUString), RTL_TEXTENCODING_ASCII_US).getStr())
61 //==============================================================================
63 namespace {
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('?'))
92 aArg = aArg.copy(1);
93 return true;
95 else
97 return false;
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)
129 ,mListenerList()
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);
148 else
150 throw uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
151 "MultiStratumBackend: Object was never Initialised")),*this);
154 return true;
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")),
168 *this, 0) ;
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;
187 if (bAdminMode)
189 // find given entity
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;
200 break;
204 else
206 mBackendStrata.resize(1);
210 if(mOwnerEntity.getLength()==0)
212 uno::Reference< backenduno::XBackendEntities > xEntities(
213 mBackendStrata[mBackendStrata.size()-1], uno::UNO_QUERY );
214 if (xEntities.is())
216 mOwnerEntity = xEntities->getOwnerEntity();
218 else
220 mOwnerEntity = kThisOwnerEntity;
223 mStrataListener = new BackendStrataListener(*this);
226 catch(uno::Exception& )
228 mSchemaSupplier.clear();
229 mBackendStrata.clear() ;
231 throw;
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")),
250 *this, uno::Any()) ;
254 //------------------------------------------------------------------------------
255 static
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;
263 try {
264 uno::Reference< css::task::XInteractionHandler > h(handler.get());
265 if (h.is()) {
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));
276 switch (chosen)
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
285 return false;
287 //------------------------------------------------------------------------------
288 void MultiStratumBackend::initializeBackendStrata(const uno::Reference<uno::XComponentContext>& aContext)
291 rtl::OUString sStrata;
292 //Get Strata
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")),
299 *this, uno::Any()) ;
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)
322 if(!bOptional)
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))
332 throw error;
336 if (xBackend.is())
338 mBackendStrata.push_back(xBackend) ;
342 //---------------------------------------------------------------------------------------------
343 // XBackendEntities
344 rtl::OUString SAL_CALL
345 MultiStratumBackend::getOwnerEntity( )
346 throw (uno::RuntimeException)
349 if (checkOkState())
351 return mOwnerEntity;
353 return rtl::OUString();
355 //------------------------------------------------------------------------------
357 rtl::OUString SAL_CALL
358 MultiStratumBackend::getAdminEntity()
359 throw (uno::RuntimeException)
361 osl::MutexGuard aGuard(mMutex);
362 if (checkOkState())
364 uno::Reference< backenduno::XBackendEntities > xEntities( mBackendStrata[0], uno::UNO_QUERY );
365 if(xEntities.is())
367 return xEntities->getAdminEntity();
369 else
371 return rtl::OUString();
374 return rtl::OUString();
376 //------------------------------------------------------------------------------
378 sal_Bool SAL_CALL
379 MultiStratumBackend::supportsEntity( const rtl::OUString& aEntity )
380 throw (backenduno::BackendAccessException, uno::RuntimeException)
383 osl::MutexGuard aGuard(mMutex);
384 if (checkOkState())
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 );
389 if (xEntities.is())
391 if( xEntities->supportsEntity(aEntity))
392 return true;
395 return false;
397 return false;
399 //------------------------------------------------------------------------------
401 sal_Bool SAL_CALL
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))
426 return true;
429 if (checkOkState())
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 );
434 if (xEntities.is())
436 if( xEntities->supportsEntity(aEntity))
437 return xEntities->isEqualEntity(aEntity,aOtherEntity);
440 return false;
442 return false;
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);
454 if (checkOkState())
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);
472 if (checkOkState())
474 return mSchemaSupplier->getComponentSchema(aComponent) ;
476 return NULL;
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)
486 if (checkOkState())
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)
501 if (checkOkState())
503 return getUpdateHandler(aComponent, mOwnerEntity) ;
505 return NULL;
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);
518 if (checkOkState())
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 );
536 if (xEntities.is())
538 if( xEntities->supportsEntity(aEntity))
540 return nNumLayers;
543 nNumLayers--;
545 rtl::OUStringBuffer sMsg;
546 sMsg.appendAscii("\n MultiStratumBackend: No Backend supports Entity: \"");
547 sMsg.append(aEntity);
548 throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),
549 *this, 0) ;
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) ;
565 if (xBackend.is())
567 if (xEntities.is())
569 if( !xEntities->supportsEntity(aEntity))
571 aEntity = xEntities->getOwnerEntity();
573 aMultiLayers = xBackend->listLayers(aComponent, aEntity) ;
575 else
577 aMultiLayers = xBackend->listOwnLayers(aComponent);
580 else
582 uno::Reference<backenduno::XMultiLayerStratum> xMultiLayerStratum(
583 mBackendStrata[i], uno::UNO_QUERY) ;
585 if (xMultiLayerStratum.is())
587 if (xEntities.is())
589 if( !xEntities->supportsEntity(aEntity))
591 aEntity = xEntities->getOwnerEntity();
593 aMultiLayers = xMultiLayerStratum->getLayers(
594 xMultiLayerStratum->listLayerIds(aComponent, aEntity),
595 rtl::OUString()) ;
598 else
600 throw backenduno::BackendSetupException(
601 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
602 "MultiStratumBackend: XMultiLayerStratum must support XBackendEntities")),
603 *this, uno::Any()) ;
607 else
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
615 if (xLayer.is())
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];
638 return aLayers;
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);
651 if (checkOkState())
654 sal_Int32 nNumSupportedLayers = mBackendStrata.size();
655 rtl::OUString aUsedEntity;
657 if(aEntity != mOwnerEntity)
659 nNumSupportedLayers = findSupportingStratum(aEntity);
660 aUsedEntity = aEntity;
662 else
664 uno::Reference< backenduno::XBackendEntities > xEntities( mBackendStrata[mBackendStrata.size()-1], uno::UNO_QUERY );
665 if (xEntities.is())
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;
675 if(xBackend.is())
677 if (aUsedEntity.getLength()==0)
679 xHandler = xBackend->getOwnUpdateHandler(aComponent) ;
680 return uno::Reference<backenduno::XUpdateHandler>(xHandler,uno::UNO_REF_QUERY_THROW);
682 else
684 xHandler = xBackend->getUpdateHandler(aComponent, aUsedEntity) ;
685 return uno::Reference<backenduno::XUpdateHandler>(xHandler,uno::UNO_REF_QUERY_THROW);
688 else
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));
700 else
702 uno::Reference< backenduno::XSingleLayerStratum > xSingleLayerStratum(
703 mBackendStrata[nStrataIndex], uno::UNO_REF_QUERY_THROW );
705 arguments [0] <<= xSingleLayerStratum->getUpdatableLayer(aComponent);
709 if(!xHandler.is())
713 const rtl::OUString kUpdateMerger(RTL_CONSTASCII_USTRINGPARAM(
714 "com.sun.star.configuration.backend.LayerUpdateMerger")) ;
717 if(!mFactory.is())
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 & )
726 {throw;}
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) ;
737 return NULL;
739 // ---------------------------------------------------------------------------
740 // ComponentHelper
741 void SAL_CALL MultiStratumBackend::disposing()
743 osl::MutexGuard aGuard(mMutex);
744 if (mFactory.is())
746 mFactory.clear();
748 if (mSchemaSupplier.is())
750 uno::Reference< lang::XComponent> xComp( mSchemaSupplier, uno::UNO_QUERY);
751 if (xComp.is())
753 xComp->dispose();
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 );
765 if (xComp.is())
769 xComp->dispose();
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 [] =
788 kBackendService,
791 static const ServiceImplementationInfo kServiceInfo =
793 kImplementation,
794 kServiceNames,
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 //------------------------------------------------------------------------------
822 sal_Bool SAL_CALL
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);
841 if(checkOkState())
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) ;
849 if (xBackend.is())
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);
862 if(checkOkState())
864 sal_Int32 nCount = mListenerList.count(aComponent);
865 if (nCount == 0)
867 OSL_TRACE("MultiStratumBackend: removeListener: no listener registered for component %s"
868 , aComponent.getStr());
870 else
872 ListenerList::iterator aIter;
873 aIter = mListenerList.find(aComponent);
874 mListenerList.erase(aIter);
875 if (nCount == 1)
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) ;
881 if (xBackend.is())
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());
920 else
922 aIter = mListenerList.begin();
924 if (aIter->first == aComponentName)
926 aIter->second->componentDataChanged(aEvent);
928 aIter++;
929 }while (aIter != mListenerList.end());
932 //------------------------------------------------------------------------------
933 } } // configmgr.backend