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