1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_ucb.hxx"
26
27 /**************************************************************************
28 TODO
29 **************************************************************************
30
31 Note: Configuration Management classes do not support XAggregation.
32 So I have to wrap the interesting interfaces manually.
33
34 *************************************************************************/
35 #include "hierarchydatasource.hxx"
36 #include <osl/diagnose.h>
37
38 #include "osl/doublecheckedlocking.h"
39 #include <cppuhelper/interfacecontainer.hxx>
40 #include <com/sun/star/beans/PropertyValue.hpp>
41 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
42 #include <com/sun/star/container/XNameContainer.hpp>
43 #include <com/sun/star/util/XChangesBatch.hpp>
44 #include <com/sun/star/util/XChangesNotifier.hpp>
45
46 using namespace com::sun::star;
47 using namespace hierarchy_ucp;
48
49 //=========================================================================
50
51 // describe path of cfg entry
52 #define CFGPROPERTY_NODEPATH "nodepath"
53 // true->async. update; false->sync. update
54 #define CFGPROPERTY_LAZYWRITE "lazywrite"
55
56 #define READ_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadAccess"
57 #define READWRITE_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadWriteAccess"
58
59 #define CONFIG_PROVIDER_SERVICE_NAME \
60 "com.sun.star.configuration.ConfigurationProvider"
61 #define CONFIG_READ_SERVICE_NAME \
62 "com.sun.star.configuration.ConfigurationAccess"
63 #define CONFIG_READWRITE_SERVICE_NAME \
64 "com.sun.star.configuration.ConfigurationUpdateAccess"
65 #define CONFIG_DATA_ROOT_KEY \
66 "/org.openoffice.ucb.Hierarchy/Root"
67
68 //=========================================================================
69
70 namespace hcp_impl
71 {
72
73 //=========================================================================
74 //
75 // HierarchyDataReadAccess Implementation.
76 //
77 //=========================================================================
78
79 class HierarchyDataAccess : public cppu::OWeakObject,
80 public lang::XServiceInfo,
81 public lang::XTypeProvider,
82 public lang::XComponent,
83 public lang::XSingleServiceFactory,
84 public container::XHierarchicalNameAccess,
85 public container::XNameContainer,
86 public util::XChangesNotifier,
87 public util::XChangesBatch
88 {
89 osl::Mutex m_aMutex;
90 uno::Reference< uno::XInterface > m_xConfigAccess;
91 uno::Reference< lang::XComponent > m_xCfgC;
92 uno::Reference< lang::XSingleServiceFactory > m_xCfgSSF;
93 uno::Reference< container::XHierarchicalNameAccess > m_xCfgHNA;
94 uno::Reference< container::XNameContainer > m_xCfgNC;
95 uno::Reference< container::XNameReplace > m_xCfgNR;
96 uno::Reference< container::XNameAccess > m_xCfgNA;
97 uno::Reference< container::XElementAccess > m_xCfgEA;
98 uno::Reference< util::XChangesNotifier > m_xCfgCN;
99 uno::Reference< util::XChangesBatch > m_xCfgCB;
100 bool m_bReadOnly;
101
102 public:
103 HierarchyDataAccess( const uno::Reference<
104 uno::XInterface > & xConfigAccess,
105 bool bReadOnly );
106 virtual ~HierarchyDataAccess();
107
108 // XInterface
109 XINTERFACE_DECL()
110
111 // XServiceInfo
112 XSERVICEINFO_DECL()
113
114 // XTypeProvider
115 XTYPEPROVIDER_DECL()
116
117 // XComponent
118 virtual void SAL_CALL
119 dispose()
120 throw ( uno::RuntimeException );
121 virtual void SAL_CALL
122 addEventListener( const uno::Reference< lang::XEventListener > & xListener )
123 throw ( uno::RuntimeException );
124 virtual void SAL_CALL
125 removeEventListener( const uno::Reference<
126 lang::XEventListener > & aListener )
127 throw ( uno::RuntimeException );
128
129 // XSingleServiceFactory
130 virtual uno::Reference< uno::XInterface > SAL_CALL
131 createInstance()
132 throw ( uno::Exception, uno::RuntimeException );
133 virtual uno::Reference< uno::XInterface > SAL_CALL
134 createInstanceWithArguments( const uno::Sequence< uno::Any > & aArguments )
135 throw ( uno::Exception, uno::RuntimeException );
136
137 // XHierarchicalNameAccess
138 virtual uno::Any SAL_CALL
139 getByHierarchicalName( const rtl::OUString & aName )
140 throw ( container::NoSuchElementException, uno::RuntimeException );
141 virtual sal_Bool SAL_CALL
142 hasByHierarchicalName( const rtl::OUString & aName )
143 throw ( uno::RuntimeException );
144
145 // XNameContainer
146 virtual void SAL_CALL
147 insertByName( const rtl::OUString & aName, const uno::Any & aElement )
148 throw ( lang::IllegalArgumentException,
149 container::ElementExistException,
150 lang::WrappedTargetException,
151 uno::RuntimeException );
152 virtual void SAL_CALL
153 removeByName( const rtl::OUString & Name )
154 throw ( container::NoSuchElementException,
155 lang::WrappedTargetException,
156 uno::RuntimeException );
157
158 // XNameReplace ( base of XNameContainer )
159 virtual void SAL_CALL
160 replaceByName( const rtl::OUString & aName, const uno::Any & aElement )
161 throw ( lang::IllegalArgumentException,
162 container::NoSuchElementException,
163 lang::WrappedTargetException,
164 uno::RuntimeException );
165
166 // XNameAccess ( base of XNameReplace )
167 virtual uno::Any SAL_CALL
168 getByName( const rtl::OUString & aName )
169 throw ( container::NoSuchElementException,
170 lang::WrappedTargetException,
171 uno::RuntimeException );
172 virtual uno::Sequence< rtl::OUString > SAL_CALL
173 getElementNames()
174 throw ( uno::RuntimeException );
175 virtual sal_Bool SAL_CALL
176 hasByName( const rtl::OUString & aName )
177 throw ( uno::RuntimeException );
178
179 // XElementAccess ( base of XNameAccess )
180 virtual uno::Type SAL_CALL
181 getElementType()
182 throw ( uno::RuntimeException );
183 virtual sal_Bool SAL_CALL
184 hasElements()
185 throw ( uno::RuntimeException );
186
187 // XChangesNotifier
188 virtual void SAL_CALL
189 addChangesListener( const uno::Reference<
190 util::XChangesListener > & aListener )
191 throw ( uno::RuntimeException );
192 virtual void SAL_CALL
193 removeChangesListener( const uno::Reference<
194 util::XChangesListener > & aListener )
195 throw ( uno::RuntimeException );
196
197 // XChangesBatch
198 virtual void SAL_CALL
199 commitChanges()
200 throw ( lang::WrappedTargetException, uno::RuntimeException );
201 virtual sal_Bool SAL_CALL
202 hasPendingChanges()
203 throw ( uno::RuntimeException );
204 virtual uno::Sequence< util::ElementChange > SAL_CALL
205 getPendingChanges()
206 throw ( uno::RuntimeException );
207 };
208
209 } // namespace hcp_impl
210
211 using namespace hcp_impl;
212
213 //=========================================================================
214 //=========================================================================
215 //
216 // HierarchyDataSource Implementation.
217 //
218 //=========================================================================
219 //=========================================================================
220
HierarchyDataSource(const uno::Reference<lang::XMultiServiceFactory> & rxServiceMgr)221 HierarchyDataSource::HierarchyDataSource(
222 const uno::Reference< lang::XMultiServiceFactory > & rxServiceMgr )
223 : m_xSMgr( rxServiceMgr ),
224 m_pDisposeEventListeners( 0 )
225 {
226 }
227
228 //=========================================================================
229 // virtual
~HierarchyDataSource()230 HierarchyDataSource::~HierarchyDataSource()
231 {
232 delete m_pDisposeEventListeners;
233 }
234
235 //=========================================================================
236 //
237 // XInterface methods.
238 //
239 //=========================================================================
240
241 XINTERFACE_IMPL_4( HierarchyDataSource,
242 lang::XTypeProvider,
243 lang::XServiceInfo,
244 lang::XComponent,
245 lang::XMultiServiceFactory );
246
247 //=========================================================================
248 //
249 // XTypeProvider methods.
250 //
251 //=========================================================================
252
253 XTYPEPROVIDER_IMPL_4( HierarchyDataSource,
254 lang::XTypeProvider,
255 lang::XServiceInfo,
256 lang::XComponent,
257 lang::XMultiServiceFactory );
258
259 //=========================================================================
260 //
261 // XServiceInfo methods.
262 //
263 //=========================================================================
264
265 XSERVICEINFO_IMPL_0( HierarchyDataSource,
266 rtl::OUString::createFromAscii(
267 "com.sun.star.comp.ucb.HierarchyDataSource" ) )
268 {
269 uno::Sequence< rtl::OUString > aSNS( 2 );
270 aSNS[ 0 ] = rtl::OUString::createFromAscii(
271 "com.sun.star.ucb.DefaultHierarchyDataSource" );
272 aSNS[ 1 ] = rtl::OUString::createFromAscii(
273 "com.sun.star.ucb.HierarchyDataSource" );
274 return aSNS;
275 }
276
277 ONE_INSTANCE_SERVICE_FACTORY_IMPL( HierarchyDataSource );
278
279 //=========================================================================
280 //
281 // XComponent methods.
282 //
283 //=========================================================================
284
285 // virtual
dispose()286 void SAL_CALL HierarchyDataSource::dispose()
287 throw( uno::RuntimeException )
288 {
289 osl::Guard< osl::Mutex > aGuard( m_aMutex );
290
291 if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
292 {
293 lang::EventObject aEvt;
294 aEvt.Source = static_cast< lang::XComponent * >( this );
295 m_pDisposeEventListeners->disposeAndClear( aEvt );
296 }
297 }
298
299 //=========================================================================
300 // virtual
addEventListener(const uno::Reference<lang::XEventListener> & Listener)301 void SAL_CALL HierarchyDataSource::addEventListener(
302 const uno::Reference< lang::XEventListener > & Listener )
303 throw( uno::RuntimeException )
304 {
305 osl::Guard< osl::Mutex > aGuard( m_aMutex );
306
307 if ( !m_pDisposeEventListeners )
308 m_pDisposeEventListeners
309 = new cppu::OInterfaceContainerHelper( m_aMutex );
310
311 m_pDisposeEventListeners->addInterface( Listener );
312 }
313
314 //=========================================================================
315 // virtual
removeEventListener(const uno::Reference<lang::XEventListener> & Listener)316 void SAL_CALL HierarchyDataSource::removeEventListener(
317 const uno::Reference< lang::XEventListener > & Listener )
318 throw( uno::RuntimeException )
319 {
320 osl::Guard< osl::Mutex > aGuard( m_aMutex );
321
322 if ( m_pDisposeEventListeners )
323 m_pDisposeEventListeners->removeInterface( Listener );
324 }
325
326 //=========================================================================
327 //
328 // XMultiServiceFactory methods.
329 //
330 //=========================================================================
331
332 // virtual
333 uno::Reference< uno::XInterface > SAL_CALL
createInstance(const rtl::OUString & aServiceSpecifier)334 HierarchyDataSource::createInstance( const rtl::OUString & aServiceSpecifier )
335 throw ( uno::Exception, uno::RuntimeException )
336 {
337 // Create view to root node.
338
339 beans::PropertyValue aProp;
340 aProp.Name = rtl::OUString(
341 RTL_CONSTASCII_USTRINGPARAM( CFGPROPERTY_NODEPATH ) );
342 aProp.Value <<=
343 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY ) );
344
345 uno::Sequence< uno::Any > aArguments( 1 );
346 aArguments[ 0 ] <<= aProp;
347
348 return createInstanceWithArguments( aServiceSpecifier, aArguments, false );
349 }
350
351 //=========================================================================
352 // virtual
353 uno::Reference< uno::XInterface > SAL_CALL
createInstanceWithArguments(const rtl::OUString & ServiceSpecifier,const uno::Sequence<uno::Any> & Arguments)354 HierarchyDataSource::createInstanceWithArguments(
355 const rtl::OUString & ServiceSpecifier,
356 const uno::Sequence< uno::Any > & Arguments )
357 throw ( uno::Exception, uno::RuntimeException )
358 {
359 return createInstanceWithArguments( ServiceSpecifier, Arguments, true );
360 }
361
362 //=========================================================================
363 // virtual
364 uno::Sequence< rtl::OUString > SAL_CALL
getAvailableServiceNames()365 HierarchyDataSource::getAvailableServiceNames()
366 throw ( uno::RuntimeException )
367 {
368 uno::Sequence< rtl::OUString > aNames( 2 );
369 aNames[ 0 ] = rtl::OUString(
370 RTL_CONSTASCII_USTRINGPARAM( READ_SERVICE_NAME ) );
371 aNames[ 1 ] = rtl::OUString(
372 RTL_CONSTASCII_USTRINGPARAM( READWRITE_SERVICE_NAME ) );
373 return aNames;
374 }
375
376 //=========================================================================
377 //
378 // Non-interface methods
379 //
380 //=========================================================================
381
382 uno::Reference< uno::XInterface > SAL_CALL
createInstanceWithArguments(const rtl::OUString & ServiceSpecifier,const uno::Sequence<uno::Any> & Arguments,bool bCheckArgs)383 HierarchyDataSource::createInstanceWithArguments(
384 const rtl::OUString & ServiceSpecifier,
385 const uno::Sequence< uno::Any > & Arguments,
386 bool bCheckArgs )
387 throw ( uno::Exception, uno::RuntimeException )
388 {
389 osl::Guard< osl::Mutex > aGuard( m_aMutex );
390
391 // Check service specifier.
392 bool bReadOnly = !!ServiceSpecifier.equalsAsciiL(
393 RTL_CONSTASCII_STRINGPARAM( READ_SERVICE_NAME ) );
394 bool bReadWrite = !bReadOnly &&
395 ServiceSpecifier.equalsAsciiL(
396 RTL_CONSTASCII_STRINGPARAM( READWRITE_SERVICE_NAME ) );
397
398 if ( !bReadOnly && !bReadWrite )
399 {
400 OSL_ENSURE( false,
401 "HierarchyDataSource::createInstanceWithArguments - "
402 "Unsupported service specifier!" );
403 return uno::Reference< uno::XInterface >();
404 }
405
406 uno::Sequence< uno::Any > aNewArgs( Arguments );
407
408 bool bHasLazyWriteProp = bReadOnly; // property must be added only if
409 // a writable view is requested.
410 if ( bCheckArgs )
411 {
412 // Check arguments.
413 bool bHasNodePath = false;
414 sal_Int32 nCount = Arguments.getLength();
415 for ( sal_Int32 n = 0; n < nCount; ++n )
416 {
417 beans::PropertyValue aProp;
418 if ( Arguments[ n ] >>= aProp )
419 {
420 if ( aProp.Name.equalsAsciiL(
421 RTL_CONSTASCII_STRINGPARAM( CFGPROPERTY_NODEPATH ) ) )
422 {
423 rtl::OUString aPath;
424 if ( aProp.Value >>= aPath )
425 {
426 bHasNodePath = true;
427
428 // Create path to data inside the configuration.
429 rtl::OUString aConfigPath;
430 if ( !createConfigPath( aPath, aConfigPath ) )
431 {
432 OSL_ENSURE( false,
433 "HierarchyDataSource::"
434 "createInstanceWithArguments - "
435 "Invalid node path!" );
436 return uno::Reference< uno::XInterface >();
437 }
438
439 aProp.Value <<= aConfigPath;
440
441 // Set new path in arguments.
442 aNewArgs[ n ] <<= aProp;
443
444 if ( bHasLazyWriteProp )
445 break;
446 }
447 else
448 {
449 OSL_ENSURE( false,
450 "HierarchyDataSource::createInstanceWithArguments - "
451 "Invalid type for property 'nodepath'!" );
452 return uno::Reference< uno::XInterface >();
453 }
454 }
455 else if ( aProp.Name.equalsAsciiL(
456 RTL_CONSTASCII_STRINGPARAM(
457 CFGPROPERTY_LAZYWRITE ) ) )
458 {
459 if ( aProp.Value.getValueType() == getCppuBooleanType() )
460 {
461 bHasLazyWriteProp = true;
462
463 if ( bHasNodePath )
464 break;
465 }
466 else
467 {
468 OSL_ENSURE( false,
469 "HierarchyDataSource::createInstanceWithArguments - "
470 "Invalid type for property 'lazywrite'!" );
471 return uno::Reference< uno::XInterface >();
472 }
473 }
474 }
475 }
476
477 if ( !bHasNodePath )
478 {
479 OSL_ENSURE( false,
480 "HierarchyDataSource::createInstanceWithArguments - "
481 "No 'nodepath' property!" );
482 return uno::Reference< uno::XInterface >();
483 }
484 }
485
486 // Create Configuration Provider.
487 uno::Reference< lang::XMultiServiceFactory > xProv = getConfigProvider();
488 if ( !xProv.is() )
489 return uno::Reference< uno::XInterface >();
490
491 uno::Reference< uno::XInterface > xConfigAccess;
492 try
493 {
494 if ( bReadOnly )
495 {
496 // Create configuration read-only access object.
497 xConfigAccess = xProv->createInstanceWithArguments(
498 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
499 CONFIG_READ_SERVICE_NAME ) ),
500 aNewArgs );
501 }
502 else
503 {
504 // Append 'lazywrite' property value, if not already present.
505 if ( !bHasLazyWriteProp )
506 {
507 sal_Int32 nLen = aNewArgs.getLength();
508 aNewArgs.realloc( nLen + 1 );
509
510 beans::PropertyValue aProp;
511 aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
512 CFGPROPERTY_LAZYWRITE ) );
513 aProp.Value <<= sal_True;
514 aNewArgs[ nLen ] <<= aProp;
515 }
516
517 // Create configuration read-write access object.
518 xConfigAccess = xProv->createInstanceWithArguments(
519 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
520 CONFIG_READWRITE_SERVICE_NAME ) ),
521 aNewArgs );
522 }
523 }
524 catch ( uno::Exception const & )
525 {
526 OSL_ENSURE( false,
527 "HierarchyDataSource::createInstanceWithArguments - "
528 "Cannot instanciate configuration access!" );
529 throw;
530 }
531
532 if ( !xConfigAccess.is() )
533 {
534 OSL_ENSURE( false,
535 "HierarchyDataSource::createInstanceWithArguments - "
536 "Cannot instanciate configuration access!" );
537 return xConfigAccess;
538 }
539
540 return uno::Reference< uno::XInterface >(
541 static_cast< cppu::OWeakObject * >(
542 new HierarchyDataAccess( xConfigAccess, bReadOnly ) ) );
543 }
544
545 //=========================================================================
546 uno::Reference< lang::XMultiServiceFactory >
getConfigProvider()547 HierarchyDataSource::getConfigProvider()
548 {
549 if ( !m_xConfigProvider.is() )
550 {
551 osl::Guard< osl::Mutex > aGuard( m_aMutex );
552 if ( !m_xConfigProvider.is() )
553 {
554 try
555 {
556 m_xConfigProvider
557 = uno::Reference< lang::XMultiServiceFactory >(
558 m_xSMgr->createInstance(
559 rtl::OUString(
560 RTL_CONSTASCII_USTRINGPARAM(
561 CONFIG_PROVIDER_SERVICE_NAME ) ) ),
562 uno::UNO_QUERY );
563
564 OSL_ENSURE( m_xConfigProvider.is(),
565 "HierarchyDataSource::getConfigProvider - "
566 "No configuration provider!" );
567 }
568 catch ( uno::Exception const & )
569 {
570 OSL_ENSURE( false,
571 "HierarchyDataSource::getConfigProvider - "
572 "caught exception!" );
573 }
574 }
575 }
576
577 return m_xConfigProvider;
578 }
579
580 //=========================================================================
createConfigPath(const rtl::OUString & rInPath,rtl::OUString & rOutPath)581 bool HierarchyDataSource::createConfigPath(
582 const rtl::OUString & rInPath, rtl::OUString & rOutPath )
583 {
584 if ( rInPath.getLength() )
585 {
586 if ( rInPath.indexOf( '/' ) == 0 )
587 {
588 OSL_ENSURE( false,
589 "HierarchyDataSource::createConfigPath - "
590 "Leading slash in node path!" );
591 return false;
592 }
593
594 if ( rInPath.lastIndexOf( '/' ) == rInPath.getLength() - 1 )
595 {
596 OSL_ENSURE( false,
597 "HierarchyDataSource::createConfigPath - "
598 "Trailing slash in node path!" );
599 return false;
600 }
601
602 rtl::OUString aOutPath(
603 RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY "/" ) );
604 aOutPath += rInPath;
605 rOutPath = aOutPath;
606 }
607 else
608 {
609 rOutPath = rtl::OUString(
610 RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY ) );
611 }
612
613 return true;
614 }
615
616 //=========================================================================
617 //=========================================================================
618 //
619 // HierarchyDataAccess Implementation.
620 //
621 //=========================================================================
622 //=========================================================================
623
624 #define ENSURE_ORIG_INTERFACE( interface_name, member_name ) \
625 m_xCfg##member_name; \
626 if ( !m_xCfg##member_name.is() ) \
627 { \
628 osl::Guard< osl::Mutex > aGuard( m_aMutex ); \
629 if ( !m_xCfg##member_name.is() ) \
630 m_xCfg##member_name \
631 = uno::Reference< interface_name >( \
632 m_xConfigAccess, uno::UNO_QUERY ); \
633 xOrig = m_xCfg##member_name; \
634 }
635
636 //=========================================================================
HierarchyDataAccess(const uno::Reference<uno::XInterface> & xConfigAccess,bool bReadOnly)637 HierarchyDataAccess::HierarchyDataAccess( const uno::Reference<
638 uno::XInterface > & xConfigAccess,
639 bool bReadOnly )
640 : m_xConfigAccess( xConfigAccess ),
641 m_bReadOnly( bReadOnly )
642 {
643 }
644
645 //=========================================================================
646 // virtual
~HierarchyDataAccess()647 HierarchyDataAccess::~HierarchyDataAccess()
648 {
649 }
650
651 //=========================================================================
652 //
653 // XInterface methods.
654 //
655 //=========================================================================
656
657 XINTERFACE_COMMON_IMPL( HierarchyDataAccess );
658
659 //=========================================================================
660 // virtual
queryInterface(const uno::Type & aType)661 uno::Any SAL_CALL HierarchyDataAccess::queryInterface( const uno::Type & aType )
662 throw ( uno::RuntimeException )
663 {
664 // Interfaces supported in read-only and read-write mode.
665 uno::Any aRet = cppu::queryInterface( aType,
666 static_cast< lang::XTypeProvider * >( this ),
667 static_cast< lang::XServiceInfo * >( this ),
668 static_cast< lang::XComponent * >( this ),
669 static_cast< container::XHierarchicalNameAccess * >( this ),
670 static_cast< container::XNameAccess * >( this ),
671 static_cast< container::XElementAccess * >( this ),
672 static_cast< util::XChangesNotifier * >( this ) );
673
674 // Interfaces supported only in read-write mode.
675 if ( !aRet.hasValue() && !m_bReadOnly )
676 {
677 aRet = cppu::queryInterface( aType,
678 static_cast< lang::XSingleServiceFactory * >( this ),
679 static_cast< container::XNameContainer * >( this ),
680 static_cast< container::XNameReplace * >( this ),
681 static_cast< util::XChangesBatch * >( this ) );
682 }
683
684 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( aType );
685 }
686
687 //=========================================================================
688 //
689 // XTypeProvider methods.
690 //
691 //=========================================================================
692
693 XTYPEPROVIDER_COMMON_IMPL( HierarchyDataAccess );
694
695 //=========================================================================
696 // virtual
getTypes()697 uno::Sequence< uno::Type > SAL_CALL HierarchyDataAccess::getTypes()
698 throw( uno::RuntimeException )
699 {
700 cppu::OTypeCollection * pCollection = 0;
701
702 if ( m_bReadOnly )
703 {
704 static cppu::OTypeCollection* pReadOnlyTypes = 0;
705
706 pCollection = pReadOnlyTypes;
707 if ( !pCollection )
708 {
709 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
710
711 pCollection = pReadOnlyTypes;
712 if ( !pCollection )
713 {
714 static cppu::OTypeCollection aCollection(
715 CPPU_TYPE_REF( lang::XTypeProvider ),
716 CPPU_TYPE_REF( lang::XServiceInfo ),
717 CPPU_TYPE_REF( lang::XComponent ),
718 CPPU_TYPE_REF( container::XHierarchicalNameAccess ),
719 CPPU_TYPE_REF( container::XNameAccess ),
720 CPPU_TYPE_REF( util::XChangesNotifier ) );
721 pCollection = &aCollection;
722 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
723 pReadOnlyTypes = pCollection;
724 }
725 }
726 else {
727 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
728 }
729 }
730 else
731 {
732 static cppu::OTypeCollection* pReadWriteTypes = 0;
733
734 pCollection = pReadWriteTypes;
735 if ( !pCollection )
736 {
737 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
738
739 pCollection = pReadWriteTypes;
740 if ( !pCollection )
741 {
742 static cppu::OTypeCollection aCollection(
743 CPPU_TYPE_REF( lang::XTypeProvider ),
744 CPPU_TYPE_REF( lang::XServiceInfo ),
745 CPPU_TYPE_REF( lang::XComponent ),
746 CPPU_TYPE_REF( lang::XSingleServiceFactory ),
747 CPPU_TYPE_REF( container::XHierarchicalNameAccess ),
748 CPPU_TYPE_REF( container::XNameContainer ),
749 CPPU_TYPE_REF( util::XChangesBatch ),
750 CPPU_TYPE_REF( util::XChangesNotifier ) );
751 pCollection = &aCollection;
752 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
753 pReadWriteTypes = pCollection;
754 }
755 }
756 else {
757 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
758 }
759 }
760
761 return (*pCollection).getTypes();
762 }
763
764 //=========================================================================
765 //
766 // XServiceInfo methods.
767 //
768 //=========================================================================
769
770 XSERVICEINFO_NOFACTORY_IMPL_0(
771 HierarchyDataAccess,
772 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
773 "com.sun.star.comp.ucb.HierarchyDataAccess" ) ) )
774 {
775 uno::Sequence< rtl::OUString > aSNS( 2 );
776 aSNS[ 0 ] = rtl::OUString(
777 RTL_CONSTASCII_USTRINGPARAM( READ_SERVICE_NAME ) );
778 aSNS[ 1 ] = rtl::OUString(
779 RTL_CONSTASCII_USTRINGPARAM( READWRITE_SERVICE_NAME ) );
780 return aSNS;
781 }
782
783 //=========================================================================
784 //
785 // XComponent methods.
786 //
787 //=========================================================================
788
789 // virtual
dispose()790 void SAL_CALL HierarchyDataAccess::dispose()
791 throw ( uno::RuntimeException )
792 {
793 uno::Reference< lang::XComponent > xOrig
794 = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
795
796 OSL_ENSURE( xOrig.is(),
797 "HierarchyDataAccess : Data source is not an XComponent!" );
798 xOrig->dispose();
799 }
800
801 //=========================================================================
802 // virtual
addEventListener(const uno::Reference<lang::XEventListener> & xListener)803 void SAL_CALL HierarchyDataAccess::addEventListener(
804 const uno::Reference< lang::XEventListener > & xListener )
805 throw ( uno::RuntimeException )
806 {
807 uno::Reference< lang::XComponent > xOrig
808 = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
809
810 OSL_ENSURE( xOrig.is(),
811 "HierarchyDataAccess : Data source is not an XComponent!" );
812 xOrig->addEventListener( xListener );
813 }
814
815 //=========================================================================
816 // virtual
removeEventListener(const uno::Reference<lang::XEventListener> & aListener)817 void SAL_CALL HierarchyDataAccess::removeEventListener(
818 const uno::Reference< lang::XEventListener > & aListener )
819 throw ( uno::RuntimeException )
820 {
821 uno::Reference< lang::XComponent > xOrig
822 = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
823
824 OSL_ENSURE( xOrig.is(),
825 "HierarchyDataAccess : Data source is not an XComponent!" );
826 xOrig->removeEventListener( aListener );
827 }
828
829 //=========================================================================
830 //
831 // XHierarchicalNameAccess methods.
832 //
833 //=========================================================================
834
835 // virtual
getByHierarchicalName(const rtl::OUString & aName)836 uno::Any SAL_CALL HierarchyDataAccess::getByHierarchicalName(
837 const rtl::OUString & aName )
838 throw ( container::NoSuchElementException, uno::RuntimeException )
839 {
840 uno::Reference< container::XHierarchicalNameAccess > xOrig
841 = ENSURE_ORIG_INTERFACE( container::XHierarchicalNameAccess, HNA );
842
843 OSL_ENSURE( xOrig.is(),
844 "HierarchyDataAccess : "
845 "Data source is not an XHierarchicalNameAccess!" );
846 return xOrig->getByHierarchicalName( aName );
847 }
848
849 //=========================================================================
850 // virtual
hasByHierarchicalName(const rtl::OUString & aName)851 sal_Bool SAL_CALL HierarchyDataAccess::hasByHierarchicalName(
852 const rtl::OUString & aName )
853 throw ( uno::RuntimeException )
854 {
855 uno::Reference< container::XHierarchicalNameAccess > xOrig
856 = ENSURE_ORIG_INTERFACE( container::XHierarchicalNameAccess, HNA );
857
858 OSL_ENSURE( xOrig.is(),
859 "HierarchyDataAccess : "
860 "Data source is not an XHierarchicalNameAccess!" );
861 return xOrig->hasByHierarchicalName( aName );
862 }
863
864 //=========================================================================
865 //
866 // XNameAccess methods.
867 //
868 //=========================================================================
869
870 // virtual
getByName(const rtl::OUString & aName)871 uno::Any SAL_CALL HierarchyDataAccess::getByName( const rtl::OUString & aName )
872 throw ( container::NoSuchElementException,
873 lang::WrappedTargetException,
874 uno::RuntimeException )
875 {
876 uno::Reference< container::XNameAccess > xOrig
877 = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
878
879 OSL_ENSURE( xOrig.is(),
880 "HierarchyDataAccess : Data source is not an XNameAccess!" );
881 return xOrig->getByName( aName );
882 }
883
884 //=========================================================================
885 // virtual
getElementNames()886 uno::Sequence< rtl::OUString > SAL_CALL HierarchyDataAccess::getElementNames()
887 throw ( uno::RuntimeException )
888 {
889 uno::Reference< container::XNameAccess > xOrig
890 = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
891
892 OSL_ENSURE( xOrig.is(),
893 "HierarchyDataAccess : Data source is not an XNameAccess!" );
894 return xOrig->getElementNames();
895 }
896
897 //=========================================================================
898 // virtual
hasByName(const rtl::OUString & aName)899 sal_Bool SAL_CALL HierarchyDataAccess::hasByName( const rtl::OUString & aName )
900 throw ( uno::RuntimeException )
901 {
902 uno::Reference< container::XNameAccess > xOrig
903 = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
904
905 OSL_ENSURE( xOrig.is(),
906 "HierarchyDataAccess : Data source is not an XNameAccess!" );
907 return xOrig->hasByName( aName );
908 }
909
910 //=========================================================================
911 //
912 // XElementAccess methods.
913 //
914 //=========================================================================
915
916 // virtual
getElementType()917 uno::Type SAL_CALL HierarchyDataAccess::getElementType()
918 throw ( uno::RuntimeException )
919 {
920 uno::Reference< container::XElementAccess > xOrig
921 = ENSURE_ORIG_INTERFACE( container::XElementAccess, EA );
922
923 OSL_ENSURE( xOrig.is(),
924 "HierarchyDataAccess : Data source is not an XElementAccess!" );
925 return xOrig->getElementType();
926 }
927
928 //=========================================================================
929 // virtual
hasElements()930 sal_Bool SAL_CALL HierarchyDataAccess::hasElements()
931 throw ( uno::RuntimeException )
932 {
933 uno::Reference< container::XElementAccess > xOrig
934 = ENSURE_ORIG_INTERFACE( container::XElementAccess, EA );
935
936 OSL_ENSURE( xOrig.is(),
937 "HierarchyDataAccess : Data source is not an XElementAccess!" );
938 return xOrig->hasElements();
939 }
940
941 //=========================================================================
942 //
943 // XChangesNotifier methods.
944 //
945 //=========================================================================
946
947 // virtual
addChangesListener(const uno::Reference<util::XChangesListener> & aListener)948 void SAL_CALL HierarchyDataAccess::addChangesListener(
949 const uno::Reference< util::XChangesListener > & aListener )
950 throw ( uno::RuntimeException )
951 {
952 uno::Reference< util::XChangesNotifier > xOrig
953 = ENSURE_ORIG_INTERFACE( util::XChangesNotifier, CN );
954
955 OSL_ENSURE( xOrig.is(),
956 "HierarchyDataAccess : Data source is not an XChangesNotifier!" );
957 xOrig->addChangesListener( aListener );
958 }
959
960 //=========================================================================
961 // virtual
removeChangesListener(const uno::Reference<util::XChangesListener> & aListener)962 void SAL_CALL HierarchyDataAccess::removeChangesListener(
963 const uno::Reference< util::XChangesListener > & aListener )
964 throw ( uno::RuntimeException )
965 {
966 uno::Reference< util::XChangesNotifier > xOrig
967 = ENSURE_ORIG_INTERFACE( util::XChangesNotifier, CN );
968
969 OSL_ENSURE( xOrig.is(),
970 "HierarchyDataAccess : Data source is not an XChangesNotifier!" );
971 xOrig->removeChangesListener( aListener );
972 }
973
974 //=========================================================================
975 //
976 // XSingleServiceFactory methods.
977 //
978 //=========================================================================
979
980 // virtual
createInstance()981 uno::Reference< uno::XInterface > SAL_CALL HierarchyDataAccess::createInstance()
982 throw ( uno::Exception, uno::RuntimeException )
983 {
984 uno::Reference< lang::XSingleServiceFactory > xOrig
985 = ENSURE_ORIG_INTERFACE( lang::XSingleServiceFactory, SSF );
986
987 OSL_ENSURE( xOrig.is(),
988 "HierarchyDataAccess : Data source is not an XSingleServiceFactory!" );
989 return xOrig->createInstance();
990 }
991
992 //=========================================================================
993 // virtual
994 uno::Reference< uno::XInterface > SAL_CALL
createInstanceWithArguments(const uno::Sequence<uno::Any> & aArguments)995 HierarchyDataAccess::createInstanceWithArguments(
996 const uno::Sequence< uno::Any > & aArguments )
997 throw ( uno::Exception, uno::RuntimeException )
998 {
999 uno::Reference< lang::XSingleServiceFactory > xOrig
1000 = ENSURE_ORIG_INTERFACE( lang::XSingleServiceFactory, SSF );
1001
1002 OSL_ENSURE( xOrig.is(),
1003 "HierarchyDataAccess : Data source is not an XSingleServiceFactory!" );
1004 return xOrig->createInstanceWithArguments( aArguments );
1005 }
1006
1007 //=========================================================================
1008 //
1009 // XNameContainer methods.
1010 //
1011 //=========================================================================
1012
1013 // virtual
1014 void SAL_CALL
insertByName(const rtl::OUString & aName,const uno::Any & aElement)1015 HierarchyDataAccess::insertByName( const rtl::OUString & aName,
1016 const uno::Any & aElement )
1017 throw ( lang::IllegalArgumentException,
1018 container::ElementExistException,
1019 lang::WrappedTargetException,
1020 uno::RuntimeException )
1021 {
1022 uno::Reference< container::XNameContainer > xOrig
1023 = ENSURE_ORIG_INTERFACE( container::XNameContainer, NC );
1024
1025 OSL_ENSURE( xOrig.is(),
1026 "HierarchyDataAccess : Data source is not an XNameContainer!" );
1027 xOrig->insertByName( aName, aElement );
1028 }
1029
1030 //=========================================================================
1031 // virtual
1032 void SAL_CALL
removeByName(const rtl::OUString & Name)1033 HierarchyDataAccess::removeByName( const rtl::OUString & Name )
1034 throw ( container::NoSuchElementException,
1035 lang::WrappedTargetException,
1036 uno::RuntimeException )
1037 {
1038 uno::Reference< container::XNameContainer > xOrig
1039 = ENSURE_ORIG_INTERFACE( container::XNameContainer, NC );
1040
1041 OSL_ENSURE( xOrig.is(),
1042 "HierarchyDataAccess : Data source is not an XNameContainer!" );
1043 xOrig->removeByName( Name );
1044 }
1045
1046 //=========================================================================
1047 //
1048 // XNameReplace methods.
1049 //
1050 //=========================================================================
1051
1052 // virtual
replaceByName(const rtl::OUString & aName,const uno::Any & aElement)1053 void SAL_CALL HierarchyDataAccess::replaceByName( const rtl::OUString & aName,
1054 const uno::Any & aElement )
1055 throw ( lang::IllegalArgumentException,
1056 container::NoSuchElementException,
1057 lang::WrappedTargetException,
1058 uno::RuntimeException )
1059 {
1060 uno::Reference< container::XNameReplace > xOrig
1061 = ENSURE_ORIG_INTERFACE( container::XNameReplace, NR );
1062
1063 OSL_ENSURE( xOrig.is(),
1064 "HierarchyDataAccess : Data source is not an XNameReplace!" );
1065 xOrig->replaceByName( aName, aElement );
1066 }
1067
1068 //=========================================================================
1069 //
1070 // XChangesBatch methods.
1071 //
1072 //=========================================================================
1073
1074 // virtual
commitChanges()1075 void SAL_CALL HierarchyDataAccess::commitChanges()
1076 throw ( lang::WrappedTargetException, uno::RuntimeException )
1077 {
1078 uno::Reference< util::XChangesBatch > xOrig
1079 = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
1080
1081 OSL_ENSURE( xOrig.is(),
1082 "HierarchyDataAccess : Data source is not an XChangesBatch!" );
1083 xOrig->commitChanges();
1084 }
1085
1086 //=========================================================================
1087 // virtual
hasPendingChanges()1088 sal_Bool SAL_CALL HierarchyDataAccess::hasPendingChanges()
1089 throw ( uno::RuntimeException )
1090 {
1091 uno::Reference< util::XChangesBatch > xOrig
1092 = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
1093
1094 OSL_ENSURE( xOrig.is(),
1095 "HierarchyDataAccess : Data source is not an XChangesBatch!" );
1096 return xOrig->hasPendingChanges();
1097 }
1098
1099 //=========================================================================
1100 // virtual
1101 uno::Sequence< util::ElementChange > SAL_CALL
getPendingChanges()1102 HierarchyDataAccess::getPendingChanges()
1103 throw ( uno::RuntimeException )
1104 {
1105 uno::Reference< util::XChangesBatch > xOrig
1106 = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
1107
1108 OSL_ENSURE( xOrig.is(),
1109 "HierarchyDataAccess : Data source is not an XChangesBatch!" );
1110 return xOrig->getPendingChanges();
1111 }
1112
1113