xref: /AOO41X/main/ucb/source/core/ucbstore.cxx (revision 2f86921c33504fdff5a030df6c0b258927045abb)
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   *************************************************************************/
32 
33 #include <list>
34 #include <hash_map>
35 #include <osl/diagnose.h>
36 #include <rtl/ustrbuf.hxx>
37 #include <cppuhelper/interfacecontainer.hxx>
38 #include <com/sun/star/beans/PropertyAttribute.hpp>
39 #include <com/sun/star/beans/PropertySetInfoChange.hpp>
40 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
41 #include <com/sun/star/container/XNameContainer.hpp>
42 #include <com/sun/star/container/XNameReplace.hpp>
43 #include <com/sun/star/util/XChangesBatch.hpp>
44 #include "ucbstore.hxx"
45 
46 using namespace com::sun::star::beans;
47 using namespace com::sun::star::container;
48 using namespace com::sun::star::lang;
49 using namespace com::sun::star::ucb;
50 using namespace com::sun::star::uno;
51 using namespace com::sun::star::util;
52 using namespace cppu;
53 using namespace rtl;
54 
55 //=========================================================================
makeHierarchalNameSegment(const rtl::OUString & rIn)56 rtl::OUString makeHierarchalNameSegment( const rtl::OUString & rIn  )
57 {
58     rtl::OUStringBuffer aBuffer;
59     aBuffer.appendAscii( "['" );
60 
61     sal_Int32 nCount = rIn.getLength();
62     for ( sal_Int32 n = 0; n < nCount; ++n )
63     {
64         const sal_Unicode c = rIn.getStr()[ n ];
65         switch ( c )
66         {
67             case '&':
68                 aBuffer.appendAscii( "&amp;" );
69                 break;
70 
71             case '"':
72                 aBuffer.appendAscii( "&quot;" );
73                 break;
74 
75             case '\'':
76                 aBuffer.appendAscii( "&apos;" );
77                 break;
78 
79             case '<':
80                 aBuffer.appendAscii( "&lt;" );
81                 break;
82 
83             case '>':
84                 aBuffer.appendAscii( "&gt;" );
85                 break;
86 
87             default:
88                 aBuffer.append( c );
89                 break;
90         }
91     }
92 
93     aBuffer.appendAscii( "']" );
94     return rtl::OUString( aBuffer.makeStringAndClear() );
95 }
96 
97 //=========================================================================
98 
99 #define STORE_CONTENTPROPERTIES_KEY "/org.openoffice.ucb.Store/ContentProperties"
100 
101 // describe path of cfg entry
102 #define CFGPROPERTY_NODEPATH        "nodepath"
103 // true->async. update; false->sync. update
104 #define CFGPROPERTY_LAZYWRITE       "lazywrite"
105 
106 //=========================================================================
107 
108 struct equalString_Impl
109 {
operator ()equalString_Impl110   bool operator()( const OUString& s1, const OUString& s2 ) const
111   {
112         return !!( s1 == s2 );
113   }
114 };
115 
116 struct hashString_Impl
117 {
operator ()hashString_Impl118     size_t operator()( const OUString & rName ) const
119     {
120         return rName.hashCode();
121     }
122 };
123 
124 //=========================================================================
125 //
126 // PropertySetMap_Impl.
127 //
128 //=========================================================================
129 
130 typedef std::hash_map
131 <
132     OUString,
133     PersistentPropertySet*,
134     hashString_Impl,
135     equalString_Impl
136 >
137 PropertySetMap_Impl;
138 
139 //=========================================================================
140 //
141 // class PropertySetInfo_Impl
142 //
143 //=========================================================================
144 
145 class PropertySetInfo_Impl :
146         public OWeakObject, public XTypeProvider, public XPropertySetInfo
147 {
148     Reference< XMultiServiceFactory > m_xSMgr;
149     Sequence< Property >*             m_pProps;
150     PersistentPropertySet*            m_pOwner;
151 
152 public:
153     PropertySetInfo_Impl( const Reference< XMultiServiceFactory >& rxSMgr,
154                           PersistentPropertySet* pOwner );
155     virtual ~PropertySetInfo_Impl();
156 
157     // XInterface
158     XINTERFACE_DECL()
159 
160     // XTypeProvider
161     XTYPEPROVIDER_DECL()
162 
163     // XPropertySetInfo
164     virtual Sequence< Property > SAL_CALL getProperties()
165         throw( RuntimeException );
166     virtual Property SAL_CALL getPropertyByName( const OUString& aName )
167         throw( UnknownPropertyException, RuntimeException );
168     virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
169         throw( RuntimeException );
170 
171     // Non-interface methods.
reset()172     void reset() { delete m_pProps; m_pProps = 0; }
173 };
174 
175 //=========================================================================
176 //
177 // UcbStore_Impl.
178 //
179 //=========================================================================
180 
181 struct UcbStore_Impl
182 {
183     osl::Mutex                        m_aMutex;
184     Sequence< Any >                   m_aInitArgs;
185     Reference< XPropertySetRegistry > m_xTheRegistry;
186 };
187 
188 //=========================================================================
189 //=========================================================================
190 //=========================================================================
191 //
192 // UcbStore Implementation.
193 //
194 //=========================================================================
195 //=========================================================================
196 //=========================================================================
197 
UcbStore(const Reference<XMultiServiceFactory> & rXSMgr)198 UcbStore::UcbStore( const Reference< XMultiServiceFactory >& rXSMgr )
199 : m_xSMgr( rXSMgr ),
200   m_pImpl( new UcbStore_Impl() )
201 {
202 }
203 
204 //=========================================================================
205 // virtual
~UcbStore()206 UcbStore::~UcbStore()
207 {
208     delete m_pImpl;
209 }
210 
211 //=========================================================================
212 //
213 // XInterface methods.
214 //
215 //=========================================================================
216 
217 XINTERFACE_IMPL_4( UcbStore,
218                    XTypeProvider,
219                    XServiceInfo,
220                    XPropertySetRegistryFactory,
221                    XInitialization );
222 
223 //=========================================================================
224 //
225 // XTypeProvider methods.
226 //
227 //=========================================================================
228 
229 XTYPEPROVIDER_IMPL_4( UcbStore,
230                       XTypeProvider,
231                       XServiceInfo,
232                       XPropertySetRegistryFactory,
233                       XInitialization );
234 
235 //=========================================================================
236 //
237 // XServiceInfo methods.
238 //
239 //=========================================================================
240 
241 XSERVICEINFO_IMPL_1( UcbStore,
242                      OUString::createFromAscii(
243                         "com.sun.star.comp.ucb.UcbStore" ),
244                      OUString::createFromAscii(
245                         STORE_SERVICE_NAME ) );
246 
247 //=========================================================================
248 //
249 // Service factory implementation.
250 //
251 //=========================================================================
252 
253 ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore );
254 
255 //=========================================================================
256 //
257 // XPropertySetRegistryFactory methods.
258 //
259 //=========================================================================
260 
261 // virtual
262 Reference< XPropertySetRegistry > SAL_CALL
createPropertySetRegistry(const OUString &)263 UcbStore::createPropertySetRegistry( const OUString& )
264     throw( RuntimeException )
265 {
266     // The URL parameter is ignored by this interface implementation. It always
267     // uses the configuration server as storage medium.
268 
269     if ( !m_pImpl->m_xTheRegistry.is() )
270     {
271         osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
272         if ( !m_pImpl->m_xTheRegistry.is() )
273             m_pImpl->m_xTheRegistry = new PropertySetRegistry( m_xSMgr, getInitArgs() );
274     }
275 
276     return m_pImpl->m_xTheRegistry;
277 }
278 
279 //=========================================================================
280 //
281 // XInitialization methods.
282 //
283 //=========================================================================
284 
285 // virtual
initialize(const Sequence<Any> & aArguments)286 void SAL_CALL UcbStore::initialize( const Sequence< Any >& aArguments )
287     throw( Exception, RuntimeException )
288 {
289     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
290     m_pImpl->m_aInitArgs = aArguments;
291 }
292 
293 //=========================================================================
getInitArgs() const294 const Sequence< Any >& UcbStore::getInitArgs() const
295 {
296     return m_pImpl->m_aInitArgs;
297 }
298 
299 //=========================================================================
300 //
301 // PropertySetRegistry_Impl.
302 //
303 //=========================================================================
304 
305 struct PropertySetRegistry_Impl
306 {
307     const Sequence< Any >             m_aInitArgs;
308     PropertySetMap_Impl               m_aPropSets;
309     Reference< XMultiServiceFactory > m_xConfigProvider;
310     Reference< XInterface >           m_xRootReadAccess;
311     Reference< XInterface >           m_xRootWriteAccess;
312     osl::Mutex                        m_aMutex;
313     sal_Bool                          m_bTriedToGetRootReadAccess;  // #82494#
314     sal_Bool                          m_bTriedToGetRootWriteAccess; // #82494#
315 
PropertySetRegistry_ImplPropertySetRegistry_Impl316     PropertySetRegistry_Impl( const Sequence< Any > &rInitArgs )
317     : m_aInitArgs( rInitArgs ),
318       m_bTriedToGetRootReadAccess( sal_False ),
319       m_bTriedToGetRootWriteAccess( sal_False )
320     {
321     }
322 };
323 
324 //=========================================================================
325 //=========================================================================
326 //=========================================================================
327 //
328 // PropertySetRegistry Implementation.
329 //
330 //=========================================================================
331 //=========================================================================
332 //=========================================================================
333 
PropertySetRegistry(const Reference<XMultiServiceFactory> & rXSMgr,const Sequence<Any> & rInitArgs)334 PropertySetRegistry::PropertySetRegistry(
335                         const Reference< XMultiServiceFactory >& rXSMgr,
336                         const Sequence< Any > &rInitArgs )
337 : m_xSMgr( rXSMgr ),
338   m_pImpl( new PropertySetRegistry_Impl( rInitArgs ) )
339 {
340 }
341 
342 //=========================================================================
343 // virtual
~PropertySetRegistry()344 PropertySetRegistry::~PropertySetRegistry()
345 {
346     delete m_pImpl;
347 }
348 
349 //=========================================================================
350 //
351 // XInterface methods.
352 //
353 //=========================================================================
354 
355 XINTERFACE_IMPL_5( PropertySetRegistry,
356                    XTypeProvider,
357                    XServiceInfo,
358                    XPropertySetRegistry,
359                    XElementAccess, /* base of XNameAccess */
360                    XNameAccess );
361 
362 //=========================================================================
363 //
364 // XTypeProvider methods.
365 //
366 //=========================================================================
367 
368 XTYPEPROVIDER_IMPL_4( PropertySetRegistry,
369                       XTypeProvider,
370                       XServiceInfo,
371                       XPropertySetRegistry,
372                       XNameAccess );
373 
374 //=========================================================================
375 //
376 // XServiceInfo methods.
377 //
378 //=========================================================================
379 
380 XSERVICEINFO_NOFACTORY_IMPL_1( PropertySetRegistry,
381                                OUString::createFromAscii(
382                                 "com.sun.star.comp.ucb.PropertySetRegistry" ),
383                                OUString::createFromAscii(
384                                 PROPSET_REG_SERVICE_NAME ) );
385 
386 //=========================================================================
387 //
388 // XPropertySetRegistry methods.
389 //
390 //=========================================================================
391 
392 // virtual
393 Reference< XPersistentPropertySet > SAL_CALL
openPropertySet(const OUString & key,sal_Bool create)394 PropertySetRegistry::openPropertySet( const OUString& key, sal_Bool create )
395     throw( RuntimeException )
396 {
397     if ( key.getLength() )
398     {
399         osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
400 
401         PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets;
402 
403         PropertySetMap_Impl::const_iterator it = rSets.find( key );
404         if ( it != rSets.end() )
405         {
406             // Already instanciated.
407             return Reference< XPersistentPropertySet >( (*it).second );
408         }
409         else
410         {
411             // Create new instance.
412             Reference< XNameAccess > xRootNameAccess(
413                                     getRootConfigReadAccess(), UNO_QUERY );
414             if ( xRootNameAccess.is() )
415             {
416                 // Propertyset in registry?
417                 if ( xRootNameAccess->hasByName( key ) )
418                 {
419                     // Yep!
420                     return Reference< XPersistentPropertySet >(
421                                             new PersistentPropertySet(
422                                                     m_xSMgr, *this, key ) );
423                 }
424                 else if ( create )
425                 {
426                     // No. Create entry for propertyset.
427 
428                     Reference< XSingleServiceFactory > xFac(
429                             getConfigWriteAccess( OUString() ), UNO_QUERY );
430                     Reference< XChangesBatch >  xBatch( xFac, UNO_QUERY );
431                     Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
432 
433                     OSL_ENSURE( xFac.is(),
434                                 "PropertySetRegistry::openPropertySet - "
435                                 "No factory!" );
436 
437                     OSL_ENSURE( xBatch.is(),
438                                 "PropertySetRegistry::openPropertySet - "
439                                 "No batch!" );
440 
441                     OSL_ENSURE( xContainer.is(),
442                                 "PropertySetRegistry::openPropertySet - "
443                                 "No conteiner!" );
444 
445                     if ( xFac.is() && xBatch.is() && xContainer.is() )
446                     {
447                         try
448                         {
449                             // Create new "Properties" config item.
450                             Reference< XNameReplace > xNameReplace(
451                                         xFac->createInstance(), UNO_QUERY );
452 
453                             if ( xNameReplace.is() )
454                             {
455                                 // Fill new item...
456 
457 //                              // Set Values
458 //                              xNameReplace->replaceByName(
459 //                                      OUString::createFromAscii( "Values" ),
460 //                                      makeAny( ... ) );
461 
462                                 // Insert new item.
463                                 xContainer->insertByName(
464                                         key, makeAny( xNameReplace ) );
465                                 // Commit changes.
466                                 xBatch->commitChanges();
467 
468                                 return Reference< XPersistentPropertySet >(
469                                             new PersistentPropertySet(
470                                                     m_xSMgr, *this, key ) );
471                             }
472                         }
473                         catch ( IllegalArgumentException& )
474                         {
475                             // insertByName
476 
477                             OSL_ENSURE( sal_False,
478                                         "PropertySetRegistry::openPropertySet - "
479                                         "caught IllegalArgumentException!" );
480                         }
481                         catch ( ElementExistException& )
482                         {
483                             // insertByName
484 
485                             OSL_ENSURE( sal_False,
486                                         "PropertySetRegistry::openPropertySet - "
487                                         "caught ElementExistException!" );
488                         }
489                         catch ( WrappedTargetException& )
490                         {
491                             // insertByName, commitChanges
492 
493                             OSL_ENSURE( sal_False,
494                                         "PropertySetRegistry::openPropertySet - "
495                                         "caught WrappedTargetException!" );
496                         }
497                         catch ( RuntimeException& )
498                         {
499                             OSL_ENSURE( sal_False,
500                                         "PropertySetRegistry::openPropertySet - "
501                                         "caught RuntimeException!" );
502                         }
503                         catch ( Exception& )
504                         {
505                             // createInstance
506 
507                             OSL_ENSURE( sal_False,
508                                         "PropertySetRegistry::openPropertySet - "
509                                         "caught Exception!" );
510                         }
511                     }
512                 }
513                 else
514                 {
515                     // No entry. Fail, but no error.
516                     return Reference< XPersistentPropertySet >();
517                 }
518             }
519 
520             OSL_ENSURE( sal_False,
521                         "PropertySetRegistry::openPropertySet - Error!" );
522         }
523     }
524 
525     return Reference< XPersistentPropertySet >();
526 }
527 
528 //=========================================================================
529 // virtual
removePropertySet(const OUString & key)530 void SAL_CALL PropertySetRegistry::removePropertySet( const OUString& key )
531     throw( RuntimeException )
532 {
533     if ( !key.getLength() )
534         return;
535 
536     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
537 
538     Reference< XNameAccess > xRootNameAccess(
539                                     getRootConfigReadAccess(), UNO_QUERY );
540     if ( xRootNameAccess.is() )
541     {
542         // Propertyset in registry?
543         if ( !xRootNameAccess->hasByName( key ) )
544             return;
545         Reference< XChangesBatch > xBatch(
546                             getConfigWriteAccess( OUString() ), UNO_QUERY );
547         Reference< XNameContainer > xContainer( xBatch, UNO_QUERY );
548 
549         OSL_ENSURE( xBatch.is(),
550                     "PropertySetRegistry::removePropertySet - "
551                     "No batch!" );
552 
553         OSL_ENSURE( xContainer.is(),
554                     "PropertySetRegistry::removePropertySet - "
555                     "No conteiner!" );
556 
557         if ( xBatch.is() && xContainer.is() )
558         {
559             try
560             {
561                 // Remove item.
562                 xContainer->removeByName( key );
563                 // Commit changes.
564                 xBatch->commitChanges();
565 
566                 // Success.
567                 return;
568             }
569             catch ( NoSuchElementException& )
570             {
571                 // removeByName
572 
573                 OSL_ENSURE( sal_False,
574                             "PropertySetRegistry::removePropertySet - "
575                             "caught NoSuchElementException!" );
576                 return;
577             }
578             catch ( WrappedTargetException& )
579             {
580                 // commitChanges
581 
582                 OSL_ENSURE( sal_False,
583                             "PropertySetRegistry::removePropertySet - "
584                             "caught WrappedTargetException!" );
585                 return;
586             }
587         }
588 
589         return;
590     }
591 
592     OSL_ENSURE( sal_False, "PropertySetRegistry::removePropertySet - Error!" );
593 }
594 
595 //=========================================================================
596 //
597 // XElementAccess methods.
598 //
599 //=========================================================================
600 
601 // virtual
getElementType()602 com::sun::star::uno::Type SAL_CALL PropertySetRegistry::getElementType()
603     throw( RuntimeException )
604 {
605     return getCppuType( ( Reference< XPersistentPropertySet > * ) 0 );
606 }
607 
608 //=========================================================================
609 // virtual
hasElements()610 sal_Bool SAL_CALL PropertySetRegistry::hasElements()
611     throw( RuntimeException )
612 {
613     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
614 
615     Reference< XElementAccess > xElemAccess(
616                                     getRootConfigReadAccess(), UNO_QUERY );
617     if ( xElemAccess.is() )
618         return xElemAccess->hasElements();
619 
620     return sal_False;
621 }
622 
623 //=========================================================================
624 //
625 // XNameAccess methods.
626 //
627 //=========================================================================
628 
629 // virtual
getByName(const OUString & aName)630 Any SAL_CALL PropertySetRegistry::getByName( const OUString& aName )
631     throw( NoSuchElementException, WrappedTargetException, RuntimeException )
632 {
633     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
634 
635     Reference< XNameAccess > xNameAccess(
636                                     getRootConfigReadAccess(), UNO_QUERY );
637     if ( xNameAccess.is() )
638     {
639 
640         try
641         {
642             return xNameAccess->getByName( aName );
643         }
644         catch ( NoSuchElementException& )
645         {
646             // getByName
647         }
648         catch ( WrappedTargetException& )
649         {
650             // getByName
651         }
652     }
653 
654     return Any();
655 }
656 
657 //=========================================================================
658 // virtual
getElementNames()659 Sequence< OUString > SAL_CALL PropertySetRegistry::getElementNames()
660     throw( RuntimeException )
661 {
662     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
663 
664     Reference< XNameAccess > xNameAccess(
665                                     getRootConfigReadAccess(), UNO_QUERY );
666     if ( xNameAccess.is() )
667     {
668         return xNameAccess->getElementNames();
669     }
670     return Sequence< OUString >( 0 );
671 }
672 
673 //=========================================================================
674 // virtual
hasByName(const OUString & aName)675 sal_Bool SAL_CALL PropertySetRegistry::hasByName( const OUString& aName )
676     throw( RuntimeException )
677 {
678     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
679 
680     Reference< XNameAccess > xNameAccess(
681                                     getRootConfigReadAccess(), UNO_QUERY );
682     if ( xNameAccess.is() )
683     {
684         return xNameAccess->hasByName( aName );
685     }
686 
687     return sal_False;
688 }
689 
690 //=========================================================================
add(PersistentPropertySet * pSet)691 void PropertySetRegistry::add( PersistentPropertySet* pSet )
692 {
693     OUString key( pSet->getKey() );
694 
695     if ( key.getLength() )
696     {
697         osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
698         m_pImpl->m_aPropSets[ key ] = pSet;
699     }
700 }
701 
702 //=========================================================================
remove(PersistentPropertySet * pSet)703 void PropertySetRegistry::remove( PersistentPropertySet* pSet )
704 {
705     OUString key( pSet->getKey() );
706 
707     if ( key.getLength() )
708     {
709         osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
710 
711         PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets;
712 
713         PropertySetMap_Impl::iterator it = rSets.find( key );
714         if ( it != rSets.end() )
715         {
716             // Found.
717             rSets.erase( it );
718         }
719     }
720 }
721 
722 //=========================================================================
renamePropertySet(const OUString & rOldKey,const OUString & rNewKey)723 void PropertySetRegistry::renamePropertySet( const OUString& rOldKey,
724                                              const OUString& rNewKey )
725 {
726     if ( rOldKey == rNewKey )
727         return;
728 
729     Reference< XNameAccess > xRootNameAccess(
730                             getConfigWriteAccess( OUString() ), UNO_QUERY );
731     if ( xRootNameAccess.is() )
732     {
733         // Old key present?
734         if ( xRootNameAccess->hasByName( rOldKey ) )
735         {
736             // New key not present?
737             if ( xRootNameAccess->hasByName( rNewKey ) )
738             {
739                 OSL_ENSURE( sal_False,
740                             "PropertySetRegistry::renamePropertySet - "
741                             "New key exists!" );
742                 return;
743             }
744             Reference< XSingleServiceFactory > xFac(
745                                                 xRootNameAccess, UNO_QUERY );
746             Reference< XChangesBatch >  xBatch( xFac, UNO_QUERY );
747             Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
748 
749             OSL_ENSURE( xFac.is(),
750                         "PropertySetRegistry::renamePropertySet - "
751                         "No factory!" );
752 
753             OSL_ENSURE( xBatch.is(),
754                         "PropertySetRegistry::renamePropertySet - "
755                         "No batch!" );
756 
757             OSL_ENSURE( xContainer.is(),
758                         "PropertySetRegistry::renamePropertySet - "
759                         "No container!" );
760 
761             if ( xFac.is() && xBatch.is() && xContainer.is() )
762             {
763                 //////////////////////////////////////////////////////
764                 // Create new "Properties" config item.
765                 //////////////////////////////////////////////////////
766 
767                 try
768                 {
769                     Reference< XNameReplace > xNameReplace(
770                                     xFac->createInstance(), UNO_QUERY );
771 
772                     if ( xNameReplace.is() )
773                     {
774                         // Insert new item.
775                         xContainer->insertByName(
776                                     rNewKey, makeAny( xNameReplace ) );
777                         // Commit changes.
778                         xBatch->commitChanges();
779                     }
780                 }
781                 catch ( IllegalArgumentException& )
782                 {
783                     // insertByName
784 
785                     OSL_ENSURE( sal_False,
786                                 "PropertySetRegistry::renamePropertySet - "
787                                 "caught IllegalArgumentException!" );
788                     return;
789                 }
790                 catch ( ElementExistException& )
791                 {
792                     // insertByName
793 
794                     OSL_ENSURE( sal_False,
795                                 "PropertySetRegistry::renamePropertySet - "
796                                 "caught ElementExistException!" );
797                     return;
798                 }
799                 catch ( WrappedTargetException& )
800                 {
801                     // insertByName, commitChanges
802 
803                     OSL_ENSURE( sal_False,
804                                 "PropertySetRegistry::renamePropertySet - "
805                                 "caught WrappedTargetException!" );
806                     return;
807                 }
808                 catch ( RuntimeException& )
809                 {
810                     OSL_ENSURE( sal_False,
811                                 "PropertySetRegistry::renamePropertySet - "
812                                 "caught RuntimeException!" );
813                     return;
814                 }
815                 catch ( Exception& )
816                 {
817                     // createInstance
818 
819                     OSL_ENSURE( sal_False,
820                                 "PropertySetRegistry::renamePropertySet - "
821                                 "caught Exception!" );
822                     return;
823                 }
824 
825                 //////////////////////////////////////////////////////
826                 // Copy data...
827                 //////////////////////////////////////////////////////
828 
829                 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
830                                                 xRootNameAccess, UNO_QUERY );
831                 if ( !xRootHierNameAccess.is() )
832                 {
833                     OSL_ENSURE( sal_False,
834                                 "PropertySetRegistry::renamePropertySet - "
835                                 "No hierarchical name access!" );
836                     return;
837                 }
838 
839                 try
840                 {
841                     rtl::OUString aOldValuesKey
842                         = makeHierarchalNameSegment( rOldKey );
843                     aOldValuesKey += OUString::createFromAscii( "/Values" );
844 
845                     Reference< XNameAccess > xOldNameAccess;
846                     xRootHierNameAccess->getByHierarchicalName(
847                                                         aOldValuesKey )
848                         >>= xOldNameAccess;
849                     if ( !xOldNameAccess.is() )
850                     {
851                         OSL_ENSURE( sal_False,
852                             "PersistentPropertySet::renamePropertySet - "
853                             "No old name access!" );
854                         return;
855                     }
856 
857                     // Obtain property names.
858                     Sequence< OUString > aElems
859                                     = xOldNameAccess->getElementNames();
860                     sal_Int32 nCount = aElems.getLength();
861                     if ( nCount )
862                     {
863                         rtl::OUString aNewValuesKey
864                             = makeHierarchalNameSegment( rNewKey );
865                         aNewValuesKey += OUString::createFromAscii( "/Values" );
866 
867                         Reference< XSingleServiceFactory > xNewFac;
868                         xRootHierNameAccess->getByHierarchicalName(
869                                                         aNewValuesKey )
870                             >>= xNewFac;
871                         if ( !xNewFac.is() )
872                         {
873                             OSL_ENSURE( sal_False,
874                                 "PersistentPropertySet::renamePropertySet - "
875                                 "No new factory!" );
876                             return;
877                         }
878 
879                         Reference< XNameContainer > xNewContainer(
880                                                     xNewFac, UNO_QUERY );
881                         if ( !xNewContainer.is() )
882                         {
883                             OSL_ENSURE( sal_False,
884                                 "PersistentPropertySet::renamePropertySet - "
885                                 "No new container!" );
886                             return;
887                         }
888 
889                         aOldValuesKey += OUString::createFromAscii( "/" );
890 
891                         OUString aHandleKey
892                             = OUString::createFromAscii( "/Handle" );
893                         OUString aValueKey
894                             = OUString::createFromAscii( "/Value" );
895                         OUString aStateKey
896                             = OUString::createFromAscii( "/State" );
897                         OUString aAttrKey
898                             = OUString::createFromAscii( "/Attributes" );
899 
900                         for ( sal_Int32 n = 0; n < nCount; ++n )
901                         {
902                             const OUString& rPropName = aElems[ n ];
903 
904                             // Create new item.
905                             Reference< XNameReplace > xNewPropNameReplace(
906                                 xNewFac->createInstance(), UNO_QUERY );
907 
908                             if ( !xNewPropNameReplace.is() )
909                             {
910                                 OSL_ENSURE( sal_False,
911                                     "PersistentPropertySet::renamePropertySet - "
912                                     "No new prop name replace!" );
913                                 return;
914                             }
915 
916                             // Fill new item...
917 
918                             // Set Values
919                             OUString aKey = aOldValuesKey;
920                             aKey += makeHierarchalNameSegment( rPropName );
921 
922                             // ... handle
923                             OUString aNewKey1 = aKey;
924                             aNewKey1 += aHandleKey;
925                             Any aAny =
926                                 xRootHierNameAccess->getByHierarchicalName(
927                                     aNewKey1 );
928                             xNewPropNameReplace->replaceByName(
929                                 OUString::createFromAscii( "Handle" ),
930                                 aAny );
931 
932                             // ... value
933                             aNewKey1 = aKey;
934                             aNewKey1 += aValueKey;
935                             aAny =
936                                 xRootHierNameAccess->getByHierarchicalName(
937                                     aNewKey1 );
938                             xNewPropNameReplace->replaceByName(
939                                 OUString::createFromAscii( "Value" ),
940                                 aAny );
941 
942                             // ... state
943                             aNewKey1 = aKey;
944                             aNewKey1 += aStateKey;
945                             aAny =
946                                 xRootHierNameAccess->getByHierarchicalName(
947                                     aNewKey1 );
948                             xNewPropNameReplace->replaceByName(
949                                 OUString::createFromAscii( "State" ),
950                                 aAny );
951 
952                             // ... attributes
953                             aNewKey1 = aKey;
954                             aNewKey1 += aAttrKey;
955                             aAny =
956                                 xRootHierNameAccess->getByHierarchicalName(
957                                     aNewKey1 );
958                             xNewPropNameReplace->replaceByName(
959                                 OUString::createFromAscii( "Attributes" ),
960                                 aAny );
961 
962                             // Insert new item.
963                             xNewContainer->insertByName(
964                                 rPropName, makeAny( xNewPropNameReplace ) );
965 
966                             // Commit changes.
967                             xBatch->commitChanges();
968                         }
969                     }
970                 }
971                 catch ( IllegalArgumentException& )
972                 {
973                     // insertByName, replaceByName
974 
975                     OSL_ENSURE( sal_False,
976                                 "PropertySetRegistry::renamePropertySet - "
977                                 "caught IllegalArgumentException!" );
978                     return;
979                 }
980                 catch ( ElementExistException& )
981                 {
982                     // insertByName
983 
984                     OSL_ENSURE( sal_False,
985                                 "PropertySetRegistry::renamePropertySet - "
986                                 "caught ElementExistException!" );
987                     return;
988                 }
989                 catch ( WrappedTargetException& )
990                 {
991                     // insertByName, replaceByName, commitChanges
992 
993                     OSL_ENSURE( sal_False,
994                                 "PropertySetRegistry::renamePropertySet - "
995                                 "caught WrappedTargetException!" );
996                     return;
997                 }
998                 catch ( NoSuchElementException& )
999                 {
1000                     // getByHierarchicalName, replaceByName
1001 
1002                     OSL_ENSURE( sal_False,
1003                                 "PropertySetRegistry::renamePropertySet - "
1004                                 "caught NoSuchElementException!" );
1005                     return;
1006                 }
1007                 catch ( RuntimeException& )
1008                 {
1009                     OSL_ENSURE( sal_False,
1010                                 "PropertySetRegistry::renamePropertySet - "
1011                                 "caught RuntimeException!" );
1012                     return;
1013                 }
1014                 catch ( Exception& )
1015                 {
1016                     // createInstance
1017 
1018                     OSL_ENSURE( sal_False,
1019                                 "PropertySetRegistry::renamePropertySet - "
1020                                 "caught Exception!" );
1021                     return;
1022                 }
1023 
1024                 //////////////////////////////////////////////////////
1025                 // Remove old entry...
1026                 //////////////////////////////////////////////////////
1027 
1028                 try
1029                 {
1030                     // Remove item.
1031                     xContainer->removeByName( rOldKey );
1032                     // Commit changes.
1033                     xBatch->commitChanges();
1034 
1035                     // Success.
1036                     return;
1037                 }
1038                 catch ( NoSuchElementException& )
1039                 {
1040                     // removeByName
1041 
1042                     OSL_ENSURE( sal_False,
1043                                 "PropertySetRegistry::renamePropertySet - "
1044                                 "caught NoSuchElementException!" );
1045                     return;
1046                 }
1047                 catch ( WrappedTargetException& )
1048                 {
1049                     // commitChanges
1050 
1051                     OSL_ENSURE( sal_False,
1052                                 "PropertySetRegistry::renamePropertySet - "
1053                                 "caught WrappedTargetException!" );
1054                     return;
1055                 }
1056             }
1057         }
1058     }
1059 
1060     OSL_ENSURE( sal_False, "PropertySetRegistry::renamePropertySet - Error!" );
1061 }
1062 
1063 //=========================================================================
getConfigProvider()1064 Reference< XMultiServiceFactory > PropertySetRegistry::getConfigProvider()
1065 {
1066     if ( !m_pImpl->m_xConfigProvider.is() )
1067     {
1068         osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1069         if ( !m_pImpl->m_xConfigProvider.is() )
1070         {
1071             const Sequence< Any >& rInitArgs = m_pImpl->m_aInitArgs;
1072 
1073             if ( rInitArgs.getLength() > 0 )
1074             {
1075                 // Extract config provider from service init args.
1076                 rInitArgs[ 0 ] >>= m_pImpl->m_xConfigProvider;
1077 
1078                 OSL_ENSURE( m_pImpl->m_xConfigProvider.is(),
1079                             "PropertySetRegistry::getConfigProvider - "
1080                             "No config provider!" );
1081             }
1082             else
1083             {
1084                 try
1085                 {
1086                     m_pImpl->m_xConfigProvider
1087                         = Reference< XMultiServiceFactory >(
1088                             m_xSMgr->createInstance(
1089                                 OUString::createFromAscii(
1090                                     "com.sun.star.configuration."
1091                                     "ConfigurationProvider" ) ),
1092                             UNO_QUERY );
1093 
1094                     OSL_ENSURE( m_pImpl->m_xConfigProvider.is(),
1095                                 "PropertySetRegistry::getConfigProvider - "
1096                                 "No config provider!" );
1097 
1098                 }
1099                 catch ( Exception& )
1100                 {
1101                     OSL_ENSURE( sal_False,
1102                                 "PropertySetRegistry::getConfigProvider - "
1103                                 "caught exception!" );
1104                 }
1105             }
1106         }
1107     }
1108 
1109     return m_pImpl->m_xConfigProvider;
1110 }
1111 
1112 //=========================================================================
getRootConfigReadAccess()1113 Reference< XInterface > PropertySetRegistry::getRootConfigReadAccess()
1114 {
1115     try
1116     {
1117         osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1118 
1119         if ( !m_pImpl->m_xRootReadAccess.is() )
1120         {
1121             if ( m_pImpl->m_bTriedToGetRootReadAccess ) // #82494#
1122             {
1123                 OSL_ENSURE( sal_False,
1124                             "PropertySetRegistry::getRootConfigReadAccess - "
1125                             "Unable to read any config data! -> #82494#" );
1126                 return Reference< XInterface >();
1127             }
1128 
1129             getConfigProvider();
1130 
1131             if ( m_pImpl->m_xConfigProvider.is() )
1132             {
1133                 Sequence< Any > aArguments( 1 );
1134                 PropertyValue aProperty;
1135                 aProperty.Name
1136                     = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
1137                                             CFGPROPERTY_NODEPATH ) );
1138                 aProperty.Value
1139                     <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
1140                                             STORE_CONTENTPROPERTIES_KEY ) );
1141                 aArguments[ 0 ] <<= aProperty;
1142 
1143                 m_pImpl->m_bTriedToGetRootReadAccess = sal_True;
1144 
1145                 m_pImpl->m_xRootReadAccess =
1146                     m_pImpl->m_xConfigProvider->createInstanceWithArguments(
1147                         OUString::createFromAscii(
1148                             "com.sun.star.configuration.ConfigurationAccess" ),
1149                         aArguments );
1150 
1151                 if ( m_pImpl->m_xRootReadAccess.is() )
1152                     return m_pImpl->m_xRootReadAccess;
1153             }
1154         }
1155         else
1156             return m_pImpl->m_xRootReadAccess;
1157     }
1158     catch ( RuntimeException& )
1159     {
1160         throw;
1161     }
1162     catch ( Exception& )
1163     {
1164         // createInstance, createInstanceWithArguments
1165 
1166         OSL_ENSURE( sal_False,
1167             "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" );
1168         return Reference< XInterface >();
1169     }
1170 
1171     OSL_ENSURE( sal_False,
1172                 "PropertySetRegistry::getRootConfigReadAccess - Error!" );
1173     return Reference< XInterface >();
1174 }
1175 
1176 //=========================================================================
getConfigWriteAccess(const OUString & rPath)1177 Reference< XInterface > PropertySetRegistry::getConfigWriteAccess(
1178                                                     const OUString& rPath )
1179 {
1180     try
1181     {
1182         osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1183 
1184         if ( !m_pImpl->m_xRootWriteAccess.is() )
1185         {
1186             if ( m_pImpl->m_bTriedToGetRootWriteAccess ) // #82494#
1187             {
1188                 OSL_ENSURE( sal_False,
1189                             "PropertySetRegistry::getConfigWriteAccess - "
1190                             "Unable to write any config data! -> #82494#" );
1191                 return Reference< XInterface >();
1192             }
1193 
1194             getConfigProvider();
1195 
1196             if ( m_pImpl->m_xConfigProvider.is() )
1197             {
1198                 Sequence< Any > aArguments( 2 );
1199                 PropertyValue   aProperty;
1200 
1201                 aProperty.Name
1202                     = OUString( RTL_CONSTASCII_USTRINGPARAM(
1203                                             CFGPROPERTY_NODEPATH ) );
1204                 aProperty.Value
1205                     <<= OUString( RTL_CONSTASCII_USTRINGPARAM(
1206                                             STORE_CONTENTPROPERTIES_KEY ) );
1207                 aArguments[ 0 ] <<= aProperty;
1208 
1209                 aProperty.Name
1210                     = OUString( RTL_CONSTASCII_USTRINGPARAM(
1211                                             CFGPROPERTY_LAZYWRITE ) );
1212                 aProperty.Value <<= sal_True;
1213                 aArguments[ 1 ] <<= aProperty;
1214 
1215                 m_pImpl->m_bTriedToGetRootWriteAccess = sal_True;
1216 
1217                 m_pImpl->m_xRootWriteAccess =
1218                     m_pImpl->m_xConfigProvider->createInstanceWithArguments(
1219                         OUString::createFromAscii(
1220                             "com.sun.star.configuration.ConfigurationUpdateAccess" ),
1221                         aArguments );
1222 
1223                 OSL_ENSURE( m_pImpl->m_xRootWriteAccess.is(),
1224                             "PropertySetRegistry::getConfigWriteAccess - "
1225                             "No config update access!" );
1226             }
1227         }
1228 
1229         if ( m_pImpl->m_xRootWriteAccess.is() )
1230         {
1231             if ( rPath.getLength() )
1232             {
1233                 Reference< XHierarchicalNameAccess > xNA(
1234                                 m_pImpl->m_xRootWriteAccess, UNO_QUERY );
1235                 if ( xNA.is() )
1236                 {
1237                     Reference< XInterface > xInterface;
1238                     xNA->getByHierarchicalName( rPath ) >>= xInterface;
1239 
1240                     if ( xInterface.is() )
1241                         return xInterface;
1242                 }
1243             }
1244             else
1245                 return m_pImpl->m_xRootWriteAccess;
1246         }
1247     }
1248     catch ( RuntimeException& )
1249     {
1250         throw;
1251     }
1252     catch ( NoSuchElementException& )
1253     {
1254         // getByHierarchicalName
1255 
1256         OSL_ENSURE( sal_False,
1257             "PropertySetRegistry::getConfigWriteAccess - "
1258             "caught NoSuchElementException!" );
1259         return Reference< XInterface >();
1260     }
1261     catch ( Exception& )
1262     {
1263         // createInstance, createInstanceWithArguments
1264 
1265         OSL_ENSURE( sal_False,
1266                     "PropertySetRegistry::getConfigWriteAccess - "
1267                     "caught Exception!" );
1268         return Reference< XInterface >();
1269     }
1270 
1271     OSL_ENSURE( sal_False,
1272                 "PropertySetRegistry::getConfigWriteAccess - Error!" );
1273     return Reference< XInterface >();
1274 }
1275 
1276 //=========================================================================
1277 //
1278 // PropertyListeners_Impl.
1279 //
1280 //=========================================================================
1281 
1282 typedef OMultiTypeInterfaceContainerHelperVar
1283 <
1284     OUString,
1285     hashString_Impl,
1286     equalString_Impl
1287 > PropertyListeners_Impl;
1288 
1289 //=========================================================================
1290 //
1291 // PersistentPropertySet_Impl.
1292 //
1293 //=========================================================================
1294 
1295 struct PersistentPropertySet_Impl
1296 {
1297     PropertySetRegistry*        m_pCreator;
1298     PropertySetInfo_Impl*       m_pInfo;
1299     OUString                    m_aKey;
1300     OUString                    m_aFullKey;
1301     osl::Mutex                  m_aMutex;
1302     OInterfaceContainerHelper*  m_pDisposeEventListeners;
1303     OInterfaceContainerHelper*  m_pPropSetChangeListeners;
1304     PropertyListeners_Impl*     m_pPropertyChangeListeners;
1305 
PersistentPropertySet_ImplPersistentPropertySet_Impl1306     PersistentPropertySet_Impl( PropertySetRegistry& rCreator,
1307                                 const OUString& rKey )
1308     : m_pCreator( &rCreator ), m_pInfo( NULL ), m_aKey( rKey ),
1309       m_pDisposeEventListeners( NULL ), m_pPropSetChangeListeners( NULL ),
1310       m_pPropertyChangeListeners( NULL )
1311     {
1312         m_pCreator->acquire();
1313     }
1314 
~PersistentPropertySet_ImplPersistentPropertySet_Impl1315     ~PersistentPropertySet_Impl()
1316     {
1317         m_pCreator->release();
1318 
1319         if ( m_pInfo )
1320             m_pInfo->release();
1321 
1322         delete m_pDisposeEventListeners;
1323         delete m_pPropSetChangeListeners;
1324         delete m_pPropertyChangeListeners;
1325     }
1326 };
1327 
1328 //=========================================================================
1329 //=========================================================================
1330 //=========================================================================
1331 //
1332 // PersistentPropertySet Implementation.
1333 //
1334 //=========================================================================
1335 //=========================================================================
1336 //=========================================================================
1337 
PersistentPropertySet(const Reference<XMultiServiceFactory> & rXSMgr,PropertySetRegistry & rCreator,const OUString & rKey)1338 PersistentPropertySet::PersistentPropertySet(
1339                         const Reference< XMultiServiceFactory >& rXSMgr,
1340                         PropertySetRegistry& rCreator,
1341                         const OUString& rKey )
1342 : m_xSMgr( rXSMgr ),
1343   m_pImpl( new PersistentPropertySet_Impl( rCreator, rKey ) )
1344 {
1345     // register at creator.
1346     rCreator.add( this );
1347 }
1348 
1349 //=========================================================================
1350 // virtual
~PersistentPropertySet()1351 PersistentPropertySet::~PersistentPropertySet()
1352 {
1353     // deregister at creator.
1354     m_pImpl->m_pCreator->remove( this );
1355 
1356     delete m_pImpl;
1357 }
1358 
1359 //=========================================================================
1360 //
1361 // XInterface methods.
1362 //
1363 //=========================================================================
1364 
1365 XINTERFACE_IMPL_9( PersistentPropertySet,
1366                    XTypeProvider,
1367                    XServiceInfo,
1368                    XComponent,
1369                    XPropertySet, /* base of XPersistentPropertySet */
1370                    XNamed,
1371                    XPersistentPropertySet,
1372                    XPropertyContainer,
1373                    XPropertySetInfoChangeNotifier,
1374                    XPropertyAccess );
1375 
1376 //=========================================================================
1377 //
1378 // XTypeProvider methods.
1379 //
1380 //=========================================================================
1381 
1382 XTYPEPROVIDER_IMPL_8( PersistentPropertySet,
1383                       XTypeProvider,
1384                       XServiceInfo,
1385                       XComponent,
1386                       XPersistentPropertySet,
1387                       XNamed,
1388                       XPropertyContainer,
1389                       XPropertySetInfoChangeNotifier,
1390                       XPropertyAccess );
1391 
1392 //=========================================================================
1393 //
1394 // XServiceInfo methods.
1395 //
1396 //=========================================================================
1397 
1398 XSERVICEINFO_NOFACTORY_IMPL_1( PersistentPropertySet,
1399                                OUString::createFromAscii(
1400                                 "com.sun.star.comp.ucb.PersistentPropertySet" ),
1401                                OUString::createFromAscii(
1402                                 PERS_PROPSET_SERVICE_NAME ) );
1403 
1404 //=========================================================================
1405 //
1406 // XComponent methods.
1407 //
1408 //=========================================================================
1409 
1410 // virtual
dispose()1411 void SAL_CALL PersistentPropertySet::dispose()
1412     throw( RuntimeException )
1413 {
1414     if ( m_pImpl->m_pDisposeEventListeners &&
1415          m_pImpl->m_pDisposeEventListeners->getLength() )
1416     {
1417         EventObject aEvt;
1418         aEvt.Source = static_cast< XComponent * >( this  );
1419         m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt );
1420     }
1421 
1422     if ( m_pImpl->m_pPropSetChangeListeners &&
1423          m_pImpl->m_pPropSetChangeListeners->getLength() )
1424     {
1425         EventObject aEvt;
1426         aEvt.Source = static_cast< XPropertySetInfoChangeNotifier * >( this  );
1427         m_pImpl->m_pPropSetChangeListeners->disposeAndClear( aEvt );
1428     }
1429 
1430     if ( m_pImpl->m_pPropertyChangeListeners )
1431     {
1432         EventObject aEvt;
1433         aEvt.Source = static_cast< XPropertySet * >( this  );
1434         m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt );
1435     }
1436 }
1437 
1438 //=========================================================================
1439 // virtual
addEventListener(const Reference<XEventListener> & Listener)1440 void SAL_CALL PersistentPropertySet::addEventListener(
1441                             const Reference< XEventListener >& Listener )
1442     throw( RuntimeException )
1443 {
1444     if ( !m_pImpl->m_pDisposeEventListeners )
1445         m_pImpl->m_pDisposeEventListeners =
1446                     new OInterfaceContainerHelper( m_pImpl->m_aMutex );
1447 
1448     m_pImpl->m_pDisposeEventListeners->addInterface( Listener );
1449 }
1450 
1451 //=========================================================================
1452 // virtual
removeEventListener(const Reference<XEventListener> & Listener)1453 void SAL_CALL PersistentPropertySet::removeEventListener(
1454                             const Reference< XEventListener >& Listener )
1455     throw( RuntimeException )
1456 {
1457     if ( m_pImpl->m_pDisposeEventListeners )
1458         m_pImpl->m_pDisposeEventListeners->removeInterface( Listener );
1459 
1460     // Note: Don't want to delete empty container here -> performance.
1461 }
1462 
1463 //=========================================================================
1464 //
1465 // XPropertySet methods.
1466 //
1467 //=========================================================================
1468 
1469 // virtual
1470 Reference< XPropertySetInfo > SAL_CALL
getPropertySetInfo()1471                                 PersistentPropertySet::getPropertySetInfo()
1472     throw( RuntimeException )
1473 {
1474     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1475 
1476     PropertySetInfo_Impl*& rpInfo = m_pImpl->m_pInfo;
1477     if ( !rpInfo )
1478     {
1479         rpInfo = new PropertySetInfo_Impl( m_xSMgr, this );
1480         rpInfo->acquire();
1481     }
1482     return Reference< XPropertySetInfo >( rpInfo );
1483 }
1484 
1485 //=========================================================================
1486 // virtual
setPropertyValue(const OUString & aPropertyName,const Any & aValue)1487 void SAL_CALL PersistentPropertySet::setPropertyValue(
1488                         const OUString& aPropertyName, const Any& aValue )
1489     throw( UnknownPropertyException,
1490            PropertyVetoException,
1491            IllegalArgumentException,
1492            WrappedTargetException,
1493            RuntimeException )
1494 {
1495     if ( !aPropertyName.getLength() )
1496         throw UnknownPropertyException();
1497 
1498     osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex );
1499 
1500     Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1501                 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1502     if ( xRootHierNameAccess.is() )
1503     {
1504         OUString aFullPropName( getFullKey() );
1505         aFullPropName += OUString::createFromAscii( "/" );
1506         aFullPropName += makeHierarchalNameSegment( aPropertyName );
1507 
1508         // Does property exist?
1509         if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1510         {
1511             Reference< XNameReplace > xNameReplace(
1512                     m_pImpl->m_pCreator->getConfigWriteAccess(
1513                                             aFullPropName ), UNO_QUERY );
1514             Reference< XChangesBatch > xBatch(
1515                     m_pImpl->m_pCreator->getConfigWriteAccess(
1516                                             OUString() ), UNO_QUERY );
1517 
1518             if ( xNameReplace.is() && xBatch.is() )
1519             {
1520                 try
1521                 {
1522                     // Obtain old value
1523                     OUString aValueName = aFullPropName;
1524                     aValueName += OUString::createFromAscii( "/Value" );
1525                     Any aOldValue
1526                         = xRootHierNameAccess->getByHierarchicalName(
1527                                                                 aValueName );
1528                     // Check value type.
1529                     if ( aOldValue.getValueType() != aValue.getValueType() )
1530                     {
1531                         aCGuard.clear();
1532                         throw IllegalArgumentException();
1533                     }
1534 
1535                     // Write value
1536                     xNameReplace->replaceByName(
1537                                     OUString::createFromAscii( "Value" ),
1538                                     aValue );
1539 
1540                     // Write state ( Now it is a directly set value )
1541                     xNameReplace->replaceByName(
1542                                     OUString::createFromAscii( "State" ),
1543                                     makeAny(
1544                                         sal_Int32(
1545                                             PropertyState_DIRECT_VALUE ) ) );
1546 
1547                     // Commit changes.
1548                     xBatch->commitChanges();
1549 
1550                     PropertyChangeEvent aEvt;
1551                     if ( m_pImpl->m_pPropertyChangeListeners )
1552                     {
1553                         // Obtain handle
1554                         aValueName = aFullPropName;
1555                         aValueName += OUString::createFromAscii( "/Handle" );
1556                         sal_Int32 nHandle = -1;
1557                         xRootHierNameAccess->getByHierarchicalName( aValueName )
1558                             >>= nHandle;
1559 
1560                         aEvt.Source         = (OWeakObject*)this;
1561                         aEvt.PropertyName   = aPropertyName;
1562                         aEvt.PropertyHandle = nHandle;
1563                         aEvt.Further        = sal_False;
1564                         aEvt.OldValue       = aOldValue;
1565                         aEvt.NewValue       = aValue;
1566 
1567                         // Callback follows!
1568                         aCGuard.clear();
1569 
1570                         notifyPropertyChangeEvent( aEvt );
1571                     }
1572                     return;
1573                 }
1574                 catch ( IllegalArgumentException& )
1575                 {
1576                     // replaceByName
1577                 }
1578                 catch ( NoSuchElementException& )
1579                 {
1580                     // getByHierarchicalName, replaceByName
1581                 }
1582                 catch ( WrappedTargetException& )
1583                 {
1584                     // replaceByName, commitChanges
1585                 }
1586             }
1587         }
1588     }
1589 
1590     throw UnknownPropertyException();
1591 }
1592 
1593 //=========================================================================
1594 // virtual
getPropertyValue(const OUString & PropertyName)1595 Any SAL_CALL PersistentPropertySet::getPropertyValue(
1596                                             const OUString& PropertyName )
1597     throw( UnknownPropertyException,
1598            WrappedTargetException,
1599            RuntimeException )
1600 {
1601     if ( !PropertyName.getLength() )
1602         throw UnknownPropertyException();
1603 
1604     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1605 
1606     Reference< XHierarchicalNameAccess > xNameAccess(
1607                 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1608     if ( xNameAccess.is() )
1609     {
1610         OUString aFullPropName( getFullKey() );
1611         aFullPropName += OUString::createFromAscii( "/" );
1612         aFullPropName += makeHierarchalNameSegment( PropertyName );
1613         aFullPropName += OUString::createFromAscii( "/Value" );
1614         try
1615         {
1616             return xNameAccess->getByHierarchicalName( aFullPropName );
1617         }
1618         catch ( NoSuchElementException& )
1619         {
1620             throw UnknownPropertyException();
1621         }
1622     }
1623 
1624     throw UnknownPropertyException();
1625 }
1626 
1627 //=========================================================================
1628 // virtual
addPropertyChangeListener(const OUString & aPropertyName,const Reference<XPropertyChangeListener> & xListener)1629 void SAL_CALL PersistentPropertySet::addPropertyChangeListener(
1630                     const OUString& aPropertyName,
1631                     const Reference< XPropertyChangeListener >& xListener )
1632     throw( UnknownPropertyException,
1633            WrappedTargetException,
1634            RuntimeException )
1635 {
1636 //  load();
1637 
1638     if ( !m_pImpl->m_pPropertyChangeListeners )
1639         m_pImpl->m_pPropertyChangeListeners =
1640                     new PropertyListeners_Impl( m_pImpl->m_aMutex );
1641 
1642     m_pImpl->m_pPropertyChangeListeners->addInterface(
1643                                                 aPropertyName, xListener );
1644 }
1645 
1646 //=========================================================================
1647 // virtual
removePropertyChangeListener(const OUString & aPropertyName,const Reference<XPropertyChangeListener> & aListener)1648 void SAL_CALL PersistentPropertySet::removePropertyChangeListener(
1649                     const OUString& aPropertyName,
1650                     const Reference< XPropertyChangeListener >& aListener )
1651     throw( UnknownPropertyException,
1652            WrappedTargetException,
1653            RuntimeException )
1654 {
1655 //  load();
1656 
1657     if ( m_pImpl->m_pPropertyChangeListeners )
1658         m_pImpl->m_pPropertyChangeListeners->removeInterface(
1659                                                 aPropertyName, aListener );
1660 
1661     // Note: Don't want to delete empty container here -> performance.
1662 }
1663 
1664 //=========================================================================
1665 // virtual
addVetoableChangeListener(const OUString &,const Reference<XVetoableChangeListener> &)1666 void SAL_CALL PersistentPropertySet::addVetoableChangeListener(
1667                     const OUString&,
1668                     const Reference< XVetoableChangeListener >& )
1669     throw( UnknownPropertyException,
1670            WrappedTargetException,
1671            RuntimeException )
1672 {
1673 //  load();
1674 //  OSL_ENSURE( sal_False,
1675 //              "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
1676 }
1677 
1678 //=========================================================================
1679 // virtual
removeVetoableChangeListener(const OUString &,const Reference<XVetoableChangeListener> &)1680 void SAL_CALL PersistentPropertySet::removeVetoableChangeListener(
1681                     const OUString&,
1682                     const Reference< XVetoableChangeListener >& )
1683     throw( UnknownPropertyException,
1684            WrappedTargetException,
1685            RuntimeException )
1686 {
1687 //  load();
1688 //  OSL_ENSURE( sal_False,
1689 //              "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
1690 }
1691 
1692 //=========================================================================
1693 //
1694 // XPersistentPropertySet methods.
1695 //
1696 //=========================================================================
1697 
1698 // virtual
getRegistry()1699 Reference< XPropertySetRegistry > SAL_CALL PersistentPropertySet::getRegistry()
1700     throw( RuntimeException )
1701 {
1702     return Reference< XPropertySetRegistry >( m_pImpl->m_pCreator );
1703 }
1704 
1705 //=========================================================================
1706 // virtual
getKey()1707 OUString SAL_CALL PersistentPropertySet::getKey()
1708     throw( RuntimeException )
1709 {
1710     return m_pImpl->m_aKey;
1711 }
1712 
1713 //=========================================================================
1714 //
1715 // XNamed methods.
1716 //
1717 //=========================================================================
1718 
1719 // virtual
getName()1720 rtl::OUString SAL_CALL PersistentPropertySet::getName()
1721     throw( RuntimeException )
1722 {
1723     // same as getKey()
1724     return m_pImpl->m_aKey;
1725 }
1726 
1727 //=========================================================================
1728 // virtual
setName(const OUString & aName)1729 void SAL_CALL PersistentPropertySet::setName( const OUString& aName )
1730     throw( RuntimeException )
1731 {
1732     if ( aName != m_pImpl->m_aKey )
1733         m_pImpl->m_pCreator->renamePropertySet( m_pImpl->m_aKey, aName );
1734 }
1735 
1736 //=========================================================================
1737 //
1738 // XPropertyContainer methods.
1739 //
1740 //=========================================================================
1741 
1742 // virtual
addProperty(const OUString & Name,sal_Int16 Attributes,const Any & DefaultValue)1743 void SAL_CALL PersistentPropertySet::addProperty(
1744         const OUString& Name, sal_Int16 Attributes, const Any& DefaultValue )
1745     throw( PropertyExistException,
1746            IllegalTypeException,
1747            IllegalArgumentException,
1748            RuntimeException )
1749 {
1750     if ( !Name.getLength() )
1751         throw IllegalArgumentException();
1752 
1753     // @@@ What other types can't be written to config server?
1754 
1755     // Check type class ( Not all types can be written to storage )
1756     TypeClass eTypeClass = DefaultValue.getValueTypeClass();
1757     if ( eTypeClass == TypeClass_INTERFACE )
1758         throw IllegalTypeException();
1759 
1760     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1761 
1762     // Property already in set?
1763 
1764     OUString aFullValuesName;
1765 
1766     Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1767                 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1768     if ( xRootHierNameAccess.is() )
1769     {
1770         aFullValuesName = getFullKey();
1771         OUString aFullPropName = aFullValuesName;
1772         aFullPropName += OUString::createFromAscii( "/" );
1773         aFullPropName += makeHierarchalNameSegment( Name );
1774 
1775         if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1776         {
1777             // Already in set.
1778             throw PropertyExistException();
1779         }
1780     }
1781 
1782     // Property is always removeable.
1783     Attributes |= PropertyAttribute::REMOVEABLE;
1784 
1785     // Add property.
1786 
1787     Reference< XSingleServiceFactory > xFac(
1788                 m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ),
1789                 UNO_QUERY );
1790     Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
1791     Reference< XChangesBatch >  xBatch(
1792                 m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ),
1793                 UNO_QUERY );
1794 
1795     OSL_ENSURE( xFac.is(),
1796                 "PersistentPropertySet::addProperty - No factory!" );
1797 
1798     OSL_ENSURE( xBatch.is(),
1799                 "PersistentPropertySet::addProperty - No batch!" );
1800 
1801     OSL_ENSURE( xContainer.is(),
1802                 "PersistentPropertySet::addProperty - No container!" );
1803 
1804     if ( xFac.is() && xBatch.is() && xContainer.is() )
1805     {
1806         try
1807         {
1808             // Create new "PropertyValue" config item.
1809             Reference< XNameReplace > xNameReplace(
1810                                         xFac->createInstance(), UNO_QUERY );
1811 
1812             if ( xNameReplace.is() )
1813             {
1814                 // Fill new item...
1815 
1816                 // Set handle
1817                 xNameReplace->replaceByName(
1818                                     OUString::createFromAscii( "Handle" ),
1819                                     makeAny( sal_Int32( -1 ) ) );
1820 
1821                 // Set default value
1822                 xNameReplace->replaceByName(
1823                                     OUString::createFromAscii( "Value" ),
1824                                     DefaultValue );
1825 
1826                 // Set state ( always "default" )
1827                 xNameReplace->replaceByName(
1828                                     OUString::createFromAscii( "State" ),
1829                                     makeAny(
1830                                         sal_Int32(
1831                                             PropertyState_DEFAULT_VALUE ) ) );
1832 
1833                 // Set attributes
1834                 xNameReplace->replaceByName(
1835                                     OUString::createFromAscii( "Attributes" ),
1836                                     makeAny( sal_Int32( Attributes ) ) );
1837 
1838                 // Insert new item.
1839                 xContainer->insertByName( Name, makeAny( xNameReplace ) );
1840 
1841                 // Commit changes.
1842                 xBatch->commitChanges();
1843 
1844                 // Property set info is invalid.
1845                 if ( m_pImpl->m_pInfo )
1846                     m_pImpl->m_pInfo->reset();
1847 
1848                 // Notify propertyset info change listeners.
1849                 if ( m_pImpl->m_pPropSetChangeListeners &&
1850                     m_pImpl->m_pPropSetChangeListeners->getLength() )
1851                 {
1852                     PropertySetInfoChangeEvent evt(
1853                                     static_cast< OWeakObject * >( this ),
1854                                     Name,
1855                                     -1,
1856                                     PropertySetInfoChange::PROPERTY_INSERTED );
1857                     notifyPropertySetInfoChange( evt );
1858                 }
1859 
1860                 // Success.
1861                 return;
1862             }
1863         }
1864         catch ( IllegalArgumentException& )
1865         {
1866             // insertByName
1867 
1868             OSL_ENSURE( sal_False,
1869                         "PersistentPropertySet::addProperty - "
1870                         "caught IllegalArgumentException!" );
1871             return;
1872         }
1873         catch ( ElementExistException& )
1874         {
1875             // insertByName
1876 
1877             OSL_ENSURE( sal_False,
1878                         "PersistentPropertySet::addProperty - "
1879                         "caught ElementExistException!" );
1880             return;
1881         }
1882         catch ( WrappedTargetException& )
1883         {
1884             // replaceByName, insertByName, commitChanges
1885 
1886             OSL_ENSURE( sal_False,
1887                         "PersistentPropertySet::addProperty - "
1888                         "caught WrappedTargetException!" );
1889             return;
1890         }
1891         catch ( RuntimeException& )
1892         {
1893             throw;
1894         }
1895         catch ( Exception& )
1896         {
1897             // createInstance
1898 
1899             OSL_ENSURE( sal_False,
1900                         "PersistentPropertySet::addProperty - "
1901                         "caught Exception!" );
1902             return;
1903         }
1904     }
1905 
1906     OSL_ENSURE( sal_False,
1907                 "PersistentPropertySet::addProperty - Error!" );
1908 }
1909 
1910 //=========================================================================
1911 // virtual
removeProperty(const OUString & Name)1912 void SAL_CALL PersistentPropertySet::removeProperty( const OUString& Name )
1913     throw( UnknownPropertyException,
1914            NotRemoveableException,
1915            RuntimeException )
1916 {
1917     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1918 
1919     OUString aFullValuesName;
1920     OUString aFullPropName;
1921 
1922     Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1923                 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1924     if ( xRootHierNameAccess.is() )
1925     {
1926         aFullValuesName = getFullKey();
1927         aFullPropName   = aFullValuesName;
1928         aFullPropName   += OUString::createFromAscii( "/" );
1929         aFullPropName   += makeHierarchalNameSegment( Name );
1930 
1931         // Property in set?
1932         if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1933             throw UnknownPropertyException();
1934 
1935         // Property removeable?
1936         try
1937         {
1938             OUString aFullAttrName = aFullPropName;
1939             aFullAttrName += OUString::createFromAscii( "/Attributes" );
1940 
1941             sal_Int32 nAttribs = 0;
1942             if ( xRootHierNameAccess->getByHierarchicalName( aFullAttrName )
1943                     >>= nAttribs )
1944             {
1945                 if ( !( nAttribs & PropertyAttribute::REMOVEABLE ) )
1946                 {
1947                     // Not removeable!
1948                     throw NotRemoveableException();
1949                 }
1950             }
1951             else
1952             {
1953                 OSL_ENSURE( sal_False,
1954                             "PersistentPropertySet::removeProperty - "
1955                             "No attributes!" );
1956                 return;
1957             }
1958         }
1959         catch ( NoSuchElementException& )
1960         {
1961             // getByHierarchicalName
1962 
1963             OSL_ENSURE( sal_False,
1964                         "PersistentPropertySet::removeProperty - "
1965                         "caught NoSuchElementException!" );
1966         }
1967 
1968         // Remove property...
1969 
1970         Reference< XNameContainer > xContainer(
1971                 m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ),
1972                 UNO_QUERY );
1973         Reference< XChangesBatch > xBatch(
1974                 m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ),
1975                 UNO_QUERY );
1976 
1977         OSL_ENSURE( xBatch.is(),
1978                     "PersistentPropertySet::removeProperty - No batch!" );
1979 
1980         OSL_ENSURE( xContainer.is(),
1981                     "PersistentPropertySet::removeProperty - No container!" );
1982 
1983         if ( xBatch.is() && xContainer.is() )
1984         {
1985             try
1986             {
1987                 sal_Int32 nHandle = -1;
1988 
1989                 if ( m_pImpl->m_pPropSetChangeListeners &&
1990                      m_pImpl->m_pPropSetChangeListeners->getLength() )
1991                 {
1992                     // Obtain property handle ( needed for propertysetinfo
1993                     // change event )...
1994 
1995                     try
1996                     {
1997                         OUString aFullHandleName = aFullPropName;
1998                         aFullHandleName
1999                                 += OUString::createFromAscii( "/Handle" );
2000 
2001                         if ( ! ( xRootHierNameAccess->getByHierarchicalName(
2002                                         aFullHandleName ) >>= nHandle ) )
2003                             nHandle = -1;
2004 
2005                     }
2006                     catch ( NoSuchElementException& )
2007                     {
2008                         // getByHierarchicalName
2009 
2010                         OSL_ENSURE( sal_False,
2011                                     "PersistentPropertySet::removeProperty - "
2012                                     "caught NoSuchElementException!" );
2013                         nHandle = -1;
2014                     }
2015                 }
2016 
2017                 xContainer->removeByName( Name );
2018                 xBatch->commitChanges();
2019 
2020                 // Property set info is invalid.
2021                 if ( m_pImpl->m_pInfo )
2022                     m_pImpl->m_pInfo->reset();
2023 
2024                 // Notify propertyset info change listeners.
2025                 if ( m_pImpl->m_pPropSetChangeListeners &&
2026                     m_pImpl->m_pPropSetChangeListeners->getLength() )
2027                 {
2028                     PropertySetInfoChangeEvent evt(
2029                                     static_cast< OWeakObject * >( this ),
2030                                     Name,
2031                                     nHandle,
2032                                     PropertySetInfoChange::PROPERTY_REMOVED );
2033                     notifyPropertySetInfoChange( evt );
2034                 }
2035 
2036                 // Success.
2037                 return;
2038             }
2039             catch ( NoSuchElementException& )
2040             {
2041                 // removeByName
2042 
2043                 OSL_ENSURE( sal_False,
2044                             "PersistentPropertySet::removeProperty - "
2045                             "caught NoSuchElementException!" );
2046                 return;
2047             }
2048             catch ( WrappedTargetException& )
2049             {
2050                 // commitChanges
2051 
2052                 OSL_ENSURE( sal_False,
2053                             "PersistentPropertySet::removeProperty - "
2054                             "caught WrappedTargetException!" );
2055                 return;
2056             }
2057         }
2058     }
2059 
2060     OSL_ENSURE( sal_False,
2061                 "PersistentPropertySet::removeProperty - Error!" );
2062 }
2063 
2064 //=========================================================================
2065 //
2066 // XPropertySetInfoChangeNotifier methods.
2067 //
2068 //=========================================================================
2069 
2070 // virtual
addPropertySetInfoChangeListener(const Reference<XPropertySetInfoChangeListener> & Listener)2071 void SAL_CALL PersistentPropertySet::addPropertySetInfoChangeListener(
2072                 const Reference< XPropertySetInfoChangeListener >& Listener )
2073     throw( RuntimeException )
2074 {
2075     if ( !m_pImpl->m_pPropSetChangeListeners )
2076         m_pImpl->m_pPropSetChangeListeners =
2077                     new OInterfaceContainerHelper( m_pImpl->m_aMutex );
2078 
2079     m_pImpl->m_pPropSetChangeListeners->addInterface( Listener );
2080 }
2081 
2082 //=========================================================================
2083 // virtual
removePropertySetInfoChangeListener(const Reference<XPropertySetInfoChangeListener> & Listener)2084 void SAL_CALL PersistentPropertySet::removePropertySetInfoChangeListener(
2085                 const Reference< XPropertySetInfoChangeListener >& Listener )
2086     throw( RuntimeException )
2087 {
2088     if ( m_pImpl->m_pPropSetChangeListeners )
2089         m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener );
2090 }
2091 
2092 //=========================================================================
2093 //
2094 // XPropertyAccess methods.
2095 //
2096 //=========================================================================
2097 
2098 // virtual
getPropertyValues()2099 Sequence< PropertyValue > SAL_CALL PersistentPropertySet::getPropertyValues()
2100     throw( RuntimeException )
2101 {
2102     osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
2103 
2104     Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2105                 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
2106     if ( xRootHierNameAccess.is() )
2107     {
2108         try
2109         {
2110             Reference< XNameAccess > xNameAccess;
2111             xRootHierNameAccess->getByHierarchicalName(getFullKey())
2112                 >>= xNameAccess;
2113             if ( xNameAccess.is() )
2114             {
2115                 // Obtain property names.
2116 
2117                 Sequence< OUString > aElems = xNameAccess->getElementNames();
2118 
2119                 sal_Int32 nCount = aElems.getLength();
2120                 if ( nCount )
2121                 {
2122                     Reference< XHierarchicalNameAccess > xHierNameAccess(
2123                                                     xNameAccess, UNO_QUERY );
2124 
2125                     OSL_ENSURE( xHierNameAccess.is(),
2126                                 "PersistentPropertySet::getPropertyValues - "
2127                                 "No hierarchical name access!" );
2128 
2129                     if ( xHierNameAccess.is() )
2130                     {
2131                         Sequence< PropertyValue > aValues( nCount );
2132 
2133                         const OUString aHandleName
2134                                     = OUString::createFromAscii( "/Handle" );
2135                         const OUString aValueName
2136                                     = OUString::createFromAscii( "/Value" );
2137                         const OUString aStateName
2138                                     = OUString::createFromAscii( "/State" );
2139 
2140                         for ( sal_Int32 n = 0; n < nCount; ++n )
2141                         {
2142                             PropertyValue& rValue = aValues[ n ];
2143                             OUString rName    = aElems[ n ];
2144                             OUString aXMLName
2145                                         = makeHierarchalNameSegment( rName );
2146 
2147                             // Set property name.
2148 
2149                             rValue.Name = rName;
2150 
2151                             try
2152                             {
2153                                 // Obtain and set property handle
2154                                 OUString aHierName = aXMLName;
2155                                 aHierName += aHandleName;
2156                                 Any aKeyValue
2157                                     = xHierNameAccess->getByHierarchicalName(
2158                                         aHierName );
2159 
2160                                 if ( !( aKeyValue >>= rValue.Handle ) )
2161                                     OSL_ENSURE( sal_False,
2162                                       "PersistentPropertySet::getPropertyValues - "
2163                                       "Error getting property handle!" );
2164                             }
2165                             catch ( NoSuchElementException& )
2166                             {
2167                                 // getByHierarchicalName
2168 
2169                                 OSL_ENSURE( sal_False,
2170                                   "PersistentPropertySet::getPropertyValues - "
2171                                   "NoSuchElementException!" );
2172                             }
2173 
2174                             try
2175                             {
2176                                 // Obtain and set property value
2177                                 OUString aHierName = aXMLName;
2178                                 aHierName += aValueName;
2179                                 rValue.Value
2180                                     = xHierNameAccess->getByHierarchicalName(
2181                                         aHierName );
2182 
2183                                 // Note: The value may be void if addProperty
2184                                 //       was called with a default value
2185                                 //       of type void.
2186                             }
2187                             catch ( NoSuchElementException& )
2188                             {
2189                                 // getByHierarchicalName
2190 
2191                                 OSL_ENSURE( sal_False,
2192                                   "PersistentPropertySet::getPropertyValues - "
2193                                   "NoSuchElementException!" );
2194                             }
2195 
2196                             try
2197                             {
2198                                 // Obtain and set property state
2199                                 OUString aHierName = aXMLName;
2200                                 aHierName += aStateName;
2201                                 Any aKeyValue
2202                                     = xHierNameAccess->getByHierarchicalName(
2203                                         aHierName );
2204 
2205                                 sal_Int32 nState = 0;
2206                                 if ( !( aKeyValue >>= nState ) )
2207                                     OSL_ENSURE( sal_False,
2208                                       "PersistentPropertySet::getPropertyValues - "
2209                                       "Error getting property state!" );
2210                                 else
2211                                     rValue.State = PropertyState( nState );
2212                             }
2213                             catch ( NoSuchElementException& )
2214                             {
2215                                 // getByHierarchicalName
2216 
2217                                 OSL_ENSURE( sal_False,
2218                                   "PersistentPropertySet::getPropertyValues - "
2219                                   "NoSuchElementException!" );
2220                             }
2221                         }
2222 
2223                         return aValues;
2224                     }
2225                 }
2226             }
2227         }
2228         catch ( NoSuchElementException& )
2229         {
2230             // getByHierarchicalName
2231         }
2232     }
2233 
2234     return Sequence< PropertyValue >( 0 );
2235 }
2236 
2237 //=========================================================================
2238 // virtual
setPropertyValues(const Sequence<PropertyValue> & aProps)2239 void SAL_CALL PersistentPropertySet::setPropertyValues(
2240                                 const Sequence< PropertyValue >& aProps )
2241     throw( UnknownPropertyException,
2242            PropertyVetoException,
2243            IllegalArgumentException,
2244            WrappedTargetException,
2245            RuntimeException )
2246 {
2247     sal_Int32 nCount = aProps.getLength();
2248     if ( !nCount )
2249         return;
2250 
2251     osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex );
2252 
2253     Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2254                 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
2255     if ( xRootHierNameAccess.is() )
2256     {
2257         const PropertyValue* pNewValues = aProps.getConstArray();
2258 
2259         typedef std::list< PropertyChangeEvent > Events;
2260         Events aEvents;
2261 
2262         OUString aFullPropNamePrefix( getFullKey() );
2263         aFullPropNamePrefix += OUString::createFromAscii( "/" );
2264 
2265         // Iterate over given property value sequence.
2266         for ( sal_Int32 n = 0; n < nCount; ++n )
2267         {
2268             const PropertyValue& rNewValue = pNewValues[ n ];
2269             const OUString& rName = rNewValue.Name;
2270 
2271             OUString aFullPropName = aFullPropNamePrefix;
2272             aFullPropName += makeHierarchalNameSegment( rName );
2273 
2274             // Does property exist?
2275             if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
2276             {
2277                 Reference< XNameReplace > xNameReplace(
2278                     m_pImpl->m_pCreator->getConfigWriteAccess(
2279                                             aFullPropName ), UNO_QUERY );
2280                 Reference< XChangesBatch > xBatch(
2281                     m_pImpl->m_pCreator->getConfigWriteAccess(
2282                                             OUString() ), UNO_QUERY );
2283 
2284                 if ( xNameReplace.is() && xBatch.is() )
2285                 {
2286                     try
2287                     {
2288                         // Write handle
2289                         xNameReplace->replaceByName(
2290                                     OUString::createFromAscii( "Handle" ),
2291                                     makeAny( rNewValue.Handle ) );
2292 
2293                         // Save old value
2294                         OUString aValueName = aFullPropName;
2295                         aValueName += OUString::createFromAscii( "/Value" );
2296                         Any aOldValue
2297                             = xRootHierNameAccess->getByHierarchicalName(
2298                                                                 aValueName );
2299                         // Write value
2300                         xNameReplace->replaceByName(
2301                                     OUString::createFromAscii( "Value" ),
2302                                     rNewValue.Value );
2303 
2304                         // Write state ( Now it is a directly set value )
2305                         xNameReplace->replaceByName(
2306                                     OUString::createFromAscii( "State" ),
2307                                     makeAny(
2308                                         sal_Int32(
2309                                             PropertyState_DIRECT_VALUE ) ) );
2310 
2311                         // Commit changes.
2312                         xBatch->commitChanges();
2313 
2314                         if ( m_pImpl->m_pPropertyChangeListeners )
2315                         {
2316                             PropertyChangeEvent aEvt;
2317                             aEvt.Source         = (OWeakObject*)this;
2318                             aEvt.PropertyName   = rNewValue.Name;
2319                             aEvt.PropertyHandle = rNewValue.Handle;
2320                             aEvt.Further        = sal_False;
2321                             aEvt.OldValue       = aOldValue;
2322                             aEvt.NewValue       = rNewValue.Value;
2323 
2324                             aEvents.push_back( aEvt );
2325                         }
2326                     }
2327                     catch ( IllegalArgumentException& )
2328                     {
2329                         // replaceByName
2330                     }
2331                     catch ( NoSuchElementException& )
2332                     {
2333                         // getByHierarchicalName, replaceByName
2334                     }
2335                     catch ( WrappedTargetException& )
2336                     {
2337                         // replaceByName, commitChanges
2338                     }
2339                 }
2340             }
2341         }
2342 
2343         // Callback follows!
2344         aCGuard.clear();
2345 
2346         if ( m_pImpl->m_pPropertyChangeListeners )
2347         {
2348             // Notify property changes.
2349             Events::const_iterator it  = aEvents.begin();
2350             Events::const_iterator end = aEvents.end();
2351 
2352             while ( it != end )
2353             {
2354                 notifyPropertyChangeEvent( (*it) );
2355                 it++;
2356             }
2357         }
2358 
2359         return;
2360     }
2361 
2362     OSL_ENSURE( sal_False,
2363                 "PersistentPropertySet::setPropertyValues - Nothing set!" );
2364 }
2365 
2366 //=========================================================================
2367 //
2368 // Non-interface methods
2369 //
2370 //=========================================================================
2371 
notifyPropertyChangeEvent(const PropertyChangeEvent & rEvent) const2372 void PersistentPropertySet::notifyPropertyChangeEvent(
2373                                     const PropertyChangeEvent& rEvent ) const
2374 {
2375     // Get "normal" listeners for the property.
2376     OInterfaceContainerHelper* pContainer =
2377             m_pImpl->m_pPropertyChangeListeners->getContainer(
2378                                                     rEvent.PropertyName );
2379     if ( pContainer && pContainer->getLength() )
2380     {
2381         OInterfaceIteratorHelper aIter( *pContainer );
2382         while ( aIter.hasMoreElements() )
2383         {
2384             // Propagate event.
2385             Reference< XPropertyChangeListener > xListener(
2386                                                     aIter.next(), UNO_QUERY );
2387             if ( xListener.is() )
2388                 xListener->propertyChange( rEvent );
2389         }
2390     }
2391 
2392     // Get "normal" listeners for all properties.
2393     OInterfaceContainerHelper* pNoNameContainer =
2394             m_pImpl->m_pPropertyChangeListeners->getContainer( OUString() );
2395     if ( pNoNameContainer && pNoNameContainer->getLength() )
2396     {
2397         OInterfaceIteratorHelper aIter( *pNoNameContainer );
2398         while ( aIter.hasMoreElements() )
2399         {
2400             // Propagate event.
2401             Reference< XPropertyChangeListener > xListener(
2402                                                     aIter.next(), UNO_QUERY );
2403             if ( xListener.is() )
2404                 xListener->propertyChange( rEvent );
2405         }
2406     }
2407 }
2408 
2409 //=========================================================================
notifyPropertySetInfoChange(const PropertySetInfoChangeEvent & evt) const2410 void PersistentPropertySet::notifyPropertySetInfoChange(
2411                                 const PropertySetInfoChangeEvent& evt ) const
2412 {
2413     if ( !m_pImpl->m_pPropSetChangeListeners )
2414         return;
2415 
2416     // Notify event listeners.
2417     OInterfaceIteratorHelper aIter( *( m_pImpl->m_pPropSetChangeListeners ) );
2418     while ( aIter.hasMoreElements() )
2419     {
2420         // Propagate event.
2421         Reference< XPropertySetInfoChangeListener >
2422                             xListener( aIter.next(), UNO_QUERY );
2423         if ( xListener.is() )
2424             xListener->propertySetInfoChange( evt );
2425     }
2426 }
2427 
2428 //=========================================================================
getFullKey()2429 const OUString& PersistentPropertySet::getFullKey()
2430 {
2431     if ( !m_pImpl->m_aFullKey.getLength() )
2432     {
2433         osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
2434         if ( !m_pImpl->m_aFullKey.getLength() )
2435         {
2436             m_pImpl->m_aFullKey
2437                 = makeHierarchalNameSegment( m_pImpl->m_aKey );
2438             m_pImpl->m_aFullKey
2439                 += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/Values" ) );
2440         }
2441     }
2442 
2443     return m_pImpl->m_aFullKey;
2444 }
2445 
2446 //=========================================================================
getPropertySetRegistry()2447 PropertySetRegistry& PersistentPropertySet::getPropertySetRegistry()
2448 {
2449     return *m_pImpl->m_pCreator;
2450 }
2451 
2452 //=========================================================================
2453 //=========================================================================
2454 //
2455 // PropertySetInfo_Impl Implementation.
2456 //
2457 //=========================================================================
2458 //=========================================================================
2459 
PropertySetInfo_Impl(const Reference<XMultiServiceFactory> & rxSMgr,PersistentPropertySet * pOwner)2460 PropertySetInfo_Impl::PropertySetInfo_Impl(
2461                         const Reference< XMultiServiceFactory >& rxSMgr,
2462                         PersistentPropertySet* pOwner )
2463 : m_xSMgr( rxSMgr ),
2464   m_pProps( NULL ),
2465   m_pOwner( pOwner )
2466 {
2467 }
2468 
2469 //=========================================================================
2470 // virtual
~PropertySetInfo_Impl()2471 PropertySetInfo_Impl::~PropertySetInfo_Impl()
2472 {
2473     delete m_pProps;
2474 
2475     // !!! Do not delete m_pOwner !!!
2476 }
2477 
2478 //=========================================================================
2479 //
2480 // XInterface methods.
2481 //
2482 //=========================================================================
2483 
2484 XINTERFACE_IMPL_2( PropertySetInfo_Impl,
2485                    XTypeProvider,
2486                    XPropertySetInfo );
2487 
2488 //=========================================================================
2489 //
2490 // XTypeProvider methods.
2491 //
2492 //=========================================================================
2493 
2494 XTYPEPROVIDER_IMPL_2( PropertySetInfo_Impl,
2495                       XTypeProvider,
2496                       XPropertySetInfo );
2497 
2498 //=========================================================================
2499 //
2500 // XPropertySetInfo methods.
2501 //
2502 //=========================================================================
2503 
2504 // virtual
getProperties()2505 Sequence< Property > SAL_CALL PropertySetInfo_Impl::getProperties()
2506     throw( RuntimeException )
2507 {
2508     if ( !m_pProps )
2509     {
2510         Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2511             m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2512             UNO_QUERY );
2513         if ( xRootHierNameAccess.is() )
2514         {
2515             try
2516             {
2517                 Reference< XNameAccess > xNameAccess;
2518                 xRootHierNameAccess->getByHierarchicalName(
2519                             m_pOwner->getFullKey() )
2520                     >>= xNameAccess;
2521                 if ( xNameAccess.is() )
2522                 {
2523                     // Obtain property names.
2524 
2525                     Sequence< OUString > aElems
2526                                             = xNameAccess->getElementNames();
2527 
2528                     sal_uInt32 nCount = aElems.getLength();
2529                     Sequence< Property >* pPropSeq
2530                                         = new Sequence< Property >( nCount );
2531 
2532                     if ( nCount )
2533                     {
2534                         Reference< XHierarchicalNameAccess > xHierNameAccess(
2535                                                     xNameAccess, UNO_QUERY );
2536 
2537                         OSL_ENSURE( xHierNameAccess.is(),
2538                                     "PropertySetInfo_Impl::getProperties - "
2539                                     "No hierarchical name access!" );
2540 
2541                         if ( xHierNameAccess.is() )
2542                         {
2543                             const OUString aHandleName
2544                                 = OUString::createFromAscii( "/Handle" );
2545                             const OUString aValueName
2546                                 = OUString::createFromAscii( "/Value" );
2547                             const OUString aAttrName
2548                                 = OUString::createFromAscii( "/Attributes" );
2549 
2550                             Property* pProps = pPropSeq->getArray();
2551 
2552                             for ( sal_uInt32 n = 0; n < nCount; ++n )
2553                             {
2554                                 Property& rProp = pProps[ n ];
2555                                 OUString  rName = aElems[ n ];
2556                                 OUString aXMLName
2557                                     = makeHierarchalNameSegment( rName );
2558 
2559                                 // Set property name.
2560 
2561                                 rProp.Name = rName;
2562 
2563                                 try
2564                                 {
2565                                     // Obtain and set property handle
2566                                     rtl::OUString aHierName = aXMLName;
2567                                     aHierName += aHandleName;
2568                                     Any aKeyValue
2569                                         = xHierNameAccess->getByHierarchicalName(
2570                                             aHierName );
2571 
2572                                     if ( !( aKeyValue >>= rProp.Handle ) )
2573                                         OSL_ENSURE( sal_False,
2574                                         "PropertySetInfo_Impl::getProperties - "
2575                                         "Error getting property handle!" );
2576                                 }
2577                                 catch ( NoSuchElementException& )
2578                                 {
2579                                     // getByHierarchicalName
2580 
2581                                     OSL_ENSURE( sal_False,
2582                                     "PropertySetInfo_Impl::getProperties - "
2583                                     "NoSuchElementException!" );
2584                                 }
2585 
2586                                 try
2587                                 {
2588                                     // Obtain and set property type
2589                                     rtl::OUString aHierName = aXMLName;
2590                                     aHierName += aValueName;
2591                                     Any aKeyValue
2592                                         = xHierNameAccess->getByHierarchicalName(
2593                                             aHierName );
2594 
2595                                     // Note: The type may be void if addProperty
2596                                     //       was called with a default value
2597                                     //       of type void.
2598 
2599                                     rProp.Type = aKeyValue.getValueType();
2600                                 }
2601                                 catch ( NoSuchElementException& )
2602                                 {
2603                                     // getByHierarchicalName
2604 
2605                                     OSL_ENSURE( sal_False,
2606                                     "PropertySetInfo_Impl::getProperties - "
2607                                     "NoSuchElementException!" );
2608                                 }
2609 
2610                                 try
2611                                 {
2612                                     // Obtain and set property attributes
2613                                     rtl::OUString aHierName = aXMLName;
2614                                     aHierName += aAttrName;
2615                                     Any aKeyValue
2616                                         = xHierNameAccess->getByHierarchicalName(
2617                                             aHierName );
2618 
2619                                     sal_Int32 nAttribs = 0;
2620                                     if ( aKeyValue >>= nAttribs )
2621                                         rProp.Attributes
2622                                             = sal_Int16( nAttribs );
2623                                     else
2624                                         OSL_ENSURE( sal_False,
2625                                         "PropertySetInfo_Impl::getProperties - "
2626                                         "Error getting property attributes!" );
2627                                 }
2628                                 catch ( NoSuchElementException& )
2629                                 {
2630                                     // getByHierarchicalName
2631 
2632                                     OSL_ENSURE( sal_False,
2633                                     "PropertySetInfo_Impl::getProperties - "
2634                                     "NoSuchElementException!" );
2635                                 }
2636                             }
2637                         }
2638                     }
2639 
2640                     // Success.
2641                     m_pProps = pPropSeq;
2642                     return *m_pProps;
2643                 }
2644             }
2645             catch ( NoSuchElementException& )
2646             {
2647                 // getByHierarchicalName
2648             }
2649         }
2650 
2651         OSL_ENSURE( sal_False, "PropertySetInfo_Impl::getProperties - Error!" );
2652         m_pProps = new Sequence< Property >( 0 );
2653     }
2654 
2655     return *m_pProps;
2656 }
2657 
2658 //=========================================================================
2659 // virtual
getPropertyByName(const OUString & aName)2660 Property SAL_CALL PropertySetInfo_Impl::getPropertyByName(
2661                                                     const OUString& aName )
2662     throw( UnknownPropertyException, RuntimeException )
2663 {
2664     Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2665             m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2666             UNO_QUERY );
2667     if ( xRootHierNameAccess.is() )
2668     {
2669         OUString aFullPropName( m_pOwner->getFullKey() );
2670         aFullPropName += OUString::createFromAscii( "/" );
2671         aFullPropName += makeHierarchalNameSegment( aName );
2672 
2673         // Does property exist?
2674         if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
2675             throw UnknownPropertyException();
2676 
2677         try
2678         {
2679             Property aProp;
2680 
2681             // Obtain handle.
2682             OUString aKey = aFullPropName;
2683             aKey += OUString::createFromAscii( "/Handle" );
2684 
2685             if ( !( xRootHierNameAccess->getByHierarchicalName( aKey )
2686                     >>= aProp.Handle ) )
2687             {
2688                 OSL_ENSURE( sal_False,
2689                             "PropertySetInfo_Impl::getPropertyByName - "
2690                             "No handle!" );
2691                 return Property();
2692             }
2693 
2694             // Obtain Value and extract type.
2695             aKey = aFullPropName;
2696             aKey += OUString::createFromAscii( "/Value" );
2697 
2698             Any aValue = xRootHierNameAccess->getByHierarchicalName( aKey );
2699             if ( !aValue.hasValue() )
2700             {
2701                 OSL_ENSURE( sal_False,
2702                             "PropertySetInfo_Impl::getPropertyByName - "
2703                             "No Value!" );
2704                 return Property();
2705             }
2706 
2707             aProp.Type = aValue.getValueType();
2708 
2709             // Obtain Attributes.
2710             aKey = aFullPropName;
2711             aKey += OUString::createFromAscii( "/Attributes" );
2712 
2713             sal_Int32 nAttribs = 0;
2714             if ( xRootHierNameAccess->getByHierarchicalName( aKey )
2715                     >>= nAttribs )
2716                 aProp.Attributes = sal_Int16( nAttribs );
2717             else
2718             {
2719                 OSL_ENSURE( sal_False,
2720                             "PropertySetInfo_Impl::getPropertyByName - "
2721                             "No attributes!" );
2722                 return Property();
2723             }
2724 
2725             // set name.
2726             aProp.Name = aName;
2727 
2728             // Success.
2729             return aProp;
2730         }
2731         catch ( NoSuchElementException& )
2732         {
2733             // getByHierarchicalName
2734 
2735             OSL_ENSURE( sal_False,
2736                         "PropertySetInfo_Impl::getPropertyByName - "
2737                         "caught NoSuchElementException!" );
2738         }
2739 
2740     }
2741 
2742     OSL_ENSURE( sal_False, "PropertySetInfo_Impl::getPropertyByName - Error!" );
2743     return Property();
2744 }
2745 
2746 //=========================================================================
2747 // virtual
hasPropertyByName(const OUString & Name)2748 sal_Bool SAL_CALL PropertySetInfo_Impl::hasPropertyByName(
2749                                                     const OUString& Name )
2750     throw( RuntimeException )
2751 {
2752     Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2753             m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2754             UNO_QUERY );
2755     if ( xRootHierNameAccess.is() )
2756     {
2757         OUString aFullPropName( m_pOwner->getFullKey() );
2758         aFullPropName += OUString::createFromAscii( "/" );
2759         aFullPropName += makeHierarchalNameSegment( Name );
2760 
2761         return xRootHierNameAccess->hasByHierarchicalName( aFullPropName );
2762     }
2763 
2764     return sal_False;
2765 }
2766 
2767