xref: /trunk/main/ucb/source/ucp/hierarchy/hierarchydatasource.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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