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