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