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