1*647a425cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647a425cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647a425cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647a425cSAndrew Rist  * distributed with this work for additional information
6*647a425cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647a425cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647a425cSAndrew Rist  * "License"); you may not use this file except in compliance
9*647a425cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*647a425cSAndrew Rist  *
11*647a425cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*647a425cSAndrew Rist  *
13*647a425cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647a425cSAndrew Rist  * software distributed under the License is distributed on an
15*647a425cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647a425cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647a425cSAndrew Rist  * specific language governing permissions and limitations
18*647a425cSAndrew Rist  * under the License.
19*647a425cSAndrew Rist  *
20*647a425cSAndrew Rist  *************************************************************/
21*647a425cSAndrew Rist 
22*647a425cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_stoc.hxx"
26cdf0e10cSrcweir #include <osl/diagnose.h>
27cdf0e10cSrcweir #include <osl/mutex.hxx>
28cdf0e10cSrcweir #include <uno/dispatcher.h>
29cdf0e10cSrcweir #include <uno/mapping.hxx>
30cdf0e10cSrcweir #include <cppuhelper/factory.hxx>
31cdf0e10cSrcweir #include <cppuhelper/compbase4.hxx>
32cdf0e10cSrcweir #include <cppuhelper/implbase2.hxx>
33cdf0e10cSrcweir #include <cppuhelper/typeprovider.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <cppuhelper/weakref.hxx>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
38cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp>
39cdf0e10cSrcweir #include <com/sun/star/lang/XTypeProvider.hpp>
40cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
41cdf0e10cSrcweir #include <com/sun/star/registry/XSimpleRegistry.hpp>
42cdf0e10cSrcweir #include <com/sun/star/registry/XRegistryKey.hpp>
43cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
44cdf0e10cSrcweir #include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
45cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
46cdf0e10cSrcweir 
47cdf0e10cSrcweir #include "registry/reader.hxx"
48cdf0e10cSrcweir #include "registry/version.h"
49cdf0e10cSrcweir #include "base.hxx"
50cdf0e10cSrcweir #include "rdbtdp_tdenumeration.hxx"
51cdf0e10cSrcweir #include "structtypedescription.hxx"
52cdf0e10cSrcweir 
53cdf0e10cSrcweir #define SERVICENAME "com.sun.star.reflection.TypeDescriptionProvider"
54cdf0e10cSrcweir #define IMPLNAME	"com.sun.star.comp.stoc.RegistryTypeDescriptionProvider"
55cdf0e10cSrcweir 
56cdf0e10cSrcweir using namespace com::sun::star;
57cdf0e10cSrcweir using namespace com::sun::star::beans;
58cdf0e10cSrcweir using namespace com::sun::star::registry;
59cdf0e10cSrcweir 
60cdf0e10cSrcweir extern rtl_StandardModuleCount g_moduleCount;
61cdf0e10cSrcweir 
62cdf0e10cSrcweir namespace stoc_bootstrap
63cdf0e10cSrcweir {
rdbtdp_getSupportedServiceNames()64cdf0e10cSrcweir uno::Sequence< OUString > rdbtdp_getSupportedServiceNames()
65cdf0e10cSrcweir {
66cdf0e10cSrcweir 	static Sequence < OUString > *pNames = 0;
67cdf0e10cSrcweir 	if( ! pNames )
68cdf0e10cSrcweir 	{
69cdf0e10cSrcweir 		MutexGuard guard( Mutex::getGlobalMutex() );
70cdf0e10cSrcweir 		if( !pNames )
71cdf0e10cSrcweir 		{
72cdf0e10cSrcweir 			static Sequence< OUString > seqNames(1);
73cdf0e10cSrcweir 			seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
74cdf0e10cSrcweir 			pNames = &seqNames;
75cdf0e10cSrcweir 		}
76cdf0e10cSrcweir 	}
77cdf0e10cSrcweir 	return *pNames;
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
rdbtdp_getImplementationName()80cdf0e10cSrcweir OUString rdbtdp_getImplementationName()
81cdf0e10cSrcweir {
82cdf0e10cSrcweir 	static OUString *pImplName = 0;
83cdf0e10cSrcweir 	if( ! pImplName )
84cdf0e10cSrcweir 	{
85cdf0e10cSrcweir 		MutexGuard guard( Mutex::getGlobalMutex() );
86cdf0e10cSrcweir 		if( ! pImplName )
87cdf0e10cSrcweir 		{
88cdf0e10cSrcweir 			static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
89cdf0e10cSrcweir 			pImplName = &implName;
90cdf0e10cSrcweir 		}
91cdf0e10cSrcweir 	}
92cdf0e10cSrcweir 	return *pImplName;
93cdf0e10cSrcweir }
94cdf0e10cSrcweir }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir namespace stoc_rdbtdp
97cdf0e10cSrcweir {
98cdf0e10cSrcweir struct MutexHolder
99cdf0e10cSrcweir {
100cdf0e10cSrcweir 	Mutex _aComponentMutex;
101cdf0e10cSrcweir };
102cdf0e10cSrcweir //==================================================================================================
103cdf0e10cSrcweir class ProviderImpl
104cdf0e10cSrcweir 	: public MutexHolder
105cdf0e10cSrcweir     , public WeakComponentImplHelper4< XServiceInfo,
106cdf0e10cSrcweir                                        XHierarchicalNameAccess,
107cdf0e10cSrcweir                                        XTypeDescriptionEnumerationAccess,
108cdf0e10cSrcweir                                        XInitialization >
109cdf0e10cSrcweir {
110cdf0e10cSrcweir     // XHierarchicalNameAccess + XTypeDescriptionEnumerationAccess wrapper
111cdf0e10cSrcweir     // first asking the tdmgr instance, then looking up locally
112cdf0e10cSrcweir     class TypeDescriptionManagerWrapper
113cdf0e10cSrcweir         : public ::cppu::WeakImplHelper2<
114cdf0e10cSrcweir             container::XHierarchicalNameAccess,
115cdf0e10cSrcweir             reflection::XTypeDescriptionEnumerationAccess>
116cdf0e10cSrcweir     {
117cdf0e10cSrcweir         com::sun::star::uno::Reference<container::XHierarchicalNameAccess>
118cdf0e10cSrcweir         m_xTDMgr;
119cdf0e10cSrcweir         com::sun::star::uno::Reference<container::XHierarchicalNameAccess>
120cdf0e10cSrcweir         m_xThisProvider;
121cdf0e10cSrcweir     public:
TypeDescriptionManagerWrapper(ProviderImpl * pProvider)122cdf0e10cSrcweir         TypeDescriptionManagerWrapper( ProviderImpl * pProvider )
123cdf0e10cSrcweir             : m_xTDMgr( pProvider->_xContext->getValueByName(
124cdf0e10cSrcweir                             OUString( RTL_CONSTASCII_USTRINGPARAM(
125cdf0e10cSrcweir                                           "/singletons/com.sun.star.reflection."
126cdf0e10cSrcweir                                           "theTypeDescriptionManager") ) ),
127cdf0e10cSrcweir                         UNO_QUERY_THROW ),
128cdf0e10cSrcweir               m_xThisProvider( pProvider )
129cdf0e10cSrcweir             {}
130cdf0e10cSrcweir         // XHierarchicalNameAccess
131cdf0e10cSrcweir         virtual Any SAL_CALL getByHierarchicalName( OUString const & name )
132cdf0e10cSrcweir             throw (container::NoSuchElementException, RuntimeException);
133cdf0e10cSrcweir         virtual sal_Bool SAL_CALL hasByHierarchicalName( OUString const & name )
134cdf0e10cSrcweir             throw (RuntimeException);
135cdf0e10cSrcweir 
136cdf0e10cSrcweir         // XTypeDescriptionEnumerationAccess
137cdf0e10cSrcweir         virtual uno::Reference<
138cdf0e10cSrcweir             reflection::XTypeDescriptionEnumeration > SAL_CALL
139cdf0e10cSrcweir         createTypeDescriptionEnumeration(
140cdf0e10cSrcweir             const ::rtl::OUString& moduleName,
141cdf0e10cSrcweir             const uno::Sequence< uno::TypeClass >& types,
142cdf0e10cSrcweir             reflection::TypeDescriptionSearchDepth depth )
143cdf0e10cSrcweir                 throw ( reflection::NoSuchTypeNameException,
144cdf0e10cSrcweir                         reflection::InvalidTypeNameException,
145cdf0e10cSrcweir                         uno::RuntimeException );
146cdf0e10cSrcweir     };
147cdf0e10cSrcweir     friend class TypeDescriptionManagerWrapper;
148cdf0e10cSrcweir 
149cdf0e10cSrcweir     com::sun::star::uno::Reference< XComponentContext >              _xContext;
150cdf0e10cSrcweir     com::sun::star::uno::WeakReference<XHierarchicalNameAccess> _xTDMgr;
151cdf0e10cSrcweir     com::sun::star::uno::Reference< XHierarchicalNameAccess > getTDMgr() SAL_THROW( () );
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 	RegistryKeyList                             _aBaseKeys;
154cdf0e10cSrcweir 
155cdf0e10cSrcweir protected:
156cdf0e10cSrcweir     virtual void SAL_CALL disposing();
157cdf0e10cSrcweir 
158cdf0e10cSrcweir public:
159cdf0e10cSrcweir     ProviderImpl( const com::sun::star::uno::Reference< XComponentContext > & xContext );
160cdf0e10cSrcweir 	virtual ~ProviderImpl();
161cdf0e10cSrcweir 
162cdf0e10cSrcweir     // XInitialization
163cdf0e10cSrcweir     virtual void SAL_CALL initialize( const Sequence< Any > & args ) throw (Exception, RuntimeException);
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 	// XServiceInfo
166cdf0e10cSrcweir 	virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
167cdf0e10cSrcweir 	virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException);
168cdf0e10cSrcweir 	virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 	// XHierarchicalNameAccess
171cdf0e10cSrcweir 	Any getByHierarchicalNameImpl( const OUString & rName );
172cdf0e10cSrcweir 
173cdf0e10cSrcweir 	virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
174cdf0e10cSrcweir 	virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
175cdf0e10cSrcweir 
176cdf0e10cSrcweir     // XTypeDescriptionEnumerationAccess
177cdf0e10cSrcweir     virtual ::com::sun::star::uno::Reference<
178cdf0e10cSrcweir         ::com::sun::star::reflection::XTypeDescriptionEnumeration > SAL_CALL
179cdf0e10cSrcweir     createTypeDescriptionEnumeration(
180cdf0e10cSrcweir         const ::rtl::OUString& moduleName,
181cdf0e10cSrcweir         const ::com::sun::star::uno::Sequence<
182cdf0e10cSrcweir             ::com::sun::star::uno::TypeClass >& types,
183cdf0e10cSrcweir         ::com::sun::star::reflection::TypeDescriptionSearchDepth depth )
184cdf0e10cSrcweir             throw ( ::com::sun::star::reflection::NoSuchTypeNameException,
185cdf0e10cSrcweir                     ::com::sun::star::reflection::InvalidTypeNameException,
186cdf0e10cSrcweir                     ::com::sun::star::uno::RuntimeException );
187cdf0e10cSrcweir };
188cdf0e10cSrcweir //__________________________________________________________________________________________________
ProviderImpl(const com::sun::star::uno::Reference<XComponentContext> & xContext)189cdf0e10cSrcweir ProviderImpl::ProviderImpl( const com::sun::star::uno::Reference< XComponentContext > & xContext )
190cdf0e10cSrcweir     : WeakComponentImplHelper4<
191cdf0e10cSrcweir         XServiceInfo, XHierarchicalNameAccess,
192cdf0e10cSrcweir         XTypeDescriptionEnumerationAccess, XInitialization >( _aComponentMutex )
193cdf0e10cSrcweir 	, _xContext( xContext )
194cdf0e10cSrcweir {
195cdf0e10cSrcweir 	g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
196cdf0e10cSrcweir }
197cdf0e10cSrcweir //__________________________________________________________________________________________________
~ProviderImpl()198cdf0e10cSrcweir ProviderImpl::~ProviderImpl()
199cdf0e10cSrcweir {
200cdf0e10cSrcweir 	g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
201cdf0e10cSrcweir }
202cdf0e10cSrcweir 
203cdf0e10cSrcweir //______________________________________________________________________________
getByHierarchicalName(OUString const & name)204cdf0e10cSrcweir Any ProviderImpl::TypeDescriptionManagerWrapper::getByHierarchicalName(
205cdf0e10cSrcweir     OUString const & name ) throw (container::NoSuchElementException,
206cdf0e10cSrcweir                                    RuntimeException)
207cdf0e10cSrcweir {
208cdf0e10cSrcweir     try
209cdf0e10cSrcweir     {
210cdf0e10cSrcweir         // first try tdmgr:
211cdf0e10cSrcweir 		return m_xTDMgr->getByHierarchicalName( name );
212cdf0e10cSrcweir     }
213cdf0e10cSrcweir     catch (container::NoSuchElementException &)
214cdf0e10cSrcweir     {
215cdf0e10cSrcweir         // then lookup locally:
216cdf0e10cSrcweir 		return m_xThisProvider->getByHierarchicalName( name );
217cdf0e10cSrcweir     }
218cdf0e10cSrcweir }
219cdf0e10cSrcweir 
220cdf0e10cSrcweir //______________________________________________________________________________
hasByHierarchicalName(OUString const & name)221cdf0e10cSrcweir sal_Bool ProviderImpl::TypeDescriptionManagerWrapper::hasByHierarchicalName(
222cdf0e10cSrcweir     OUString const & name ) throw (RuntimeException)
223cdf0e10cSrcweir {
224cdf0e10cSrcweir 	return m_xTDMgr->hasByHierarchicalName( name ) || m_xThisProvider->hasByHierarchicalName( name );
225cdf0e10cSrcweir }
226cdf0e10cSrcweir 
227cdf0e10cSrcweir //______________________________________________________________________________
228cdf0e10cSrcweir uno::Reference< reflection::XTypeDescriptionEnumeration > SAL_CALL
createTypeDescriptionEnumeration(const::rtl::OUString & moduleName,const uno::Sequence<uno::TypeClass> & types,reflection::TypeDescriptionSearchDepth depth)229cdf0e10cSrcweir ProviderImpl::TypeDescriptionManagerWrapper::createTypeDescriptionEnumeration(
230cdf0e10cSrcweir         const ::rtl::OUString& moduleName,
231cdf0e10cSrcweir         const uno::Sequence< uno::TypeClass >& types,
232cdf0e10cSrcweir         reflection::TypeDescriptionSearchDepth depth )
233cdf0e10cSrcweir     throw ( reflection::NoSuchTypeNameException,
234cdf0e10cSrcweir             reflection::InvalidTypeNameException,
235cdf0e10cSrcweir             uno::RuntimeException )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir     try
238cdf0e10cSrcweir     {
239cdf0e10cSrcweir         // first try tdmgr:
240cdf0e10cSrcweir         uno::Reference< reflection::XTypeDescriptionEnumerationAccess > xTDEA(
241cdf0e10cSrcweir             m_xTDMgr, uno::UNO_QUERY_THROW );
242cdf0e10cSrcweir         return
243cdf0e10cSrcweir             xTDEA->createTypeDescriptionEnumeration( moduleName, types, depth );
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir     catch (reflection::NoSuchTypeNameException &)
246cdf0e10cSrcweir     {
247cdf0e10cSrcweir         // then lookup locally:
248cdf0e10cSrcweir         uno::Reference< reflection::XTypeDescriptionEnumerationAccess > xTDEA(
249cdf0e10cSrcweir             m_xThisProvider, uno::UNO_QUERY_THROW );
250cdf0e10cSrcweir         return
251cdf0e10cSrcweir             xTDEA->createTypeDescriptionEnumeration( moduleName, types, depth );
252cdf0e10cSrcweir     }
253cdf0e10cSrcweir }
254cdf0e10cSrcweir 
255cdf0e10cSrcweir //__________________________________________________________________________________________________
getTDMgr()256cdf0e10cSrcweir com::sun::star::uno::Reference< XHierarchicalNameAccess > ProviderImpl::getTDMgr()
257cdf0e10cSrcweir     SAL_THROW( () )
258cdf0e10cSrcweir {
259cdf0e10cSrcweir     // harden weak reference:
260cdf0e10cSrcweir     com::sun::star::uno::Reference<container::XHierarchicalNameAccess> xTDMgr(
261cdf0e10cSrcweir         _xTDMgr );
262cdf0e10cSrcweir     if (! xTDMgr.is())
263cdf0e10cSrcweir     {
264cdf0e10cSrcweir         xTDMgr.set( new TypeDescriptionManagerWrapper(this) );
265cdf0e10cSrcweir         {
266cdf0e10cSrcweir         MutexGuard guard( _aComponentMutex );
267cdf0e10cSrcweir         _xTDMgr = xTDMgr;
268cdf0e10cSrcweir         }
269cdf0e10cSrcweir     }
270cdf0e10cSrcweir     return xTDMgr;
271cdf0e10cSrcweir }
272cdf0e10cSrcweir 
273cdf0e10cSrcweir //__________________________________________________________________________________________________
disposing()274cdf0e10cSrcweir void ProviderImpl::disposing()
275cdf0e10cSrcweir {
276cdf0e10cSrcweir 	_xContext.clear();
277cdf0e10cSrcweir 
278cdf0e10cSrcweir 	for ( RegistryKeyList::const_iterator iPos( _aBaseKeys.begin() );
279cdf0e10cSrcweir 		  iPos != _aBaseKeys.end(); ++iPos )
280cdf0e10cSrcweir 	{
281cdf0e10cSrcweir 		(*iPos)->closeKey();
282cdf0e10cSrcweir 	}
283cdf0e10cSrcweir 	_aBaseKeys.clear();
284cdf0e10cSrcweir }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir // XInitialization
287cdf0e10cSrcweir //__________________________________________________________________________________________________
initialize(const Sequence<Any> & args)288cdf0e10cSrcweir void ProviderImpl::initialize(
289cdf0e10cSrcweir     const Sequence< Any > & args )
290cdf0e10cSrcweir     throw (Exception, RuntimeException)
291cdf0e10cSrcweir {
292cdf0e10cSrcweir     // registries to read from
293cdf0e10cSrcweir     Any const * pRegistries = args.getConstArray();
294cdf0e10cSrcweir     for ( sal_Int32 nPos = 0; nPos < args.getLength(); ++nPos )
295cdf0e10cSrcweir     {
296cdf0e10cSrcweir         com::sun::star::uno::Reference< XSimpleRegistry > xRegistry( pRegistries[ nPos ], UNO_QUERY );
297cdf0e10cSrcweir         if (xRegistry.is() && xRegistry->isValid())
298cdf0e10cSrcweir         {
299cdf0e10cSrcweir             com::sun::star::uno::Reference< XRegistryKey > xKey( xRegistry->getRootKey()->openKey(
300cdf0e10cSrcweir                 OUString( RTL_CONSTASCII_USTRINGPARAM("/UCR") ) ) );
301cdf0e10cSrcweir             if (xKey.is() && xKey->isValid())
302cdf0e10cSrcweir             {
303cdf0e10cSrcweir                 _aBaseKeys.push_back( xKey );
304cdf0e10cSrcweir             }
305cdf0e10cSrcweir         }
306cdf0e10cSrcweir     }
307cdf0e10cSrcweir }
308cdf0e10cSrcweir 
309cdf0e10cSrcweir // XServiceInfo
310cdf0e10cSrcweir //__________________________________________________________________________________________________
getImplementationName()311cdf0e10cSrcweir OUString ProviderImpl::getImplementationName()
312cdf0e10cSrcweir 	throw(::com::sun::star::uno::RuntimeException)
313cdf0e10cSrcweir {
314cdf0e10cSrcweir 	return stoc_bootstrap::rdbtdp_getImplementationName();
315cdf0e10cSrcweir }
316cdf0e10cSrcweir //__________________________________________________________________________________________________
supportsService(const OUString & rServiceName)317cdf0e10cSrcweir sal_Bool ProviderImpl::supportsService( const OUString & rServiceName )
318cdf0e10cSrcweir 	throw(::com::sun::star::uno::RuntimeException)
319cdf0e10cSrcweir {
320cdf0e10cSrcweir 	const Sequence< OUString > & rSNL = getSupportedServiceNames();
321cdf0e10cSrcweir 	const OUString * pArray = rSNL.getConstArray();
322cdf0e10cSrcweir 	for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
323cdf0e10cSrcweir 	{
324cdf0e10cSrcweir 		if (pArray[nPos] == rServiceName)
325cdf0e10cSrcweir 			return sal_True;
326cdf0e10cSrcweir 	}
327cdf0e10cSrcweir 	return sal_False;
328cdf0e10cSrcweir }
329cdf0e10cSrcweir //__________________________________________________________________________________________________
getSupportedServiceNames()330cdf0e10cSrcweir Sequence< OUString > ProviderImpl::getSupportedServiceNames()
331cdf0e10cSrcweir 	throw(::com::sun::star::uno::RuntimeException)
332cdf0e10cSrcweir {
333cdf0e10cSrcweir 	return stoc_bootstrap::rdbtdp_getSupportedServiceNames();
334cdf0e10cSrcweir }
335cdf0e10cSrcweir 
336cdf0e10cSrcweir // XHierarchicalNameAccess
337cdf0e10cSrcweir //__________________________________________________________________________________________________
getByHierarchicalNameImpl(const OUString & rName)338cdf0e10cSrcweir Any ProviderImpl::getByHierarchicalNameImpl( const OUString & rName )
339cdf0e10cSrcweir {
340cdf0e10cSrcweir 	Any aRet;
341cdf0e10cSrcweir 
342cdf0e10cSrcweir     // read from registry
343cdf0e10cSrcweir     OUString aKey( rName.replace( '.', '/' ) );
344cdf0e10cSrcweir     for ( RegistryKeyList::const_iterator iPos( _aBaseKeys.begin() );
345cdf0e10cSrcweir           !aRet.hasValue() && iPos != _aBaseKeys.end(); ++iPos )
346cdf0e10cSrcweir     {
347cdf0e10cSrcweir         try
348cdf0e10cSrcweir         {
349cdf0e10cSrcweir             com::sun::star::uno::Reference< XRegistryKey > xBaseKey( *iPos );
350cdf0e10cSrcweir             com::sun::star::uno::Reference< XRegistryKey > xKey( xBaseKey->openKey( aKey ) );
351cdf0e10cSrcweir             if (xKey.is())
352cdf0e10cSrcweir             {
353cdf0e10cSrcweir                 // closes key in it's dtor (which is
354cdf0e10cSrcweir                 // called even in case of exceptions).
355cdf0e10cSrcweir                 RegistryKeyCloser aCloser( xKey );
356cdf0e10cSrcweir 
357cdf0e10cSrcweir                 if ( xKey->isValid() )
358cdf0e10cSrcweir                 {
359cdf0e10cSrcweir                     if (xKey->getValueType() == RegistryValueType_BINARY)
360cdf0e10cSrcweir                     {
361cdf0e10cSrcweir                         Sequence< sal_Int8 > aBytes( xKey->getBinaryValue() );
362cdf0e10cSrcweir                         com::sun::star::uno::Reference< XTypeDescription > xTD(
363cdf0e10cSrcweir                             createTypeDescription( aBytes,
364cdf0e10cSrcweir                                                    getTDMgr(),
365cdf0e10cSrcweir                                                    true ) );
366cdf0e10cSrcweir                         if ( xTD.is() )
367cdf0e10cSrcweir                             aRet <<= xTD;
368cdf0e10cSrcweir                     }
369cdf0e10cSrcweir                 }
370cdf0e10cSrcweir             }
371cdf0e10cSrcweir             else // might be a constant
372cdf0e10cSrcweir             {
373cdf0e10cSrcweir                 sal_Int32 nIndex = aKey.lastIndexOf( '/' );
374cdf0e10cSrcweir                 if (nIndex > 0)
375cdf0e10cSrcweir                 {
376cdf0e10cSrcweir                     // open module
377cdf0e10cSrcweir                     com::sun::star::uno::Reference< XRegistryKey > xKey2( xBaseKey->openKey( aKey.copy( 0, nIndex ) ) );
378cdf0e10cSrcweir                     if (xKey2.is())
379cdf0e10cSrcweir                     {
380cdf0e10cSrcweir                         // closes key in it's dtor (which is
381cdf0e10cSrcweir                         // called even in case of exceptions).
382cdf0e10cSrcweir                         RegistryKeyCloser aCloser( xKey2 );
383cdf0e10cSrcweir 
384cdf0e10cSrcweir                         if ( xKey2->isValid() )
385cdf0e10cSrcweir                         {
386cdf0e10cSrcweir                             if (xKey2->getValueType() == RegistryValueType_BINARY)
387cdf0e10cSrcweir                             {
388cdf0e10cSrcweir                                 Sequence< sal_Int8 > aBytes( xKey2->getBinaryValue() );
389cdf0e10cSrcweir                                 typereg::Reader aReader(
390cdf0e10cSrcweir                                     aBytes.getConstArray(), aBytes.getLength(),
391cdf0e10cSrcweir                                     false, TYPEREG_VERSION_1);
392cdf0e10cSrcweir 
393cdf0e10cSrcweir                                 if (aReader.getTypeClass() == RT_TYPE_MODULE ||
394cdf0e10cSrcweir                                     aReader.getTypeClass() == RT_TYPE_CONSTANTS ||
395cdf0e10cSrcweir                                     aReader.getTypeClass() == RT_TYPE_ENUM)
396cdf0e10cSrcweir                                 {
397cdf0e10cSrcweir                                     OUString aFieldName( aKey.copy( nIndex+1, aKey.getLength() - nIndex -1 ) );
398cdf0e10cSrcweir                                     sal_Int16 nPos = aReader.getFieldCount();
399cdf0e10cSrcweir                                     while (nPos--)
400cdf0e10cSrcweir                                     {
401cdf0e10cSrcweir                                         if (aFieldName.equals(
402cdf0e10cSrcweir                                                 aReader.getFieldName(nPos)))
403cdf0e10cSrcweir                                             break;
404cdf0e10cSrcweir                                     }
405cdf0e10cSrcweir                                     if (nPos >= 0)
406cdf0e10cSrcweir                                         aRet = getRTValue(
407cdf0e10cSrcweir                                             aReader.getFieldValue(nPos));
408cdf0e10cSrcweir                                 }
409cdf0e10cSrcweir                             }
410cdf0e10cSrcweir                         }
411cdf0e10cSrcweir                     }
412cdf0e10cSrcweir                 }
413cdf0e10cSrcweir             }
414cdf0e10cSrcweir         }
415cdf0e10cSrcweir         catch ( InvalidRegistryException const & )
416cdf0e10cSrcweir         {
417cdf0e10cSrcweir             OSL_ENSURE( sal_False,
418cdf0e10cSrcweir                         "ProviderImpl::getByHierarchicalName "
419cdf0e10cSrcweir                         "- Caught InvalidRegistryException!" );
420cdf0e10cSrcweir 
421cdf0e10cSrcweir             // openKey, closeKey, getValueType, getBinaryValue, isValid
422cdf0e10cSrcweir 
423cdf0e10cSrcweir             // Don't stop iteration in this case.
424cdf0e10cSrcweir         }
425cdf0e10cSrcweir 		catch ( NoSuchElementException const & )
426cdf0e10cSrcweir 		{
427cdf0e10cSrcweir 		}
428cdf0e10cSrcweir     }
429cdf0e10cSrcweir 	return aRet;
430cdf0e10cSrcweir }
431cdf0e10cSrcweir 
getByHierarchicalName(const OUString & rName)432cdf0e10cSrcweir Any SAL_CALL ProviderImpl::getByHierarchicalName( const OUString & rName )
433cdf0e10cSrcweir 	throw(::com::sun::star::uno::RuntimeException, com::sun::star::container::NoSuchElementException)
434cdf0e10cSrcweir {
435cdf0e10cSrcweir 	Any aRet( getByHierarchicalNameImpl( rName ) );
436cdf0e10cSrcweir 
437cdf0e10cSrcweir     if ( !aRet.hasValue() )
438cdf0e10cSrcweir         throw NoSuchElementException(
439cdf0e10cSrcweir             rName, static_cast< cppu::OWeakObject * >( this  ) );
440cdf0e10cSrcweir 
441cdf0e10cSrcweir 	return aRet;
442cdf0e10cSrcweir }
443cdf0e10cSrcweir 
444cdf0e10cSrcweir //__________________________________________________________________________________________________
hasByHierarchicalName(const OUString & rName)445cdf0e10cSrcweir sal_Bool ProviderImpl::hasByHierarchicalName( const OUString & rName )
446cdf0e10cSrcweir 	throw(::com::sun::star::uno::RuntimeException)
447cdf0e10cSrcweir {
448cdf0e10cSrcweir 	return getByHierarchicalNameImpl( rName ).hasValue();
449cdf0e10cSrcweir }
450cdf0e10cSrcweir 
451cdf0e10cSrcweir // XTypeDescriptionEnumerationAccess
452cdf0e10cSrcweir //__________________________________________________________________________________________________
453cdf0e10cSrcweir // virtual
454cdf0e10cSrcweir com::sun::star::uno::Reference< XTypeDescriptionEnumeration > SAL_CALL
createTypeDescriptionEnumeration(const OUString & moduleName,const Sequence<TypeClass> & types,TypeDescriptionSearchDepth depth)455cdf0e10cSrcweir ProviderImpl::createTypeDescriptionEnumeration(
456cdf0e10cSrcweir         const OUString & moduleName,
457cdf0e10cSrcweir         const Sequence< TypeClass > & types,
458cdf0e10cSrcweir         TypeDescriptionSearchDepth depth )
459cdf0e10cSrcweir     throw ( NoSuchTypeNameException,
460cdf0e10cSrcweir             InvalidTypeNameException,
461cdf0e10cSrcweir             RuntimeException )
462cdf0e10cSrcweir {
463cdf0e10cSrcweir     return com::sun::star::uno::Reference< XTypeDescriptionEnumeration >(
464cdf0e10cSrcweir         TypeDescriptionEnumerationImpl::createInstance( getTDMgr(),
465cdf0e10cSrcweir                                                         moduleName,
466cdf0e10cSrcweir                                                         types,
467cdf0e10cSrcweir                                                         depth,
468cdf0e10cSrcweir                                                         _aBaseKeys ).get() );
469cdf0e10cSrcweir }
470cdf0e10cSrcweir 
471cdf0e10cSrcweir //__________________________________________________________________________________________________
472cdf0e10cSrcweir // global helper function
473cdf0e10cSrcweir 
resolveTypedefs(com::sun::star::uno::Reference<XTypeDescription> const & type)474cdf0e10cSrcweir com::sun::star::uno::Reference< XTypeDescription > resolveTypedefs(
475cdf0e10cSrcweir     com::sun::star::uno::Reference< XTypeDescription > const & type)
476cdf0e10cSrcweir {
477cdf0e10cSrcweir     com::sun::star::uno::Reference< XTypeDescription > resolved(type);
478cdf0e10cSrcweir     while (resolved->getTypeClass() == TypeClass_TYPEDEF) {
479cdf0e10cSrcweir         resolved = com::sun::star::uno::Reference< XIndirectTypeDescription >(
480cdf0e10cSrcweir             resolved, UNO_QUERY_THROW)->getReferencedType();
481cdf0e10cSrcweir     }
482cdf0e10cSrcweir     return resolved;
483cdf0e10cSrcweir }
484cdf0e10cSrcweir 
createTypeDescription(const Sequence<sal_Int8> & rData,const com::sun::star::uno::Reference<XHierarchicalNameAccess> & xNameAccess,bool bReturnEmptyRefForUnknownType)485cdf0e10cSrcweir com::sun::star::uno::Reference< XTypeDescription > createTypeDescription(
486cdf0e10cSrcweir     const Sequence< sal_Int8 > & rData,
487cdf0e10cSrcweir     const com::sun::star::uno::Reference< XHierarchicalNameAccess > & xNameAccess,
488cdf0e10cSrcweir     bool bReturnEmptyRefForUnknownType )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir     typereg::Reader aReader(
491cdf0e10cSrcweir         rData.getConstArray(), rData.getLength(), false, TYPEREG_VERSION_1);
492cdf0e10cSrcweir 
493cdf0e10cSrcweir     OUString aName( aReader.getTypeName().replace( '/', '.' ) );
494cdf0e10cSrcweir 
495cdf0e10cSrcweir     switch (aReader.getTypeClass())
496cdf0e10cSrcweir     {
497cdf0e10cSrcweir         case RT_TYPE_INTERFACE:
498cdf0e10cSrcweir         {
499cdf0e10cSrcweir             sal_uInt16 n = aReader.getSuperTypeCount();
500cdf0e10cSrcweir             com::sun::star::uno::Sequence< rtl::OUString > aBaseTypeNames(n);
501cdf0e10cSrcweir             {for (sal_uInt16 i = 0; i < n; ++i) {
502cdf0e10cSrcweir                 aBaseTypeNames[i] = aReader.getSuperTypeName(i).replace(
503cdf0e10cSrcweir                     '/', '.');
504cdf0e10cSrcweir             }}
505cdf0e10cSrcweir             sal_uInt16 n2 = aReader.getReferenceCount();
506cdf0e10cSrcweir             com::sun::star::uno::Sequence< rtl::OUString >
507cdf0e10cSrcweir                 aOptionalBaseTypeNames(n2);
508cdf0e10cSrcweir             {for (sal_uInt16 i = 0; i < n2; ++i) {
509cdf0e10cSrcweir                 OSL_ASSERT(
510cdf0e10cSrcweir                     aReader.getReferenceSort(i) == RT_REF_SUPPORTS
511cdf0e10cSrcweir                     && aReader.getReferenceFlags(i) == RT_ACCESS_OPTIONAL);
512cdf0e10cSrcweir                 aOptionalBaseTypeNames[i] = aReader.getReferenceTypeName(i);
513cdf0e10cSrcweir             }}
514cdf0e10cSrcweir             return com::sun::star::uno::Reference< XTypeDescription >(
515cdf0e10cSrcweir                 new InterfaceTypeDescriptionImpl( xNameAccess,
516cdf0e10cSrcweir                                                   aName,
517cdf0e10cSrcweir                                                   aBaseTypeNames,
518cdf0e10cSrcweir                                                   aOptionalBaseTypeNames,
519cdf0e10cSrcweir                                                   rData,
520cdf0e10cSrcweir                                                   aReader.isPublished() ) );
521cdf0e10cSrcweir         }
522cdf0e10cSrcweir 
523cdf0e10cSrcweir         case RT_TYPE_MODULE:
524cdf0e10cSrcweir         {
525cdf0e10cSrcweir             com::sun::star::uno::Reference<
526cdf0e10cSrcweir                 XTypeDescriptionEnumerationAccess > xTDEA(
527cdf0e10cSrcweir                     xNameAccess, UNO_QUERY );
528cdf0e10cSrcweir 
529cdf0e10cSrcweir             OSL_ENSURE( xTDEA.is(),
530cdf0e10cSrcweir                         "No XTypeDescriptionEnumerationAccess!" );
531cdf0e10cSrcweir 
532cdf0e10cSrcweir             return com::sun::star::uno::Reference< XTypeDescription >(
533cdf0e10cSrcweir                 new ModuleTypeDescriptionImpl( xTDEA, aName ) );
534cdf0e10cSrcweir         }
535cdf0e10cSrcweir 
536cdf0e10cSrcweir         case RT_TYPE_STRUCT:
537cdf0e10cSrcweir             {
538cdf0e10cSrcweir                 rtl::OUString superTypeName;
539cdf0e10cSrcweir                 if (aReader.getSuperTypeCount() == 1) {
540cdf0e10cSrcweir                     superTypeName = aReader.getSuperTypeName(0).replace(
541cdf0e10cSrcweir                         '/', '.');
542cdf0e10cSrcweir                 }
543cdf0e10cSrcweir                 return com::sun::star::uno::Reference< XTypeDescription >(
544cdf0e10cSrcweir                     new stoc::registry_tdprovider::StructTypeDescription(
545cdf0e10cSrcweir                         xNameAccess, aName, superTypeName, rData,
546cdf0e10cSrcweir                         aReader.isPublished()));
547cdf0e10cSrcweir             }
548cdf0e10cSrcweir 
549cdf0e10cSrcweir         case RT_TYPE_ENUM:
550cdf0e10cSrcweir             return com::sun::star::uno::Reference< XTypeDescription >(
551cdf0e10cSrcweir                 new EnumTypeDescriptionImpl( xNameAccess,
552cdf0e10cSrcweir                                              aName,
553cdf0e10cSrcweir                                              getRTValueAsInt32(
554cdf0e10cSrcweir                                                 aReader.getFieldValue( 0 ) ),
555cdf0e10cSrcweir                                              rData, aReader.isPublished() ) );
556cdf0e10cSrcweir 
557cdf0e10cSrcweir         case RT_TYPE_EXCEPTION:
558cdf0e10cSrcweir             {
559cdf0e10cSrcweir                 rtl::OUString superTypeName;
560cdf0e10cSrcweir                 if (aReader.getSuperTypeCount() == 1) {
561cdf0e10cSrcweir                     superTypeName = aReader.getSuperTypeName(0).replace(
562cdf0e10cSrcweir                         '/', '.');
563cdf0e10cSrcweir                 }
564cdf0e10cSrcweir                 return com::sun::star::uno::Reference< XTypeDescription >(
565cdf0e10cSrcweir                     new CompoundTypeDescriptionImpl(
566cdf0e10cSrcweir                         xNameAccess, TypeClass_EXCEPTION, aName, superTypeName,
567cdf0e10cSrcweir                         rData, aReader.isPublished()));
568cdf0e10cSrcweir             }
569cdf0e10cSrcweir 
570cdf0e10cSrcweir         case RT_TYPE_TYPEDEF:
571cdf0e10cSrcweir             return com::sun::star::uno::Reference< XTypeDescription >(
572cdf0e10cSrcweir                 new TypedefTypeDescriptionImpl( xNameAccess,
573cdf0e10cSrcweir                                                 aName,
574cdf0e10cSrcweir                                                 aReader.getSuperTypeName(0)
575cdf0e10cSrcweir                                                     .replace( '/', '.' ),
576cdf0e10cSrcweir                                                 aReader.isPublished() ) );
577cdf0e10cSrcweir         case RT_TYPE_SERVICE:
578cdf0e10cSrcweir             return com::sun::star::uno::Reference< XTypeDescription >(
579cdf0e10cSrcweir                 new ServiceTypeDescriptionImpl(
580cdf0e10cSrcweir                     xNameAccess, aName, rData, aReader.isPublished() ) );
581cdf0e10cSrcweir 
582cdf0e10cSrcweir         case RT_TYPE_CONSTANTS:
583cdf0e10cSrcweir             return com::sun::star::uno::Reference< XTypeDescription >(
584cdf0e10cSrcweir                 new ConstantsTypeDescriptionImpl(
585cdf0e10cSrcweir                     aName, rData, aReader.isPublished() ) );
586cdf0e10cSrcweir 
587cdf0e10cSrcweir         case RT_TYPE_SINGLETON:
588cdf0e10cSrcweir             return com::sun::star::uno::Reference< XTypeDescription >(
589cdf0e10cSrcweir                 new SingletonTypeDescriptionImpl( xNameAccess,
590cdf0e10cSrcweir                                                   aName,
591cdf0e10cSrcweir                                                   aReader.getSuperTypeName(0)
592cdf0e10cSrcweir                                                     .replace( '/', '.' ),
593cdf0e10cSrcweir                                                   aReader.isPublished() ) );
594cdf0e10cSrcweir         case RT_TYPE_INVALID:
595cdf0e10cSrcweir         case RT_TYPE_OBJECT:      // deprecated and not used
596cdf0e10cSrcweir         case RT_TYPE_UNION:       // deprecated and not used
597cdf0e10cSrcweir             OSL_ENSURE( sal_False, "createTypeDescription - Unsupported Type!" );
598cdf0e10cSrcweir             break;
599cdf0e10cSrcweir 
600cdf0e10cSrcweir         default:
601cdf0e10cSrcweir             OSL_ENSURE( sal_False, "createTypeDescription - Unknown Type!" );
602cdf0e10cSrcweir             break;
603cdf0e10cSrcweir     }
604cdf0e10cSrcweir 
605cdf0e10cSrcweir     // Unknown type.
606cdf0e10cSrcweir 
607cdf0e10cSrcweir     if ( bReturnEmptyRefForUnknownType )
608cdf0e10cSrcweir         return com::sun::star::uno::Reference< XTypeDescription >();
609cdf0e10cSrcweir 
610cdf0e10cSrcweir     return com::sun::star::uno::Reference< XTypeDescription >(
611cdf0e10cSrcweir                 new TypeDescriptionImpl( TypeClass_UNKNOWN, aName ) );
612cdf0e10cSrcweir }
613cdf0e10cSrcweir 
614cdf0e10cSrcweir }
615cdf0e10cSrcweir 
616cdf0e10cSrcweir namespace stoc_bootstrap
617cdf0e10cSrcweir {
618cdf0e10cSrcweir //==================================================================================================
ProviderImpl_create(com::sun::star::uno::Reference<XComponentContext> const & xContext)619cdf0e10cSrcweir com::sun::star::uno::Reference< XInterface > SAL_CALL ProviderImpl_create(
620cdf0e10cSrcweir     com::sun::star::uno::Reference< XComponentContext > const & xContext )
621cdf0e10cSrcweir 	throw(::com::sun::star::uno::Exception)
622cdf0e10cSrcweir {
623cdf0e10cSrcweir     return com::sun::star::uno::Reference< XInterface >( *new stoc_rdbtdp::ProviderImpl( xContext ) );
624cdf0e10cSrcweir }
625cdf0e10cSrcweir }
626