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