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( "&" );
67 break;
68
69 case '"':
70 aBuffer.appendAscii( """ );
71 break;
72
73 case '\'':
74 aBuffer.appendAscii( "'" );
75 break;
76
77 case '<':
78 aBuffer.appendAscii( "<" );
79 break;
80
81 case '>':
82 aBuffer.appendAscii( ">" );
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