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_hier.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 virtual void SAL_CALL
121 addEventListener( const uno::Reference< lang::XEventListener > & xListener );
122 virtual void SAL_CALL
123 removeEventListener( const uno::Reference<
124 lang::XEventListener > & aListener );
125
126 // XSingleServiceFactory
127 virtual uno::Reference< uno::XInterface > SAL_CALL
128 createInstance();
129 virtual uno::Reference< uno::XInterface > SAL_CALL
130 createInstanceWithArguments( const uno::Sequence< uno::Any > & aArguments );
131
132 // XHierarchicalNameAccess
133 virtual uno::Any SAL_CALL
134 getByHierarchicalName( const rtl::OUString & aName );
135 virtual sal_Bool SAL_CALL
136 hasByHierarchicalName( const rtl::OUString & aName );
137
138 // XNameContainer
139 virtual void SAL_CALL
140 insertByName( const rtl::OUString & aName, const uno::Any & aElement );
141 virtual void SAL_CALL
142 removeByName( const rtl::OUString & Name );
143
144 // XNameReplace ( base of XNameContainer )
145 virtual void SAL_CALL
146 replaceByName( const rtl::OUString & aName, const uno::Any & aElement );
147
148 // XNameAccess ( base of XNameReplace )
149 virtual uno::Any SAL_CALL
150 getByName( const rtl::OUString & aName );
151 virtual uno::Sequence< rtl::OUString > SAL_CALL
152 getElementNames();
153 virtual sal_Bool SAL_CALL
154 hasByName( const rtl::OUString & aName );
155
156 // XElementAccess ( base of XNameAccess )
157 virtual uno::Type SAL_CALL
158 getElementType();
159 virtual sal_Bool SAL_CALL
160 hasElements();
161
162 // XChangesNotifier
163 virtual void SAL_CALL
164 addChangesListener( const uno::Reference<
165 util::XChangesListener > & aListener );
166 virtual void SAL_CALL
167 removeChangesListener( const uno::Reference<
168 util::XChangesListener > & aListener );
169
170 // XChangesBatch
171 virtual void SAL_CALL
172 commitChanges();
173 virtual sal_Bool SAL_CALL
174 hasPendingChanges();
175 virtual uno::Sequence< util::ElementChange > SAL_CALL
176 getPendingChanges();
177 };
178
179 } // namespace hcp_impl
180
181 using namespace hcp_impl;
182
183 //=========================================================================
184 //=========================================================================
185 //
186 // HierarchyDataSource Implementation.
187 //
188 //=========================================================================
189 //=========================================================================
190
HierarchyDataSource(const uno::Reference<lang::XMultiServiceFactory> & rxServiceMgr)191 HierarchyDataSource::HierarchyDataSource(
192 const uno::Reference< lang::XMultiServiceFactory > & rxServiceMgr )
193 : m_xSMgr( rxServiceMgr ),
194 m_pDisposeEventListeners( 0 )
195 {
196 }
197
198 //=========================================================================
199 // virtual
~HierarchyDataSource()200 HierarchyDataSource::~HierarchyDataSource()
201 {
202 delete m_pDisposeEventListeners;
203 }
204
205 //=========================================================================
206 //
207 // XInterface methods.
208 //
209 //=========================================================================
210
211 XINTERFACE_IMPL_4( HierarchyDataSource,
212 lang::XTypeProvider,
213 lang::XServiceInfo,
214 lang::XComponent,
215 lang::XMultiServiceFactory );
216
217 //=========================================================================
218 //
219 // XTypeProvider methods.
220 //
221 //=========================================================================
222
223 XTYPEPROVIDER_IMPL_4( HierarchyDataSource,
224 lang::XTypeProvider,
225 lang::XServiceInfo,
226 lang::XComponent,
227 lang::XMultiServiceFactory );
228
229 //=========================================================================
230 //
231 // XServiceInfo methods.
232 //
233 //=========================================================================
234
235 XSERVICEINFO_IMPL_0( HierarchyDataSource,
236 rtl::OUString::createFromAscii(
237 "com.sun.star.comp.ucb.HierarchyDataSource" ) )
238 {
239 uno::Sequence< rtl::OUString > aSNS( 2 );
240 aSNS[ 0 ] = rtl::OUString::createFromAscii(
241 "com.sun.star.ucb.DefaultHierarchyDataSource" );
242 aSNS[ 1 ] = rtl::OUString::createFromAscii(
243 "com.sun.star.ucb.HierarchyDataSource" );
244 return aSNS;
245 }
246
247 ONE_INSTANCE_SERVICE_FACTORY_IMPL( HierarchyDataSource );
248
249 //=========================================================================
250 //
251 // XComponent methods.
252 //
253 //=========================================================================
254
255 // virtual
dispose()256 void SAL_CALL HierarchyDataSource::dispose()
257 {
258 osl::Guard< osl::Mutex > aGuard( m_aMutex );
259
260 if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
261 {
262 lang::EventObject aEvt;
263 aEvt.Source = static_cast< lang::XComponent * >( this );
264 m_pDisposeEventListeners->disposeAndClear( aEvt );
265 }
266 }
267
268 //=========================================================================
269 // virtual
addEventListener(const uno::Reference<lang::XEventListener> & Listener)270 void SAL_CALL HierarchyDataSource::addEventListener(
271 const uno::Reference< lang::XEventListener > & Listener )
272 {
273 osl::Guard< osl::Mutex > aGuard( m_aMutex );
274
275 if ( !m_pDisposeEventListeners )
276 m_pDisposeEventListeners
277 = new cppu::OInterfaceContainerHelper( m_aMutex );
278
279 m_pDisposeEventListeners->addInterface( Listener );
280 }
281
282 //=========================================================================
283 // virtual
removeEventListener(const uno::Reference<lang::XEventListener> & Listener)284 void SAL_CALL HierarchyDataSource::removeEventListener(
285 const uno::Reference< lang::XEventListener > & Listener )
286 {
287 osl::Guard< osl::Mutex > aGuard( m_aMutex );
288
289 if ( m_pDisposeEventListeners )
290 m_pDisposeEventListeners->removeInterface( Listener );
291 }
292
293 //=========================================================================
294 //
295 // XMultiServiceFactory methods.
296 //
297 //=========================================================================
298
299 // virtual
300 uno::Reference< uno::XInterface > SAL_CALL
createInstance(const rtl::OUString & aServiceSpecifier)301 HierarchyDataSource::createInstance( const rtl::OUString & aServiceSpecifier )
302 {
303 // Create view to root node.
304
305 beans::PropertyValue aProp;
306 aProp.Name = rtl::OUString(
307 RTL_CONSTASCII_USTRINGPARAM( CFGPROPERTY_NODEPATH ) );
308 aProp.Value <<=
309 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY ) );
310
311 uno::Sequence< uno::Any > aArguments( 1 );
312 aArguments[ 0 ] <<= aProp;
313
314 return createInstanceWithArguments( aServiceSpecifier, aArguments, false );
315 }
316
317 //=========================================================================
318 // virtual
319 uno::Reference< uno::XInterface > SAL_CALL
createInstanceWithArguments(const rtl::OUString & ServiceSpecifier,const uno::Sequence<uno::Any> & Arguments)320 HierarchyDataSource::createInstanceWithArguments(
321 const rtl::OUString & ServiceSpecifier,
322 const uno::Sequence< uno::Any > & Arguments )
323 {
324 return createInstanceWithArguments( ServiceSpecifier, Arguments, true );
325 }
326
327 //=========================================================================
328 // virtual
329 uno::Sequence< rtl::OUString > SAL_CALL
getAvailableServiceNames()330 HierarchyDataSource::getAvailableServiceNames()
331 {
332 uno::Sequence< rtl::OUString > aNames( 2 );
333 aNames[ 0 ] = rtl::OUString(
334 RTL_CONSTASCII_USTRINGPARAM( READ_SERVICE_NAME ) );
335 aNames[ 1 ] = rtl::OUString(
336 RTL_CONSTASCII_USTRINGPARAM( READWRITE_SERVICE_NAME ) );
337 return aNames;
338 }
339
340 //=========================================================================
341 //
342 // Non-interface methods
343 //
344 //=========================================================================
345
346 uno::Reference< uno::XInterface > SAL_CALL
createInstanceWithArguments(const rtl::OUString & ServiceSpecifier,const uno::Sequence<uno::Any> & Arguments,bool bCheckArgs)347 HierarchyDataSource::createInstanceWithArguments(
348 const rtl::OUString & ServiceSpecifier,
349 const uno::Sequence< uno::Any > & Arguments,
350 bool bCheckArgs )
351 {
352 osl::Guard< osl::Mutex > aGuard( m_aMutex );
353
354 // Check service specifier.
355 bool bReadOnly = !!ServiceSpecifier.equalsAsciiL(
356 RTL_CONSTASCII_STRINGPARAM( READ_SERVICE_NAME ) );
357 bool bReadWrite = !bReadOnly &&
358 ServiceSpecifier.equalsAsciiL(
359 RTL_CONSTASCII_STRINGPARAM( READWRITE_SERVICE_NAME ) );
360
361 if ( !bReadOnly && !bReadWrite )
362 {
363 OSL_ENSURE( false,
364 "HierarchyDataSource::createInstanceWithArguments - "
365 "Unsupported service specifier!" );
366 return uno::Reference< uno::XInterface >();
367 }
368
369 uno::Sequence< uno::Any > aNewArgs( Arguments );
370
371 bool bHasLazyWriteProp = bReadOnly; // property must be added only if
372 // a writable view is requested.
373 if ( bCheckArgs )
374 {
375 // Check arguments.
376 bool bHasNodePath = false;
377 sal_Int32 nCount = Arguments.getLength();
378 for ( sal_Int32 n = 0; n < nCount; ++n )
379 {
380 beans::PropertyValue aProp;
381 if ( Arguments[ n ] >>= aProp )
382 {
383 if ( aProp.Name.equalsAsciiL(
384 RTL_CONSTASCII_STRINGPARAM( CFGPROPERTY_NODEPATH ) ) )
385 {
386 rtl::OUString aPath;
387 if ( aProp.Value >>= aPath )
388 {
389 bHasNodePath = true;
390
391 // Create path to data inside the configuration.
392 rtl::OUString aConfigPath;
393 if ( !createConfigPath( aPath, aConfigPath ) )
394 {
395 OSL_ENSURE( false,
396 "HierarchyDataSource::"
397 "createInstanceWithArguments - "
398 "Invalid node path!" );
399 return uno::Reference< uno::XInterface >();
400 }
401
402 aProp.Value <<= aConfigPath;
403
404 // Set new path in arguments.
405 aNewArgs[ n ] <<= aProp;
406
407 if ( bHasLazyWriteProp )
408 break;
409 }
410 else
411 {
412 OSL_ENSURE( false,
413 "HierarchyDataSource::createInstanceWithArguments - "
414 "Invalid type for property 'nodepath'!" );
415 return uno::Reference< uno::XInterface >();
416 }
417 }
418 else if ( aProp.Name.equalsAsciiL(
419 RTL_CONSTASCII_STRINGPARAM(
420 CFGPROPERTY_LAZYWRITE ) ) )
421 {
422 if ( aProp.Value.getValueType() == getCppuBooleanType() )
423 {
424 bHasLazyWriteProp = true;
425
426 if ( bHasNodePath )
427 break;
428 }
429 else
430 {
431 OSL_ENSURE( false,
432 "HierarchyDataSource::createInstanceWithArguments - "
433 "Invalid type for property 'lazywrite'!" );
434 return uno::Reference< uno::XInterface >();
435 }
436 }
437 }
438 }
439
440 if ( !bHasNodePath )
441 {
442 OSL_ENSURE( false,
443 "HierarchyDataSource::createInstanceWithArguments - "
444 "No 'nodepath' property!" );
445 return uno::Reference< uno::XInterface >();
446 }
447 }
448
449 // Create Configuration Provider.
450 uno::Reference< lang::XMultiServiceFactory > xProv = getConfigProvider();
451 if ( !xProv.is() )
452 return uno::Reference< uno::XInterface >();
453
454 uno::Reference< uno::XInterface > xConfigAccess;
455 try
456 {
457 if ( bReadOnly )
458 {
459 // Create configuration read-only access object.
460 xConfigAccess = xProv->createInstanceWithArguments(
461 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
462 CONFIG_READ_SERVICE_NAME ) ),
463 aNewArgs );
464 }
465 else
466 {
467 // Append 'lazywrite' property value, if not already present.
468 if ( !bHasLazyWriteProp )
469 {
470 sal_Int32 nLen = aNewArgs.getLength();
471 aNewArgs.realloc( nLen + 1 );
472
473 beans::PropertyValue aProp;
474 aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
475 CFGPROPERTY_LAZYWRITE ) );
476 aProp.Value <<= sal_True;
477 aNewArgs[ nLen ] <<= aProp;
478 }
479
480 // Create configuration read-write access object.
481 xConfigAccess = xProv->createInstanceWithArguments(
482 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
483 CONFIG_READWRITE_SERVICE_NAME ) ),
484 aNewArgs );
485 }
486 }
487 catch ( uno::Exception const & )
488 {
489 OSL_ENSURE( false,
490 "HierarchyDataSource::createInstanceWithArguments - "
491 "Cannot instantiate configuration access!" );
492 throw;
493 }
494
495 if ( !xConfigAccess.is() )
496 {
497 OSL_ENSURE( false,
498 "HierarchyDataSource::createInstanceWithArguments - "
499 "Cannot instantiate configuration access!" );
500 return xConfigAccess;
501 }
502
503 return uno::Reference< uno::XInterface >(
504 static_cast< cppu::OWeakObject * >(
505 new HierarchyDataAccess( xConfigAccess, bReadOnly ) ) );
506 }
507
508 //=========================================================================
509 uno::Reference< lang::XMultiServiceFactory >
getConfigProvider()510 HierarchyDataSource::getConfigProvider()
511 {
512 if ( !m_xConfigProvider.is() )
513 {
514 osl::Guard< osl::Mutex > aGuard( m_aMutex );
515 if ( !m_xConfigProvider.is() )
516 {
517 try
518 {
519 m_xConfigProvider
520 = uno::Reference< lang::XMultiServiceFactory >(
521 m_xSMgr->createInstance(
522 rtl::OUString(
523 RTL_CONSTASCII_USTRINGPARAM(
524 CONFIG_PROVIDER_SERVICE_NAME ) ) ),
525 uno::UNO_QUERY );
526
527 OSL_ENSURE( m_xConfigProvider.is(),
528 "HierarchyDataSource::getConfigProvider - "
529 "No configuration provider!" );
530 }
531 catch ( uno::Exception const & )
532 {
533 OSL_ENSURE( false,
534 "HierarchyDataSource::getConfigProvider - "
535 "caught exception!" );
536 }
537 }
538 }
539
540 return m_xConfigProvider;
541 }
542
543 //=========================================================================
createConfigPath(const rtl::OUString & rInPath,rtl::OUString & rOutPath)544 bool HierarchyDataSource::createConfigPath(
545 const rtl::OUString & rInPath, rtl::OUString & rOutPath )
546 {
547 if ( rInPath.getLength() )
548 {
549 if ( rInPath.indexOf( '/' ) == 0 )
550 {
551 OSL_ENSURE( false,
552 "HierarchyDataSource::createConfigPath - "
553 "Leading slash in node path!" );
554 return false;
555 }
556
557 if ( rInPath.lastIndexOf( '/' ) == rInPath.getLength() - 1 )
558 {
559 OSL_ENSURE( false,
560 "HierarchyDataSource::createConfigPath - "
561 "Trailing slash in node path!" );
562 return false;
563 }
564
565 rtl::OUString aOutPath(
566 RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY "/" ) );
567 aOutPath += rInPath;
568 rOutPath = aOutPath;
569 }
570 else
571 {
572 rOutPath = rtl::OUString(
573 RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY ) );
574 }
575
576 return true;
577 }
578
579 //=========================================================================
580 //=========================================================================
581 //
582 // HierarchyDataAccess Implementation.
583 //
584 //=========================================================================
585 //=========================================================================
586
587 #define ENSURE_ORIG_INTERFACE( interface_name, member_name ) \
588 m_xCfg##member_name; \
589 if ( !m_xCfg##member_name.is() ) \
590 { \
591 osl::Guard< osl::Mutex > aGuard( m_aMutex ); \
592 if ( !m_xCfg##member_name.is() ) \
593 m_xCfg##member_name \
594 = uno::Reference< interface_name >( \
595 m_xConfigAccess, uno::UNO_QUERY ); \
596 xOrig = m_xCfg##member_name; \
597 }
598
599 //=========================================================================
HierarchyDataAccess(const uno::Reference<uno::XInterface> & xConfigAccess,bool bReadOnly)600 HierarchyDataAccess::HierarchyDataAccess( const uno::Reference<
601 uno::XInterface > & xConfigAccess,
602 bool bReadOnly )
603 : m_xConfigAccess( xConfigAccess ),
604 m_bReadOnly( bReadOnly )
605 {
606 }
607
608 //=========================================================================
609 // virtual
~HierarchyDataAccess()610 HierarchyDataAccess::~HierarchyDataAccess()
611 {
612 }
613
614 //=========================================================================
615 //
616 // XInterface methods.
617 //
618 //=========================================================================
619
620 XINTERFACE_COMMON_IMPL( HierarchyDataAccess );
621
622 //=========================================================================
623 // virtual
queryInterface(const uno::Type & aType)624 uno::Any SAL_CALL HierarchyDataAccess::queryInterface( const uno::Type & aType )
625 {
626 // Interfaces supported in read-only and read-write mode.
627 uno::Any aRet = cppu::queryInterface( aType,
628 static_cast< lang::XTypeProvider * >( this ),
629 static_cast< lang::XServiceInfo * >( this ),
630 static_cast< lang::XComponent * >( this ),
631 static_cast< container::XHierarchicalNameAccess * >( this ),
632 static_cast< container::XNameAccess * >( this ),
633 static_cast< container::XElementAccess * >( this ),
634 static_cast< util::XChangesNotifier * >( this ) );
635
636 // Interfaces supported only in read-write mode.
637 if ( !aRet.hasValue() && !m_bReadOnly )
638 {
639 aRet = cppu::queryInterface( aType,
640 static_cast< lang::XSingleServiceFactory * >( this ),
641 static_cast< container::XNameContainer * >( this ),
642 static_cast< container::XNameReplace * >( this ),
643 static_cast< util::XChangesBatch * >( this ) );
644 }
645
646 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( aType );
647 }
648
649 //=========================================================================
650 //
651 // XTypeProvider methods.
652 //
653 //=========================================================================
654
655 XTYPEPROVIDER_COMMON_IMPL( HierarchyDataAccess );
656
657 //=========================================================================
658 // virtual
getTypes()659 uno::Sequence< uno::Type > SAL_CALL HierarchyDataAccess::getTypes()
660 {
661 cppu::OTypeCollection * pCollection = 0;
662
663 if ( m_bReadOnly )
664 {
665 static cppu::OTypeCollection* pReadOnlyTypes = 0;
666
667 pCollection = pReadOnlyTypes;
668 if ( !pCollection )
669 {
670 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
671
672 pCollection = pReadOnlyTypes;
673 if ( !pCollection )
674 {
675 static cppu::OTypeCollection aCollection(
676 CPPU_TYPE_REF( lang::XTypeProvider ),
677 CPPU_TYPE_REF( lang::XServiceInfo ),
678 CPPU_TYPE_REF( lang::XComponent ),
679 CPPU_TYPE_REF( container::XHierarchicalNameAccess ),
680 CPPU_TYPE_REF( container::XNameAccess ),
681 CPPU_TYPE_REF( util::XChangesNotifier ) );
682 pCollection = &aCollection;
683 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
684 pReadOnlyTypes = pCollection;
685 }
686 }
687 else {
688 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
689 }
690 }
691 else
692 {
693 static cppu::OTypeCollection* pReadWriteTypes = 0;
694
695 pCollection = pReadWriteTypes;
696 if ( !pCollection )
697 {
698 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
699
700 pCollection = pReadWriteTypes;
701 if ( !pCollection )
702 {
703 static cppu::OTypeCollection aCollection(
704 CPPU_TYPE_REF( lang::XTypeProvider ),
705 CPPU_TYPE_REF( lang::XServiceInfo ),
706 CPPU_TYPE_REF( lang::XComponent ),
707 CPPU_TYPE_REF( lang::XSingleServiceFactory ),
708 CPPU_TYPE_REF( container::XHierarchicalNameAccess ),
709 CPPU_TYPE_REF( container::XNameContainer ),
710 CPPU_TYPE_REF( util::XChangesBatch ),
711 CPPU_TYPE_REF( util::XChangesNotifier ) );
712 pCollection = &aCollection;
713 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
714 pReadWriteTypes = pCollection;
715 }
716 }
717 else {
718 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
719 }
720 }
721
722 return (*pCollection).getTypes();
723 }
724
725 //=========================================================================
726 //
727 // XServiceInfo methods.
728 //
729 //=========================================================================
730
731 XSERVICEINFO_NOFACTORY_IMPL_0(
732 HierarchyDataAccess,
733 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
734 "com.sun.star.comp.ucb.HierarchyDataAccess" ) ) )
735 {
736 uno::Sequence< rtl::OUString > aSNS( 2 );
737 aSNS[ 0 ] = rtl::OUString(
738 RTL_CONSTASCII_USTRINGPARAM( READ_SERVICE_NAME ) );
739 aSNS[ 1 ] = rtl::OUString(
740 RTL_CONSTASCII_USTRINGPARAM( READWRITE_SERVICE_NAME ) );
741 return aSNS;
742 }
743
744 //=========================================================================
745 //
746 // XComponent methods.
747 //
748 //=========================================================================
749
750 // virtual
dispose()751 void SAL_CALL HierarchyDataAccess::dispose()
752 {
753 uno::Reference< lang::XComponent > xOrig
754 = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
755
756 OSL_ENSURE( xOrig.is(),
757 "HierarchyDataAccess : Data source is not an XComponent!" );
758 xOrig->dispose();
759 }
760
761 //=========================================================================
762 // virtual
addEventListener(const uno::Reference<lang::XEventListener> & xListener)763 void SAL_CALL HierarchyDataAccess::addEventListener(
764 const uno::Reference< lang::XEventListener > & xListener )
765 {
766 uno::Reference< lang::XComponent > xOrig
767 = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
768
769 OSL_ENSURE( xOrig.is(),
770 "HierarchyDataAccess : Data source is not an XComponent!" );
771 xOrig->addEventListener( xListener );
772 }
773
774 //=========================================================================
775 // virtual
removeEventListener(const uno::Reference<lang::XEventListener> & aListener)776 void SAL_CALL HierarchyDataAccess::removeEventListener(
777 const uno::Reference< lang::XEventListener > & aListener )
778 {
779 uno::Reference< lang::XComponent > xOrig
780 = ENSURE_ORIG_INTERFACE( lang::XComponent, C );
781
782 OSL_ENSURE( xOrig.is(),
783 "HierarchyDataAccess : Data source is not an XComponent!" );
784 xOrig->removeEventListener( aListener );
785 }
786
787 //=========================================================================
788 //
789 // XHierarchicalNameAccess methods.
790 //
791 //=========================================================================
792
793 // virtual
getByHierarchicalName(const rtl::OUString & aName)794 uno::Any SAL_CALL HierarchyDataAccess::getByHierarchicalName(
795 const rtl::OUString & aName )
796 {
797 uno::Reference< container::XHierarchicalNameAccess > xOrig
798 = ENSURE_ORIG_INTERFACE( container::XHierarchicalNameAccess, HNA );
799
800 OSL_ENSURE( xOrig.is(),
801 "HierarchyDataAccess : "
802 "Data source is not an XHierarchicalNameAccess!" );
803 return xOrig->getByHierarchicalName( aName );
804 }
805
806 //=========================================================================
807 // virtual
hasByHierarchicalName(const rtl::OUString & aName)808 sal_Bool SAL_CALL HierarchyDataAccess::hasByHierarchicalName(
809 const rtl::OUString & aName )
810 {
811 uno::Reference< container::XHierarchicalNameAccess > xOrig
812 = ENSURE_ORIG_INTERFACE( container::XHierarchicalNameAccess, HNA );
813
814 OSL_ENSURE( xOrig.is(),
815 "HierarchyDataAccess : "
816 "Data source is not an XHierarchicalNameAccess!" );
817 return xOrig->hasByHierarchicalName( aName );
818 }
819
820 //=========================================================================
821 //
822 // XNameAccess methods.
823 //
824 //=========================================================================
825
826 // virtual
getByName(const rtl::OUString & aName)827 uno::Any SAL_CALL HierarchyDataAccess::getByName( const rtl::OUString & aName )
828 {
829 uno::Reference< container::XNameAccess > xOrig
830 = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
831
832 OSL_ENSURE( xOrig.is(),
833 "HierarchyDataAccess : Data source is not an XNameAccess!" );
834 return xOrig->getByName( aName );
835 }
836
837 //=========================================================================
838 // virtual
getElementNames()839 uno::Sequence< rtl::OUString > SAL_CALL HierarchyDataAccess::getElementNames()
840 {
841 uno::Reference< container::XNameAccess > xOrig
842 = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
843
844 OSL_ENSURE( xOrig.is(),
845 "HierarchyDataAccess : Data source is not an XNameAccess!" );
846 return xOrig->getElementNames();
847 }
848
849 //=========================================================================
850 // virtual
hasByName(const rtl::OUString & aName)851 sal_Bool SAL_CALL HierarchyDataAccess::hasByName( const rtl::OUString & aName )
852 {
853 uno::Reference< container::XNameAccess > xOrig
854 = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA );
855
856 OSL_ENSURE( xOrig.is(),
857 "HierarchyDataAccess : Data source is not an XNameAccess!" );
858 return xOrig->hasByName( aName );
859 }
860
861 //=========================================================================
862 //
863 // XElementAccess methods.
864 //
865 //=========================================================================
866
867 // virtual
getElementType()868 uno::Type SAL_CALL HierarchyDataAccess::getElementType()
869 {
870 uno::Reference< container::XElementAccess > xOrig
871 = ENSURE_ORIG_INTERFACE( container::XElementAccess, EA );
872
873 OSL_ENSURE( xOrig.is(),
874 "HierarchyDataAccess : Data source is not an XElementAccess!" );
875 return xOrig->getElementType();
876 }
877
878 //=========================================================================
879 // virtual
hasElements()880 sal_Bool SAL_CALL HierarchyDataAccess::hasElements()
881 {
882 uno::Reference< container::XElementAccess > xOrig
883 = ENSURE_ORIG_INTERFACE( container::XElementAccess, EA );
884
885 OSL_ENSURE( xOrig.is(),
886 "HierarchyDataAccess : Data source is not an XElementAccess!" );
887 return xOrig->hasElements();
888 }
889
890 //=========================================================================
891 //
892 // XChangesNotifier methods.
893 //
894 //=========================================================================
895
896 // virtual
addChangesListener(const uno::Reference<util::XChangesListener> & aListener)897 void SAL_CALL HierarchyDataAccess::addChangesListener(
898 const uno::Reference< util::XChangesListener > & aListener )
899 {
900 uno::Reference< util::XChangesNotifier > xOrig
901 = ENSURE_ORIG_INTERFACE( util::XChangesNotifier, CN );
902
903 OSL_ENSURE( xOrig.is(),
904 "HierarchyDataAccess : Data source is not an XChangesNotifier!" );
905 xOrig->addChangesListener( aListener );
906 }
907
908 //=========================================================================
909 // virtual
removeChangesListener(const uno::Reference<util::XChangesListener> & aListener)910 void SAL_CALL HierarchyDataAccess::removeChangesListener(
911 const uno::Reference< util::XChangesListener > & aListener )
912 {
913 uno::Reference< util::XChangesNotifier > xOrig
914 = ENSURE_ORIG_INTERFACE( util::XChangesNotifier, CN );
915
916 OSL_ENSURE( xOrig.is(),
917 "HierarchyDataAccess : Data source is not an XChangesNotifier!" );
918 xOrig->removeChangesListener( aListener );
919 }
920
921 //=========================================================================
922 //
923 // XSingleServiceFactory methods.
924 //
925 //=========================================================================
926
927 // virtual
createInstance()928 uno::Reference< uno::XInterface > SAL_CALL HierarchyDataAccess::createInstance()
929 {
930 uno::Reference< lang::XSingleServiceFactory > xOrig
931 = ENSURE_ORIG_INTERFACE( lang::XSingleServiceFactory, SSF );
932
933 OSL_ENSURE( xOrig.is(),
934 "HierarchyDataAccess : Data source is not an XSingleServiceFactory!" );
935 return xOrig->createInstance();
936 }
937
938 //=========================================================================
939 // virtual
940 uno::Reference< uno::XInterface > SAL_CALL
createInstanceWithArguments(const uno::Sequence<uno::Any> & aArguments)941 HierarchyDataAccess::createInstanceWithArguments(
942 const uno::Sequence< uno::Any > & aArguments )
943 {
944 uno::Reference< lang::XSingleServiceFactory > xOrig
945 = ENSURE_ORIG_INTERFACE( lang::XSingleServiceFactory, SSF );
946
947 OSL_ENSURE( xOrig.is(),
948 "HierarchyDataAccess : Data source is not an XSingleServiceFactory!" );
949 return xOrig->createInstanceWithArguments( aArguments );
950 }
951
952 //=========================================================================
953 //
954 // XNameContainer methods.
955 //
956 //=========================================================================
957
958 // virtual
959 void SAL_CALL
insertByName(const rtl::OUString & aName,const uno::Any & aElement)960 HierarchyDataAccess::insertByName( const rtl::OUString & aName,
961 const uno::Any & aElement )
962 {
963 uno::Reference< container::XNameContainer > xOrig
964 = ENSURE_ORIG_INTERFACE( container::XNameContainer, NC );
965
966 OSL_ENSURE( xOrig.is(),
967 "HierarchyDataAccess : Data source is not an XNameContainer!" );
968 xOrig->insertByName( aName, aElement );
969 }
970
971 //=========================================================================
972 // virtual
973 void SAL_CALL
removeByName(const rtl::OUString & Name)974 HierarchyDataAccess::removeByName( const rtl::OUString & Name )
975 {
976 uno::Reference< container::XNameContainer > xOrig
977 = ENSURE_ORIG_INTERFACE( container::XNameContainer, NC );
978
979 OSL_ENSURE( xOrig.is(),
980 "HierarchyDataAccess : Data source is not an XNameContainer!" );
981 xOrig->removeByName( Name );
982 }
983
984 //=========================================================================
985 //
986 // XNameReplace methods.
987 //
988 //=========================================================================
989
990 // virtual
replaceByName(const rtl::OUString & aName,const uno::Any & aElement)991 void SAL_CALL HierarchyDataAccess::replaceByName( const rtl::OUString & aName,
992 const uno::Any & aElement )
993 {
994 uno::Reference< container::XNameReplace > xOrig
995 = ENSURE_ORIG_INTERFACE( container::XNameReplace, NR );
996
997 OSL_ENSURE( xOrig.is(),
998 "HierarchyDataAccess : Data source is not an XNameReplace!" );
999 xOrig->replaceByName( aName, aElement );
1000 }
1001
1002 //=========================================================================
1003 //
1004 // XChangesBatch methods.
1005 //
1006 //=========================================================================
1007
1008 // virtual
commitChanges()1009 void SAL_CALL HierarchyDataAccess::commitChanges()
1010 {
1011 uno::Reference< util::XChangesBatch > xOrig
1012 = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
1013
1014 OSL_ENSURE( xOrig.is(),
1015 "HierarchyDataAccess : Data source is not an XChangesBatch!" );
1016 xOrig->commitChanges();
1017 }
1018
1019 //=========================================================================
1020 // virtual
hasPendingChanges()1021 sal_Bool SAL_CALL HierarchyDataAccess::hasPendingChanges()
1022 {
1023 uno::Reference< util::XChangesBatch > xOrig
1024 = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
1025
1026 OSL_ENSURE( xOrig.is(),
1027 "HierarchyDataAccess : Data source is not an XChangesBatch!" );
1028 return xOrig->hasPendingChanges();
1029 }
1030
1031 //=========================================================================
1032 // virtual
1033 uno::Sequence< util::ElementChange > SAL_CALL
getPendingChanges()1034 HierarchyDataAccess::getPendingChanges()
1035 {
1036 uno::Reference< util::XChangesBatch > xOrig
1037 = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB );
1038
1039 OSL_ENSURE( xOrig.is(),
1040 "HierarchyDataAccess : Data source is not an XChangesBatch!" );
1041 return xOrig->getPendingChanges();
1042 }
1043