1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: providerhelper.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucbhelper.hxx"
34 /**************************************************************************
36 **************************************************************************
38 *************************************************************************/
41 #include <com/sun/star/beans/XPropertyAccess.hpp>
42 #include <com/sun/star/container/XNameAccess.hpp>
43 #include <com/sun/star/container/XNamed.hpp>
44 #include <com/sun/star/ucb/XPropertySetRegistryFactory.hpp>
45 #include <com/sun/star/ucb/XPropertySetRegistry.hpp>
47 #include "osl/diagnose.h"
48 #include "osl/mutex.hxx"
49 #include "cppuhelper/weakref.hxx"
50 #include <ucbhelper/contentidentifier.hxx>
51 #include <ucbhelper/providerhelper.hxx>
52 #include <ucbhelper/contenthelper.hxx>
54 using namespace com::sun::star
;
56 namespace ucbhelper_impl
59 //=========================================================================
63 //=========================================================================
68 const rtl::OUString
& rKey11
, const rtl::OUString
& rKey22
) const
70 return !!( rKey11
== rKey22
);
76 size_t operator()( const rtl::OUString
& rName
) const
78 return rName
.hashCode();
85 uno::WeakReference
< ucb::XContent
>,
91 //=========================================================================
93 // struct ContentProviderImplHelper_Impl.
95 //=========================================================================
97 struct ContentProviderImplHelper_Impl
99 uno::Reference
< com::sun::star::ucb::XPropertySetRegistry
>
100 m_xPropertySetRegistry
;
105 } // namespace ucbhelper_impl
107 //=========================================================================
108 //=========================================================================
110 // ContentProviderImplHelper Implementation.
112 //=========================================================================
113 //=========================================================================
115 namespace ucbhelper
{
117 ContentProviderImplHelper::ContentProviderImplHelper(
118 const uno::Reference
< lang::XMultiServiceFactory
>& rXSMgr
)
119 : m_pImpl( new ucbhelper_impl::ContentProviderImplHelper_Impl
),
124 //=========================================================================
126 ContentProviderImplHelper::~ContentProviderImplHelper()
131 //=========================================================================
133 // XInterface methods.
135 //=========================================================================
137 XINTERFACE_IMPL_3( ContentProviderImplHelper
,
140 com::sun::star::ucb::XContentProvider
);
142 //=========================================================================
144 // XTypeProvider methods.
146 //=========================================================================
148 XTYPEPROVIDER_IMPL_3( ContentProviderImplHelper
,
151 com::sun::star::ucb::XContentProvider
);
153 //=========================================================================
155 // XServiceInfo methods.
157 //=========================================================================
160 sal_Bool SAL_CALL
ContentProviderImplHelper::supportsService(
161 const rtl::OUString
& ServiceName
)
162 throw( uno::RuntimeException
)
164 uno::Sequence
< rtl::OUString
> aSNL
= getSupportedServiceNames();
165 const rtl::OUString
* pArray
= aSNL
.getConstArray();
166 for ( sal_Int32 i
= 0; i
< aSNL
.getLength(); i
++ )
168 if ( pArray
[ i
] == ServiceName
)
175 //=========================================================================
177 // XContentProvider methods.
179 //=========================================================================
182 sal_Int32 SAL_CALL
ContentProviderImplHelper::compareContentIds(
183 const uno::Reference
< com::sun::star::ucb::XContentIdentifier
>& Id1
,
184 const uno::Reference
< com::sun::star::ucb::XContentIdentifier
>& Id2
)
185 throw( uno::RuntimeException
)
187 // Simply do a string compare.
189 rtl::OUString
aURL1( Id1
->getContentIdentifier() );
190 rtl::OUString
aURL2( Id2
->getContentIdentifier() );
192 return aURL1
.compareTo( aURL2
);;
195 //=========================================================================
197 // Non-interface methods
199 //=========================================================================
201 void ContentProviderImplHelper::cleanupRegisteredContents()
203 osl::MutexGuard
aGuard( m_aMutex
);
205 ucbhelper_impl::Contents::iterator it
206 = m_pImpl
->m_aContents
.begin();
207 while( it
!= m_pImpl
->m_aContents
.end() )
209 uno::Reference
< ucb::XContent
> xContent( (*it
).second
);
210 if ( !xContent
.is() )
212 ucbhelper_impl::Contents::iterator tmp
= it
;
214 m_pImpl
->m_aContents
.erase( tmp
);
223 //=========================================================================
225 void ContentProviderImplHelper::removeContent( ContentImplHelper
* pContent
)
227 osl::MutexGuard
aGuard( m_aMutex
);
229 cleanupRegisteredContents();
231 const rtl::OUString
aURL(
232 pContent
->getIdentifier()->getContentIdentifier() );
234 ucbhelper_impl::Contents::iterator it
= m_pImpl
->m_aContents
.find( aURL
);
236 if ( it
!= m_pImpl
->m_aContents
.end() )
237 m_pImpl
->m_aContents
.erase( it
);
240 //=========================================================================
241 rtl::Reference
< ContentImplHelper
>
242 ContentProviderImplHelper::queryExistingContent(
243 const uno::Reference
< com::sun::star::ucb::XContentIdentifier
>&
246 return queryExistingContent( Identifier
->getContentIdentifier() );
249 //=========================================================================
250 rtl::Reference
< ContentImplHelper
>
251 ContentProviderImplHelper::queryExistingContent( const rtl::OUString
& rURL
)
253 osl::MutexGuard
aGuard( m_aMutex
);
255 cleanupRegisteredContents();
257 // Check, if a content with given id already exists...
259 ucbhelper_impl::Contents::const_iterator it
260 = m_pImpl
->m_aContents
.find( rURL
);
261 if ( it
!= m_pImpl
->m_aContents
.end() )
263 uno::Reference
< ucb::XContent
> xContent( (*it
).second
);
266 return rtl::Reference
< ContentImplHelper
>(
267 static_cast< ContentImplHelper
* >( xContent
.get() ) );
270 return rtl::Reference
< ContentImplHelper
>();
273 //=========================================================================
274 void ContentProviderImplHelper::queryExistingContents(
275 ContentRefList
& rContents
)
277 osl::MutexGuard
aGuard( m_aMutex
);
279 cleanupRegisteredContents();
281 ucbhelper_impl::Contents::const_iterator it
282 = m_pImpl
->m_aContents
.begin();
283 ucbhelper_impl::Contents::const_iterator end
284 = m_pImpl
->m_aContents
.end();
288 uno::Reference
< ucb::XContent
> xContent( (*it
).second
);
292 rtl::Reference
< ContentImplHelper
>(
293 static_cast< ContentImplHelper
* >( xContent
.get() ) ) );
299 //=========================================================================
300 void ContentProviderImplHelper::registerNewContent(
301 const uno::Reference
< ucb::XContent
> & xContent
)
305 osl::MutexGuard
aGuard( m_aMutex
);
307 cleanupRegisteredContents();
309 const rtl::OUString
aURL(
310 xContent
->getIdentifier()->getContentIdentifier() );
311 ucbhelper_impl::Contents::const_iterator it
312 = m_pImpl
->m_aContents
.find( aURL
);
313 if ( it
== m_pImpl
->m_aContents
.end() )
314 m_pImpl
->m_aContents
[ aURL
] = xContent
;
318 //=========================================================================
319 uno::Reference
< com::sun::star::ucb::XPropertySetRegistry
>
320 ContentProviderImplHelper::getAdditionalPropertySetRegistry()
322 // Get propertyset registry.
324 osl::MutexGuard
aGuard( m_aMutex
);
326 if ( !m_pImpl
->m_xPropertySetRegistry
.is() )
328 uno::Reference
< com::sun::star::ucb::XPropertySetRegistryFactory
>
330 m_xSMgr
->createInstance(
331 rtl::OUString::createFromAscii(
332 "com.sun.star.ucb.Store" ) ),
335 OSL_ENSURE( xRegFac
.is(),
336 "ContentProviderImplHelper::getAdditionalPropertySet - "
337 "No UCB-Store service!" );
341 // Open/create a registry.
342 m_pImpl
->m_xPropertySetRegistry
343 = xRegFac
->createPropertySetRegistry( rtl::OUString() );
345 OSL_ENSURE( m_pImpl
->m_xPropertySetRegistry
.is(),
346 "ContentProviderImplHelper::getAdditionalPropertySet - "
347 "Error opening registry!" );
351 return m_pImpl
->m_xPropertySetRegistry
;
355 //=========================================================================
356 uno::Reference
< com::sun::star::ucb::XPersistentPropertySet
>
357 ContentProviderImplHelper::getAdditionalPropertySet(
358 const rtl::OUString
& rKey
, sal_Bool bCreate
)
360 // Get propertyset registry.
361 getAdditionalPropertySetRegistry();
363 if ( m_pImpl
->m_xPropertySetRegistry
.is() )
365 // Open/create persistent property set.
366 return uno::Reference
< com::sun::star::ucb::XPersistentPropertySet
>(
367 m_pImpl
->m_xPropertySetRegistry
->openPropertySet(
371 return uno::Reference
< com::sun::star::ucb::XPersistentPropertySet
>();
374 //=========================================================================
375 sal_Bool
ContentProviderImplHelper::renameAdditionalPropertySet(
376 const rtl::OUString
& rOldKey
,
377 const rtl::OUString
& rNewKey
,
378 sal_Bool bRecursive
)
380 if ( rOldKey
== rNewKey
)
383 osl::MutexGuard
aGuard( m_aMutex
);
387 // Get propertyset registry.
388 getAdditionalPropertySetRegistry();
390 if ( m_pImpl
->m_xPropertySetRegistry
.is() )
392 uno::Reference
< container::XNameAccess
> xNameAccess(
393 m_pImpl
->m_xPropertySetRegistry
, uno::UNO_QUERY
);
394 if ( xNameAccess
.is() )
396 uno::Sequence
< rtl::OUString
> aKeys
397 = xNameAccess
->getElementNames();
398 sal_Int32 nCount
= aKeys
.getLength();
401 rtl::OUString aOldKeyWithSlash
= rOldKey
;
402 rtl::OUString aOldKeyWithoutSlash
;
403 if ( aOldKeyWithSlash
.lastIndexOf(
405 != aOldKeyWithSlash
.getLength() - 1 ) )
407 aOldKeyWithSlash
+= rtl::OUString( sal_Unicode('/') );
408 aOldKeyWithoutSlash
= rOldKey
;
410 else if ( rOldKey
.getLength() )
412 = rOldKey
.copy( 0, rOldKey
.getLength() - 1 );
414 const rtl::OUString
* pKeys
= aKeys
.getConstArray();
415 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
417 const rtl::OUString
& rKey
= pKeys
[ n
];
420 aOldKeyWithSlash
.getLength() ) == 0
421 || rKey
.equals( aOldKeyWithoutSlash
) )
423 rtl::OUString aNewKey
425 0, rOldKey
.getLength(), rNewKey
);
426 if ( !renameAdditionalPropertySet(
427 rKey
, aNewKey
, sal_False
) )
441 // Get old property set, if exists.
442 uno::Reference
< com::sun::star::ucb::XPersistentPropertySet
> xOldSet
443 = getAdditionalPropertySet( rOldKey
, sal_False
);
446 // Rename property set.
447 uno::Reference
< container::XNamed
> xNamed(
448 xOldSet
, uno::UNO_QUERY
);
451 // ??? throws no exceptions and has no return value ???
452 xNamed
->setName( rNewKey
);
461 //=========================================================================
462 sal_Bool
ContentProviderImplHelper::copyAdditionalPropertySet(
463 const rtl::OUString
& rSourceKey
,
464 const rtl::OUString
& rTargetKey
,
465 sal_Bool bRecursive
)
467 if ( rSourceKey
== rTargetKey
)
470 osl::MutexGuard
aGuard( m_aMutex
);
474 // Get propertyset registry.
475 getAdditionalPropertySetRegistry();
477 if ( m_pImpl
->m_xPropertySetRegistry
.is() )
479 uno::Reference
< container::XNameAccess
> xNameAccess(
480 m_pImpl
->m_xPropertySetRegistry
, uno::UNO_QUERY
);
481 if ( xNameAccess
.is() )
483 uno::Sequence
< rtl::OUString
> aKeys
484 = xNameAccess
->getElementNames();
485 sal_Int32 nCount
= aKeys
.getLength();
488 rtl::OUString aSrcKeyWithSlash
= rSourceKey
;
489 rtl::OUString aSrcKeyWithoutSlash
;
490 if ( aSrcKeyWithSlash
.lastIndexOf(
492 != aSrcKeyWithSlash
.getLength() - 1 ) )
494 aSrcKeyWithSlash
+= rtl::OUString( sal_Unicode('/') );
495 aSrcKeyWithoutSlash
= rSourceKey
;
497 else if ( rSourceKey
.getLength() )
498 aSrcKeyWithoutSlash
= rSourceKey
.copy(
499 0, rSourceKey
.getLength() - 1 );
501 const rtl::OUString
* pKeys
= aKeys
.getConstArray();
502 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
504 const rtl::OUString
& rKey
= pKeys
[ n
];
507 aSrcKeyWithSlash
.getLength() ) == 0
508 || rKey
.equals( aSrcKeyWithoutSlash
) )
510 rtl::OUString aNewKey
512 0, rSourceKey
.getLength(), rTargetKey
);
513 if ( !copyAdditionalPropertySet(
514 rKey
, aNewKey
, sal_False
) )
528 // Get old property set, if exists.
529 uno::Reference
< com::sun::star::ucb::XPersistentPropertySet
>
530 xOldPropSet
= getAdditionalPropertySet( rSourceKey
, sal_False
);
531 if ( !xOldPropSet
.is() )
534 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
535 = xOldPropSet
->getPropertySetInfo();
536 if ( !xPropSetInfo
.is() )
539 uno::Reference
< beans::XPropertyAccess
> xOldPropAccess(
540 xOldPropSet
, uno::UNO_QUERY
);
541 if ( !xOldPropAccess
.is() )
544 // Obtain all values from old set.
545 uno::Sequence
< beans::PropertyValue
> aValues
546 = xOldPropAccess
->getPropertyValues();
547 sal_Int32 nCount
= aValues
.getLength();
549 uno::Sequence
< beans::Property
> aProps
550 = xPropSetInfo
->getProperties();
554 // Fail, if property set with new key already exists.
555 uno::Reference
< com::sun::star::ucb::XPersistentPropertySet
>
557 = getAdditionalPropertySet( rTargetKey
, sal_False
);
558 if ( xNewPropSet
.is() )
561 // Create new, empty set.
562 xNewPropSet
= getAdditionalPropertySet( rTargetKey
, sal_True
);
563 if ( !xNewPropSet
.is() )
566 uno::Reference
< beans::XPropertyContainer
> xNewPropContainer(
567 xNewPropSet
, uno::UNO_QUERY
);
568 if ( !xNewPropContainer
.is() )
571 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
573 const beans::PropertyValue
& rValue
= aValues
[ n
];
575 sal_Int16 nAttribs
= 0;
576 for ( sal_Int32 m
= 0; m
< aProps
.getLength(); ++m
)
578 if ( aProps
[ m
].Name
== rValue
.Name
)
580 nAttribs
= aProps
[ m
].Attributes
;
587 xNewPropContainer
->addProperty(
588 rValue
.Name
, nAttribs
, rValue
.Value
);
590 catch ( beans::PropertyExistException
& )
593 catch ( beans::IllegalTypeException
& )
596 catch ( lang::IllegalArgumentException
& )
605 //=========================================================================
606 sal_Bool
ContentProviderImplHelper::removeAdditionalPropertySet(
607 const rtl::OUString
& rKey
, sal_Bool bRecursive
)
609 osl::MutexGuard
aGuard( m_aMutex
);
613 // Get propertyset registry.
614 getAdditionalPropertySetRegistry();
616 if ( m_pImpl
->m_xPropertySetRegistry
.is() )
618 uno::Reference
< container::XNameAccess
> xNameAccess(
619 m_pImpl
->m_xPropertySetRegistry
, uno::UNO_QUERY
);
620 if ( xNameAccess
.is() )
622 uno::Sequence
< rtl::OUString
> aKeys
623 = xNameAccess
->getElementNames();
624 sal_Int32 nCount
= aKeys
.getLength();
627 rtl::OUString aKeyWithSlash
= rKey
;
628 rtl::OUString aKeyWithoutSlash
;
629 if ( aKeyWithSlash
.lastIndexOf(
631 != aKeyWithSlash
.getLength() - 1 ) )
633 aKeyWithSlash
+= rtl::OUString( (sal_Unicode
)'/' );
634 aKeyWithoutSlash
= rKey
;
636 else if ( rKey
.getLength() )
638 = rKey
.copy( 0, rKey
.getLength() - 1 );
640 const rtl::OUString
* pKeys
= aKeys
.getConstArray();
641 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
643 const rtl::OUString
& rCurrKey
= pKeys
[ n
];
644 if ( rCurrKey
.compareTo(
646 aKeyWithSlash
.getLength() ) == 0
647 || rCurrKey
.equals( aKeyWithoutSlash
) )
649 if ( !removeAdditionalPropertySet(
650 rCurrKey
, sal_False
) )
664 // Get propertyset registry.
665 getAdditionalPropertySetRegistry();
667 if ( m_pImpl
->m_xPropertySetRegistry
.is() )
668 m_pImpl
->m_xPropertySetRegistry
->removePropertySet( rKey
);
675 } // namespace ucbhelper