LibreOffice Module ucb (master) 1
ucbstore.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21/**************************************************************************
22 TODO
23 **************************************************************************
24
25 *************************************************************************/
26
27#include <optional>
28#include <unordered_map>
29#include <sal/log.hxx>
31#include <rtl/ustrbuf.hxx>
32#include <rtl/ref.hxx>
35#include <com/sun/star/beans/IllegalTypeException.hpp>
36#include <com/sun/star/beans/NotRemoveableException.hpp>
37#include <com/sun/star/beans/PropertyAttribute.hpp>
38#include <com/sun/star/beans/PropertyExistException.hpp>
39#include <com/sun/star/beans/PropertySetInfoChange.hpp>
40#include <com/sun/star/configuration/theDefaultProvider.hpp>
41#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
42#include <com/sun/star/container/XNameContainer.hpp>
43#include <com/sun/star/container/XNameReplace.hpp>
44#include <com/sun/star/util/XChangesBatch.hpp>
45#include <com/sun/star/lang/XSingleServiceFactory.hpp>
48#include <cppuhelper/weak.hxx>
49#include <utility>
50#include "ucbstore.hxx"
51
52using namespace com::sun::star::beans;
53using namespace com::sun::star::configuration;
54using namespace com::sun::star::container;
55using namespace com::sun::star::lang;
56using namespace com::sun::star::ucb;
57using namespace com::sun::star::uno;
58using namespace com::sun::star::util;
59using namespace comphelper;
60using namespace cppu;
61
62static OUString makeHierarchalNameSegment( std::u16string_view rIn )
63{
64 OUStringBuffer aBuffer( "['" );
65
66 size_t nCount = rIn.size();
67 for ( size_t n = 0; n < nCount; ++n )
68 {
69 const sal_Unicode c = rIn[ n ];
70 switch ( c )
71 {
72 case '&':
73 aBuffer.append( "&amp;" );
74 break;
75
76 case '"':
77 aBuffer.append( "&quot;" );
78 break;
79
80 case '\'':
81 aBuffer.append( "&apos;" );
82 break;
83
84 case '<':
85 aBuffer.append( "&lt;" );
86 break;
87
88 case '>':
89 aBuffer.append( "&gt;" );
90 break;
91
92 default:
93 aBuffer.append( c );
94 break;
95 }
96 }
97
98 aBuffer.append( "']" );
99 return aBuffer.makeStringAndClear();
100}
101
102constexpr OUStringLiteral STORE_CONTENTPROPERTIES_KEY = u"/org.openoffice.ucb.Store/ContentProperties";
103
104// describe path of cfg entry
105constexpr OUStringLiteral CFGPROPERTY_NODEPATH = u"nodepath";
106
107class PropertySetInfo_Impl : public cppu::WeakImplHelper < XPropertySetInfo >
108{
109 std::optional<Sequence< Property >>
112
113public:
115
116 // XPropertySetInfo
117 virtual Sequence< Property > SAL_CALL getProperties() override;
118 virtual Property SAL_CALL getPropertyByName( const OUString& aName ) override;
119 virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override;
120
121 // Non-interface methods.
122 void reset() { m_xProps.reset(); }
123};
124
125
126// UcbStore Implementation.
127
128
130: m_xContext( xContext )
131{
132}
133
134
135// virtual
137{
138}
139
141{
142 return "com.sun.star.comp.ucb.UcbStore";
143}
144sal_Bool SAL_CALL UcbStore::supportsService( const OUString& ServiceName )
145{
146 return cppu::supportsService( this, ServiceName );
147}
148css::uno::Sequence< OUString > SAL_CALL UcbStore::getSupportedServiceNames()
149{
150 return { "com.sun.star.ucb.Store" };
151}
152
153// Service factory implementation.
154
155extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
157 css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any> const&)
158{
159 return cppu::acquire(new UcbStore(context));
160}
161
162
163// XPropertySetRegistryFactory methods.
164
165
166// virtual
169{
170 // The URL parameter is ignored by this interface implementation. It always
171 // uses the configuration server as storage medium.
172
173 if ( !m_xTheRegistry.is() )
174 {
175 std::unique_lock aGuard( m_aMutex );
176 if ( !m_xTheRegistry.is() )
178 }
179
180 return m_xTheRegistry;
181}
182
183
184// XInitialization methods.
185
186
187// virtual
188void SAL_CALL UcbStore::initialize( const Sequence< Any >& aArguments )
189{
190 std::unique_lock aGuard( m_aMutex );
192}
193
194
195
196// PropertySetRegistry Implementation.
197
198
200 const Reference< XComponentContext >& xContext,
201 const Sequence< Any > &rInitArgs )
202: m_xContext( xContext )
203, m_aInitArgs(rInitArgs)
204, m_bTriedToGetRootReadAccess(false)
205, m_bTriedToGetRootWriteAccess(false)
206{
207}
208
209
210// virtual
212{
213}
214
215
216// XServiceInfo methods.
217
218
220{
221 return "com.sun.star.comp.ucb.PropertySetRegistry";
222}
223
224sal_Bool SAL_CALL PropertySetRegistry::supportsService( const OUString& ServiceName )
225{
226 return cppu::supportsService( this, ServiceName );
227}
228
229css::uno::Sequence< OUString > SAL_CALL PropertySetRegistry::getSupportedServiceNames()
230{
231 return { "com.sun.star.ucb.PropertySetRegistry" };
232}
233
234
235// XPropertySetRegistry methods.
236
237
238// virtual
240PropertySetRegistry::openPropertySet( const OUString& key, sal_Bool create )
241{
242 if ( key.isEmpty() )
244
245 std::unique_lock aGuard( m_aMutex );
246
248
249 PropertySetMap_Impl::const_iterator it = rSets.find( key );
250 if ( it != rSets.end() )
251 // Already instantiated.
252 return Reference< XPersistentPropertySet >( (*it).second );
253
254 // Create new instance.
255 Reference< XNameAccess > xRootNameAccess(
256 getRootConfigReadAccessImpl(aGuard), UNO_QUERY );
257 if ( !xRootNameAccess.is() )
258 {
259 SAL_WARN( "ucb", "no root access" );
261 }
262
263 // Propertyset in registry?
264 if ( xRootNameAccess->hasByName( key ) )
265 {
266 // Yep!
269 aGuard, *this, key ) );
270 }
271 else if ( create )
272 {
273 // No. Create entry for propertyset.
274
276 getConfigWriteAccessImpl( aGuard, OUString() ), UNO_QUERY );
277 Reference< XChangesBatch > xBatch( xFac, UNO_QUERY );
278 Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
279
280 OSL_ENSURE( xFac.is(),
281 "PropertySetRegistry::openPropertySet - "
282 "No factory!" );
283
284 OSL_ENSURE( xBatch.is(),
285 "PropertySetRegistry::openPropertySet - "
286 "No batch!" );
287
288 OSL_ENSURE( xContainer.is(),
289 "PropertySetRegistry::openPropertySet - "
290 "No container!" );
291
292 if ( xFac.is() && xBatch.is() && xContainer.is() )
293 {
294 try
295 {
296 // Create new "Properties" config item.
297 Reference< XNameReplace > xNameReplace(
298 xFac->createInstance(), UNO_QUERY );
299
300 if ( xNameReplace.is() )
301 {
302 // Fill new item...
303
304 // Insert new item.
305 xContainer->insertByName(
306 key, Any( xNameReplace ) );
307 // Commit changes.
308 xBatch->commitChanges();
309
312 aGuard, *this, key ) );
313 }
314 }
315 catch (const IllegalArgumentException&)
316 {
317 // insertByName
318
319 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
320 "caught IllegalArgumentException!" );
321 }
322 catch (const ElementExistException&)
323 {
324 // insertByName
325
326 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
327 "caught ElementExistException!" );
328 }
329 catch (const WrappedTargetException&)
330 {
331 // insertByName, commitChanges
332
333 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
334 "caught WrappedTargetException!" );
335 }
336 catch (const RuntimeException&)
337 {
338 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
339 "caught RuntimeException!" );
340 }
341 catch (const Exception&)
342 {
343 // createInstance
344
345 OSL_FAIL( "PropertySetRegistry::openPropertySet - "
346 "caught Exception!" );
347 }
348 }
349 }
350 else
351 {
352 // No entry. Fail, but no error.
354 }
355
356 SAL_WARN( "ucb", "no root access" );
357
359}
360
361
362// virtual
363void SAL_CALL PropertySetRegistry::removePropertySet( const OUString& key )
364{
365 if ( key.isEmpty() )
366 return;
367
368 std::unique_lock aGuard( m_aMutex );
369
370 Reference< XNameAccess > xRootNameAccess(
371 getRootConfigReadAccessImpl(aGuard), UNO_QUERY );
372 if ( xRootNameAccess.is() )
373 {
374 // Propertyset in registry?
375 if ( !xRootNameAccess->hasByName( key ) )
376 return;
378 getConfigWriteAccessImpl( aGuard, OUString() ), UNO_QUERY );
379 Reference< XNameContainer > xContainer( xBatch, UNO_QUERY );
380
381 if ( xBatch.is() && xContainer.is() )
382 {
383 try
384 {
385 // Remove item.
386 xContainer->removeByName( key );
387 // Commit changes.
388 xBatch->commitChanges();
389
390 // Success.
391 return;
392 }
393 catch (const NoSuchElementException&)
394 {
395 // removeByName
396
397 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
398 "caught NoSuchElementException!" );
399 return;
400 }
401 catch (const WrappedTargetException&)
402 {
403 // commitChanges
404
405 OSL_FAIL( "PropertySetRegistry::removePropertySet - "
406 "caught WrappedTargetException!" );
407 return;
408 }
409 }
410
411 return;
412 }
413
414 SAL_WARN( "ucb", "no root access" );
415}
416
417
418// XElementAccess methods.
419
420
421// virtual
422css::uno::Type SAL_CALL PropertySetRegistry::getElementType()
423{
425}
426
427
428// virtual
430{
431 Reference< XElementAccess > xElemAccess(
432 getRootConfigReadAccess(), UNO_QUERY );
433 if ( xElemAccess.is() )
434 return xElemAccess->hasElements();
435
436 return false;
437}
438
439
440// XNameAccess methods.
441
442
443// virtual
444Any SAL_CALL PropertySetRegistry::getByName( const OUString& aName )
445{
446 Reference< XNameAccess > xNameAccess(
447 getRootConfigReadAccess(), UNO_QUERY );
448 if ( xNameAccess.is() )
449 {
450
451 try
452 {
453 return xNameAccess->getByName( aName );
454 }
455 catch (const NoSuchElementException&)
456 {
457 // getByName
458 }
459 catch (const WrappedTargetException&)
460 {
461 // getByName
462 }
463 }
464
465 return Any();
466}
467
468
469// virtual
471{
472 Reference< XNameAccess > xNameAccess(
473 getRootConfigReadAccess(), UNO_QUERY );
474 if ( xNameAccess.is() )
475 {
476 return xNameAccess->getElementNames();
477 }
478 return Sequence< OUString >( 0 );
479}
480
481
482// virtual
483sal_Bool SAL_CALL PropertySetRegistry::hasByName( const OUString& aName )
484{
485 Reference< XNameAccess > xNameAccess(
486 getRootConfigReadAccess(), UNO_QUERY );
487 if ( xNameAccess.is() )
488 {
489 return xNameAccess->hasByName( aName );
490 }
491
492 return false;
493}
494
495
497 std::unique_lock<std::mutex>& /*rCreatorGuard*/,
499{
500 OUString key( pSet->getKey() );
501
502 if ( !key.isEmpty() )
503 {
504 m_aPropSets[ key ] = pSet;
505 }
506}
507
508
510{
511 OUString key( pSet->getKey() );
512
513 if ( key.isEmpty() )
514 return;
515
516 std::unique_lock aGuard( m_aMutex );
517
519
520 PropertySetMap_Impl::iterator it = rSets.find( key );
521 if ( it != rSets.end() )
522 {
523 // Found.
524 rSets.erase( it );
525 }
526}
527
528
529void PropertySetRegistry::renamePropertySet( const OUString& rOldKey,
530 const OUString& rNewKey )
531{
532 if ( rOldKey == rNewKey )
533 return;
534
535 Reference< XNameAccess > xRootNameAccess(
536 getConfigWriteAccess( OUString() ), UNO_QUERY );
537 if ( xRootNameAccess.is() )
538 {
539 // Old key present?
540 if ( xRootNameAccess->hasByName( rOldKey ) )
541 {
542 // New key not present?
543 if ( xRootNameAccess->hasByName( rNewKey ) )
544 {
545 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
546 "New key exists!" );
547 return;
548 }
550 xRootNameAccess, UNO_QUERY );
551 Reference< XChangesBatch > xBatch( xFac, UNO_QUERY );
552 Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
553
554 OSL_ENSURE( xFac.is(),
555 "PropertySetRegistry::renamePropertySet - "
556 "No factory!" );
557
558 OSL_ENSURE( xBatch.is(),
559 "PropertySetRegistry::renamePropertySet - "
560 "No batch!" );
561
562 OSL_ENSURE( xContainer.is(),
563 "PropertySetRegistry::renamePropertySet - "
564 "No container!" );
565
566 if ( xFac.is() && xBatch.is() && xContainer.is() )
567 {
568
569 // Create new "Properties" config item.
570
571
572 try
573 {
574 Reference< XNameReplace > xNameReplace(
575 xFac->createInstance(), UNO_QUERY );
576
577 if ( xNameReplace.is() )
578 {
579 // Insert new item.
580 xContainer->insertByName(
581 rNewKey, Any( xNameReplace ) );
582 // Commit changes.
583 xBatch->commitChanges();
584 }
585 }
586 catch (const IllegalArgumentException&)
587 {
588 // insertByName
589
590 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
591 "caught IllegalArgumentException!" );
592 return;
593 }
594 catch (const ElementExistException&)
595 {
596 // insertByName
597
598 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
599 "caught ElementExistException!" );
600 return;
601 }
602 catch (const WrappedTargetException&)
603 {
604 // insertByName, commitChanges
605
606 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
607 "caught WrappedTargetException!" );
608 return;
609 }
610 catch (const RuntimeException&)
611 {
612 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
613 "caught RuntimeException!" );
614 return;
615 }
616 catch (const Exception&)
617 {
618 // createInstance
619
620 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
621 "caught Exception!" );
622 return;
623 }
624
625
626 // Copy data...
627
628
629 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
630 xRootNameAccess, UNO_QUERY );
631 if ( !xRootHierNameAccess.is() )
632 {
633 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
634 "No hierarchical name access!" );
635 return;
636 }
637
638 try
639 {
640 OUString aOldValuesKey
641 = makeHierarchalNameSegment( rOldKey ) + "/Values";
642
643 Reference< XNameAccess > xOldNameAccess;
644 xRootHierNameAccess->getByHierarchicalName(
645 aOldValuesKey )
646 >>= xOldNameAccess;
647 if ( !xOldNameAccess.is() )
648 {
649 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
650 "No old name access!" );
651 return;
652 }
653
654 // Obtain property names.
655 const Sequence< OUString > aElems
656 = xOldNameAccess->getElementNames();
657 if ( aElems.hasElements() )
658 {
659 OUString aNewValuesKey
660 = makeHierarchalNameSegment( rNewKey ) + "/Values";
661
663 xRootHierNameAccess->getByHierarchicalName(
664 aNewValuesKey )
665 >>= xNewFac;
666 if ( !xNewFac.is() )
667 {
668 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
669 "No new factory!" );
670 return;
671 }
672
673 Reference< XNameContainer > xNewContainer(
674 xNewFac, UNO_QUERY );
675 if ( !xNewContainer.is() )
676 {
677 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
678 "No new container!" );
679 return;
680 }
681
682 aOldValuesKey += "/";
683
684 for ( const OUString& rPropName : aElems )
685 {
686 // Create new item.
687 Reference< XNameReplace > xNewPropNameReplace(
688 xNewFac->createInstance(), UNO_QUERY );
689
690 if ( !xNewPropNameReplace.is() )
691 {
692 OSL_FAIL( "PersistentPropertySet::renamePropertySet - "
693 "No new prop name replace!" );
694 return;
695 }
696
697 // Fill new item...
698
699 // Set Values
700 OUString aKey = aOldValuesKey + makeHierarchalNameSegment( rPropName );
701
702 // ... handle
703 OUString aNewKey1 = aKey + "/Handle";
704 Any aAny =
705 xRootHierNameAccess->getByHierarchicalName(
706 aNewKey1 );
707 xNewPropNameReplace->replaceByName( "Handle", aAny );
708
709 // ... value
710 aNewKey1 = aKey + "/Value";
711 aAny =
712 xRootHierNameAccess->getByHierarchicalName(
713 aNewKey1 );
714 xNewPropNameReplace->replaceByName( "Value", aAny );
715
716 // ... state
717 aNewKey1 = aKey + "/State";
718 aAny =
719 xRootHierNameAccess->getByHierarchicalName(
720 aNewKey1 );
721 xNewPropNameReplace->replaceByName( "State", aAny );
722
723 // ... attributes
724 aNewKey1 = aKey + "/Attributes";
725 aAny =
726 xRootHierNameAccess->getByHierarchicalName(
727 aNewKey1 );
728 xNewPropNameReplace->replaceByName( "Attributes", aAny );
729
730 // Insert new item.
731 xNewContainer->insertByName(
732 rPropName, Any( xNewPropNameReplace ) );
733
734 // Commit changes.
735 xBatch->commitChanges();
736 }
737 }
738 }
739 catch (const IllegalArgumentException&)
740 {
741 // insertByName, replaceByName
742
743 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
744 "caught IllegalArgumentException!" );
745 return;
746 }
747 catch (const ElementExistException&)
748 {
749 // insertByName
750
751 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
752 "caught ElementExistException!" );
753 return;
754 }
755 catch (const WrappedTargetException&)
756 {
757 // insertByName, replaceByName, commitChanges
758
759 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
760 "caught WrappedTargetException!" );
761 return;
762 }
763 catch (const NoSuchElementException&)
764 {
765 // getByHierarchicalName, replaceByName
766
767 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
768 "caught NoSuchElementException!" );
769 return;
770 }
771 catch (const RuntimeException&)
772 {
773 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
774 "caught RuntimeException!" );
775 return;
776 }
777 catch (const Exception&)
778 {
779 // createInstance
780
781 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
782 "caught Exception!" );
783 return;
784 }
785
786
787 // Remove old entry...
788
789
790 try
791 {
792 // Remove item.
793 xContainer->removeByName( rOldKey );
794 // Commit changes.
795 xBatch->commitChanges();
796
797 // Success.
798 return;
799 }
800 catch (const NoSuchElementException&)
801 {
802 // removeByName
803
804 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
805 "caught NoSuchElementException!" );
806 return;
807 }
808 catch (const WrappedTargetException&)
809 {
810 // commitChanges
811
812 OSL_FAIL( "PropertySetRegistry::renamePropertySet - "
813 "caught WrappedTargetException!" );
814 return;
815 }
816 }
817 }
818 }
819
820 OSL_FAIL( "PropertySetRegistry::renamePropertySet - Error!" );
821}
822
823
825{
826 if ( !m_xConfigProvider.is() )
827 {
828 const Sequence< Any >& rInitArgs = m_aInitArgs;
829
830 if ( rInitArgs.hasElements() )
831 {
832 // Extract config provider from service init args.
833 rInitArgs[ 0 ] >>= m_xConfigProvider;
834
835 OSL_ENSURE( m_xConfigProvider.is(),
836 "PropertySetRegistry::getConfigProvider - "
837 "No config provider!" );
838 }
839 else
840 {
841 try
842 {
843 m_xConfigProvider = theDefaultProvider::get( m_xContext );
844 }
845 catch (const Exception&)
846 {
847 TOOLS_WARN_EXCEPTION( "ucb", "");
848 }
849 }
850 }
851
852 return m_xConfigProvider;
853}
854
855
857{
858 std::unique_lock aGuard( m_aMutex );
859 return getRootConfigReadAccessImpl(aGuard);
860}
861
863{
864 try
865 {
866 if ( !m_xRootReadAccess.is() )
867 {
869 {
870 OSL_FAIL( "PropertySetRegistry::getRootConfigReadAccess - "
871 "Unable to read any config data! -> #82494#" );
873 }
874
875 getConfigProvider(rGuard);
876
877 if ( m_xConfigProvider.is() )
878 {
880 {
882 }));
883
885
887 m_xConfigProvider->createInstanceWithArguments(
888 "com.sun.star.configuration.ConfigurationAccess",
889 aArguments );
890
891 if ( m_xRootReadAccess.is() )
892 return m_xRootReadAccess;
893 }
894 }
895 else
896 return m_xRootReadAccess;
897 }
898 catch (const RuntimeException&)
899 {
900 throw;
901 }
902 catch (const Exception&)
903 {
904 // createInstance, createInstanceWithArguments
905
906 TOOLS_WARN_EXCEPTION("ucb", "");
908 }
909
910 SAL_WARN( "ucb", "Error!" );
912}
913
914
916 const OUString& rPath )
917{
918 std::unique_lock aGuard( m_aMutex );
919 return getConfigWriteAccessImpl(aGuard, rPath);
920}
921
923 const OUString& rPath )
924{
925 try
926 {
927 if ( !m_xRootWriteAccess.is() )
928 {
930 {
931 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
932 "Unable to write any config data! -> #82494#" );
934 }
935
936 getConfigProvider(rGuard);
937
938 if ( m_xConfigProvider.is() )
939 {
941 {
943 }));
944
946
948 m_xConfigProvider->createInstanceWithArguments(
949 "com.sun.star.configuration.ConfigurationUpdateAccess",
950 aArguments );
951
952 OSL_ENSURE( m_xRootWriteAccess.is(),
953 "PropertySetRegistry::getConfigWriteAccess - "
954 "No config update access!" );
955 }
956 }
957
958 if ( m_xRootWriteAccess.is() )
959 {
960 if ( !rPath.isEmpty() )
961 {
963 m_xRootWriteAccess, UNO_QUERY );
964 if ( xNA.is() )
965 {
966 Reference< XInterface > xInterface;
967 xNA->getByHierarchicalName( rPath ) >>= xInterface;
968
969 if ( xInterface.is() )
970 return xInterface;
971 }
972 }
973 else
974 return m_xRootWriteAccess;
975 }
976 }
977 catch (const RuntimeException&)
978 {
979 throw;
980 }
981 catch (const NoSuchElementException&)
982 {
983 // getByHierarchicalName
984
985 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
986 "caught NoSuchElementException!" );
988 }
989 catch (const Exception&)
990 {
991 // createInstance, createInstanceWithArguments
992
993 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - "
994 "caught Exception!" );
996 }
997
998 OSL_FAIL( "PropertySetRegistry::getConfigWriteAccess - Error!" );
1000}
1001
1002
1003// PersistentPropertySet Implementation.
1004
1005
1007 std::unique_lock<std::mutex>& rCreatorGuard,
1008 PropertySetRegistry& rCreator,
1009 OUString aKey )
1010: m_pCreator( &rCreator ), m_aKey(std::move( aKey ))
1011{
1012 // register at creator.
1013 rCreator.add( rCreatorGuard, this );
1014}
1015
1016
1017// virtual
1019{
1020 // deregister at creator.
1021 m_pCreator->remove( this );
1022}
1023
1024// XServiceInfo methods.
1025
1027{
1028 return "com.sun.star.comp.ucb.PersistentPropertySet";
1029}
1030
1031sal_Bool SAL_CALL PersistentPropertySet::supportsService( const OUString& ServiceName )
1032{
1033 return cppu::supportsService( this, ServiceName );
1034}
1035
1036css::uno::Sequence< OUString > SAL_CALL PersistentPropertySet::getSupportedServiceNames()
1037{
1038 return { "com.sun.star.ucb.PersistentPropertySet" };
1039}
1040
1041
1042// XComponent methods.
1043
1044
1045// virtual
1047{
1048 std::unique_lock l(m_aMutex);
1050 {
1051 EventObject aEvt;
1052 aEvt.Source = static_cast< XComponent * >( this );
1054 }
1055
1057 {
1058 EventObject aEvt;
1059 aEvt.Source = static_cast< XPropertySetInfoChangeNotifier * >( this );
1061 }
1062
1064 {
1065 EventObject aEvt;
1066 aEvt.Source = static_cast< XPropertySet * >( this );
1068 }
1069}
1070
1071
1072// virtual
1074 const Reference< XEventListener >& Listener )
1075{
1076 std::unique_lock l(m_aMutex);
1077
1079}
1080
1081
1082// virtual
1084 const Reference< XEventListener >& Listener )
1085{
1086 std::unique_lock l(m_aMutex);
1088
1089 // Note: Don't want to delete empty container here -> performance.
1090}
1091
1092
1093// XPropertySet methods.
1094
1095
1096// virtual
1098{
1099 std::unique_lock l(m_aMutex);
1100
1101 if ( !m_pInfo.is() )
1102 {
1103 m_pInfo = new PropertySetInfo_Impl( this );
1104 }
1105 return m_pInfo;
1106}
1107
1108
1109// virtual
1110void SAL_CALL PersistentPropertySet::setPropertyValue( const OUString& aPropertyName,
1111 const Any& aValue )
1112{
1113 std::unique_lock aCGuard(m_aMutex);
1114
1115 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1116 m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1117 if ( xRootHierNameAccess.is() )
1118 {
1119 OUString aFullPropName( getFullKeyImpl(aCGuard) + "/" +
1120 makeHierarchalNameSegment( aPropertyName ) );
1121
1122 // Does property exist?
1123 if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1124 {
1125 Reference< XNameReplace > xNameReplace(
1126 m_pCreator->getConfigWriteAccess(
1127 aFullPropName ), UNO_QUERY );
1129 m_pCreator->getConfigWriteAccess(
1130 OUString() ), UNO_QUERY );
1131
1132 if ( xNameReplace.is() && xBatch.is() )
1133 {
1134 try
1135 {
1136 // Obtain old value
1137 OUString aValueName = aFullPropName + "/Value";
1138 Any aOldValue
1139 = xRootHierNameAccess->getByHierarchicalName(
1140 aValueName );
1141 // Check value type.
1142 if ( aOldValue.getValueType() != aValue.getValueType() )
1143 {
1144 throw IllegalArgumentException();
1145 }
1146
1147 // Write value
1148 xNameReplace->replaceByName( "Value", aValue );
1149
1150 // Write state ( Now it is a directly set value )
1151 xNameReplace->replaceByName(
1152 "State",
1153 Any(
1154 sal_Int32(
1155 PropertyState_DIRECT_VALUE ) ) );
1156
1157 // Commit changes.
1158 xBatch->commitChanges();
1159
1160 PropertyChangeEvent aEvt;
1162 {
1163 // Obtain handle
1164 aValueName = aFullPropName + "/Handle";
1165 sal_Int32 nHandle = -1;
1166 xRootHierNameAccess->getByHierarchicalName( aValueName )
1167 >>= nHandle;
1168
1169 aEvt.Source = getXWeak();
1170 aEvt.PropertyName = aPropertyName;
1171 aEvt.PropertyHandle = nHandle;
1172 aEvt.Further = false;
1173 aEvt.OldValue = aOldValue;
1174 aEvt.NewValue = aValue;
1175
1176 notifyPropertyChangeEvent( aCGuard, aEvt );
1177 }
1178 return;
1179 }
1180 catch (const IllegalArgumentException&)
1181 {
1182 // replaceByName
1183 }
1184 catch (const NoSuchElementException&)
1185 {
1186 // getByHierarchicalName, replaceByName
1187 }
1188 catch (const WrappedTargetException&)
1189 {
1190 // replaceByName, commitChanges
1191 }
1192 }
1193 }
1194 }
1195
1196 throw UnknownPropertyException(aPropertyName);
1197}
1198
1199
1200// virtual
1202 const OUString& PropertyName )
1203{
1204 std::unique_lock aGuard(m_aMutex);
1205
1207 m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1208 if ( xNameAccess.is() )
1209 {
1210 OUString aFullPropName( getFullKeyImpl(aGuard) + "/" +
1211 makeHierarchalNameSegment( PropertyName ) + "/Value" );
1212 try
1213 {
1214 return xNameAccess->getByHierarchicalName( aFullPropName );
1215 }
1216 catch (const NoSuchElementException&)
1217 {
1218 throw UnknownPropertyException(aFullPropName);
1219 }
1220 }
1221
1222 throw UnknownPropertyException(PropertyName);
1223}
1224
1225
1226// virtual
1228 const OUString& aPropertyName,
1229 const Reference< XPropertyChangeListener >& xListener )
1230{
1231// load();
1232
1233 std::unique_lock aGuard(m_aMutex);
1234
1235 m_aPropertyChangeListeners.addInterface(aGuard, aPropertyName, xListener );
1236}
1237
1238
1239// virtual
1241 const OUString& aPropertyName,
1242 const Reference< XPropertyChangeListener >& aListener )
1243{
1244// load();
1245
1246 std::unique_lock aGuard(m_aMutex);
1247
1249 aPropertyName, aListener );
1250
1251 // Note: Don't want to delete empty container here -> performance.
1252}
1253
1254
1255// virtual
1257 const OUString&,
1259{
1260// load();
1261// OSL_FAIL( // "PersistentPropertySet::addVetoableChangeListener - N.Y.I." );
1262}
1263
1264
1265// virtual
1267 const OUString&,
1269{
1270// load();
1271// OSL_FAIL( // "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." );
1272}
1273
1274
1275// XPersistentPropertySet methods.
1276
1277
1278// virtual
1280{
1281 return m_pCreator;
1282}
1283
1284
1285// virtual
1287{
1288 return m_aKey;
1289}
1290
1291
1292// XNamed methods.
1293
1294
1295// virtual
1297{
1298 // same as getKey()
1299 return m_aKey;
1300}
1301
1302
1303// virtual
1304void SAL_CALL PersistentPropertySet::setName( const OUString& aName )
1305{
1306 if ( aName != m_aKey )
1307 m_pCreator->renamePropertySet( m_aKey, aName );
1308}
1309
1310
1311// XPropertyContainer methods.
1312
1313
1314// virtual
1316 const OUString& Name, sal_Int16 Attributes, const Any& DefaultValue )
1317{
1318 if ( Name.isEmpty() )
1319 throw IllegalArgumentException();
1320
1321 // @@@ What other types can't be written to config server?
1322
1323 // Check type class ( Not all types can be written to storage )
1324 TypeClass eTypeClass = DefaultValue.getValueTypeClass();
1325 if ( eTypeClass == TypeClass_INTERFACE )
1326 throw IllegalTypeException();
1327
1328 std::unique_lock aGuard(m_aMutex);
1329
1330 // Property already in set?
1331
1332 OUString aFullValuesName;
1333
1334 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1335 m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1336 if ( xRootHierNameAccess.is() )
1337 {
1338 aFullValuesName = getFullKeyImpl(aGuard);
1339 OUString aFullPropName = aFullValuesName + "/" +
1341
1342 if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1343 {
1344 // Already in set.
1345 throw PropertyExistException();
1346 }
1347 }
1348
1349 // Property is always removable.
1350 Attributes |= PropertyAttribute::REMOVABLE;
1351
1352 // Add property.
1353
1355 m_pCreator->getConfigWriteAccess( aFullValuesName ),
1356 UNO_QUERY );
1357 Reference< XNameContainer > xContainer( xFac, UNO_QUERY );
1359 m_pCreator->getConfigWriteAccess( OUString() ),
1360 UNO_QUERY );
1361
1362 OSL_ENSURE( xFac.is(),
1363 "PersistentPropertySet::addProperty - No factory!" );
1364
1365 OSL_ENSURE( xBatch.is(),
1366 "PersistentPropertySet::addProperty - No batch!" );
1367
1368 OSL_ENSURE( xContainer.is(),
1369 "PersistentPropertySet::addProperty - No container!" );
1370
1371 if ( xFac.is() && xBatch.is() && xContainer.is() )
1372 {
1373 try
1374 {
1375 // Create new "PropertyValue" config item.
1376 Reference< XNameReplace > xNameReplace(
1377 xFac->createInstance(), UNO_QUERY );
1378
1379 if ( xNameReplace.is() )
1380 {
1381 // Fill new item...
1382
1383 // Set handle
1384 xNameReplace->replaceByName(
1385 "Handle",
1386 Any( sal_Int32( -1 ) ) );
1387
1388 // Set default value
1389 xNameReplace->replaceByName(
1390 "Value",
1391 DefaultValue );
1392
1393 // Set state ( always "default" )
1394 xNameReplace->replaceByName(
1395 "State",
1396 Any(
1397 sal_Int32(
1398 PropertyState_DEFAULT_VALUE ) ) );
1399
1400 // Set attributes
1401 xNameReplace->replaceByName(
1402 "Attributes",
1403 Any( sal_Int32( Attributes ) ) );
1404
1405 // Insert new item.
1406 xContainer->insertByName( Name, Any( xNameReplace ) );
1407
1408 // Commit changes.
1409 xBatch->commitChanges();
1410
1411 // Property set info is invalid.
1412 if ( m_pInfo.is() )
1413 m_pInfo->reset();
1414
1415 // Notify propertyset info change listeners.
1417 {
1418 PropertySetInfoChangeEvent evt(
1419 getXWeak(),
1420 Name,
1421 -1,
1422 PropertySetInfoChange::PROPERTY_INSERTED );
1423 notifyPropertySetInfoChange(aGuard, evt);
1424 }
1425
1426 // Success.
1427 return;
1428 }
1429 }
1430 catch (const IllegalArgumentException&)
1431 {
1432 // insertByName
1433
1434 OSL_FAIL( "PersistentPropertySet::addProperty - "
1435 "caught IllegalArgumentException!" );
1436 return;
1437 }
1438 catch (const ElementExistException&)
1439 {
1440 // insertByName
1441
1442 OSL_FAIL( "PersistentPropertySet::addProperty - "
1443 "caught ElementExistException!" );
1444 return;
1445 }
1446 catch (const WrappedTargetException&)
1447 {
1448 // replaceByName, insertByName, commitChanges
1449
1450 OSL_FAIL( "PersistentPropertySet::addProperty - "
1451 "caught WrappedTargetException!" );
1452 return;
1453 }
1454 catch (const RuntimeException&)
1455 {
1456 throw;
1457 }
1458 catch (const Exception&)
1459 {
1460 // createInstance
1461
1462 OSL_FAIL( "PersistentPropertySet::addProperty - "
1463 "caught Exception!" );
1464 return;
1465 }
1466 }
1467
1468 OSL_FAIL( "PersistentPropertySet::addProperty - Error!" );
1469}
1470
1471
1472// virtual
1473void SAL_CALL PersistentPropertySet::removeProperty( const OUString& Name )
1474{
1475 std::unique_lock aGuard(m_aMutex);
1476
1477 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1478 m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1479 if ( xRootHierNameAccess.is() )
1480 {
1481 OUString aFullValuesName = getFullKeyImpl(aGuard);
1482 OUString aFullPropName = aFullValuesName + "/" +
1484
1485 // Property in set?
1486 if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1487 throw UnknownPropertyException(aFullPropName);
1488
1489 // Property removable?
1490 try
1491 {
1492 OUString aFullAttrName = aFullPropName + "/Attributes";
1493
1494 sal_Int32 nAttribs = 0;
1495 if ( xRootHierNameAccess->getByHierarchicalName( aFullAttrName )
1496 >>= nAttribs )
1497 {
1498 if ( !( nAttribs & PropertyAttribute::REMOVABLE ) )
1499 {
1500 // Not removable!
1501 throw NotRemoveableException();
1502 }
1503 }
1504 else
1505 {
1506 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1507 "No attributes!" );
1508 return;
1509 }
1510 }
1511 catch (const NoSuchElementException&)
1512 {
1513 // getByHierarchicalName
1514
1515 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1516 "caught NoSuchElementException!" );
1517 }
1518
1519 // Remove property...
1520
1521 Reference< XNameContainer > xContainer(
1522 m_pCreator->getConfigWriteAccess( aFullValuesName ),
1523 UNO_QUERY );
1525 m_pCreator->getConfigWriteAccess( OUString() ),
1526 UNO_QUERY );
1527
1528 OSL_ENSURE( xBatch.is(),
1529 "PersistentPropertySet::removeProperty - No batch!" );
1530
1531 OSL_ENSURE( xContainer.is(),
1532 "PersistentPropertySet::removeProperty - No container!" );
1533
1534 if ( xBatch.is() && xContainer.is() )
1535 {
1536 try
1537 {
1538 sal_Int32 nHandle = -1;
1539
1541 {
1542 // Obtain property handle ( needed for propertysetinfo
1543 // change event )...
1544
1545 try
1546 {
1547 OUString aFullHandleName = aFullPropName + "/Handle";
1548
1549 if ( ! ( xRootHierNameAccess->getByHierarchicalName(
1550 aFullHandleName ) >>= nHandle ) )
1551 nHandle = -1;
1552
1553 }
1554 catch (const NoSuchElementException&)
1555 {
1556 // getByHierarchicalName
1557
1558 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1559 "caught NoSuchElementException!" );
1560 nHandle = -1;
1561 }
1562 }
1563
1564 xContainer->removeByName( Name );
1565 xBatch->commitChanges();
1566
1567 // Property set info is invalid.
1568 if ( m_pInfo.is() )
1569 m_pInfo->reset();
1570
1571 // Notify propertyset info change listeners.
1573 {
1574 PropertySetInfoChangeEvent evt(
1575 getXWeak(),
1576 Name,
1577 nHandle,
1578 PropertySetInfoChange::PROPERTY_REMOVED );
1579 notifyPropertySetInfoChange( aGuard, evt );
1580 }
1581
1582 // Success.
1583 return;
1584 }
1585 catch (const NoSuchElementException&)
1586 {
1587 // removeByName
1588
1589 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1590 "caught NoSuchElementException!" );
1591 return;
1592 }
1593 catch (const WrappedTargetException&)
1594 {
1595 // commitChanges
1596
1597 OSL_FAIL( "PersistentPropertySet::removeProperty - "
1598 "caught WrappedTargetException!" );
1599 return;
1600 }
1601 }
1602 }
1603
1604 OSL_FAIL( "PersistentPropertySet::removeProperty - Error!" );
1605}
1606
1607
1608// XPropertySetInfoChangeNotifier methods.
1609
1610
1611// virtual
1614{
1615 std::unique_lock aGuard(m_aMutex);
1616
1617 m_aPropSetChangeListeners.addInterface( aGuard, Listener );
1618}
1619
1620
1621// virtual
1624{
1625 std::unique_lock aGuard(m_aMutex);
1626 m_aPropSetChangeListeners.removeInterface( aGuard, Listener );
1627}
1628
1629
1630// XPropertyAccess methods.
1631
1632
1633// virtual
1635{
1636 std::unique_lock aGuard(m_aMutex);
1637
1638 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1639 m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1640 if ( xRootHierNameAccess.is() )
1641 {
1642 try
1643 {
1644 Reference< XNameAccess > xNameAccess;
1645 xRootHierNameAccess->getByHierarchicalName(getFullKeyImpl(aGuard))
1646 >>= xNameAccess;
1647 if ( xNameAccess.is() )
1648 {
1649 // Obtain property names.
1650
1651 Sequence< OUString > aElems = xNameAccess->getElementNames();
1652
1653 sal_Int32 nCount = aElems.getLength();
1654 if ( nCount )
1655 {
1657 xNameAccess, UNO_QUERY );
1658
1659 OSL_ENSURE( xHierNameAccess.is(),
1660 "PersistentPropertySet::getPropertyValues - "
1661 "No hierarchical name access!" );
1662
1663 if ( xHierNameAccess.is() )
1664 {
1666 auto pValues = aValues.getArray();
1667
1668 static constexpr OUStringLiteral aHandleName(u"/Handle");
1669 static constexpr OUStringLiteral aValueName(u"/Value");
1670 static constexpr OUStringLiteral aStateName(u"/State");
1671
1672 for ( sal_Int32 n = 0; n < nCount; ++n )
1673 {
1674 PropertyValue& rValue = pValues[ n ];
1675 OUString rName = aElems[ n ];
1676 OUString aXMLName
1677 = makeHierarchalNameSegment( rName );
1678
1679 // Set property name.
1680
1681 rValue.Name = rName;
1682
1683 try
1684 {
1685 // Obtain and set property handle
1686 OUString aHierName = aXMLName + aHandleName;
1687 Any aKeyValue
1688 = xHierNameAccess->getByHierarchicalName(
1689 aHierName );
1690
1691 if ( !( aKeyValue >>= rValue.Handle ) )
1692 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1693 "Error getting property handle!" );
1694 }
1695 catch (const NoSuchElementException&)
1696 {
1697 // getByHierarchicalName
1698
1699 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1700 "NoSuchElementException!" );
1701 }
1702
1703 try
1704 {
1705 // Obtain and set property value
1706 OUString aHierName = aXMLName + aValueName;
1707 rValue.Value
1708 = xHierNameAccess->getByHierarchicalName(
1709 aHierName );
1710
1711 // Note: The value may be void if addProperty
1712 // was called with a default value
1713 // of type void.
1714 }
1715 catch (const NoSuchElementException&)
1716 {
1717 // getByHierarchicalName
1718
1719 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1720 "NoSuchElementException!" );
1721 }
1722
1723 try
1724 {
1725 // Obtain and set property state
1726 OUString aHierName = aXMLName +aStateName;
1727 Any aKeyValue
1728 = xHierNameAccess->getByHierarchicalName(
1729 aHierName );
1730
1731 sal_Int32 nState = 0;
1732 if ( !( aKeyValue >>= nState ) )
1733 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1734 "Error getting property state!" );
1735 else
1736 rValue.State = PropertyState( nState );
1737 }
1738 catch (const NoSuchElementException&)
1739 {
1740 // getByHierarchicalName
1741
1742 OSL_FAIL( "PersistentPropertySet::getPropertyValues - "
1743 "NoSuchElementException!" );
1744 }
1745 }
1746
1747 return aValues;
1748 }
1749 }
1750 }
1751 }
1752 catch (const NoSuchElementException&)
1753 {
1754 // getByHierarchicalName
1755 }
1756 }
1757
1758 return Sequence< PropertyValue >( 0 );
1759}
1760
1761
1762// virtual
1764 const Sequence< PropertyValue >& aProps )
1765{
1766 if ( !aProps.hasElements() )
1767 return;
1768
1769 std::unique_lock aCGuard(m_aMutex);
1770
1771 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1772 m_pCreator->getRootConfigReadAccess(), UNO_QUERY );
1773 if ( xRootHierNameAccess.is() )
1774 {
1775 std::vector< PropertyChangeEvent > aEvents;
1776
1777 OUString aFullPropNamePrefix( getFullKeyImpl(aCGuard) + "/" );
1778
1779 // Iterate over given property value sequence.
1780 for ( const PropertyValue& rNewValue : aProps )
1781 {
1782 const OUString& rName = rNewValue.Name;
1783
1784 OUString aFullPropName = aFullPropNamePrefix +
1786
1787 // Does property exist?
1788 if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
1789 {
1790 Reference< XNameReplace > xNameReplace(
1791 m_pCreator->getConfigWriteAccess(
1792 aFullPropName ), UNO_QUERY );
1794 m_pCreator->getConfigWriteAccess(
1795 OUString() ), UNO_QUERY );
1796
1797 if ( xNameReplace.is() && xBatch.is() )
1798 {
1799 try
1800 {
1801 // Write handle
1802 xNameReplace->replaceByName(
1803 "Handle",
1804 Any( rNewValue.Handle ) );
1805
1806 // Save old value
1807 OUString aValueName = aFullPropName +"/Value";
1808 Any aOldValue
1809 = xRootHierNameAccess->getByHierarchicalName(
1810 aValueName );
1811 // Write value
1812 xNameReplace->replaceByName(
1813 "Value",
1814 rNewValue.Value );
1815
1816 // Write state ( Now it is a directly set value )
1817 xNameReplace->replaceByName(
1818 "State",
1819 Any(
1820 sal_Int32(
1821 PropertyState_DIRECT_VALUE ) ) );
1822
1823 // Commit changes.
1824 xBatch->commitChanges();
1825
1827 {
1828 PropertyChangeEvent aEvt;
1829 aEvt.Source = getXWeak();
1830 aEvt.PropertyName = rNewValue.Name;
1831 aEvt.PropertyHandle = rNewValue.Handle;
1832 aEvt.Further = false;
1833 aEvt.OldValue = aOldValue;
1834 aEvt.NewValue = rNewValue.Value;
1835
1836 aEvents.push_back( aEvt );
1837 }
1838 }
1839 catch (const IllegalArgumentException&)
1840 {
1841 // replaceByName
1842 }
1843 catch (const NoSuchElementException&)
1844 {
1845 // getByHierarchicalName, replaceByName
1846 }
1847 catch (const WrappedTargetException&)
1848 {
1849 // replaceByName, commitChanges
1850 }
1851 }
1852 }
1853 }
1854
1856 {
1857 // Notify property changes.
1858 for (auto const& event : aEvents)
1859 {
1860 notifyPropertyChangeEvent( aCGuard, event );
1861 }
1862 }
1863
1864 return;
1865 }
1866
1867 OSL_FAIL( "PersistentPropertySet::setPropertyValues - Nothing set!" );
1868}
1869
1870
1871// Non-interface methods
1872
1873
1875 std::unique_lock<std::mutex>& rGuard,
1876 const PropertyChangeEvent& rEvent ) const
1877{
1878 // Get "normal" listeners for the property.
1880 m_aPropertyChangeListeners.getContainer( rGuard, rEvent.PropertyName );
1881 if ( pContainer && pContainer->getLength(rGuard) )
1882 {
1883 pContainer->notifyEach( rGuard, &XPropertyChangeListener::propertyChange, rEvent );
1884 }
1885
1886 // Get "normal" listeners for all properties.
1888 m_aPropertyChangeListeners.getContainer( rGuard, OUString() );
1889 if ( pNoNameContainer && pNoNameContainer->getLength(rGuard) )
1890 {
1891 pNoNameContainer->notifyEach( rGuard, &XPropertyChangeListener::propertyChange, rEvent );
1892 }
1893}
1894
1895
1897 std::unique_lock<std::mutex>& rGuard,
1898 const PropertySetInfoChangeEvent& evt ) const
1899{
1900 // Notify event listeners.
1901 m_aPropSetChangeListeners.notifyEach( rGuard, &XPropertySetInfoChangeListener::propertySetInfoChange, evt );
1902}
1903
1904
1906{
1907 std::unique_lock aGuard(m_aMutex);
1908 return getFullKeyImpl(aGuard);
1909}
1910
1911const OUString& PersistentPropertySet::getFullKeyImpl(std::unique_lock<std::mutex>& )
1912{
1913 if ( m_aFullKey.isEmpty() )
1914 {
1916 m_aFullKey += "/Values";
1917 }
1918
1919 return m_aFullKey;
1920}
1921
1922
1924{
1925 return *m_pCreator;
1926}
1927
1928
1929// PropertySetInfo_Impl Implementation.
1930
1931
1933 PersistentPropertySet* pOwner )
1934: m_pOwner( pOwner )
1935{
1936}
1937
1938
1939// XPropertySetInfo methods.
1940
1941
1942// virtual
1944{
1945 if ( !m_xProps )
1946 {
1947 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
1949 UNO_QUERY );
1950 if ( xRootHierNameAccess.is() )
1951 {
1952 try
1953 {
1954 Reference< XNameAccess > xNameAccess;
1955 xRootHierNameAccess->getByHierarchicalName(
1956 m_pOwner->getFullKey() )
1957 >>= xNameAccess;
1958 if ( xNameAccess.is() )
1959 {
1960 // Obtain property names.
1961
1963 = xNameAccess->getElementNames();
1964
1965 sal_uInt32 nCount = aElems.getLength();
1966 Sequence< Property > aPropSeq( nCount );
1967
1968 if ( nCount )
1969 {
1971 xNameAccess, UNO_QUERY );
1972
1973 OSL_ENSURE( xHierNameAccess.is(),
1974 "PropertySetInfo_Impl::getProperties - "
1975 "No hierarchical name access!" );
1976
1977 if ( xHierNameAccess.is() )
1978 {
1979 static constexpr OUStringLiteral aHandleName(u"/Handle");
1980 static constexpr OUStringLiteral aValueName(u"/Value");
1981 static constexpr OUStringLiteral aAttrName(u"/Attributes");
1982
1983 Property* pProps = aPropSeq.getArray();
1984
1985 for ( sal_uInt32 n = 0; n < nCount; ++n )
1986 {
1987 Property& rProp = pProps[ n ];
1988 OUString rName = aElems[ n ];
1989 OUString aXMLName
1990 = makeHierarchalNameSegment( rName );
1991
1992 // Set property name.
1993
1994 rProp.Name = rName;
1995
1996 try
1997 {
1998 // Obtain and set property handle
1999 OUString aHierName = aXMLName + aHandleName;
2000 Any aKeyValue
2001 = xHierNameAccess->getByHierarchicalName(
2002 aHierName );
2003
2004 if ( !( aKeyValue >>= rProp.Handle ) )
2005 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2006 "Error getting property handle!" );
2007 }
2008 catch (const NoSuchElementException&)
2009 {
2010 // getByHierarchicalName
2011
2012 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2013 "NoSuchElementException!" );
2014 }
2015
2016 try
2017 {
2018 // Obtain and set property type
2019 OUString aHierName = aXMLName + aValueName;
2020 Any aKeyValue
2021 = xHierNameAccess->getByHierarchicalName(
2022 aHierName );
2023
2024 // Note: The type may be void if addProperty
2025 // was called with a default value
2026 // of type void.
2027
2028 rProp.Type = aKeyValue.getValueType();
2029 }
2030 catch (const NoSuchElementException&)
2031 {
2032 // getByHierarchicalName
2033
2034 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2035 "NoSuchElementException!" );
2036 }
2037
2038 try
2039 {
2040 // Obtain and set property attributes
2041 OUString aHierName = aXMLName + aAttrName;
2042 Any aKeyValue
2043 = xHierNameAccess->getByHierarchicalName(
2044 aHierName );
2045
2046 sal_Int32 nAttribs = 0;
2047 if ( aKeyValue >>= nAttribs )
2048 rProp.Attributes
2049 = sal_Int16( nAttribs );
2050 else
2051 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2052 "Error getting property attributes!" );
2053 }
2054 catch (const NoSuchElementException&)
2055 {
2056 // getByHierarchicalName
2057
2058 OSL_FAIL( "PropertySetInfo_Impl::getProperties - "
2059 "NoSuchElementException!" );
2060 }
2061 }
2062 }
2063 }
2064
2065 // Success.
2066 m_xProps = std::move(aPropSeq);
2067 return *m_xProps;
2068 }
2069 }
2070 catch (const NoSuchElementException&)
2071 {
2072 // getByHierarchicalName
2073 }
2074 }
2075
2076 OSL_FAIL( "PropertySetInfo_Impl::getProperties - Error!" );
2077 m_xProps.emplace();
2078 }
2079
2080 return *m_xProps;
2081}
2082
2083
2084// virtual
2086 const OUString& aName )
2087{
2088 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2090 UNO_QUERY );
2091 if ( xRootHierNameAccess.is() )
2092 {
2093 OUString aFullPropName( m_pOwner->getFullKey() + "/" +
2095
2096 // Does property exist?
2097 if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) )
2098 throw UnknownPropertyException(aFullPropName);
2099
2100 try
2101 {
2102 Property aProp;
2103
2104 // Obtain handle.
2105 OUString aKey = aFullPropName + "/Handle";
2106
2107 if ( !( xRootHierNameAccess->getByHierarchicalName( aKey )
2108 >>= aProp.Handle ) )
2109 {
2110 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2111 "No handle!" );
2112 return Property();
2113 }
2114
2115 // Obtain Value and extract type.
2116 aKey = aFullPropName + "/Value";
2117
2118 Any aValue = xRootHierNameAccess->getByHierarchicalName( aKey );
2119 if ( !aValue.hasValue() )
2120 {
2121 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2122 "No Value!" );
2123 return Property();
2124 }
2125
2126 aProp.Type = aValue.getValueType();
2127
2128 // Obtain Attributes.
2129 aKey = aFullPropName + "/Attributes";
2130
2131 sal_Int32 nAttribs = 0;
2132 if ( xRootHierNameAccess->getByHierarchicalName( aKey )
2133 >>= nAttribs )
2134 aProp.Attributes = sal_Int16( nAttribs );
2135 else
2136 {
2137 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2138 "No attributes!" );
2139 return Property();
2140 }
2141
2142 // set name.
2143 aProp.Name = aName;
2144
2145 // Success.
2146 return aProp;
2147 }
2148 catch (const NoSuchElementException&)
2149 {
2150 // getByHierarchicalName
2151
2152 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - "
2153 "caught NoSuchElementException!" );
2154 }
2155
2156 }
2157
2158 OSL_FAIL( "PropertySetInfo_Impl::getPropertyByName - Error!" );
2159 return Property();
2160}
2161
2162
2163// virtual
2165 const OUString& Name )
2166{
2167 Reference< XHierarchicalNameAccess > xRootHierNameAccess(
2169 UNO_QUERY );
2170 if ( xRootHierNameAccess.is() )
2171 {
2172 OUString aFullPropName( m_pOwner->getFullKey() + "/" +
2174
2175 return xRootHierNameAccess->hasByHierarchicalName( aFullPropName );
2176 }
2177
2178 return false;
2179}
2180
2181/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
Reference< XComponentContext > m_xContext
virtual void SAL_CALL dispose() override
Definition: ucbstore.cxx:1046
comphelper::OInterfaceContainerHelper4< css::beans::XPropertySetInfoChangeListener > m_aPropSetChangeListeners
Definition: ucbstore.hxx:167
virtual void SAL_CALL removeProperty(const OUString &Name) override
Definition: ucbstore.cxx:1473
void notifyPropertyChangeEvent(std::unique_lock< std::mutex > &rGuard, const css::beans::PropertyChangeEvent &rEvent) const
Definition: ucbstore.cxx:1874
comphelper::OInterfaceContainerHelper4< css::lang::XEventListener > m_aDisposeEventListeners
Definition: ucbstore.hxx:166
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: ucbstore.cxx:1110
PropertyListeners_Impl m_aPropertyChangeListeners
Definition: ucbstore.hxx:168
virtual void SAL_CALL addPropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: ucbstore.cxx:1227
virtual void SAL_CALL setPropertyValues(const css::uno::Sequence< css::beans::PropertyValue > &aProps) override
Definition: ucbstore.cxx:1763
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: ucbstore.cxx:1266
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: ucbstore.cxx:1201
virtual void SAL_CALL removePropertySetInfoChangeListener(const css::uno::Reference< css::beans::XPropertySetInfoChangeListener > &Listener) override
Definition: ucbstore.cxx:1622
PropertySetRegistry & getPropertySetRegistry()
Definition: ucbstore.cxx:1923
void notifyPropertySetInfoChange(std::unique_lock< std::mutex > &rGuard, const css::beans::PropertySetInfoChangeEvent &evt) const
Definition: ucbstore.cxx:1896
virtual OUString SAL_CALL getKey() override
Definition: ucbstore.cxx:1286
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: ucbstore.cxx:1031
virtual css::uno::Reference< css::ucb::XPropertySetRegistry > SAL_CALL getRegistry() override
Definition: ucbstore.cxx:1279
virtual void SAL_CALL addPropertySetInfoChangeListener(const css::uno::Reference< css::beans::XPropertySetInfoChangeListener > &Listener) override
Definition: ucbstore.cxx:1612
virtual void SAL_CALL setName(const OUString &aName) override
Definition: ucbstore.cxx:1304
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: ucbstore.cxx:1097
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &Listener) override
Definition: ucbstore.cxx:1083
rtl::Reference< PropertySetInfo_Impl > m_pInfo
Definition: ucbstore.hxx:162
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: ucbstore.cxx:1036
rtl::Reference< PropertySetRegistry > m_pCreator
Definition: ucbstore.hxx:161
PersistentPropertySet(std::unique_lock< std::mutex > &rCreatorGuard, PropertySetRegistry &rCreator, OUString aKey)
Definition: ucbstore.cxx:1006
virtual OUString SAL_CALL getImplementationName() override
Definition: ucbstore.cxx:1026
virtual void SAL_CALL addProperty(const OUString &Name, sal_Int16 Attributes, const css::uno::Any &DefaultValue) override
Definition: ucbstore.cxx:1315
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getPropertyValues() override
Definition: ucbstore.cxx:1634
virtual ~PersistentPropertySet() override
Definition: ucbstore.cxx:1018
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
Definition: ucbstore.cxx:1240
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &Listener) override
Definition: ucbstore.cxx:1073
virtual OUString SAL_CALL getName() override
Definition: ucbstore.cxx:1296
const OUString & getFullKeyImpl(std::unique_lock< std::mutex > &)
Definition: ucbstore.cxx:1911
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: ucbstore.cxx:1256
std::optional< Sequence< Property > > m_xProps
Definition: ucbstore.cxx:110
virtual Property SAL_CALL getPropertyByName(const OUString &aName) override
Definition: ucbstore.cxx:2085
PersistentPropertySet * m_pOwner
Definition: ucbstore.cxx:111
virtual sal_Bool SAL_CALL hasPropertyByName(const OUString &Name) override
Definition: ucbstore.cxx:2164
virtual Sequence< Property > SAL_CALL getProperties() override
Definition: ucbstore.cxx:1943
PropertySetInfo_Impl(PersistentPropertySet *pOwner)
Definition: ucbstore.cxx:1932
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: ucbstore.hxx:84
virtual void SAL_CALL removePropertySet(const OUString &key) override
Definition: ucbstore.cxx:363
css::uno::Reference< css::uno::XInterface > getRootConfigReadAccessImpl(std::unique_lock< std::mutex > &l)
Definition: ucbstore.cxx:862
friend class PersistentPropertySet
Definition: ucbstore.hxx:82
css::uno::Reference< css::uno::XInterface > getConfigWriteAccessImpl(std::unique_lock< std::mutex > &l, const OUString &rPath)
Definition: ucbstore.cxx:922
css::uno::Reference< css::lang::XMultiServiceFactory > getConfigProvider(std::unique_lock< std::mutex > &l)
Definition: ucbstore.cxx:824
css::uno::Reference< css::uno::XInterface > getRootConfigReadAccess()
Definition: ucbstore.cxx:856
virtual css::uno::Reference< css::ucb::XPersistentPropertySet > SAL_CALL openPropertySet(const OUString &key, sal_Bool create) override
Definition: ucbstore.cxx:240
css::uno::Reference< css::uno::XInterface > getConfigWriteAccess(const OUString &rPath)
Definition: ucbstore.cxx:915
const css::uno::Sequence< css::uno::Any > m_aInitArgs
Definition: ucbstore.hxx:85
PropertySetMap_Impl m_aPropSets
Definition: ucbstore.hxx:86
virtual css::uno::Type SAL_CALL getElementType() override
Definition: ucbstore.cxx:422
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: ucbstore.cxx:229
virtual OUString SAL_CALL getImplementationName() override
Definition: ucbstore.cxx:219
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: ucbstore.cxx:224
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: ucbstore.cxx:444
bool m_bTriedToGetRootReadAccess
Definition: ucbstore.hxx:91
std::mutex m_aMutex
Definition: ucbstore.hxx:90
PropertySetRegistry(const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Sequence< css::uno::Any > &rInitArgs)
Definition: ucbstore.cxx:199
css::uno::Reference< css::lang::XMultiServiceFactory > m_xConfigProvider
Definition: ucbstore.hxx:87
void renamePropertySet(const OUString &rOldKey, const OUString &rNewKey)
Definition: ucbstore.cxx:529
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: ucbstore.cxx:483
void remove(PersistentPropertySet *pSet)
Definition: ucbstore.cxx:509
virtual sal_Bool SAL_CALL hasElements() override
Definition: ucbstore.cxx:429
void add(std::unique_lock< std::mutex > &rCreatorGuard, PersistentPropertySet *pSet)
Definition: ucbstore.cxx:496
css::uno::Reference< css::uno::XInterface > m_xRootWriteAccess
Definition: ucbstore.hxx:89
bool m_bTriedToGetRootWriteAccess
Definition: ucbstore.hxx:92
css::uno::Reference< css::uno::XInterface > m_xRootReadAccess
Definition: ucbstore.hxx:88
virtual ~PropertySetRegistry() override
Definition: ucbstore.cxx:211
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: ucbstore.cxx:470
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: ucbstore.hxx:49
UcbStore(const css::uno::Reference< css::uno::XComponentContext > &xContext)
Definition: ucbstore.cxx:129
virtual OUString SAL_CALL getImplementationName() override
Definition: ucbstore.cxx:140
virtual css::uno::Reference< css::ucb::XPropertySetRegistry > SAL_CALL createPropertySetRegistry(const OUString &URL) override
Definition: ucbstore.cxx:168
css::uno::Reference< css::ucb::XPropertySetRegistry > m_xTheRegistry
Definition: ucbstore.hxx:51
virtual ~UcbStore() override
Definition: ucbstore.cxx:136
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: ucbstore.cxx:148
css::uno::Sequence< css::uno::Any > m_aInitArgs
Definition: ucbstore.hxx:50
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: ucbstore.cxx:144
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &aArguments) override
Definition: ucbstore.cxx:188
sal_Int32 addInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
void notifyEach(std::unique_lock< std::mutex > &rGuard, void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event) const
void disposeAndClear(::std::unique_lock<::std::mutex > &rGuard, const css::lang::EventObject &rEvt)
sal_Int32 getLength(std::unique_lock< std::mutex > &rGuard) const
sal_Int32 removeInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
sal_Int32 removeInterface(::std::unique_lock<::std::mutex > &rGuard, const key &rKey, const css::uno::Reference< listener > &rListener)
bool hasContainedTypes(std::unique_lock< std::mutex > &rGuard) const
sal_Int32 addInterface(::std::unique_lock<::std::mutex > &rGuard, const key &rKey, const css::uno::Reference< listener > &rListener)
void disposeAndClear(std::unique_lock< std::mutex > &rGuard, const css::lang::EventObject &rEvt)
OInterfaceContainerHelper4< listener > * getContainer(std::unique_lock< std::mutex > &rGuard, const key &rKey) const
css::uno::Type const & get()
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
float u
sal_Int32 nState
Sequence< PropertyValue > aArguments
OUString aName
sal_Int64 n
SvLinkSource * pOwner
#define SAL_WARN(area, stream)
@ Exception
class SAL_NO_VTABLE XPropertySet
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
ContentProvider * m_pOwner
Definition: pkgprovider.cxx:58
sal_Int32 nHandle
OUString Name
unsigned char sal_Bool
sal_uInt16 sal_Unicode
constexpr OUStringLiteral CFGPROPERTY_NODEPATH
Definition: ucbstore.cxx:105
static OUString makeHierarchalNameSegment(std::u16string_view rIn)
Definition: ucbstore.cxx:62
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * ucb_UcbStore_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Definition: ucbstore.cxx:156
constexpr OUStringLiteral STORE_CONTENTPROPERTIES_KEY
Definition: ucbstore.cxx:102
std::unordered_map< OUString, PersistentPropertySet * > PropertySetMap_Impl
Definition: ucbstore.hxx:72
std::unique_ptr< char[]> aBuffer