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