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