update dev300-m58
[ooovba.git] / configmgr / source / platformbe / systemintegrationmanager.cxx
blob0fee745f4e1a8b694d8513886e4d7797382d5ce9
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: systemintegrationmanager.cxx,v $
10 * $Revision: 1.8 $
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"
33 #include "systemintegrationmanager.hxx"
34 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
35 #include <com/sun/star/container/XEnumeration.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/registry/XRegistryKey.hpp>
39 namespace configmgr { namespace backend {
42 //==============================================================================
43 #define OU2A( oustr ) (rtl::OUStringToOString( oustr, RTL_TEXTENCODING_ASCII_US ).getStr())
44 //==============================================================================
45 uno::Reference<backenduno::XSingleLayerStratum> BackendRef::getBackend(uno::Reference<uno::XComponentContext> const & xContext)
47 if (!mBackend.is() && mFactory.is())
48 try
50 mBackend.set( mFactory->createInstanceWithContext(xContext), uno::UNO_QUERY_THROW );
52 catch(uno::Exception& e)
54 OSL_TRACE("SystemIntegration::getSupportingBackend - could not create platform Backend: %s",
55 OU2A(e.Message) );
57 return mBackend;
59 //------------------------------------------------------------------------------
60 void BackendRef::disposeBackend()
62 uno::Reference< lang::XComponent> xComp( mBackend, uno::UNO_QUERY );
63 if (xComp.is())
64 try
66 xComp->dispose();
68 catch(uno::Exception &)
70 mBackend.clear();
72 //==============================================================================
73 SystemIntegrationManager::SystemIntegrationManager(const uno::Reference<uno::XComponentContext>& xContext)
74 : cppu::WeakComponentImplHelper4< backenduno::XBackend, backenduno::XBackendChangesNotifier, lang::XInitialization, lang::XServiceInfo>(mMutex)
75 , mMutex()
76 , mContext(xContext)
77 , mPlatformBackends()
80 //------------------------------------------------------------------------------
81 SystemIntegrationManager::~SystemIntegrationManager()
84 //------------------------------------------------------------------------------
85 void SAL_CALL SystemIntegrationManager::initialize(
86 const uno::Sequence<uno::Any>& /*aParameters*/)
87 throw (uno::RuntimeException, uno::Exception,
88 lang::IllegalArgumentException,
89 backenduno::BackendSetupException)
91 buildLookupTable();
93 //------------------------------------------------------------------------------
94 static const rtl::OUString getAllComponentsName()
96 sal_Unicode const kStar = '*';
97 return rtl::OUString(&kStar,1);
100 //------------------------------------------------------------------------------
102 void SystemIntegrationManager::buildLookupTable()
104 static const rtl::OUString kPlatformServiceName(
105 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.PlatformBackend")) ;
107 //Build platform backend map componentName -> servicefactory
108 uno::Reference<css::container::XContentEnumerationAccess> xEnumAccess
109 (mContext->getServiceManager(),uno::UNO_QUERY_THROW);
111 uno::Reference<css::container::XEnumeration> xEnum =
112 xEnumAccess->createContentEnumeration(kPlatformServiceName);
113 if (xEnum.is())
115 osl::MutexGuard lock(mMutex);
116 while (xEnum->hasMoreElements())
118 uno::Reference<lang::XSingleComponentFactory> xServiceFactory( xEnum->nextElement(),uno::UNO_QUERY);
119 if (xServiceFactory.is())
121 uno::Sequence<rtl::OUString> aKeys = getSupportedComponents(xServiceFactory);
123 for (sal_Int32 i = 0 ; i < aKeys.getLength() ; ++i)
125 BackendRef aBackendRef(xServiceFactory);
126 //OSL_TRACE("SystemInteg -Adding Factory Backend to map for key %s",
127 //rtl::OUStringToOString(aKeys[i], RTL_TEXTENCODING_ASCII_US).getStr() );
128 mPlatformBackends.insert( std::multimap<rtl::OUString, BackendRef>::value_type(aKeys[i],aBackendRef));
134 //---------------------------------------------------------------------------------------------
136 uno::Sequence<rtl::OUString>
137 SystemIntegrationManager::getSupportedComponents(const uno::Reference<lang::XSingleComponentFactory>& xFactory)
139 static const rtl::OUString kProperSubkeyName( RTL_CONSTASCII_USTRINGPARAM("/DATA/SupportedComponents")) ;
140 static const rtl::OUString kImplKeyPropertyName( RTL_CONSTASCII_USTRINGPARAM("ImplementationKey")) ;
142 uno::Reference<css::beans::XPropertySet> xSMProp(xFactory,uno::UNO_QUERY);
143 if (xSMProp.is())
147 uno::Reference< css::registry::XRegistryKey > xImplKey(
148 xSMProp->getPropertyValue(kImplKeyPropertyName), uno::UNO_QUERY);
150 if (xImplKey.is())
152 uno::Reference< css::registry::XRegistryKey > xKey(
153 xImplKey->openKey(kProperSubkeyName));
154 if(xKey.is())
155 return xKey->getAsciiListValue();
158 catch(css::beans::UnknownPropertyException&){}
159 catch(css::registry::InvalidValueException&){}
160 catch(css::registry::InvalidRegistryException&){}
162 static const rtl::OUString kAllComponentsName = getAllComponentsName();
163 return uno::Sequence<rtl::OUString>(&kAllComponentsName, 1);
165 //---------------------------------------------------------------------------------------------
167 uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
168 SystemIntegrationManager::listOwnLayers(const rtl::OUString& aComponent)
169 throw (backenduno::BackendAccessException,
170 lang::IllegalArgumentException,
171 uno::RuntimeException)
173 return listLayers(aComponent, rtl::OUString() ) ;
175 //------------------------------------------------------------------------------
177 uno::Reference<backenduno::XUpdateHandler> SAL_CALL
178 SystemIntegrationManager::getOwnUpdateHandler(const rtl::OUString& aComponent)
179 throw (backenduno::BackendAccessException,
180 lang::NoSupportException,
181 lang::IllegalArgumentException,
182 uno::RuntimeException)
185 return getUpdateHandler(aComponent, rtl::OUString()) ;
187 //------------------------------------------------------------------------------
189 std::vector< uno::Reference<backenduno::XSingleLayerStratum> > SystemIntegrationManager::getSupportingBackends(const rtl::OUString& aComponent)
191 std::vector< uno::Reference<backenduno::XSingleLayerStratum> > backends;
193 osl::MutexGuard lock(mMutex);
194 std::pair<std::multimap<rtl::OUString, BackendRef>::iterator, std::multimap<rtl::OUString, BackendRef>::iterator> aRange = mPlatformBackends.equal_range(aComponent);
195 for (std::multimap<rtl::OUString, BackendRef>::iterator it=aRange.first; it != aRange.second; )
197 std::multimap<rtl::OUString, BackendRef>::iterator cur = it++; // increment here, as erase() may invalidate cur
198 uno::Reference<backenduno::XSingleLayerStratum> xBackend = cur->second.getBackend(mContext);
199 if (xBackend.is())
200 backends.push_back(xBackend);
202 else // prevent repeated attempts to create
203 mPlatformBackends.erase(cur);
205 return backends;
207 //------------------------------------------------------------------------------
208 uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
209 SystemIntegrationManager::listLayers(const rtl::OUString& aComponent,
210 const rtl::OUString& /*aEntity*/)
211 throw (backenduno::BackendAccessException,
212 lang::IllegalArgumentException,
213 uno::RuntimeException)
215 std::vector< uno::Reference<backenduno::XSingleLayerStratum> > const aUniversalBackends = getSupportingBackends(getAllComponentsName());
216 std::vector< uno::Reference<backenduno::XSingleLayerStratum> > const aSpecialBackends = getSupportingBackends(aComponent);
218 uno::Sequence< uno::Reference<backenduno::XLayer> > aLayers(aUniversalBackends.size() + aSpecialBackends.size());
220 uno::Reference<backenduno::XLayer> * pLayer = aLayers.getArray();
222 for (std::vector< uno::Reference<backenduno::XSingleLayerStratum> >::size_type i=0 ; i< aUniversalBackends.size(); ++i, ++pLayer)
223 *pLayer = aUniversalBackends[i]->getLayer(aComponent, rtl::OUString());
225 for (std::vector< uno::Reference<backenduno::XSingleLayerStratum> >::size_type j=0 ; j< aSpecialBackends.size(); ++j, ++pLayer)
226 *pLayer = aSpecialBackends[j]->getLayer(aComponent, rtl::OUString());
228 OSL_ASSERT( aLayers.getConstArray()+aLayers.getLength() == pLayer );
229 return aLayers;
231 //------------------------------------------------------------------------------
233 uno::Reference<backenduno::XUpdateHandler> SAL_CALL
234 SystemIntegrationManager::getUpdateHandler(const rtl::OUString& /*aComponent*/,
235 const rtl::OUString& /*aEntity*/)
236 throw (backenduno::BackendAccessException,
237 lang::NoSupportException,
238 lang::IllegalArgumentException,
239 uno::RuntimeException)
242 throw lang::NoSupportException(
243 rtl::OUString::createFromAscii(
244 "SystemIntegrationManager: No Update Operation allowed, Read Only access"),
245 *this) ;
247 // ---------------------------------------------------------------------------
248 // ComponentHelper
249 void SAL_CALL SystemIntegrationManager::disposing()
251 osl::MutexGuard lock(mMutex);
252 for (std::multimap<rtl::OUString, BackendRef>::iterator it = mPlatformBackends.begin(); it != mPlatformBackends.end(); ++it)
253 it->second.disposeBackend();
255 mPlatformBackends.clear();
256 mContext.clear();
258 //------------------------------------------------------------------------------
260 rtl::OUString SAL_CALL SystemIntegrationManager::
261 getSystemIntegrationManagerName(void)
263 static const rtl::OUString kImplementationName(
264 RTL_CONSTASCII_USTRINGPARAM(
265 "com.sun.star.comp.configuration.backend.SystemIntegration")) ;
267 return kImplementationName ;
269 //------------------------------------------------------------------------------
271 rtl::OUString SAL_CALL SystemIntegrationManager::getImplementationName(void)
272 throw (uno::RuntimeException)
274 return getSystemIntegrationManagerName() ;
276 //------------------------------------------------------------------------------
278 uno::Sequence<rtl::OUString> SAL_CALL SystemIntegrationManager::
279 getServiceNames(void)
281 uno::Sequence<rtl::OUString> aServices(2) ;
282 aServices[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.SystemIntegration")) ;
283 aServices[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.Backend")) ;
285 return aServices ;
287 //------------------------------------------------------------------------------
289 sal_Bool SAL_CALL SystemIntegrationManager::supportsService(
290 const rtl::OUString& aServiceName)
291 throw (uno::RuntimeException)
293 uno::Sequence< rtl::OUString > const svc = getServiceNames();
295 for(sal_Int32 i = 0; i < svc.getLength(); ++i )
296 if(svc[i] == aServiceName)
297 return true;
298 return false;
300 //------------------------------------------------------------------------------
302 uno::Sequence<rtl::OUString>
303 SAL_CALL SystemIntegrationManager::getSupportedServiceNames(void)
304 throw (uno::RuntimeException)
306 return getServiceNames() ;
308 //------------------------------------------------------------------------------
310 void SAL_CALL SystemIntegrationManager::addChangesListener(
311 const uno::Reference<backenduno::XBackendChangesListener>& xListener,
312 const rtl::OUString& aComponent)
313 throw (::com::sun::star::uno::RuntimeException)
315 osl::MutexGuard aGuard(mMutex);
317 // FIXME: we really need our own InterfaceContainer plus a helper object
318 // that listens on the backends and forwards notifications
320 //Simply forward listener to platform backend that support listening
322 std::vector< uno::Reference<backenduno::XSingleLayerStratum> > aUniversalBackends = getSupportingBackends(getAllComponentsName());
323 for (sal_uInt32 i=0; i< aUniversalBackends.size(); i++)
325 uno::Reference<backenduno::XBackendChangesNotifier> xBackend( aUniversalBackends[i], uno::UNO_QUERY) ;
326 if (xBackend.is())
327 xBackend->addChangesListener(xListener, aComponent);
331 std::vector< uno::Reference<backenduno::XSingleLayerStratum> > aSpecialBackends = getSupportingBackends(aComponent);
332 for (sal_uInt32 i=0; i< aSpecialBackends.size(); i++)
334 uno::Reference<backenduno::XBackendChangesNotifier> xBackend( aSpecialBackends[i], uno::UNO_QUERY) ;
335 if (xBackend.is())
336 xBackend->addChangesListener(xListener, aComponent);
340 //------------------------------------------------------------------------------
341 void SAL_CALL SystemIntegrationManager::removeChangesListener(
342 const uno::Reference<backenduno::XBackendChangesListener>& xListener,
343 const rtl::OUString& aComponent)
344 throw (::com::sun::star::uno::RuntimeException)
346 osl::MutexGuard aGuard(mMutex);
348 std::vector< uno::Reference<backenduno::XSingleLayerStratum> > aUniversalBackends = getSupportingBackends(getAllComponentsName());
349 for (sal_uInt32 i=0; i< aUniversalBackends.size(); i++)
351 uno::Reference<backenduno::XBackendChangesNotifier> xBackend( aUniversalBackends[i], uno::UNO_QUERY) ;
352 if (xBackend.is())
353 xBackend->removeChangesListener(xListener, aComponent);
357 std::vector< uno::Reference<backenduno::XSingleLayerStratum> > aSpecialBackends = getSupportingBackends(aComponent);
358 for (sal_uInt32 i=0; i< aSpecialBackends.size(); i++)
360 uno::Reference<backenduno::XBackendChangesNotifier> xBackend( aSpecialBackends[i], uno::UNO_QUERY) ;
361 if (xBackend.is())
362 xBackend->removeChangesListener(xListener, aComponent);
366 //------------------------------------------------------------------------------
369 } } // configmgr.backend