fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / stoc / source / registry_tdprovider / tdprovider.cxx
blob9a739f0fc303076f485fe0c9c386cd8964580a28
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <osl/diagnose.h>
21 #include <osl/mutex.hxx>
22 #include <uno/dispatcher.h>
23 #include <uno/mapping.hxx>
24 #include <cppuhelper/factory.hxx>
25 #include <cppuhelper/compbase4.hxx>
26 #include <cppuhelper/implbase2.hxx>
27 #include <cppuhelper/typeprovider.hxx>
29 #include <cppuhelper/weakref.hxx>
31 #include <com/sun/star/lang/XServiceInfo.hpp>
32 #include <com/sun/star/lang/XComponent.hpp>
33 #include <com/sun/star/lang/XTypeProvider.hpp>
34 #include <com/sun/star/lang/XInitialization.hpp>
35 #include <com/sun/star/registry/XSimpleRegistry.hpp>
36 #include <com/sun/star/registry/XRegistryKey.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
39 #include "com/sun/star/uno/RuntimeException.hpp"
41 #include "registry/reader.hxx"
42 #include "registry/version.h"
43 #include "base.hxx"
44 #include "rdbtdp_tdenumeration.hxx"
45 #include "structtypedescription.hxx"
47 #define SERVICENAME "com.sun.star.reflection.TypeDescriptionProvider"
48 #define IMPLNAME "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider"
50 using namespace com::sun::star;
51 using namespace com::sun::star::beans;
52 using namespace com::sun::star::registry;
54 namespace stoc_bootstrap
56 uno::Sequence< OUString > rdbtdp_getSupportedServiceNames()
58 Sequence< OUString > seqNames(1);
59 seqNames.getArray()[0] = OUString(SERVICENAME);
60 return seqNames;
63 OUString rdbtdp_getImplementationName()
65 return OUString(IMPLNAME);
69 namespace stoc_rdbtdp
71 struct MutexHolder
73 Mutex _aComponentMutex;
75 //==================================================================================================
76 class ProviderImpl
77 : public MutexHolder
78 , public WeakComponentImplHelper4< XServiceInfo,
79 XHierarchicalNameAccess,
80 XTypeDescriptionEnumerationAccess,
81 XInitialization >
83 // XHierarchicalNameAccess + XTypeDescriptionEnumerationAccess wrapper
84 // first asking the tdmgr instance, then looking up locally
85 class TypeDescriptionManagerWrapper
86 : public ::cppu::WeakImplHelper2<
87 container::XHierarchicalNameAccess,
88 reflection::XTypeDescriptionEnumerationAccess>
90 com::sun::star::uno::Reference<container::XHierarchicalNameAccess>
91 m_xTDMgr;
92 com::sun::star::uno::Reference<container::XHierarchicalNameAccess>
93 m_xThisProvider;
94 public:
95 TypeDescriptionManagerWrapper( ProviderImpl * pProvider )
96 : m_xTDMgr( pProvider->_xContext->getValueByName(
97 OUString(
98 "/singletons/com.sun.star.reflection."
99 "theTypeDescriptionManager" ) ),
100 UNO_QUERY_THROW ),
101 m_xThisProvider( pProvider )
103 // XHierarchicalNameAccess
104 virtual Any SAL_CALL getByHierarchicalName( OUString const & name )
105 throw (container::NoSuchElementException, RuntimeException);
106 virtual sal_Bool SAL_CALL hasByHierarchicalName( OUString const & name )
107 throw (RuntimeException);
109 // XTypeDescriptionEnumerationAccess
110 virtual uno::Reference<
111 reflection::XTypeDescriptionEnumeration > SAL_CALL
112 createTypeDescriptionEnumeration(
113 const OUString& moduleName,
114 const uno::Sequence< uno::TypeClass >& types,
115 reflection::TypeDescriptionSearchDepth depth )
116 throw ( reflection::NoSuchTypeNameException,
117 reflection::InvalidTypeNameException,
118 uno::RuntimeException );
120 friend class TypeDescriptionManagerWrapper;
122 com::sun::star::uno::Reference< XComponentContext > _xContext;
123 com::sun::star::uno::WeakReference<XHierarchicalNameAccess> _xTDMgr;
124 com::sun::star::uno::Reference< XHierarchicalNameAccess > getTDMgr() SAL_THROW(());
126 RegistryKeyList _aBaseKeys;
128 protected:
129 virtual void SAL_CALL disposing();
131 public:
132 ProviderImpl( const com::sun::star::uno::Reference< XComponentContext > & xContext );
133 virtual ~ProviderImpl();
135 // XInitialization
136 virtual void SAL_CALL initialize( const Sequence< Any > & args ) throw (Exception, RuntimeException);
138 // XServiceInfo
139 virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
140 virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException);
141 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
143 // XHierarchicalNameAccess
144 Any getByHierarchicalNameImpl( const OUString & rName );
146 virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
147 virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
149 // XTypeDescriptionEnumerationAccess
150 virtual ::com::sun::star::uno::Reference<
151 ::com::sun::star::reflection::XTypeDescriptionEnumeration > SAL_CALL
152 createTypeDescriptionEnumeration(
153 const OUString& moduleName,
154 const ::com::sun::star::uno::Sequence<
155 ::com::sun::star::uno::TypeClass >& types,
156 ::com::sun::star::reflection::TypeDescriptionSearchDepth depth )
157 throw ( ::com::sun::star::reflection::NoSuchTypeNameException,
158 ::com::sun::star::reflection::InvalidTypeNameException,
159 ::com::sun::star::uno::RuntimeException );
161 //__________________________________________________________________________________________________
162 ProviderImpl::ProviderImpl( const com::sun::star::uno::Reference< XComponentContext > & xContext )
163 : WeakComponentImplHelper4<
164 XServiceInfo, XHierarchicalNameAccess,
165 XTypeDescriptionEnumerationAccess, XInitialization >( _aComponentMutex )
166 , _xContext( xContext )
168 //__________________________________________________________________________________________________
169 ProviderImpl::~ProviderImpl() {}
171 //______________________________________________________________________________
172 Any ProviderImpl::TypeDescriptionManagerWrapper::getByHierarchicalName(
173 OUString const & name ) throw (container::NoSuchElementException,
174 RuntimeException)
178 // first try tdmgr:
179 return m_xTDMgr->getByHierarchicalName( name );
181 catch (container::NoSuchElementException &)
183 // then lookup locally:
184 return m_xThisProvider->getByHierarchicalName( name );
188 //______________________________________________________________________________
189 sal_Bool ProviderImpl::TypeDescriptionManagerWrapper::hasByHierarchicalName(
190 OUString const & name ) throw (RuntimeException)
192 return m_xTDMgr->hasByHierarchicalName( name ) || m_xThisProvider->hasByHierarchicalName( name );
195 //______________________________________________________________________________
196 uno::Reference< reflection::XTypeDescriptionEnumeration > SAL_CALL
197 ProviderImpl::TypeDescriptionManagerWrapper::createTypeDescriptionEnumeration(
198 const OUString& moduleName,
199 const uno::Sequence< uno::TypeClass >& types,
200 reflection::TypeDescriptionSearchDepth depth )
201 throw ( reflection::NoSuchTypeNameException,
202 reflection::InvalidTypeNameException,
203 uno::RuntimeException )
207 // first try tdmgr:
208 uno::Reference< reflection::XTypeDescriptionEnumerationAccess > xTDEA(
209 m_xTDMgr, uno::UNO_QUERY_THROW );
210 return
211 xTDEA->createTypeDescriptionEnumeration( moduleName, types, depth );
213 catch (reflection::NoSuchTypeNameException &)
215 // then lookup locally:
216 uno::Reference< reflection::XTypeDescriptionEnumerationAccess > xTDEA(
217 m_xThisProvider, uno::UNO_QUERY_THROW );
218 return
219 xTDEA->createTypeDescriptionEnumeration( moduleName, types, depth );
223 //__________________________________________________________________________________________________
224 com::sun::star::uno::Reference< XHierarchicalNameAccess > ProviderImpl::getTDMgr()
225 SAL_THROW(())
227 // harden weak reference:
228 com::sun::star::uno::Reference<container::XHierarchicalNameAccess> xTDMgr(
229 _xTDMgr );
230 if (! xTDMgr.is())
232 xTDMgr.set( new TypeDescriptionManagerWrapper(this) );
234 MutexGuard guard( _aComponentMutex );
235 _xTDMgr = xTDMgr;
238 return xTDMgr;
241 //__________________________________________________________________________________________________
242 void ProviderImpl::disposing()
244 _xContext.clear();
246 for ( RegistryKeyList::const_iterator iPos( _aBaseKeys.begin() );
247 iPos != _aBaseKeys.end(); ++iPos )
249 (*iPos)->closeKey();
251 _aBaseKeys.clear();
254 // XInitialization
255 //__________________________________________________________________________________________________
256 void ProviderImpl::initialize(
257 const Sequence< Any > & args )
258 throw (Exception, RuntimeException)
260 // registries to read from
261 Any const * pRegistries = args.getConstArray();
262 for ( sal_Int32 nPos = 0; nPos < args.getLength(); ++nPos )
264 com::sun::star::uno::Reference< XSimpleRegistry > xRegistry( pRegistries[ nPos ], UNO_QUERY );
265 if (xRegistry.is() && xRegistry->isValid())
267 com::sun::star::uno::Reference< XRegistryKey > xKey( xRegistry->getRootKey()->openKey(
268 OUString("/UCR") ) );
269 if (xKey.is() && xKey->isValid())
271 _aBaseKeys.push_back( xKey );
277 // XServiceInfo
278 //__________________________________________________________________________________________________
279 OUString ProviderImpl::getImplementationName()
280 throw(::com::sun::star::uno::RuntimeException)
282 return stoc_bootstrap::rdbtdp_getImplementationName();
284 //__________________________________________________________________________________________________
285 sal_Bool ProviderImpl::supportsService( const OUString & rServiceName )
286 throw(::com::sun::star::uno::RuntimeException)
288 const Sequence< OUString > & rSNL = getSupportedServiceNames();
289 const OUString * pArray = rSNL.getConstArray();
290 for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
292 if (pArray[nPos] == rServiceName)
293 return sal_True;
295 return sal_False;
297 //__________________________________________________________________________________________________
298 Sequence< OUString > ProviderImpl::getSupportedServiceNames()
299 throw(::com::sun::star::uno::RuntimeException)
301 return stoc_bootstrap::rdbtdp_getSupportedServiceNames();
304 // XHierarchicalNameAccess
305 //__________________________________________________________________________________________________
306 Any ProviderImpl::getByHierarchicalNameImpl( const OUString & rName )
308 Any aRet;
310 // read from registry
311 OUString aKey( rName.replace( '.', '/' ) );
312 for ( RegistryKeyList::const_iterator iPos( _aBaseKeys.begin() );
313 !aRet.hasValue() && iPos != _aBaseKeys.end(); ++iPos )
317 com::sun::star::uno::Reference< XRegistryKey > xBaseKey( *iPos );
318 com::sun::star::uno::Reference< XRegistryKey > xKey( xBaseKey->openKey( aKey ) );
319 if (xKey.is())
321 // closes key in it's dtor (which is
322 // called even in case of exceptions).
323 RegistryKeyCloser aCloser( xKey );
325 if ( xKey->isValid() )
327 if (xKey->getValueType() == RegistryValueType_BINARY)
329 Sequence< sal_Int8 > aBytes( xKey->getBinaryValue() );
330 com::sun::star::uno::Reference< XTypeDescription > xTD(
331 createTypeDescription( aBytes,
332 getTDMgr(),
333 true ) );
334 if ( xTD.is() )
335 aRet <<= xTD;
339 else // might be a constant
341 sal_Int32 nIndex = aKey.lastIndexOf( '/' );
342 if (nIndex > 0)
344 // open module
345 com::sun::star::uno::Reference< XRegistryKey > xKey2( xBaseKey->openKey( aKey.copy( 0, nIndex ) ) );
346 if (xKey2.is())
348 // closes key in it's dtor (which is
349 // called even in case of exceptions).
350 RegistryKeyCloser aCloser( xKey2 );
352 if ( xKey2->isValid() )
354 if (xKey2->getValueType() == RegistryValueType_BINARY)
356 Sequence< sal_Int8 > aBytes( xKey2->getBinaryValue() );
357 typereg::Reader aReader(
358 aBytes.getConstArray(), aBytes.getLength(),
359 false, TYPEREG_VERSION_1);
361 RTTypeClass tc = aReader.getTypeClass();
362 if (tc == RT_TYPE_MODULE ||
363 tc == RT_TYPE_CONSTANTS ||
364 tc == RT_TYPE_ENUM)
366 OUString aFieldName( aKey.copy( nIndex+1, aKey.getLength() - nIndex -1 ) );
367 sal_Int16 nPos = aReader.getFieldCount();
368 while (nPos--)
370 if (aFieldName.equals(
371 aReader.getFieldName(nPos)))
372 break;
374 if (nPos >= 0)
376 aRet = getRTValue(
377 aReader.getFieldValue(nPos));
378 if (tc != RT_TYPE_ENUM)
380 aRet = css::uno::makeAny<
381 css::uno::Reference<
382 css::reflection::XTypeDescription > >(
383 new ConstantTypeDescriptionImpl(
384 rName, aRet));
394 catch ( InvalidRegistryException const & )
396 OSL_FAIL( "ProviderImpl::getByHierarchicalName "
397 "- Caught InvalidRegistryException!" );
399 // openKey, closeKey, getValueType, getBinaryValue, isValid
401 // Don't stop iteration in this case.
403 catch ( NoSuchElementException const & )
407 return aRet;
410 Any SAL_CALL ProviderImpl::getByHierarchicalName( const OUString & rName )
411 throw(::com::sun::star::uno::RuntimeException, com::sun::star::container::NoSuchElementException)
413 Any aRet( getByHierarchicalNameImpl( rName ) );
415 if ( !aRet.hasValue() )
416 throw NoSuchElementException(
417 rName, static_cast< cppu::OWeakObject * >( this ) );
419 return aRet;
422 //__________________________________________________________________________________________________
423 sal_Bool ProviderImpl::hasByHierarchicalName( const OUString & rName )
424 throw(::com::sun::star::uno::RuntimeException)
426 return getByHierarchicalNameImpl( rName ).hasValue();
429 // XTypeDescriptionEnumerationAccess
430 //__________________________________________________________________________________________________
431 // virtual
432 com::sun::star::uno::Reference< XTypeDescriptionEnumeration > SAL_CALL
433 ProviderImpl::createTypeDescriptionEnumeration(
434 const OUString & moduleName,
435 const Sequence< TypeClass > & types,
436 TypeDescriptionSearchDepth depth )
437 throw ( NoSuchTypeNameException,
438 InvalidTypeNameException,
439 RuntimeException )
441 return com::sun::star::uno::Reference< XTypeDescriptionEnumeration >(
442 TypeDescriptionEnumerationImpl::createInstance( getTDMgr(),
443 moduleName,
444 types,
445 depth,
446 _aBaseKeys ).get() );
449 //__________________________________________________________________________________________________
450 // global helper function
452 com::sun::star::uno::Reference< XTypeDescription > resolveTypedefs(
453 com::sun::star::uno::Reference< XTypeDescription > const & type)
455 com::sun::star::uno::Reference< XTypeDescription > resolved(type);
456 while (resolved->getTypeClass() == TypeClass_TYPEDEF) {
457 resolved = com::sun::star::uno::Reference< XIndirectTypeDescription >(
458 resolved, UNO_QUERY_THROW)->getReferencedType();
460 return resolved;
463 com::sun::star::uno::Reference< XTypeDescription > createTypeDescription(
464 const Sequence< sal_Int8 > & rData,
465 const com::sun::star::uno::Reference< XHierarchicalNameAccess > & xNameAccess,
466 bool bReturnEmptyRefForUnknownType )
468 typereg::Reader aReader(
469 rData.getConstArray(), rData.getLength(), false, TYPEREG_VERSION_1);
471 OUString aName( aReader.getTypeName().replace( '/', '.' ) );
473 switch (aReader.getTypeClass())
475 case RT_TYPE_INTERFACE:
477 sal_uInt16 n = aReader.getSuperTypeCount();
478 com::sun::star::uno::Sequence< OUString > aBaseTypeNames(n);
479 for (sal_uInt16 i = 0; i < n; ++i) {
480 aBaseTypeNames[i] = aReader.getSuperTypeName(i).replace(
481 '/', '.');
483 sal_uInt16 n2 = aReader.getReferenceCount();
484 com::sun::star::uno::Sequence< OUString >
485 aOptionalBaseTypeNames(n2);
486 for (sal_uInt16 i = 0; i < n2; ++i) {
487 OSL_ASSERT(
488 aReader.getReferenceSort(i) == RT_REF_SUPPORTS
489 && aReader.getReferenceFlags(i) == RT_ACCESS_OPTIONAL);
490 aOptionalBaseTypeNames[i] = aReader.getReferenceTypeName(i);
492 return com::sun::star::uno::Reference< XTypeDescription >(
493 new InterfaceTypeDescriptionImpl( xNameAccess,
494 aName,
495 aBaseTypeNames,
496 aOptionalBaseTypeNames,
497 rData,
498 aReader.isPublished() ) );
501 case RT_TYPE_MODULE:
503 com::sun::star::uno::Reference<
504 XTypeDescriptionEnumerationAccess > xTDEA(
505 xNameAccess, UNO_QUERY );
507 OSL_ENSURE( xTDEA.is(),
508 "No XTypeDescriptionEnumerationAccess!" );
510 return com::sun::star::uno::Reference< XTypeDescription >(
511 new ModuleTypeDescriptionImpl( xTDEA, aName ) );
514 case RT_TYPE_STRUCT:
516 OUString superTypeName;
517 if (aReader.getSuperTypeCount() == 1) {
518 superTypeName = aReader.getSuperTypeName(0).replace(
519 '/', '.');
521 return com::sun::star::uno::Reference< XTypeDescription >(
522 new stoc::registry_tdprovider::StructTypeDescription(
523 xNameAccess, aName, superTypeName, rData,
524 aReader.isPublished()));
527 case RT_TYPE_ENUM:
528 return com::sun::star::uno::Reference< XTypeDescription >(
529 new EnumTypeDescriptionImpl( xNameAccess,
530 aName,
531 getRTValueAsInt32(
532 aReader.getFieldValue( 0 ) ),
533 rData, aReader.isPublished() ) );
535 case RT_TYPE_EXCEPTION:
537 OUString superTypeName;
538 if (aReader.getSuperTypeCount() == 1) {
539 superTypeName = aReader.getSuperTypeName(0).replace(
540 '/', '.');
542 return com::sun::star::uno::Reference< XTypeDescription >(
543 new CompoundTypeDescriptionImpl(
544 xNameAccess, TypeClass_EXCEPTION, aName, superTypeName,
545 rData, aReader.isPublished()));
548 case RT_TYPE_TYPEDEF:
549 return com::sun::star::uno::Reference< XTypeDescription >(
550 new TypedefTypeDescriptionImpl( xNameAccess,
551 aName,
552 aReader.getSuperTypeName(0)
553 .replace( '/', '.' ),
554 aReader.isPublished() ) );
555 case RT_TYPE_SERVICE:
556 return com::sun::star::uno::Reference< XTypeDescription >(
557 new ServiceTypeDescriptionImpl(
558 xNameAccess, aName, rData, aReader.isPublished() ) );
560 case RT_TYPE_CONSTANTS:
561 return com::sun::star::uno::Reference< XTypeDescription >(
562 new ConstantsTypeDescriptionImpl(
563 aName, rData, aReader.isPublished() ) );
565 case RT_TYPE_SINGLETON:
566 return com::sun::star::uno::Reference< XTypeDescription >(
567 new SingletonTypeDescriptionImpl( xNameAccess,
568 aName,
569 aReader.getSuperTypeName(0)
570 .replace( '/', '.' ),
571 aReader.isPublished() ) );
572 case RT_TYPE_INVALID:
573 case RT_TYPE_OBJECT: // deprecated and not used
574 case RT_TYPE_UNION: // deprecated and not used
575 OSL_FAIL( "createTypeDescription - Unsupported Type!" );
576 break;
578 default:
579 OSL_FAIL( "createTypeDescription - Unknown Type!" );
580 break;
583 // Unknown type.
585 if ( bReturnEmptyRefForUnknownType )
586 return com::sun::star::uno::Reference< XTypeDescription >();
588 return com::sun::star::uno::Reference< XTypeDescription >(
589 new TypeDescriptionImpl( TypeClass_UNKNOWN, aName ) );
594 namespace stoc_bootstrap
596 //==================================================================================================
597 com::sun::star::uno::Reference< XInterface > SAL_CALL ProviderImpl_create(
598 com::sun::star::uno::Reference< XComponentContext > const & xContext )
599 throw(::com::sun::star::uno::Exception)
601 return com::sun::star::uno::Reference< XInterface >( *new stoc_rdbtdp::ProviderImpl( xContext ) );
605 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */