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 0 : OUString makeHierarchalNameSegment( const OUString & rIn )
55 : {
56 0 : OUStringBuffer aBuffer;
57 0 : aBuffer.appendAscii( "['" );
58 :
59 0 : sal_Int32 nCount = rIn.getLength();
60 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
61 : {
62 0 : const sal_Unicode c = rIn[ n ];
63 0 : 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 0 : aBuffer.append( c );
87 0 : break;
88 : }
89 : }
90 :
91 0 : aBuffer.appendAscii( "']" );
92 0 : 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 0 : 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 0 : UcbStore::UcbStore( const Reference< XComponentContext >& xContext )
171 : : m_xContext( xContext ),
172 0 : m_pImpl( new UcbStore_Impl() )
173 : {
174 0 : }
175 :
176 :
177 : // virtual
178 0 : UcbStore::~UcbStore()
179 : {
180 0 : delete m_pImpl;
181 0 : }
182 :
183 :
184 0 : 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 0 : ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore );
195 :
196 :
197 :
198 : // XPropertySetRegistryFactory methods.
199 :
200 :
201 :
202 : // virtual
203 : Reference< XPropertySetRegistry > SAL_CALL
204 0 : 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 0 : if ( !m_pImpl->m_xTheRegistry.is() )
211 : {
212 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
213 0 : if ( !m_pImpl->m_xTheRegistry.is() )
214 0 : m_pImpl->m_xTheRegistry = new PropertySetRegistry( m_xContext, getInitArgs() );
215 : }
216 :
217 0 : 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 0 : const Sequence< Any >& UcbStore::getInitArgs() const
236 : {
237 0 : return m_pImpl->m_aInitArgs;
238 : }
239 :
240 :
241 :
242 : // PropertySetRegistry_Impl.
243 :
244 :
245 :
246 0 : 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 : sal_Bool m_bTriedToGetRootReadAccess; // #82494#
255 : sal_Bool m_bTriedToGetRootWriteAccess; // #82494#
256 :
257 0 : PropertySetRegistry_Impl( const Sequence< Any > &rInitArgs )
258 : : m_aInitArgs( rInitArgs ),
259 : m_bTriedToGetRootReadAccess( sal_False ),
260 0 : m_bTriedToGetRootWriteAccess( sal_False )
261 : {
262 0 : }
263 : };
264 :
265 :
266 :
267 :
268 :
269 : // PropertySetRegistry Implementation.
270 :
271 :
272 :
273 :
274 :
275 0 : PropertySetRegistry::PropertySetRegistry(
276 : const Reference< XComponentContext >& xContext,
277 : const Sequence< Any > &rInitArgs )
278 : : m_xContext( xContext ),
279 0 : m_pImpl( new PropertySetRegistry_Impl( rInitArgs ) )
280 : {
281 0 : }
282 :
283 :
284 : // virtual
285 0 : PropertySetRegistry::~PropertySetRegistry()
286 : {
287 0 : delete m_pImpl;
288 0 : }
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 0 : PropertySetRegistry::openPropertySet( const OUString& key, sal_Bool create )
309 : throw( RuntimeException, std::exception )
310 : {
311 0 : if ( !key.isEmpty() )
312 : {
313 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
314 :
315 0 : PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets;
316 :
317 0 : PropertySetMap_Impl::const_iterator it = rSets.find( key );
318 0 : if ( it != rSets.end() )
319 : {
320 : // Already instanciated.
321 0 : return Reference< XPersistentPropertySet >( (*it).second );
322 : }
323 : else
324 : {
325 : // Create new instance.
326 : Reference< XNameAccess > xRootNameAccess(
327 0 : getRootConfigReadAccess(), UNO_QUERY );
328 0 : if ( xRootNameAccess.is() )
329 : {
330 : // Propertyset in registry?
331 0 : if ( xRootNameAccess->hasByName( key ) )
332 : {
333 : // Yep!
334 : return Reference< XPersistentPropertySet >(
335 : new PersistentPropertySet(
336 0 : m_xContext, *this, key ) );
337 : }
338 0 : else if ( create )
339 : {
340 : // No. Create entry for propertyset.
341 :
342 : Reference< XSingleServiceFactory > xFac(
343 0 : getConfigWriteAccess( OUString() ), UNO_QUERY );
344 0 : Reference< XChangesBatch > xBatch( xFac, UNO_QUERY );
345 0 : 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 conteiner!" );
358 :
359 0 : if ( xFac.is() && xBatch.is() && xContainer.is() )
360 : {
361 : try
362 : {
363 : // Create new "Properties" config item.
364 : Reference< XNameReplace > xNameReplace(
365 0 : xFac->createInstance(), UNO_QUERY );
366 :
367 0 : 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 0 : xContainer->insertByName(
378 0 : key, makeAny( xNameReplace ) );
379 : // Commit changes.
380 0 : xBatch->commitChanges();
381 :
382 : return Reference< XPersistentPropertySet >(
383 : new PersistentPropertySet(
384 0 : 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 0 : return Reference< XPersistentPropertySet >();
426 : }
427 : }
428 :
429 0 : OSL_TRACE( "PropertySetRegistry::openPropertySet no root access" );
430 0 : }
431 : }
432 :
433 0 : return Reference< XPersistentPropertySet >();
434 : }
435 :
436 :
437 : // virtual
438 0 : void SAL_CALL PropertySetRegistry::removePropertySet( const OUString& key )
439 : throw( RuntimeException, std::exception )
440 : {
441 0 : if ( key.isEmpty() )
442 0 : return;
443 :
444 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
445 :
446 : Reference< XNameAccess > xRootNameAccess(
447 0 : getRootConfigReadAccess(), UNO_QUERY );
448 0 : if ( xRootNameAccess.is() )
449 : {
450 : // Propertyset in registry?
451 0 : if ( !xRootNameAccess->hasByName( key ) )
452 0 : 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 getCppuType( ( Reference< XPersistentPropertySet > * ) 0 );
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 0 : Sequence< OUString > SAL_CALL PropertySetRegistry::getElementNames()
558 : throw( RuntimeException, std::exception )
559 : {
560 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
561 :
562 : Reference< XNameAccess > xNameAccess(
563 0 : getRootConfigReadAccess(), UNO_QUERY );
564 0 : if ( xNameAccess.is() )
565 : {
566 0 : return xNameAccess->getElementNames();
567 : }
568 0 : 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 0 : void PropertySetRegistry::add( PersistentPropertySet* pSet )
590 : {
591 0 : OUString key( pSet->getKey() );
592 :
593 0 : if ( !key.isEmpty() )
594 : {
595 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
596 0 : m_pImpl->m_aPropSets[ key ] = pSet;
597 0 : }
598 0 : }
599 :
600 :
601 0 : void PropertySetRegistry::remove( PersistentPropertySet* pSet )
602 : {
603 0 : OUString key( pSet->getKey() );
604 :
605 0 : if ( !key.isEmpty() )
606 : {
607 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
608 :
609 0 : PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets;
610 :
611 0 : PropertySetMap_Impl::iterator it = rSets.find( key );
612 0 : if ( it != rSets.end() )
613 : {
614 : // Found.
615 0 : rSets.erase( it );
616 0 : }
617 0 : }
618 0 : }
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 0 : Reference< XMultiServiceFactory > PropertySetRegistry::getConfigProvider()
940 : {
941 0 : if ( !m_pImpl->m_xConfigProvider.is() )
942 : {
943 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
944 0 : if ( !m_pImpl->m_xConfigProvider.is() )
945 : {
946 0 : const Sequence< Any >& rInitArgs = m_pImpl->m_aInitArgs;
947 :
948 0 : 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 0 : 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 0 : }
970 : }
971 :
972 0 : return m_pImpl->m_xConfigProvider;
973 : }
974 :
975 :
976 0 : Reference< XInterface > PropertySetRegistry::getRootConfigReadAccess()
977 : {
978 : try
979 : {
980 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
981 :
982 0 : if ( !m_pImpl->m_xRootReadAccess.is() )
983 : {
984 0 : 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 0 : getConfigProvider();
992 :
993 0 : if ( m_pImpl->m_xConfigProvider.is() )
994 : {
995 0 : Sequence< Any > aArguments( 1 );
996 0 : PropertyValue aProperty;
997 : aProperty.Name
998 0 : = OUString( CFGPROPERTY_NODEPATH );
999 : aProperty.Value
1000 0 : <<= OUString( STORE_CONTENTPROPERTIES_KEY );
1001 0 : aArguments[ 0 ] <<= aProperty;
1002 :
1003 0 : m_pImpl->m_bTriedToGetRootReadAccess = sal_True;
1004 :
1005 0 : m_pImpl->m_xRootReadAccess =
1006 0 : m_pImpl->m_xConfigProvider->createInstanceWithArguments(
1007 : OUString( "com.sun.star.configuration.ConfigurationAccess" ),
1008 0 : aArguments );
1009 :
1010 0 : if ( m_pImpl->m_xRootReadAccess.is() )
1011 0 : return m_pImpl->m_xRootReadAccess;
1012 : }
1013 : }
1014 : else
1015 0 : 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 0 : Reference< XInterface > PropertySetRegistry::getConfigWriteAccess(
1035 : const OUString& rPath )
1036 : {
1037 : try
1038 : {
1039 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1040 :
1041 0 : if ( !m_pImpl->m_xRootWriteAccess.is() )
1042 : {
1043 0 : 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 0 : getConfigProvider();
1051 :
1052 0 : if ( m_pImpl->m_xConfigProvider.is() )
1053 : {
1054 0 : Sequence< Any > aArguments( 2 );
1055 0 : PropertyValue aProperty;
1056 :
1057 0 : aProperty.Name = OUString( CFGPROPERTY_NODEPATH );
1058 0 : aProperty.Value <<= OUString( STORE_CONTENTPROPERTIES_KEY );
1059 0 : aArguments[ 0 ] <<= aProperty;
1060 :
1061 0 : aProperty.Name = OUString( CFGPROPERTY_LAZYWRITE );
1062 0 : aProperty.Value <<= sal_True;
1063 0 : aArguments[ 1 ] <<= aProperty;
1064 :
1065 0 : m_pImpl->m_bTriedToGetRootWriteAccess = sal_True;
1066 :
1067 0 : m_pImpl->m_xRootWriteAccess =
1068 0 : m_pImpl->m_xConfigProvider->createInstanceWithArguments(
1069 : OUString( "com.sun.star.configuration.ConfigurationUpdateAccess" ),
1070 0 : aArguments );
1071 :
1072 : OSL_ENSURE( m_pImpl->m_xRootWriteAccess.is(),
1073 : "PropertySetRegistry::getConfigWriteAccess - "
1074 0 : "No config update access!" );
1075 : }
1076 : }
1077 :
1078 0 : if ( m_pImpl->m_xRootWriteAccess.is() )
1079 : {
1080 0 : if ( !rPath.isEmpty() )
1081 : {
1082 : Reference< XHierarchicalNameAccess > xNA(
1083 0 : m_pImpl->m_xRootWriteAccess, UNO_QUERY );
1084 0 : if ( xNA.is() )
1085 : {
1086 0 : Reference< XInterface > xInterface;
1087 0 : xNA->getByHierarchicalName( rPath ) >>= xInterface;
1088 :
1089 0 : if ( xInterface.is() )
1090 0 : return xInterface;
1091 0 : }
1092 : }
1093 : else
1094 0 : 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 :
1123 :
1124 : // PropertyListeners_Impl.
1125 :
1126 :
1127 :
1128 : typedef OMultiTypeInterfaceContainerHelperVar
1129 : <
1130 : OUString,
1131 : OUStringHash
1132 : > PropertyListeners_Impl;
1133 :
1134 :
1135 :
1136 : // PersistentPropertySet_Impl.
1137 :
1138 :
1139 :
1140 : struct PersistentPropertySet_Impl
1141 : {
1142 : PropertySetRegistry* m_pCreator;
1143 : PropertySetInfo_Impl* m_pInfo;
1144 : OUString m_aKey;
1145 : OUString m_aFullKey;
1146 : osl::Mutex m_aMutex;
1147 : OInterfaceContainerHelper* m_pDisposeEventListeners;
1148 : OInterfaceContainerHelper* m_pPropSetChangeListeners;
1149 : PropertyListeners_Impl* m_pPropertyChangeListeners;
1150 :
1151 0 : PersistentPropertySet_Impl( PropertySetRegistry& rCreator,
1152 : const OUString& rKey )
1153 : : m_pCreator( &rCreator ), m_pInfo( NULL ), m_aKey( rKey ),
1154 : m_pDisposeEventListeners( NULL ), m_pPropSetChangeListeners( NULL ),
1155 0 : m_pPropertyChangeListeners( NULL )
1156 : {
1157 0 : m_pCreator->acquire();
1158 0 : }
1159 :
1160 0 : ~PersistentPropertySet_Impl()
1161 0 : {
1162 0 : m_pCreator->release();
1163 :
1164 0 : if ( m_pInfo )
1165 0 : m_pInfo->release();
1166 :
1167 0 : delete m_pDisposeEventListeners;
1168 0 : delete m_pPropSetChangeListeners;
1169 0 : delete m_pPropertyChangeListeners;
1170 0 : }
1171 : };
1172 :
1173 :
1174 :
1175 :
1176 :
1177 : // PersistentPropertySet Implementation.
1178 :
1179 :
1180 :
1181 :
1182 :
1183 0 : PersistentPropertySet::PersistentPropertySet(
1184 : const Reference< XComponentContext >& xContext,
1185 : PropertySetRegistry& rCreator,
1186 : const OUString& rKey )
1187 : : m_xContext( xContext ),
1188 0 : m_pImpl( new PersistentPropertySet_Impl( rCreator, rKey ) )
1189 : {
1190 : // register at creator.
1191 0 : rCreator.add( this );
1192 0 : }
1193 :
1194 :
1195 : // virtual
1196 0 : PersistentPropertySet::~PersistentPropertySet()
1197 : {
1198 : // deregister at creator.
1199 0 : m_pImpl->m_pCreator->remove( this );
1200 :
1201 0 : delete m_pImpl;
1202 0 : }
1203 :
1204 : // XServiceInfo methods.
1205 :
1206 :
1207 :
1208 0 : XSERVICEINFO_NOFACTORY_IMPL_1( PersistentPropertySet,
1209 : OUString( "com.sun.star.comp.ucb.PersistentPropertySet" ),
1210 : OUString( PERS_PROPSET_SERVICE_NAME ) );
1211 :
1212 :
1213 :
1214 : // XComponent methods.
1215 :
1216 :
1217 :
1218 : // virtual
1219 0 : void SAL_CALL PersistentPropertySet::dispose()
1220 : throw( RuntimeException, std::exception )
1221 : {
1222 0 : if ( m_pImpl->m_pDisposeEventListeners &&
1223 0 : m_pImpl->m_pDisposeEventListeners->getLength() )
1224 : {
1225 0 : EventObject aEvt;
1226 0 : aEvt.Source = static_cast< XComponent * >( this );
1227 0 : m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt );
1228 : }
1229 :
1230 0 : if ( m_pImpl->m_pPropSetChangeListeners &&
1231 0 : m_pImpl->m_pPropSetChangeListeners->getLength() )
1232 : {
1233 0 : EventObject aEvt;
1234 0 : aEvt.Source = static_cast< XPropertySetInfoChangeNotifier * >( this );
1235 0 : m_pImpl->m_pPropSetChangeListeners->disposeAndClear( aEvt );
1236 : }
1237 :
1238 0 : if ( m_pImpl->m_pPropertyChangeListeners )
1239 : {
1240 0 : EventObject aEvt;
1241 0 : aEvt.Source = static_cast< XPropertySet * >( this );
1242 0 : m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt );
1243 : }
1244 0 : }
1245 :
1246 :
1247 : // virtual
1248 0 : void SAL_CALL PersistentPropertySet::addEventListener(
1249 : const Reference< XEventListener >& Listener )
1250 : throw( RuntimeException, std::exception )
1251 : {
1252 0 : if ( !m_pImpl->m_pDisposeEventListeners )
1253 : m_pImpl->m_pDisposeEventListeners =
1254 0 : new OInterfaceContainerHelper( m_pImpl->m_aMutex );
1255 :
1256 0 : m_pImpl->m_pDisposeEventListeners->addInterface( Listener );
1257 0 : }
1258 :
1259 :
1260 : // virtual
1261 0 : void SAL_CALL PersistentPropertySet::removeEventListener(
1262 : const Reference< XEventListener >& Listener )
1263 : throw( RuntimeException, std::exception )
1264 : {
1265 0 : if ( m_pImpl->m_pDisposeEventListeners )
1266 0 : m_pImpl->m_pDisposeEventListeners->removeInterface( Listener );
1267 :
1268 : // Note: Don't want to delete empty container here -> performance.
1269 0 : }
1270 :
1271 :
1272 :
1273 : // XPropertySet methods.
1274 :
1275 :
1276 :
1277 : // virtual
1278 0 : Reference< XPropertySetInfo > SAL_CALL PersistentPropertySet::getPropertySetInfo()
1279 : throw( RuntimeException, std::exception )
1280 : {
1281 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1282 :
1283 0 : PropertySetInfo_Impl*& rpInfo = m_pImpl->m_pInfo;
1284 0 : if ( !rpInfo )
1285 : {
1286 0 : rpInfo = new PropertySetInfo_Impl( m_xContext, this );
1287 0 : rpInfo->acquire();
1288 : }
1289 0 : return Reference< XPropertySetInfo >( rpInfo );
1290 : }
1291 :
1292 :
1293 : // virtual
1294 0 : void SAL_CALL PersistentPropertySet::setPropertyValue( const OUString& aPropertyName,
1295 : const Any& aValue )
1296 : throw( UnknownPropertyException,
1297 : PropertyVetoException,
1298 : IllegalArgumentException,
1299 : WrappedTargetException,
1300 : RuntimeException,
1301 : std::exception )
1302 : {
1303 0 : if ( aPropertyName.isEmpty() )
1304 0 : throw UnknownPropertyException();
1305 :
1306 0 : osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex );
1307 :
1308 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1309 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1310 0 : if ( xRootHierNameAccess.is() )
1311 : {
1312 0 : OUString aFullPropName( getFullKey() );
1313 0 : aFullPropName += "/";
1314 0 : aFullPropName += makeHierarchalNameSegment( aPropertyName );
1315 :
1316 : // Does property exist?
1317 0 : if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1318 : {
1319 : Reference< XNameReplace > xNameReplace(
1320 : m_pImpl->m_pCreator->getConfigWriteAccess(
1321 0 : aFullPropName ), UNO_QUERY );
1322 : Reference< XChangesBatch > xBatch(
1323 : m_pImpl->m_pCreator->getConfigWriteAccess(
1324 0 : OUString() ), UNO_QUERY );
1325 :
1326 0 : if ( xNameReplace.is() && xBatch.is() )
1327 : {
1328 : try
1329 : {
1330 : // Obtain old value
1331 0 : OUString aValueName = aFullPropName;
1332 0 : aValueName += "/Value";
1333 : Any aOldValue
1334 0 : = xRootHierNameAccess->getByHierarchicalName(
1335 0 : aValueName );
1336 : // Check value type.
1337 0 : if ( aOldValue.getValueType() != aValue.getValueType() )
1338 : {
1339 0 : aCGuard.clear();
1340 0 : throw IllegalArgumentException();
1341 : }
1342 :
1343 : // Write value
1344 0 : xNameReplace->replaceByName(
1345 : OUString("Value"),
1346 0 : aValue );
1347 :
1348 : // Write state ( Now it is a directly set value )
1349 0 : xNameReplace->replaceByName(
1350 : OUString("State"),
1351 : makeAny(
1352 : sal_Int32(
1353 0 : PropertyState_DIRECT_VALUE ) ) );
1354 :
1355 : // Commit changes.
1356 0 : xBatch->commitChanges();
1357 :
1358 0 : PropertyChangeEvent aEvt;
1359 0 : if ( m_pImpl->m_pPropertyChangeListeners )
1360 : {
1361 : // Obtain handle
1362 0 : aValueName = aFullPropName;
1363 0 : aValueName += "/Handle";
1364 0 : sal_Int32 nHandle = -1;
1365 0 : xRootHierNameAccess->getByHierarchicalName( aValueName )
1366 0 : >>= nHandle;
1367 :
1368 0 : aEvt.Source = (OWeakObject*)this;
1369 0 : aEvt.PropertyName = aPropertyName;
1370 0 : aEvt.PropertyHandle = nHandle;
1371 0 : aEvt.Further = sal_False;
1372 0 : aEvt.OldValue = aOldValue;
1373 0 : aEvt.NewValue = aValue;
1374 :
1375 : // Callback follows!
1376 0 : aCGuard.clear();
1377 :
1378 0 : notifyPropertyChangeEvent( aEvt );
1379 : }
1380 0 : return;
1381 : }
1382 0 : catch (const IllegalArgumentException&)
1383 : {
1384 : // replaceByName
1385 : }
1386 0 : catch (const NoSuchElementException&)
1387 : {
1388 : // getByHierarchicalName, replaceByName
1389 : }
1390 0 : catch (const WrappedTargetException&)
1391 : {
1392 : // replaceByName, commitChanges
1393 : }
1394 0 : }
1395 0 : }
1396 : }
1397 :
1398 0 : throw UnknownPropertyException();
1399 : }
1400 :
1401 :
1402 : // virtual
1403 0 : Any SAL_CALL PersistentPropertySet::getPropertyValue(
1404 : const OUString& PropertyName )
1405 : throw( UnknownPropertyException,
1406 : WrappedTargetException,
1407 : RuntimeException, std::exception )
1408 : {
1409 0 : if ( PropertyName.isEmpty() )
1410 0 : throw UnknownPropertyException();
1411 :
1412 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1413 :
1414 : Reference< XHierarchicalNameAccess > xNameAccess(
1415 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1416 0 : if ( xNameAccess.is() )
1417 : {
1418 0 : OUString aFullPropName( getFullKey() );
1419 0 : aFullPropName += "/";
1420 0 : aFullPropName += makeHierarchalNameSegment( PropertyName );
1421 0 : aFullPropName += "/Value";
1422 : try
1423 : {
1424 0 : return xNameAccess->getByHierarchicalName( aFullPropName );
1425 : }
1426 0 : catch (const NoSuchElementException&)
1427 : {
1428 0 : throw UnknownPropertyException();
1429 0 : }
1430 : }
1431 :
1432 0 : throw UnknownPropertyException();
1433 : }
1434 :
1435 :
1436 : // virtual
1437 0 : void SAL_CALL PersistentPropertySet::addPropertyChangeListener(
1438 : const OUString& aPropertyName,
1439 : const Reference< XPropertyChangeListener >& xListener )
1440 : throw( UnknownPropertyException,
1441 : WrappedTargetException,
1442 : RuntimeException, std::exception )
1443 : {
1444 : // load();
1445 :
1446 0 : if ( !m_pImpl->m_pPropertyChangeListeners )
1447 : m_pImpl->m_pPropertyChangeListeners =
1448 0 : new PropertyListeners_Impl( m_pImpl->m_aMutex );
1449 :
1450 : m_pImpl->m_pPropertyChangeListeners->addInterface(
1451 0 : aPropertyName, xListener );
1452 0 : }
1453 :
1454 :
1455 : // virtual
1456 0 : void SAL_CALL PersistentPropertySet::removePropertyChangeListener(
1457 : const OUString& aPropertyName,
1458 : const Reference< XPropertyChangeListener >& aListener )
1459 : throw( UnknownPropertyException,
1460 : WrappedTargetException,
1461 : RuntimeException, std::exception )
1462 : {
1463 : // load();
1464 :
1465 0 : if ( m_pImpl->m_pPropertyChangeListeners )
1466 : m_pImpl->m_pPropertyChangeListeners->removeInterface(
1467 0 : aPropertyName, aListener );
1468 :
1469 : // Note: Don't want to delete empty container here -> performance.
1470 0 : }
1471 :
1472 :
1473 : // virtual
1474 0 : void SAL_CALL PersistentPropertySet::addVetoableChangeListener(
1475 : const OUString&,
1476 : const Reference< XVetoableChangeListener >& )
1477 : throw( UnknownPropertyException,
1478 : WrappedTargetException,
1479 : RuntimeException, std::exception )
1480 : {
1481 : // load();
1482 : // OSL_FAIL( // "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
1483 0 : }
1484 :
1485 :
1486 : // virtual
1487 0 : void SAL_CALL PersistentPropertySet::removeVetoableChangeListener(
1488 : const OUString&,
1489 : const Reference< XVetoableChangeListener >& )
1490 : throw( UnknownPropertyException,
1491 : WrappedTargetException,
1492 : RuntimeException, std::exception )
1493 : {
1494 : // load();
1495 : // OSL_FAIL( // "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
1496 0 : }
1497 :
1498 :
1499 :
1500 : // XPersistentPropertySet methods.
1501 :
1502 :
1503 :
1504 : // virtual
1505 0 : Reference< XPropertySetRegistry > SAL_CALL PersistentPropertySet::getRegistry()
1506 : throw( RuntimeException, std::exception )
1507 : {
1508 0 : return Reference< XPropertySetRegistry >( m_pImpl->m_pCreator );
1509 : }
1510 :
1511 :
1512 : // virtual
1513 0 : OUString SAL_CALL PersistentPropertySet::getKey()
1514 : throw( RuntimeException, std::exception )
1515 : {
1516 0 : return m_pImpl->m_aKey;
1517 : }
1518 :
1519 :
1520 :
1521 : // XNamed methods.
1522 :
1523 :
1524 :
1525 : // virtual
1526 0 : OUString SAL_CALL PersistentPropertySet::getName()
1527 : throw( RuntimeException, std::exception )
1528 : {
1529 : // same as getKey()
1530 0 : return m_pImpl->m_aKey;
1531 : }
1532 :
1533 :
1534 : // virtual
1535 0 : void SAL_CALL PersistentPropertySet::setName( const OUString& aName )
1536 : throw( RuntimeException, std::exception )
1537 : {
1538 0 : if ( aName != m_pImpl->m_aKey )
1539 0 : m_pImpl->m_pCreator->renamePropertySet( m_pImpl->m_aKey, aName );
1540 0 : }
1541 :
1542 :
1543 :
1544 : // XPropertyContainer methods.
1545 :
1546 :
1547 :
1548 : // virtual
1549 0 : void SAL_CALL PersistentPropertySet::addProperty(
1550 : const OUString& Name, sal_Int16 Attributes, const Any& DefaultValue )
1551 : throw( PropertyExistException,
1552 : IllegalTypeException,
1553 : IllegalArgumentException,
1554 : RuntimeException, std::exception )
1555 : {
1556 0 : if ( Name.isEmpty() )
1557 0 : throw IllegalArgumentException();
1558 :
1559 : // @@@ What other types can't be written to config server?
1560 :
1561 : // Check type class ( Not all types can be written to storage )
1562 0 : TypeClass eTypeClass = DefaultValue.getValueTypeClass();
1563 0 : if ( eTypeClass == TypeClass_INTERFACE )
1564 0 : throw IllegalTypeException();
1565 :
1566 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1567 :
1568 : // Property already in set?
1569 :
1570 0 : OUString aFullValuesName;
1571 :
1572 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1573 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1574 0 : if ( xRootHierNameAccess.is() )
1575 : {
1576 0 : aFullValuesName = getFullKey();
1577 0 : OUString aFullPropName = aFullValuesName;
1578 0 : aFullPropName += "/";
1579 0 : aFullPropName += makeHierarchalNameSegment( Name );
1580 :
1581 0 : if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1582 : {
1583 : // Already in set.
1584 0 : throw PropertyExistException();
1585 0 : }
1586 : }
1587 :
1588 : // Property is always removable.
1589 0 : Attributes |= PropertyAttribute::REMOVABLE;
1590 :
1591 : // Add property.
1592 :
1593 : Reference< XSingleServiceFactory > xFac(
1594 : m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ),
1595 0 : UNO_QUERY );
1596 0 : Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
1597 : Reference< XChangesBatch > xBatch(
1598 : m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ),
1599 0 : UNO_QUERY );
1600 :
1601 : OSL_ENSURE( xFac.is(),
1602 : "PersistentPropertySet::addProperty - No factory!" );
1603 :
1604 : OSL_ENSURE( xBatch.is(),
1605 : "PersistentPropertySet::addProperty - No batch!" );
1606 :
1607 : OSL_ENSURE( xContainer.is(),
1608 : "PersistentPropertySet::addProperty - No container!" );
1609 :
1610 0 : if ( xFac.is() && xBatch.is() && xContainer.is() )
1611 : {
1612 : try
1613 : {
1614 : // Create new "PropertyValue" config item.
1615 : Reference< XNameReplace > xNameReplace(
1616 0 : xFac->createInstance(), UNO_QUERY );
1617 :
1618 0 : if ( xNameReplace.is() )
1619 : {
1620 : // Fill new item...
1621 :
1622 : // Set handle
1623 0 : xNameReplace->replaceByName(
1624 : OUString("Handle"),
1625 0 : makeAny( sal_Int32( -1 ) ) );
1626 :
1627 : // Set default value
1628 0 : xNameReplace->replaceByName(
1629 : OUString("Value"),
1630 0 : DefaultValue );
1631 :
1632 : // Set state ( always "default" )
1633 0 : xNameReplace->replaceByName(
1634 : OUString("State"),
1635 : makeAny(
1636 : sal_Int32(
1637 0 : PropertyState_DEFAULT_VALUE ) ) );
1638 :
1639 : // Set attributes
1640 0 : xNameReplace->replaceByName(
1641 : OUString("Attributes"),
1642 0 : makeAny( sal_Int32( Attributes ) ) );
1643 :
1644 : // Insert new item.
1645 0 : xContainer->insertByName( Name, makeAny( xNameReplace ) );
1646 :
1647 : // Commit changes.
1648 0 : xBatch->commitChanges();
1649 :
1650 : // Property set info is invalid.
1651 0 : if ( m_pImpl->m_pInfo )
1652 0 : m_pImpl->m_pInfo->reset();
1653 :
1654 : // Notify propertyset info change listeners.
1655 0 : if ( m_pImpl->m_pPropSetChangeListeners &&
1656 0 : m_pImpl->m_pPropSetChangeListeners->getLength() )
1657 : {
1658 : PropertySetInfoChangeEvent evt(
1659 : static_cast< OWeakObject * >( this ),
1660 : Name,
1661 : -1,
1662 0 : PropertySetInfoChange::PROPERTY_INSERTED );
1663 0 : notifyPropertySetInfoChange( evt );
1664 : }
1665 :
1666 : // Success.
1667 0 : return;
1668 0 : }
1669 : }
1670 0 : catch (const IllegalArgumentException&)
1671 : {
1672 : // insertByName
1673 :
1674 : OSL_FAIL( "PersistentPropertySet::addProperty - "
1675 : "caught IllegalArgumentException!" );
1676 0 : return;
1677 : }
1678 0 : catch (const ElementExistException&)
1679 : {
1680 : // insertByName
1681 :
1682 : OSL_FAIL( "PersistentPropertySet::addProperty - "
1683 : "caught ElementExistException!" );
1684 0 : return;
1685 : }
1686 0 : catch (const WrappedTargetException&)
1687 : {
1688 : // replaceByName, insertByName, commitChanges
1689 :
1690 : OSL_FAIL( "PersistentPropertySet::addProperty - "
1691 : "caught WrappedTargetException!" );
1692 0 : return;
1693 : }
1694 0 : catch (const RuntimeException&)
1695 : {
1696 0 : throw;
1697 : }
1698 0 : catch (const Exception&)
1699 : {
1700 : // createInstance
1701 :
1702 : OSL_FAIL( "PersistentPropertySet::addProperty - "
1703 : "caught Exception!" );
1704 0 : return;
1705 : }
1706 : }
1707 :
1708 0 : OSL_FAIL( "PersistentPropertySet::addProperty - Error!" );
1709 : }
1710 :
1711 :
1712 : // virtual
1713 0 : void SAL_CALL PersistentPropertySet::removeProperty( const OUString& Name )
1714 : throw( UnknownPropertyException,
1715 : NotRemoveableException,
1716 : RuntimeException, std::exception )
1717 : {
1718 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1719 :
1720 0 : OUString aFullValuesName;
1721 0 : OUString aFullPropName;
1722 :
1723 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1724 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1725 0 : if ( xRootHierNameAccess.is() )
1726 : {
1727 0 : aFullValuesName = getFullKey();
1728 0 : aFullPropName = aFullValuesName;
1729 0 : aFullPropName += "/";
1730 0 : aFullPropName += makeHierarchalNameSegment( Name );
1731 :
1732 : // Property in set?
1733 0 : if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1734 0 : throw UnknownPropertyException();
1735 :
1736 : // Property removable?
1737 : try
1738 : {
1739 0 : OUString aFullAttrName = aFullPropName;
1740 0 : aFullAttrName += "/Attributes";
1741 :
1742 0 : sal_Int32 nAttribs = 0;
1743 0 : if ( xRootHierNameAccess->getByHierarchicalName( aFullAttrName )
1744 0 : >>= nAttribs )
1745 : {
1746 0 : if ( !( nAttribs & PropertyAttribute::REMOVABLE ) )
1747 : {
1748 : // Not removable!
1749 0 : throw NotRemoveableException();
1750 : }
1751 : }
1752 : else
1753 : {
1754 : OSL_FAIL( "PersistentPropertySet::removeProperty - "
1755 : "No attributes!" );
1756 0 : return;
1757 0 : }
1758 : }
1759 0 : catch (const NoSuchElementException&)
1760 : {
1761 : // getByHierarchicalName
1762 :
1763 : OSL_FAIL( "PersistentPropertySet::removeProperty - "
1764 : "caught NoSuchElementException!" );
1765 : }
1766 :
1767 : // Remove property...
1768 :
1769 : Reference< XNameContainer > xContainer(
1770 : m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ),
1771 0 : UNO_QUERY );
1772 : Reference< XChangesBatch > xBatch(
1773 : m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ),
1774 0 : UNO_QUERY );
1775 :
1776 : OSL_ENSURE( xBatch.is(),
1777 : "PersistentPropertySet::removeProperty - No batch!" );
1778 :
1779 : OSL_ENSURE( xContainer.is(),
1780 : "PersistentPropertySet::removeProperty - No container!" );
1781 :
1782 0 : if ( xBatch.is() && xContainer.is() )
1783 : {
1784 : try
1785 : {
1786 0 : sal_Int32 nHandle = -1;
1787 :
1788 0 : if ( m_pImpl->m_pPropSetChangeListeners &&
1789 0 : m_pImpl->m_pPropSetChangeListeners->getLength() )
1790 : {
1791 : // Obtain property handle ( needed for propertysetinfo
1792 : // change event )...
1793 :
1794 : try
1795 : {
1796 0 : OUString aFullHandleName = aFullPropName;
1797 : aFullHandleName
1798 0 : += "/Handle";
1799 :
1800 0 : if ( ! ( xRootHierNameAccess->getByHierarchicalName(
1801 0 : aFullHandleName ) >>= nHandle ) )
1802 0 : nHandle = -1;
1803 :
1804 : }
1805 0 : catch (const NoSuchElementException&)
1806 : {
1807 : // getByHierarchicalName
1808 :
1809 : OSL_FAIL( "PersistentPropertySet::removeProperty - "
1810 : "caught NoSuchElementException!" );
1811 0 : nHandle = -1;
1812 : }
1813 : }
1814 :
1815 0 : xContainer->removeByName( Name );
1816 0 : xBatch->commitChanges();
1817 :
1818 : // Property set info is invalid.
1819 0 : if ( m_pImpl->m_pInfo )
1820 0 : m_pImpl->m_pInfo->reset();
1821 :
1822 : // Notify propertyset info change listeners.
1823 0 : if ( m_pImpl->m_pPropSetChangeListeners &&
1824 0 : m_pImpl->m_pPropSetChangeListeners->getLength() )
1825 : {
1826 : PropertySetInfoChangeEvent evt(
1827 : static_cast< OWeakObject * >( this ),
1828 : Name,
1829 : nHandle,
1830 0 : PropertySetInfoChange::PROPERTY_REMOVED );
1831 0 : notifyPropertySetInfoChange( evt );
1832 : }
1833 :
1834 : // Success.
1835 0 : return;
1836 : }
1837 0 : catch (const NoSuchElementException&)
1838 : {
1839 : // removeByName
1840 :
1841 : OSL_FAIL( "PersistentPropertySet::removeProperty - "
1842 : "caught NoSuchElementException!" );
1843 0 : return;
1844 : }
1845 0 : catch (const WrappedTargetException&)
1846 : {
1847 : // commitChanges
1848 :
1849 : OSL_FAIL( "PersistentPropertySet::removeProperty - "
1850 : "caught WrappedTargetException!" );
1851 0 : return;
1852 : }
1853 0 : }
1854 : }
1855 :
1856 0 : OSL_FAIL( "PersistentPropertySet::removeProperty - Error!" );
1857 : }
1858 :
1859 :
1860 :
1861 : // XPropertySetInfoChangeNotifier methods.
1862 :
1863 :
1864 :
1865 : // virtual
1866 0 : void SAL_CALL PersistentPropertySet::addPropertySetInfoChangeListener(
1867 : const Reference< XPropertySetInfoChangeListener >& Listener )
1868 : throw( RuntimeException, std::exception )
1869 : {
1870 0 : if ( !m_pImpl->m_pPropSetChangeListeners )
1871 : m_pImpl->m_pPropSetChangeListeners =
1872 0 : new OInterfaceContainerHelper( m_pImpl->m_aMutex );
1873 :
1874 0 : m_pImpl->m_pPropSetChangeListeners->addInterface( Listener );
1875 0 : }
1876 :
1877 :
1878 : // virtual
1879 0 : void SAL_CALL PersistentPropertySet::removePropertySetInfoChangeListener(
1880 : const Reference< XPropertySetInfoChangeListener >& Listener )
1881 : throw( RuntimeException, std::exception )
1882 : {
1883 0 : if ( m_pImpl->m_pPropSetChangeListeners )
1884 0 : m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener );
1885 0 : }
1886 :
1887 :
1888 :
1889 : // XPropertyAccess methods.
1890 :
1891 :
1892 :
1893 : // virtual
1894 0 : Sequence< PropertyValue > SAL_CALL PersistentPropertySet::getPropertyValues()
1895 : throw( RuntimeException, std::exception )
1896 : {
1897 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
1898 :
1899 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1900 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1901 0 : if ( xRootHierNameAccess.is() )
1902 : {
1903 : try
1904 : {
1905 0 : Reference< XNameAccess > xNameAccess;
1906 0 : xRootHierNameAccess->getByHierarchicalName(getFullKey())
1907 0 : >>= xNameAccess;
1908 0 : if ( xNameAccess.is() )
1909 : {
1910 : // Obtain property names.
1911 :
1912 0 : Sequence< OUString > aElems = xNameAccess->getElementNames();
1913 :
1914 0 : sal_Int32 nCount = aElems.getLength();
1915 0 : if ( nCount )
1916 : {
1917 : Reference< XHierarchicalNameAccess > xHierNameAccess(
1918 0 : xNameAccess, UNO_QUERY );
1919 :
1920 : OSL_ENSURE( xHierNameAccess.is(),
1921 : "PersistentPropertySet::getPropertyValues - "
1922 : "No hierarchical name access!" );
1923 :
1924 0 : if ( xHierNameAccess.is() )
1925 : {
1926 0 : Sequence< PropertyValue > aValues( nCount );
1927 :
1928 0 : const OUString aHandleName("/Handle");
1929 0 : const OUString aValueName("/Value");
1930 0 : const OUString aStateName("/State");
1931 :
1932 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
1933 : {
1934 0 : PropertyValue& rValue = aValues[ n ];
1935 0 : OUString rName = aElems[ n ];
1936 : OUString aXMLName
1937 0 : = makeHierarchalNameSegment( rName );
1938 :
1939 : // Set property name.
1940 :
1941 0 : rValue.Name = rName;
1942 :
1943 : try
1944 : {
1945 : // Obtain and set property handle
1946 0 : OUString aHierName = aXMLName;
1947 0 : aHierName += aHandleName;
1948 : Any aKeyValue
1949 0 : = xHierNameAccess->getByHierarchicalName(
1950 0 : aHierName );
1951 :
1952 0 : if ( !( aKeyValue >>= rValue.Handle ) )
1953 : OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1954 0 : "Error getting property handle!" );
1955 : }
1956 0 : catch (const NoSuchElementException&)
1957 : {
1958 : // getByHierarchicalName
1959 :
1960 : OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1961 : "NoSuchElementException!" );
1962 : }
1963 :
1964 : try
1965 : {
1966 : // Obtain and set property value
1967 0 : OUString aHierName = aXMLName;
1968 0 : aHierName += aValueName;
1969 : rValue.Value
1970 0 : = xHierNameAccess->getByHierarchicalName(
1971 0 : aHierName );
1972 :
1973 : // Note: The value may be void if addProperty
1974 : // was called with a default value
1975 : // of type void.
1976 : }
1977 0 : catch (const NoSuchElementException&)
1978 : {
1979 : // getByHierarchicalName
1980 :
1981 : OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1982 : "NoSuchElementException!" );
1983 : }
1984 :
1985 : try
1986 : {
1987 : // Obtain and set property state
1988 0 : OUString aHierName = aXMLName;
1989 0 : aHierName += aStateName;
1990 : Any aKeyValue
1991 0 : = xHierNameAccess->getByHierarchicalName(
1992 0 : aHierName );
1993 :
1994 0 : sal_Int32 nState = 0;
1995 0 : if ( !( aKeyValue >>= nState ) )
1996 : OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1997 : "Error getting property state!" );
1998 : else
1999 0 : rValue.State = PropertyState( nState );
2000 : }
2001 0 : catch (const NoSuchElementException&)
2002 : {
2003 : // getByHierarchicalName
2004 :
2005 : OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
2006 : "NoSuchElementException!" );
2007 : }
2008 0 : }
2009 :
2010 0 : return aValues;
2011 0 : }
2012 0 : }
2013 0 : }
2014 : }
2015 0 : catch (const NoSuchElementException&)
2016 : {
2017 : // getByHierarchicalName
2018 : }
2019 : }
2020 :
2021 0 : return Sequence< PropertyValue >( 0 );
2022 : }
2023 :
2024 :
2025 : // virtual
2026 0 : void SAL_CALL PersistentPropertySet::setPropertyValues(
2027 : const Sequence< PropertyValue >& aProps )
2028 : throw( UnknownPropertyException,
2029 : PropertyVetoException,
2030 : IllegalArgumentException,
2031 : WrappedTargetException,
2032 : RuntimeException, std::exception )
2033 : {
2034 0 : sal_Int32 nCount = aProps.getLength();
2035 0 : if ( !nCount )
2036 0 : return;
2037 :
2038 0 : osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex );
2039 :
2040 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2041 0 : m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
2042 0 : if ( xRootHierNameAccess.is() )
2043 : {
2044 0 : const PropertyValue* pNewValues = aProps.getConstArray();
2045 :
2046 : typedef std::list< PropertyChangeEvent > Events;
2047 0 : Events aEvents;
2048 :
2049 0 : OUString aFullPropNamePrefix( getFullKey() );
2050 0 : aFullPropNamePrefix += "/";
2051 :
2052 : // Iterate over given property value sequence.
2053 0 : for ( sal_Int32 n = 0; n < nCount; ++n )
2054 : {
2055 0 : const PropertyValue& rNewValue = pNewValues[ n ];
2056 0 : const OUString& rName = rNewValue.Name;
2057 :
2058 0 : OUString aFullPropName = aFullPropNamePrefix;
2059 0 : aFullPropName += makeHierarchalNameSegment( rName );
2060 :
2061 : // Does property exist?
2062 0 : if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
2063 : {
2064 : Reference< XNameReplace > xNameReplace(
2065 : m_pImpl->m_pCreator->getConfigWriteAccess(
2066 0 : aFullPropName ), UNO_QUERY );
2067 : Reference< XChangesBatch > xBatch(
2068 : m_pImpl->m_pCreator->getConfigWriteAccess(
2069 0 : OUString() ), UNO_QUERY );
2070 :
2071 0 : if ( xNameReplace.is() && xBatch.is() )
2072 : {
2073 : try
2074 : {
2075 : // Write handle
2076 0 : xNameReplace->replaceByName(
2077 : OUString("Handle"),
2078 0 : makeAny( rNewValue.Handle ) );
2079 :
2080 : // Save old value
2081 0 : OUString aValueName = aFullPropName;
2082 0 : aValueName += "/Value";
2083 : Any aOldValue
2084 0 : = xRootHierNameAccess->getByHierarchicalName(
2085 0 : aValueName );
2086 : // Write value
2087 0 : xNameReplace->replaceByName(
2088 : OUString("Value"),
2089 0 : rNewValue.Value );
2090 :
2091 : // Write state ( Now it is a directly set value )
2092 0 : xNameReplace->replaceByName(
2093 : OUString("State"),
2094 : makeAny(
2095 : sal_Int32(
2096 0 : PropertyState_DIRECT_VALUE ) ) );
2097 :
2098 : // Commit changes.
2099 0 : xBatch->commitChanges();
2100 :
2101 0 : if ( m_pImpl->m_pPropertyChangeListeners )
2102 : {
2103 0 : PropertyChangeEvent aEvt;
2104 0 : aEvt.Source = (OWeakObject*)this;
2105 0 : aEvt.PropertyName = rNewValue.Name;
2106 0 : aEvt.PropertyHandle = rNewValue.Handle;
2107 0 : aEvt.Further = sal_False;
2108 0 : aEvt.OldValue = aOldValue;
2109 0 : aEvt.NewValue = rNewValue.Value;
2110 :
2111 0 : aEvents.push_back( aEvt );
2112 0 : }
2113 : }
2114 0 : catch (const IllegalArgumentException&)
2115 : {
2116 : // replaceByName
2117 : }
2118 0 : catch (const NoSuchElementException&)
2119 : {
2120 : // getByHierarchicalName, replaceByName
2121 : }
2122 0 : catch (const WrappedTargetException&)
2123 : {
2124 : // replaceByName, commitChanges
2125 : }
2126 0 : }
2127 : }
2128 0 : }
2129 :
2130 : // Callback follows!
2131 0 : aCGuard.clear();
2132 :
2133 0 : if ( m_pImpl->m_pPropertyChangeListeners )
2134 : {
2135 : // Notify property changes.
2136 0 : Events::const_iterator it = aEvents.begin();
2137 0 : Events::const_iterator end = aEvents.end();
2138 :
2139 0 : while ( it != end )
2140 : {
2141 0 : notifyPropertyChangeEvent( (*it) );
2142 0 : ++it;
2143 : }
2144 : }
2145 :
2146 0 : return;
2147 : }
2148 :
2149 0 : OSL_FAIL( "PersistentPropertySet::setPropertyValues - Nothing set!" );
2150 : }
2151 :
2152 :
2153 :
2154 : // Non-interface methods
2155 :
2156 :
2157 :
2158 0 : void PersistentPropertySet::notifyPropertyChangeEvent(
2159 : const PropertyChangeEvent& rEvent ) const
2160 : {
2161 : // Get "normal" listeners for the property.
2162 : OInterfaceContainerHelper* pContainer =
2163 : m_pImpl->m_pPropertyChangeListeners->getContainer(
2164 0 : rEvent.PropertyName );
2165 0 : if ( pContainer && pContainer->getLength() )
2166 : {
2167 0 : OInterfaceIteratorHelper aIter( *pContainer );
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 :
2178 : // Get "normal" listeners for all properties.
2179 : OInterfaceContainerHelper* pNoNameContainer =
2180 0 : m_pImpl->m_pPropertyChangeListeners->getContainer( OUString() );
2181 0 : if ( pNoNameContainer && pNoNameContainer->getLength() )
2182 : {
2183 0 : OInterfaceIteratorHelper aIter( *pNoNameContainer );
2184 0 : while ( aIter.hasMoreElements() )
2185 : {
2186 : // Propagate event.
2187 : Reference< XPropertyChangeListener > xListener(
2188 0 : aIter.next(), UNO_QUERY );
2189 0 : if ( xListener.is() )
2190 0 : xListener->propertyChange( rEvent );
2191 0 : }
2192 : }
2193 0 : }
2194 :
2195 :
2196 0 : void PersistentPropertySet::notifyPropertySetInfoChange(
2197 : const PropertySetInfoChangeEvent& evt ) const
2198 : {
2199 0 : if ( !m_pImpl->m_pPropSetChangeListeners )
2200 0 : return;
2201 :
2202 : // Notify event listeners.
2203 0 : OInterfaceIteratorHelper aIter( *( m_pImpl->m_pPropSetChangeListeners ) );
2204 0 : while ( aIter.hasMoreElements() )
2205 : {
2206 : // Propagate event.
2207 : Reference< XPropertySetInfoChangeListener >
2208 0 : xListener( aIter.next(), UNO_QUERY );
2209 0 : if ( xListener.is() )
2210 0 : xListener->propertySetInfoChange( evt );
2211 0 : }
2212 : }
2213 :
2214 :
2215 0 : const OUString& PersistentPropertySet::getFullKey()
2216 : {
2217 0 : if ( m_pImpl->m_aFullKey.isEmpty() )
2218 : {
2219 0 : osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex );
2220 0 : if ( m_pImpl->m_aFullKey.isEmpty() )
2221 : {
2222 : m_pImpl->m_aFullKey
2223 0 : = makeHierarchalNameSegment( m_pImpl->m_aKey );
2224 : m_pImpl->m_aFullKey
2225 0 : += "/Values";
2226 0 : }
2227 : }
2228 :
2229 0 : return m_pImpl->m_aFullKey;
2230 : }
2231 :
2232 :
2233 0 : PropertySetRegistry& PersistentPropertySet::getPropertySetRegistry()
2234 : {
2235 0 : return *m_pImpl->m_pCreator;
2236 : }
2237 :
2238 :
2239 :
2240 :
2241 : // PropertySetInfo_Impl Implementation.
2242 :
2243 :
2244 :
2245 :
2246 0 : PropertySetInfo_Impl::PropertySetInfo_Impl(
2247 : const Reference< XComponentContext >& xContext,
2248 : PersistentPropertySet* pOwner )
2249 : : m_xContext( xContext ),
2250 : m_pProps( NULL ),
2251 0 : m_pOwner( pOwner )
2252 : {
2253 0 : }
2254 :
2255 :
2256 : // virtual
2257 0 : PropertySetInfo_Impl::~PropertySetInfo_Impl()
2258 : {
2259 0 : delete m_pProps;
2260 :
2261 : // !!! Do not delete m_pOwner !!!
2262 0 : }
2263 :
2264 : // XPropertySetInfo methods.
2265 :
2266 :
2267 :
2268 : // virtual
2269 0 : Sequence< Property > SAL_CALL PropertySetInfo_Impl::getProperties()
2270 : throw( RuntimeException, std::exception )
2271 : {
2272 0 : if ( !m_pProps )
2273 : {
2274 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2275 0 : m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2276 0 : UNO_QUERY );
2277 0 : if ( xRootHierNameAccess.is() )
2278 : {
2279 : try
2280 : {
2281 0 : Reference< XNameAccess > xNameAccess;
2282 0 : xRootHierNameAccess->getByHierarchicalName(
2283 0 : m_pOwner->getFullKey() )
2284 0 : >>= xNameAccess;
2285 0 : if ( xNameAccess.is() )
2286 : {
2287 : // Obtain property names.
2288 :
2289 : Sequence< OUString > aElems
2290 0 : = xNameAccess->getElementNames();
2291 :
2292 0 : sal_uInt32 nCount = aElems.getLength();
2293 : Sequence< Property >* pPropSeq
2294 0 : = new Sequence< Property >( nCount );
2295 :
2296 0 : if ( nCount )
2297 : {
2298 : Reference< XHierarchicalNameAccess > xHierNameAccess(
2299 0 : xNameAccess, UNO_QUERY );
2300 :
2301 : OSL_ENSURE( xHierNameAccess.is(),
2302 : "PropertySetInfo_Impl::getProperties - "
2303 : "No hierarchical name access!" );
2304 :
2305 0 : if ( xHierNameAccess.is() )
2306 : {
2307 0 : const OUString aHandleName("/Handle");
2308 0 : const OUString aValueName("/Value");
2309 0 : const OUString aAttrName("/Attributes");
2310 :
2311 0 : Property* pProps = pPropSeq->getArray();
2312 :
2313 0 : for ( sal_uInt32 n = 0; n < nCount; ++n )
2314 : {
2315 0 : Property& rProp = pProps[ n ];
2316 0 : OUString rName = aElems[ n ];
2317 : OUString aXMLName
2318 0 : = makeHierarchalNameSegment( rName );
2319 :
2320 : // Set property name.
2321 :
2322 0 : rProp.Name = rName;
2323 :
2324 : try
2325 : {
2326 : // Obtain and set property handle
2327 0 : OUString aHierName = aXMLName;
2328 0 : aHierName += aHandleName;
2329 : Any aKeyValue
2330 0 : = xHierNameAccess->getByHierarchicalName(
2331 0 : aHierName );
2332 :
2333 0 : if ( !( aKeyValue >>= rProp.Handle ) )
2334 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2335 0 : "Error getting property handle!" );
2336 : }
2337 0 : catch (const NoSuchElementException&)
2338 : {
2339 : // getByHierarchicalName
2340 :
2341 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2342 : "NoSuchElementException!" );
2343 : }
2344 :
2345 : try
2346 : {
2347 : // Obtain and set property type
2348 0 : OUString aHierName = aXMLName;
2349 0 : aHierName += aValueName;
2350 : Any aKeyValue
2351 0 : = xHierNameAccess->getByHierarchicalName(
2352 0 : aHierName );
2353 :
2354 : // Note: The type may be void if addProperty
2355 : // was called with a default value
2356 : // of type void.
2357 :
2358 0 : rProp.Type = aKeyValue.getValueType();
2359 : }
2360 0 : catch (const NoSuchElementException&)
2361 : {
2362 : // getByHierarchicalName
2363 :
2364 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2365 : "NoSuchElementException!" );
2366 : }
2367 :
2368 : try
2369 : {
2370 : // Obtain and set property attributes
2371 0 : OUString aHierName = aXMLName;
2372 0 : aHierName += aAttrName;
2373 : Any aKeyValue
2374 0 : = xHierNameAccess->getByHierarchicalName(
2375 0 : aHierName );
2376 :
2377 0 : sal_Int32 nAttribs = 0;
2378 0 : if ( aKeyValue >>= nAttribs )
2379 : rProp.Attributes
2380 0 : = sal_Int16( nAttribs );
2381 : else
2382 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2383 0 : "Error getting property attributes!" );
2384 : }
2385 0 : catch (const NoSuchElementException&)
2386 : {
2387 : // getByHierarchicalName
2388 :
2389 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2390 : "NoSuchElementException!" );
2391 : }
2392 0 : }
2393 0 : }
2394 : }
2395 :
2396 : // Success.
2397 0 : m_pProps = pPropSeq;
2398 0 : return *m_pProps;
2399 0 : }
2400 : }
2401 0 : catch (const NoSuchElementException&)
2402 : {
2403 : // getByHierarchicalName
2404 : }
2405 : }
2406 :
2407 : OSL_FAIL( "PropertySetInfo_Impl::getProperties - Error!" );
2408 0 : m_pProps = new Sequence< Property >( 0 );
2409 : }
2410 :
2411 0 : return *m_pProps;
2412 : }
2413 :
2414 :
2415 : // virtual
2416 0 : Property SAL_CALL PropertySetInfo_Impl::getPropertyByName(
2417 : const OUString& aName )
2418 : throw( UnknownPropertyException, RuntimeException, std::exception )
2419 : {
2420 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2421 0 : m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2422 0 : UNO_QUERY );
2423 0 : if ( xRootHierNameAccess.is() )
2424 : {
2425 0 : OUString aFullPropName( m_pOwner->getFullKey() );
2426 0 : aFullPropName += "/";
2427 0 : aFullPropName += makeHierarchalNameSegment( aName );
2428 :
2429 : // Does property exist?
2430 0 : if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
2431 0 : throw UnknownPropertyException();
2432 :
2433 : try
2434 : {
2435 0 : Property aProp;
2436 :
2437 : // Obtain handle.
2438 0 : OUString aKey = aFullPropName;
2439 0 : aKey += "/Handle";
2440 :
2441 0 : if ( !( xRootHierNameAccess->getByHierarchicalName( aKey )
2442 0 : >>= aProp.Handle ) )
2443 : {
2444 : OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2445 : "No handle!" );
2446 0 : return Property();
2447 : }
2448 :
2449 : // Obtain Value and extract type.
2450 0 : aKey = aFullPropName;
2451 0 : aKey += "/Value";
2452 :
2453 0 : Any aValue = xRootHierNameAccess->getByHierarchicalName( aKey );
2454 0 : if ( !aValue.hasValue() )
2455 : {
2456 : OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2457 : "No Value!" );
2458 0 : return Property();
2459 : }
2460 :
2461 0 : aProp.Type = aValue.getValueType();
2462 :
2463 : // Obtain Attributes.
2464 0 : aKey = aFullPropName;
2465 0 : aKey += "/Attributes";
2466 :
2467 0 : sal_Int32 nAttribs = 0;
2468 0 : if ( xRootHierNameAccess->getByHierarchicalName( aKey )
2469 0 : >>= nAttribs )
2470 0 : aProp.Attributes = sal_Int16( nAttribs );
2471 : else
2472 : {
2473 : OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2474 : "No attributes!" );
2475 0 : return Property();
2476 : }
2477 :
2478 : // set name.
2479 0 : aProp.Name = aName;
2480 :
2481 : // Success.
2482 0 : return aProp;
2483 : }
2484 0 : catch (const NoSuchElementException&)
2485 : {
2486 : // getByHierarchicalName
2487 :
2488 : OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2489 : "caught NoSuchElementException!" );
2490 0 : }
2491 :
2492 : }
2493 :
2494 : OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - Error!" );
2495 0 : return Property();
2496 : }
2497 :
2498 :
2499 : // virtual
2500 0 : sal_Bool SAL_CALL PropertySetInfo_Impl::hasPropertyByName(
2501 : const OUString& Name )
2502 : throw( RuntimeException, std::exception )
2503 : {
2504 : Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2505 0 : m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(),
2506 0 : UNO_QUERY );
2507 0 : if ( xRootHierNameAccess.is() )
2508 : {
2509 0 : OUString aFullPropName( m_pOwner->getFullKey() );
2510 0 : aFullPropName += "/";
2511 0 : aFullPropName += makeHierarchalNameSegment( Name );
2512 :
2513 0 : return xRootHierNameAccess->hasByHierarchicalName( aFullPropName );
2514 : }
2515 :
2516 0 : return sal_False;
2517 : }
2518 :
2519 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|