1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 /**************************************************************************
23 **************************************************************************
25 - optimize transfer command. "Move" should be implementable much more
28 **************************************************************************
30 - Root Folder vs. 'normal' Folder
31 - root doesn't support command 'delete'
32 - root doesn't support command 'insert'
33 - root needs not created via XContentCreator - queryContent with root
34 folder id ( HIERARCHY_ROOT_FOLDER_URL ) always returns a value != 0
37 *************************************************************************/
38 #include <osl/diagnose.h>
40 #include <rtl/ustring.hxx>
41 #include <com/sun/star/beans/IllegalTypeException.hpp>
42 #include <com/sun/star/beans/PropertyAttribute.hpp>
43 #include <com/sun/star/beans/PropertyExistException.hpp>
44 #include <com/sun/star/beans/PropertyState.hpp>
45 #include <com/sun/star/lang/IllegalAccessException.hpp>
46 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
47 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
48 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
49 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
50 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
51 #include <com/sun/star/ucb/NameClash.hpp>
52 #include <com/sun/star/ucb/NameClashException.hpp>
53 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
54 #include <com/sun/star/ucb/TransferInfo.hpp>
55 #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
56 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
57 #include <com/sun/star/ucb/XCommandInfo.hpp>
58 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
59 #include <com/sun/star/uno/Any.hxx>
60 #include <com/sun/star/uno/Sequence.hxx>
61 #include <comphelper/propertysequence.hxx>
62 #include <comphelper/sequence.hxx>
63 #include <cppuhelper/queryinterface.hxx>
64 #include <ucbhelper/contentidentifier.hxx>
65 #include <ucbhelper/propertyvalueset.hxx>
66 #include <ucbhelper/cancelcommandexecution.hxx>
67 #include <ucbhelper/macros.hxx>
68 #include "hierarchycontent.hxx"
69 #include "hierarchyprovider.hxx"
70 #include "dynamicresultset.hxx"
71 #include "hierarchyuri.hxx"
73 #include "../inc/urihelper.hxx"
75 using namespace com::sun::star
;
76 using namespace hierarchy_ucp
;
79 // HierarchyContent Implementation.
82 // static ( "virtual" ctor )
83 rtl::Reference
<HierarchyContent
> HierarchyContent::create(
84 const uno::Reference
< uno::XComponentContext
>& rxContext
,
85 HierarchyContentProvider
* pProvider
,
86 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
88 // Fail, if content does not exist.
89 HierarchyContentProperties aProps
;
90 if ( !loadData( rxContext
, pProvider
, Identifier
, aProps
) )
93 return new HierarchyContent( rxContext
, pProvider
, Identifier
, aProps
);
97 // static ( "virtual" ctor )
98 rtl::Reference
<HierarchyContent
> HierarchyContent::create(
99 const uno::Reference
< uno::XComponentContext
>& rxContext
,
100 HierarchyContentProvider
* pProvider
,
101 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
102 const ucb::ContentInfo
& Info
)
104 if ( Info
.Type
.isEmpty() )
107 if ( Info
.Type
!= HIERARCHY_FOLDER_CONTENT_TYPE
&& Info
.Type
!= HIERARCHY_LINK_CONTENT_TYPE
)
110 return new HierarchyContent( rxContext
, pProvider
, Identifier
, Info
);
114 HierarchyContent::HierarchyContent(
115 const uno::Reference
< uno::XComponentContext
>& rxContext
,
116 HierarchyContentProvider
* pProvider
,
117 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
118 const HierarchyContentProperties
& rProps
)
119 : ContentImplHelper( rxContext
, pProvider
, Identifier
),
121 m_eState( PERSISTENT
),
122 m_pProvider( pProvider
),
123 m_bCheckedReadOnly( false ),
124 m_bIsReadOnly( true )
126 setKind( Identifier
);
130 HierarchyContent::HierarchyContent(
131 const uno::Reference
< uno::XComponentContext
>& rxContext
,
132 HierarchyContentProvider
* pProvider
,
133 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
134 const ucb::ContentInfo
& Info
)
135 : ContentImplHelper( rxContext
, pProvider
, Identifier
),
136 m_aProps( Info
.Type
== HIERARCHY_FOLDER_CONTENT_TYPE
? HierarchyEntryData::FOLDER
: HierarchyEntryData::LINK
),
137 m_eState( TRANSIENT
),
138 m_pProvider( pProvider
),
139 m_bCheckedReadOnly( false ),
140 m_bIsReadOnly( true )
142 setKind( Identifier
);
147 HierarchyContent::~HierarchyContent()
152 // XInterface methods.
156 void SAL_CALL
HierarchyContent::acquire()
159 ContentImplHelper::acquire();
164 void SAL_CALL
HierarchyContent::release()
167 ContentImplHelper::release();
172 uno::Any SAL_CALL
HierarchyContent::queryInterface( const uno::Type
& rType
)
174 uno::Any aRet
= ContentImplHelper::queryInterface( rType
);
176 if ( !aRet
.hasValue() )
178 // Note: isReadOnly may be relative expensive. So avoid calling it
179 // unless it is really necessary.
180 aRet
= cppu::queryInterface(
181 rType
, static_cast< ucb::XContentCreator
* >( this ) );
182 if ( aRet
.hasValue() )
184 if ( !isFolder() || isReadOnly() )
193 // XTypeProvider methods.
196 XTYPEPROVIDER_COMMON_IMPL( HierarchyContent
);
200 uno::Sequence
< uno::Type
> SAL_CALL
HierarchyContent::getTypes()
202 if ( isFolder() && !isReadOnly() )
204 static cppu::OTypeCollection
s_aFolderTypes(
205 CPPU_TYPE_REF( lang::XTypeProvider
),
206 CPPU_TYPE_REF( lang::XServiceInfo
),
207 CPPU_TYPE_REF( lang::XComponent
),
208 CPPU_TYPE_REF( ucb::XContent
),
209 CPPU_TYPE_REF( ucb::XCommandProcessor
),
210 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
211 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
212 CPPU_TYPE_REF( beans::XPropertyContainer
),
213 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
214 CPPU_TYPE_REF( container::XChild
),
215 CPPU_TYPE_REF( ucb::XContentCreator
) );
218 return s_aFolderTypes
.getTypes();
222 static cppu::OTypeCollection
s_aDocumentTypes(
223 CPPU_TYPE_REF( lang::XTypeProvider
),
224 CPPU_TYPE_REF( lang::XServiceInfo
),
225 CPPU_TYPE_REF( lang::XComponent
),
226 CPPU_TYPE_REF( ucb::XContent
),
227 CPPU_TYPE_REF( ucb::XCommandProcessor
),
228 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
229 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
230 CPPU_TYPE_REF( beans::XPropertyContainer
),
231 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
232 CPPU_TYPE_REF( container::XChild
) );
234 return s_aDocumentTypes
.getTypes();
239 // XServiceInfo methods.
243 OUString SAL_CALL
HierarchyContent::getImplementationName()
245 return "com.sun.star.comp.ucb.HierarchyContent";
250 uno::Sequence
< OUString
> SAL_CALL
251 HierarchyContent::getSupportedServiceNames()
253 uno::Sequence
< OUString
> aSNS( 1 );
255 if ( m_eKind
== LINK
)
256 aSNS
.getArray()[ 0 ] = "com.sun.star.ucb.HierarchyLinkContent";
257 else if ( m_eKind
== FOLDER
)
258 aSNS
.getArray()[ 0 ] = "com.sun.star.ucb.HierarchyFolderContent";
260 aSNS
.getArray()[ 0 ] = "com.sun.star.ucb.HierarchyRootFolderContent";
270 OUString SAL_CALL
HierarchyContent::getContentType()
272 return m_aProps
.getContentType();
277 uno::Reference
< ucb::XContentIdentifier
> SAL_CALL
278 HierarchyContent::getIdentifier()
281 if ( m_eState
== TRANSIENT
)
283 // Transient contents have no identifier.
284 return uno::Reference
< ucb::XContentIdentifier
>();
287 return ContentImplHelper::getIdentifier();
291 // XCommandProcessor methods.
295 uno::Any SAL_CALL
HierarchyContent::execute(
296 const ucb::Command
& aCommand
,
297 sal_Int32
/*CommandId*/,
298 const uno::Reference
< ucb::XCommandEnvironment
>& Environment
)
302 if ( aCommand
.Name
== "getPropertyValues" )
308 uno::Sequence
< beans::Property
> Properties
;
309 if ( !( aCommand
.Argument
>>= Properties
) )
311 ucbhelper::cancelCommandExecution(
312 uno::makeAny( lang::IllegalArgumentException(
313 "Wrong argument type!",
314 static_cast< cppu::OWeakObject
* >( this ),
320 aRet
<<= getPropertyValues( Properties
);
322 else if ( aCommand
.Name
== "setPropertyValues" )
328 uno::Sequence
< beans::PropertyValue
> aProperties
;
329 if ( !( aCommand
.Argument
>>= aProperties
) )
331 ucbhelper::cancelCommandExecution(
332 uno::makeAny( lang::IllegalArgumentException(
333 "Wrong argument type!",
334 static_cast< cppu::OWeakObject
* >( this ),
340 if ( !aProperties
.hasElements() )
342 ucbhelper::cancelCommandExecution(
343 uno::makeAny( lang::IllegalArgumentException(
345 static_cast< cppu::OWeakObject
* >( this ),
351 aRet
<<= setPropertyValues( aProperties
, Environment
);
353 else if ( aCommand
.Name
== "getPropertySetInfo" )
356 // getPropertySetInfo
359 aRet
<<= getPropertySetInfo( Environment
);
361 else if ( aCommand
.Name
== "getCommandInfo" )
367 aRet
<<= getCommandInfo( Environment
);
369 else if ( aCommand
.Name
== "open" && isFolder() )
372 // open command for a folder content
375 ucb::OpenCommandArgument2 aOpenCommand
;
376 if ( !( aCommand
.Argument
>>= aOpenCommand
) )
378 ucbhelper::cancelCommandExecution(
379 uno::makeAny( lang::IllegalArgumentException(
380 "Wrong argument type!",
381 static_cast< cppu::OWeakObject
* >( this ),
387 uno::Reference
< ucb::XDynamicResultSet
> xSet
388 = new DynamicResultSet( m_xContext
, this, aOpenCommand
);
391 else if ( aCommand
.Name
== "insert" && ( m_eKind
!= ROOT
) && !isReadOnly() )
395 // ( Not available at root folder )
398 ucb::InsertCommandArgument aArg
;
399 if ( !( aCommand
.Argument
>>= aArg
) )
401 ucbhelper::cancelCommandExecution(
402 uno::makeAny( lang::IllegalArgumentException(
403 "Wrong argument type!",
404 static_cast< cppu::OWeakObject
* >( this ),
410 sal_Int32 nNameClash
= aArg
.ReplaceExisting
411 ? ucb::NameClash::OVERWRITE
412 : ucb::NameClash::ERROR
;
413 insert( nNameClash
, Environment
);
415 else if ( aCommand
.Name
== "delete" && ( m_eKind
!= ROOT
) && !isReadOnly() )
419 // ( Not available at root folder )
422 bool bDeletePhysical
= false;
423 aCommand
.Argument
>>= bDeletePhysical
;
424 destroy( bDeletePhysical
, Environment
);
426 // Remove own and all children's persistent data.
429 uno::Sequence
<uno::Any
> aArgs(comphelper::InitAnyPropertySequence(
431 {"Uri", uno::Any(m_xIdentifier
->getContentIdentifier())}
433 ucbhelper::cancelCommandExecution(
434 ucb::IOErrorCode_CANT_WRITE
,
437 "Cannot remove persistent data!",
442 // Remove own and all children's Additional Core Properties.
443 removeAdditionalPropertySet();
445 else if ( aCommand
.Name
== "transfer" && isFolder() && !isReadOnly() )
449 // ( Not available at link objects )
452 ucb::TransferInfo aInfo
;
453 if ( !( aCommand
.Argument
>>= aInfo
) )
455 OSL_FAIL( "Wrong argument type!" );
456 ucbhelper::cancelCommandExecution(
457 uno::makeAny( lang::IllegalArgumentException(
458 "Wrong argument type!",
459 static_cast< cppu::OWeakObject
* >( this ),
465 transfer( aInfo
, Environment
);
467 else if ( aCommand
.Name
== "createNewContent" && isFolder() && !isReadOnly() )
471 // ( Not available at link objects )
474 ucb::ContentInfo aInfo
;
475 if ( !( aCommand
.Argument
>>= aInfo
) )
477 OSL_FAIL( "Wrong argument type!" );
478 ucbhelper::cancelCommandExecution(
479 uno::makeAny( lang::IllegalArgumentException(
480 "Wrong argument type!",
481 static_cast< cppu::OWeakObject
* >( this ),
487 aRet
<<= createNewContent( aInfo
);
492 // Unsupported command
495 ucbhelper::cancelCommandExecution(
496 uno::makeAny( ucb::UnsupportedCommandException(
498 static_cast< cppu::OWeakObject
* >( this ) ) ),
508 void SAL_CALL
HierarchyContent::abort( sal_Int32
/*CommandId*/ )
510 // @@@ Generally, no action takes much time...
514 // XContentCreator methods.
518 uno::Sequence
< ucb::ContentInfo
> SAL_CALL
519 HierarchyContent::queryCreatableContentsInfo()
521 return m_aProps
.getCreatableContentsInfo();
526 uno::Reference
< ucb::XContent
> SAL_CALL
527 HierarchyContent::createNewContent( const ucb::ContentInfo
& Info
)
531 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
533 if ( Info
.Type
.isEmpty() )
534 return uno::Reference
< ucb::XContent
>();
536 bool bCreateFolder
= Info
.Type
== HIERARCHY_FOLDER_CONTENT_TYPE
;
538 if ( !bCreateFolder
&& Info
.Type
!= HIERARCHY_LINK_CONTENT_TYPE
)
539 return uno::Reference
< ucb::XContent
>();
541 OUString aURL
= m_xIdentifier
->getContentIdentifier();
543 OSL_ENSURE( !aURL
.isEmpty(),
544 "HierarchyContent::createNewContent - empty identifier!" );
546 if ( ( aURL
.lastIndexOf( '/' ) + 1 ) != aURL
.getLength() )
550 aURL
+= "New_Folder";
554 uno::Reference
< ucb::XContentIdentifier
> xId
555 = new ::ucbhelper::ContentIdentifier( aURL
);
557 return create( m_xContext
, m_pProvider
, xId
, Info
);
561 OSL_FAIL( "createNewContent called on non-folder object!" );
562 return uno::Reference
< ucb::XContent
>();
568 OUString
HierarchyContent::getParentURL()
570 HierarchyUri
aUri( m_xIdentifier
->getContentIdentifier() );
571 return aUri
.getParentUri();
576 bool HierarchyContent::hasData(
577 const uno::Reference
< uno::XComponentContext
>& rxContext
,
578 HierarchyContentProvider
* pProvider
,
579 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
581 OUString aURL
= Identifier
->getContentIdentifier();
583 // Am I a root folder?
584 HierarchyUri
aUri( aURL
);
585 if ( aUri
.isRootFolder() )
587 // hasData must always return 'true' for root folder
588 // even if no persistent data exist!!!
592 return HierarchyEntry( rxContext
, pProvider
, aURL
).hasData();
597 bool HierarchyContent::loadData(
598 const uno::Reference
< uno::XComponentContext
>& rxContext
,
599 HierarchyContentProvider
* pProvider
,
600 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
601 HierarchyContentProperties
& rProps
)
603 OUString aURL
= Identifier
->getContentIdentifier();
605 // Am I a root folder?
606 HierarchyUri
aUri( aURL
);
607 if ( aUri
.isRootFolder() )
609 rProps
= HierarchyContentProperties( HierarchyEntryData::FOLDER
);
613 HierarchyEntry
aEntry( rxContext
, pProvider
, aURL
);
614 HierarchyEntryData aData
;
615 if ( !aEntry
.getData( aData
) )
618 rProps
= HierarchyContentProperties( aData
);
624 bool HierarchyContent::storeData()
626 HierarchyEntry
aEntry(
627 m_xContext
, m_pProvider
, m_xIdentifier
->getContentIdentifier() );
628 return aEntry
.setData( m_aProps
.getHierarchyEntryData() );
632 void HierarchyContent::renameData(
633 const uno::Reference
< ucb::XContentIdentifier
>& xOldId
,
634 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
636 HierarchyEntry
aEntry(
637 m_xContext
, m_pProvider
, xOldId
->getContentIdentifier() );
638 aEntry
.move( xNewId
->getContentIdentifier(),
639 m_aProps
.getHierarchyEntryData() );
643 bool HierarchyContent::removeData()
645 HierarchyEntry
aEntry(
646 m_xContext
, m_pProvider
, m_xIdentifier
->getContentIdentifier() );
647 return aEntry
.remove();
651 void HierarchyContent::setKind(
652 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
654 if ( m_aProps
.getIsFolder() )
656 // Am I a root folder?
657 HierarchyUri
aUri( Identifier
->getContentIdentifier() );
658 if ( aUri
.isRootFolder() )
668 bool HierarchyContent::isReadOnly()
670 if ( !m_bCheckedReadOnly
)
672 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
673 if ( !m_bCheckedReadOnly
)
675 m_bCheckedReadOnly
= true;
676 m_bIsReadOnly
= true;
678 HierarchyUri
aUri( m_xIdentifier
->getContentIdentifier() );
679 uno::Reference
< lang::XMultiServiceFactory
> xConfigProv
680 = m_pProvider
->getConfigProvider( aUri
.getService() );
681 if ( xConfigProv
.is() )
683 uno::Sequence
< OUString
> aNames
684 = xConfigProv
->getAvailableServiceNames();
685 m_bIsReadOnly
= comphelper::findValue(aNames
, "com.sun.star.ucb.HierarchyDataReadWriteAccess") == -1;
690 return m_bIsReadOnly
;
694 uno::Reference
< ucb::XContentIdentifier
>
695 HierarchyContent::makeNewIdentifier( const OUString
& rTitle
)
697 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
699 // Assemble new content identifier...
700 HierarchyUri
aUri( m_xIdentifier
->getContentIdentifier() );
701 OUString aNewURL
= aUri
.getParentUri() + "/";
702 aNewURL
+= ::ucb_impl::urihelper::encodeSegment( rTitle
);
704 return uno::Reference
< ucb::XContentIdentifier
>(
705 new ::ucbhelper::ContentIdentifier( aNewURL
) );
709 void HierarchyContent::queryChildren( HierarchyContentRefVector
& rChildren
)
711 if ( ( m_eKind
!= FOLDER
) && ( m_eKind
!= ROOT
) )
714 // Obtain a list with a snapshot of all currently instantiated contents
715 // from provider and extract the contents which are direct children
718 ::ucbhelper::ContentRefList aAllContents
;
719 m_xProvider
->queryExistingContents( aAllContents
);
721 OUString aURL
= m_xIdentifier
->getContentIdentifier();
722 sal_Int32 nURLPos
= aURL
.lastIndexOf( '/' );
724 if ( nURLPos
!= ( aURL
.getLength() - 1 ) )
726 // No trailing slash found. Append.
730 sal_Int32 nLen
= aURL
.getLength();
732 for ( const auto& rContent
: aAllContents
)
734 ::ucbhelper::ContentImplHelperRef xChild
= rContent
;
736 = xChild
->getIdentifier()->getContentIdentifier();
738 // Is aURL a prefix of aChildURL?
739 if ( ( aChildURL
.getLength() > nLen
) &&
740 ( aChildURL
.startsWith( aURL
) ) )
742 sal_Int32 nPos
= aChildURL
.indexOf( '/', nLen
);
744 if ( ( nPos
== -1 ) ||
745 ( nPos
== ( aChildURL
.getLength() - 1 ) ) )
747 // No further slashes/ only a final slash. It's a child!
748 rChildren
.emplace_back(
749 static_cast< HierarchyContent
* >( xChild
.get() ) );
756 bool HierarchyContent::exchangeIdentity(
757 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
762 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
764 uno::Reference
< ucb::XContent
> xThis
= this;
766 // Already persistent?
767 if ( m_eState
!= PERSISTENT
)
769 OSL_FAIL( "HierarchyContent::exchangeIdentity - Not persistent!" );
773 // Am I the root folder?
774 if ( m_eKind
== ROOT
)
776 OSL_FAIL( "HierarchyContent::exchangeIdentity - "
777 "Not supported by root folder!" );
781 // Exchange own identity.
783 // Fail, if a content with given id already exists.
784 if ( !hasData( xNewId
) )
786 OUString aOldURL
= m_xIdentifier
->getContentIdentifier();
789 if ( exchange( xNewId
) )
791 if ( m_eKind
== FOLDER
)
793 // Process instantiated children...
795 HierarchyContentRefVector aChildren
;
796 queryChildren( aChildren
);
798 for ( const auto& rChild
: aChildren
)
800 HierarchyContentRef xChild
= rChild
;
802 // Create new content identifier for the child...
803 uno::Reference
< ucb::XContentIdentifier
> xOldChildId
804 = xChild
->getIdentifier();
805 OUString aOldChildURL
806 = xOldChildId
->getContentIdentifier();
807 OUString aNewChildURL
808 = aOldChildURL
.replaceAt(
811 xNewId
->getContentIdentifier() );
812 uno::Reference
< ucb::XContentIdentifier
> xNewChildId
813 = new ::ucbhelper::ContentIdentifier( aNewChildURL
);
815 if ( !xChild
->exchangeIdentity( xNewChildId
) )
823 OSL_FAIL( "HierarchyContent::exchangeIdentity - "
824 "Panic! Cannot exchange identity!" );
830 uno::Reference
< sdbc::XRow
> HierarchyContent::getPropertyValues(
831 const uno::Reference
< uno::XComponentContext
>& rxContext
,
832 const uno::Sequence
< beans::Property
>& rProperties
,
833 const HierarchyContentProperties
& rData
,
834 HierarchyContentProvider
* pProvider
,
835 const OUString
& rContentId
)
837 // Note: Empty sequence means "get values of all supported properties".
839 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
840 = new ::ucbhelper::PropertyValueSet( rxContext
);
842 if ( rProperties
.hasElements() )
844 uno::Reference
< beans::XPropertySet
> xAdditionalPropSet
;
845 bool bTriedToGetAdditionalPropSet
= false;
847 for ( const beans::Property
& rProp
: rProperties
)
849 // Process Core properties.
851 if ( rProp
.Name
== "ContentType" )
853 xRow
->appendString ( rProp
, rData
.getContentType() );
855 else if ( rProp
.Name
== "Title" )
857 xRow
->appendString ( rProp
, rData
.getTitle() );
859 else if ( rProp
.Name
== "IsDocument" )
861 xRow
->appendBoolean( rProp
, rData
.getIsDocument() );
863 else if ( rProp
.Name
== "IsFolder" )
865 xRow
->appendBoolean( rProp
, rData
.getIsFolder() );
867 else if ( rProp
.Name
== "CreatableContentsInfo" )
870 rProp
, uno::makeAny( rData
.getCreatableContentsInfo() ) );
872 else if ( rProp
.Name
== "TargetURL" )
874 // TargetURL is only supported by links.
876 if ( rData
.getIsDocument() )
877 xRow
->appendString( rProp
, rData
.getTargetURL() );
879 xRow
->appendVoid( rProp
);
883 // Not a Core Property! Maybe it's an Additional Core Property?!
885 if ( !bTriedToGetAdditionalPropSet
&& !xAdditionalPropSet
.is() )
888 pProvider
->getAdditionalPropertySet( rContentId
,
890 bTriedToGetAdditionalPropSet
= true;
893 if ( xAdditionalPropSet
.is() )
895 if ( !xRow
->appendPropertySetValue(
899 // Append empty entry.
900 xRow
->appendVoid( rProp
);
905 // Append empty entry.
906 xRow
->appendVoid( rProp
);
913 // Append all Core Properties.
915 beans::Property( "ContentType",
917 cppu::UnoType
<OUString
>::get(),
918 beans::PropertyAttribute::BOUND
919 | beans::PropertyAttribute::READONLY
),
920 rData
.getContentType() );
922 beans::Property( "Title",
924 cppu::UnoType
<OUString
>::get(),
925 // @@@ Might actually be read-only!
926 beans::PropertyAttribute::BOUND
),
929 beans::Property( "IsDocument",
931 cppu::UnoType
<bool>::get(),
932 beans::PropertyAttribute::BOUND
933 | beans::PropertyAttribute::READONLY
),
934 rData
.getIsDocument() );
936 beans::Property( "IsFolder",
938 cppu::UnoType
<bool>::get(),
939 beans::PropertyAttribute::BOUND
940 | beans::PropertyAttribute::READONLY
),
941 rData
.getIsFolder() );
943 if ( rData
.getIsDocument() )
945 beans::Property( "TargetURL",
947 cppu::UnoType
<OUString
>::get(),
948 // @@@ Might actually be read-only!
949 beans::PropertyAttribute::BOUND
),
950 rData
.getTargetURL() );
953 "CreatableContentsInfo",
955 cppu::UnoType
<uno::Sequence
< ucb::ContentInfo
>>::get(),
956 beans::PropertyAttribute::BOUND
957 | beans::PropertyAttribute::READONLY
),
958 uno::makeAny( rData
.getCreatableContentsInfo() ) );
960 // Append all Additional Core Properties.
962 uno::Reference
< beans::XPropertySet
> xSet
=
963 pProvider
->getAdditionalPropertySet( rContentId
, false );
964 xRow
->appendPropertySet( xSet
);
971 uno::Reference
< sdbc::XRow
> HierarchyContent::getPropertyValues(
972 const uno::Sequence
< beans::Property
>& rProperties
)
974 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
975 return getPropertyValues( m_xContext
,
979 m_xIdentifier
->getContentIdentifier() );
983 uno::Sequence
< uno::Any
> HierarchyContent::setPropertyValues(
984 const uno::Sequence
< beans::PropertyValue
>& rValues
,
985 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
987 osl::ResettableGuard
< osl::Mutex
> aGuard( m_aMutex
);
989 uno::Sequence
< uno::Any
> aRet( rValues
.getLength() );
990 uno::Sequence
< beans::PropertyChangeEvent
> aChanges( rValues
.getLength() );
991 sal_Int32 nChanged
= 0;
993 beans::PropertyChangeEvent aEvent
;
994 aEvent
.Source
= static_cast< cppu::OWeakObject
* >( this );
995 aEvent
.Further
= false;
996 // aEvent.PropertyName =
997 aEvent
.PropertyHandle
= -1;
1001 const beans::PropertyValue
* pValues
= rValues
.getConstArray();
1002 sal_Int32 nCount
= rValues
.getLength();
1004 uno::Reference
< ucb::XPersistentPropertySet
> xAdditionalPropSet
;
1005 bool bTriedToGetAdditionalPropSet
= false;
1007 bool bExchange
= false;
1010 sal_Int32 nTitlePos
= -1;
1012 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1014 const beans::PropertyValue
& rValue
= pValues
[ n
];
1016 if ( rValue
.Name
== "ContentType" )
1018 // Read-only property!
1019 aRet
[ n
] <<= lang::IllegalAccessException(
1020 "Property is read-only!",
1021 static_cast< cppu::OWeakObject
* >( this ) );
1023 else if ( rValue
.Name
== "IsDocument" )
1025 // Read-only property!
1026 aRet
[ n
] <<= lang::IllegalAccessException(
1027 "Property is read-only!",
1028 static_cast< cppu::OWeakObject
* >( this ) );
1030 else if ( rValue
.Name
== "IsFolder" )
1032 // Read-only property!
1033 aRet
[ n
] <<= lang::IllegalAccessException(
1034 "Property is read-only!",
1035 static_cast< cppu::OWeakObject
* >( this ) );
1037 else if ( rValue
.Name
== "CreatableContentsInfo" )
1039 // Read-only property!
1040 aRet
[ n
] <<= lang::IllegalAccessException(
1041 "Property is read-only!",
1042 static_cast< cppu::OWeakObject
* >( this ) );
1044 else if ( rValue
.Name
== "Title" )
1048 aRet
[ n
] <<= lang::IllegalAccessException(
1049 "Property is read-only!",
1050 static_cast< cppu::OWeakObject
* >( this ) );
1055 if ( rValue
.Value
>>= aNewValue
)
1058 if ( !aNewValue
.isEmpty() )
1060 if ( aNewValue
!= m_aProps
.getTitle() )
1062 // modified title -> modified URL -> exchange !
1063 if ( m_eState
== PERSISTENT
)
1066 aOldTitle
= m_aProps
.getTitle();
1067 aOldName
= m_aProps
.getName();
1069 m_aProps
.setTitle( aNewValue
);
1071 ::ucb_impl::urihelper::encodeSegment(
1074 // property change event will be set later...
1076 // remember position within sequence of values
1077 // (for error handling).
1083 aRet
[ n
] <<= lang::IllegalArgumentException(
1084 "Empty title not allowed!",
1085 static_cast< cppu::OWeakObject
* >( this ),
1091 aRet
[ n
] <<= beans::IllegalTypeException(
1092 "Property value has wrong type!",
1093 static_cast< cppu::OWeakObject
* >( this ) );
1097 else if ( rValue
.Name
== "TargetURL" )
1101 aRet
[ n
] <<= lang::IllegalAccessException(
1102 "Property is read-only!",
1103 static_cast< cppu::OWeakObject
* >( this ) );
1107 // TargetURL is only supported by links.
1109 if ( m_eKind
== LINK
)
1112 if ( rValue
.Value
>>= aNewValue
)
1114 // No empty target URL's!
1115 if ( !aNewValue
.isEmpty() )
1117 if ( aNewValue
!= m_aProps
.getTargetURL() )
1119 aEvent
.PropertyName
= rValue
.Name
;
1120 aEvent
.OldValue
<<= m_aProps
.getTargetURL();
1121 aEvent
.NewValue
<<= aNewValue
;
1123 aChanges
.getArray()[ nChanged
] = aEvent
;
1125 m_aProps
.setTargetURL( aNewValue
);
1131 aRet
[ n
] <<= lang::IllegalArgumentException(
1132 "Empty target URL not allowed!",
1133 static_cast< cppu::OWeakObject
* >( this ),
1139 aRet
[ n
] <<= beans::IllegalTypeException(
1140 "Property value has wrong type!",
1141 static_cast< cppu::OWeakObject
* >( this ) );
1146 aRet
[ n
] <<= beans::UnknownPropertyException(
1147 "TargetURL only supported by links!",
1148 static_cast< cppu::OWeakObject
* >( this ) );
1154 // Not a Core Property! Maybe it's an Additional Core Property?!
1156 if ( !bTriedToGetAdditionalPropSet
&& !xAdditionalPropSet
.is() )
1158 xAdditionalPropSet
= getAdditionalPropertySet( false );
1159 bTriedToGetAdditionalPropSet
= true;
1162 if ( xAdditionalPropSet
.is() )
1166 uno::Any aOldValue
= xAdditionalPropSet
->getPropertyValue(
1168 if ( aOldValue
!= rValue
.Value
)
1170 xAdditionalPropSet
->setPropertyValue(
1171 rValue
.Name
, rValue
.Value
);
1173 aEvent
.PropertyName
= rValue
.Name
;
1174 aEvent
.OldValue
= aOldValue
;
1175 aEvent
.NewValue
= rValue
.Value
;
1177 aChanges
.getArray()[ nChanged
] = aEvent
;
1181 catch ( beans::UnknownPropertyException
const & e
)
1185 catch ( lang::WrappedTargetException
const & e
)
1189 catch ( beans::PropertyVetoException
const & e
)
1193 catch ( lang::IllegalArgumentException
const & e
)
1200 aRet
[ n
] <<= uno::Exception(
1201 "No property set for storing the value!",
1202 static_cast< cppu::OWeakObject
* >( this ) );
1209 uno::Reference
< ucb::XContentIdentifier
> xOldId
1211 uno::Reference
< ucb::XContentIdentifier
> xNewId
1212 = makeNewIdentifier( m_aProps
.getTitle() );
1215 if ( exchangeIdentity( xNewId
) )
1217 // Adapt persistent data.
1218 renameData( xOldId
, xNewId
);
1220 // Adapt Additional Core Properties.
1221 renameAdditionalPropertySet( xOldId
->getContentIdentifier(),
1222 xNewId
->getContentIdentifier() );
1227 m_aProps
.setTitle( aOldTitle
);
1228 m_aProps
.setName ( aOldName
);
1234 aRet
[ nTitlePos
] <<= uno::Exception(
1236 static_cast< cppu::OWeakObject
* >( this ) );
1241 if ( !aOldTitle
.isEmpty() )
1243 aEvent
.PropertyName
= "Title";
1244 aEvent
.OldValue
<<= aOldTitle
;
1245 aEvent
.NewValue
<<= m_aProps
.getTitle();
1247 aChanges
.getArray()[ nChanged
] = aEvent
;
1253 // Save changes, if content was already made persistent.
1254 if ( !bExchange
&& ( m_eState
== PERSISTENT
) )
1258 uno::Sequence
<uno::Any
> aArgs(comphelper::InitAnyPropertySequence(
1260 {"Uri", uno::Any(m_xIdentifier
->getContentIdentifier())}
1262 ucbhelper::cancelCommandExecution(
1263 ucb::IOErrorCode_CANT_WRITE
,
1266 "Cannot store persistent data!",
1272 aChanges
.realloc( nChanged
);
1275 notifyPropertiesChange( aChanges
);
1282 void HierarchyContent::insert( sal_Int32 nNameClashResolve
,
1283 const uno::Reference
<
1284 ucb::XCommandEnvironment
> & xEnv
)
1286 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1288 // Am I the root folder?
1289 if ( m_eKind
== ROOT
)
1291 ucbhelper::cancelCommandExecution(
1292 uno::makeAny( ucb::UnsupportedCommandException(
1293 "Not supported by root folder!",
1294 static_cast< cppu::OWeakObject
* >( this ) ) ),
1299 // Check, if all required properties were set.
1300 if ( m_aProps
.getTitle().isEmpty() )
1302 uno::Sequence
<OUString
> aProps
{ "Title" };
1303 ucbhelper::cancelCommandExecution(
1304 uno::makeAny( ucb::MissingPropertiesException(
1306 static_cast< cppu::OWeakObject
* >( this ),
1312 // Assemble new content identifier...
1314 uno::Reference
< ucb::XContentIdentifier
> xId
1315 = makeNewIdentifier( m_aProps
.getTitle() );
1317 // Handle possible name clash...
1319 switch ( nNameClashResolve
)
1322 case ucb::NameClash::ERROR
:
1323 if ( hasData( xId
) )
1325 ucbhelper::cancelCommandExecution(
1327 ucb::NameClashException(
1329 static_cast< cppu::OWeakObject
* >( this ),
1330 task::InteractionClassification_ERROR
,
1331 m_aProps
.getTitle() ) ),
1337 // replace existing object.
1338 case ucb::NameClash::OVERWRITE
:
1341 // "invent" a new valid title.
1342 case ucb::NameClash::RENAME
:
1343 if ( hasData( xId
) )
1349 OUString aNewId
= xId
->getContentIdentifier() + "_";
1350 aNewId
+= OUString::number( ++nTry
);
1351 xId
= new ::ucbhelper::ContentIdentifier( aNewId
);
1353 while ( hasData( xId
) && ( nTry
< 1000 ) );
1357 ucbhelper::cancelCommandExecution(
1359 ucb::UnsupportedNameClashException(
1360 "Unable to resolve name clash!",
1361 static_cast< cppu::OWeakObject
* >( this ),
1362 nNameClashResolve
) ),
1368 OUString
aNewTitle( m_aProps
.getTitle() );
1370 OUString::number( nTry
);
1371 m_aProps
.setTitle( aNewTitle
);
1376 case ucb::NameClash::KEEP
: // deprecated
1377 case ucb::NameClash::ASK
:
1379 if ( hasData( xId
) )
1381 ucbhelper::cancelCommandExecution(
1383 ucb::UnsupportedNameClashException(
1385 static_cast< cppu::OWeakObject
* >( this ),
1386 nNameClashResolve
) ),
1393 // Identifier changed?
1394 bool bNewId
= ( xId
->getContentIdentifier()
1395 != m_xIdentifier
->getContentIdentifier() );
1396 m_xIdentifier
= xId
;
1400 uno::Sequence
<uno::Any
> aArgs(comphelper::InitAnyPropertySequence(
1402 {"Uri", uno::Any(m_xIdentifier
->getContentIdentifier())}
1404 ucbhelper::cancelCommandExecution(
1405 ucb::IOErrorCode_CANT_WRITE
,
1408 "Cannot store persistent data!",
1413 m_eState
= PERSISTENT
;
1423 void HierarchyContent::destroy( bool bDeletePhysical
,
1424 const uno::Reference
<
1425 ucb::XCommandEnvironment
> & xEnv
)
1427 // @@@ take care about bDeletePhysical -> trashcan support
1429 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1431 uno::Reference
< ucb::XContent
> xThis
= this;
1434 if ( m_eState
!= PERSISTENT
)
1436 ucbhelper::cancelCommandExecution(
1437 uno::makeAny( ucb::UnsupportedCommandException(
1439 static_cast< cppu::OWeakObject
* >( this ) ) ),
1444 // Am I the root folder?
1445 if ( m_eKind
== ROOT
)
1447 ucbhelper::cancelCommandExecution(
1448 uno::makeAny( ucb::UnsupportedCommandException(
1449 "Not supported by root folder!",
1450 static_cast< cppu::OWeakObject
* >( this ) ) ),
1460 if ( m_eKind
== FOLDER
)
1462 // Process instantiated children...
1464 HierarchyContentRefVector aChildren
;
1465 queryChildren( aChildren
);
1467 for ( auto & child
: aChildren
)
1469 child
->destroy( bDeletePhysical
, xEnv
);
1475 void HierarchyContent::transfer(
1476 const ucb::TransferInfo
& rInfo
,
1477 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1479 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1482 if ( m_eState
!= PERSISTENT
)
1484 ucbhelper::cancelCommandExecution(
1485 uno::makeAny( ucb::UnsupportedCommandException(
1487 static_cast< cppu::OWeakObject
* >( this ) ) ),
1492 // Is source a hierarchy content?
1493 if ( !rInfo
.SourceURL
.startsWith( HIERARCHY_URL_SCHEME
":/" ) )
1495 ucbhelper::cancelCommandExecution(
1496 uno::makeAny( ucb::InteractiveBadTransferURLException(
1498 static_cast< cppu::OWeakObject
* >( this ) ) ),
1503 // Is source not a parent of me / not me?
1504 OUString aId
= m_xIdentifier
->getContentIdentifier();
1505 sal_Int32 nPos
= aId
.lastIndexOf( '/' );
1506 if ( nPos
!= ( aId
.getLength() - 1 ) )
1508 // No trailing slash found. Append.
1512 if ( rInfo
.SourceURL
.getLength() <= aId
.getLength() )
1514 if ( aId
.startsWith( rInfo
.SourceURL
) )
1516 uno::Sequence
<uno::Any
> aArgs(comphelper::InitAnyPropertySequence(
1518 {"Uri", uno::Any(rInfo
.SourceURL
)}
1520 ucbhelper::cancelCommandExecution(
1521 ucb::IOErrorCode_RECURSIVE
,
1524 "Target is equal to or is a child of source!",
1531 // 0) Obtain content object for source.
1534 uno::Reference
< ucb::XContentIdentifier
> xId
1535 = new ::ucbhelper::ContentIdentifier( rInfo
.SourceURL
);
1537 // Note: The static cast is okay here, because its sure that
1538 // m_xProvider is always the HierarchyContentProvider.
1539 rtl::Reference
< HierarchyContent
> xSource
;
1543 xSource
= static_cast< HierarchyContent
* >(
1544 m_xProvider
->queryContent( xId
).get() );
1546 catch ( ucb::IllegalIdentifierException
const & )
1551 if ( !xSource
.is() )
1553 uno::Sequence
<uno::Any
> aArgs(comphelper::InitAnyPropertySequence(
1555 {"Uri", uno::Any(xId
->getContentIdentifier())}
1557 ucbhelper::cancelCommandExecution(
1558 ucb::IOErrorCode_CANT_READ
,
1561 "Cannot instantiate source object!",
1567 // 1) Create new child content.
1570 OUString aType
= xSource
->isFolder()
1571 ? OUString( HIERARCHY_FOLDER_CONTENT_TYPE
)
1572 : OUString( HIERARCHY_LINK_CONTENT_TYPE
);
1573 ucb::ContentInfo aContentInfo
;
1574 aContentInfo
.Type
= aType
;
1575 aContentInfo
.Attributes
= 0;
1577 // Note: The static cast is okay here, because its sure that
1578 // createNewContent always creates a HierarchyContent.
1579 rtl::Reference
< HierarchyContent
> xTarget
1580 = static_cast< HierarchyContent
* >(
1581 createNewContent( aContentInfo
).get() );
1582 if ( !xTarget
.is() )
1584 uno::Sequence
<uno::Any
> aArgs(comphelper::InitAnyPropertySequence(
1586 {"Folder", uno::Any(aId
)}
1588 ucbhelper::cancelCommandExecution(
1589 ucb::IOErrorCode_CANT_CREATE
,
1592 "XContentCreator::createNewContent failed!",
1598 // 2) Copy data from source content to child content.
1601 uno::Sequence
< beans::Property
> aSourceProps
1602 = xSource
->getPropertySetInfo( xEnv
)->getProperties();
1603 sal_Int32 nCount
= aSourceProps
.getLength();
1607 bool bHadTitle
= rInfo
.NewTitle
.isEmpty();
1609 // Get all source values.
1610 uno::Reference
< sdbc::XRow
> xRow
1611 = xSource
->getPropertyValues( aSourceProps
);
1613 uno::Sequence
< beans::PropertyValue
> aValues( nCount
);
1614 beans::PropertyValue
* pValues
= aValues
.getArray();
1616 const beans::Property
* pProps
= aSourceProps
.getConstArray();
1617 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1619 const beans::Property
& rProp
= pProps
[ n
];
1620 beans::PropertyValue
& rValue
= pValues
[ n
];
1622 rValue
.Name
= rProp
.Name
;
1623 rValue
.Handle
= rProp
.Handle
;
1625 if ( !bHadTitle
&& rProp
.Name
== "Title" )
1627 // Set new title instead of original.
1629 rValue
.Value
<<= rInfo
.NewTitle
;
1632 rValue
.Value
= xRow
->getObject(
1634 uno::Reference
< container::XNameAccess
>() );
1636 rValue
.State
= beans::PropertyState_DIRECT_VALUE
;
1638 if ( rProp
.Attributes
& beans::PropertyAttribute::REMOVABLE
)
1640 // Add Additional Core Property.
1643 xTarget
->addProperty( rProp
.Name
,
1647 catch ( beans::PropertyExistException
const & )
1650 catch ( beans::IllegalTypeException
const & )
1653 catch ( lang::IllegalArgumentException
const & )
1659 // Set target values.
1660 xTarget
->setPropertyValues( aValues
, xEnv
);
1664 // 3) Commit (insert) child.
1667 xTarget
->insert( rInfo
.NameClash
, xEnv
);
1670 // 4) Transfer (copy) children of source.
1673 if ( xSource
->isFolder() )
1675 HierarchyEntry
aFolder(
1676 m_xContext
, m_pProvider
, xId
->getContentIdentifier() );
1677 HierarchyEntry::iterator it
;
1679 while ( aFolder
.next( it
) )
1681 const HierarchyEntryData
& rResult
= *it
;
1683 OUString aChildId
= xId
->getContentIdentifier();
1684 if ( ( aChildId
.lastIndexOf( '/' ) + 1 ) != aChildId
.getLength() )
1687 aChildId
+= rResult
.getName();
1689 ucb::TransferInfo aInfo
;
1690 aInfo
.MoveData
= false;
1691 aInfo
.NewTitle
.clear();
1692 aInfo
.SourceURL
= aChildId
;
1693 aInfo
.NameClash
= rInfo
.NameClash
;
1695 // Transfer child to target.
1696 xTarget
->transfer( aInfo
, xEnv
);
1701 // 5) Destroy source ( when moving only ) .
1704 if ( !rInfo
.MoveData
)
1707 xSource
->destroy( true, xEnv
);
1709 // Remove all persistent data of source and its children.
1710 if ( !xSource
->removeData() )
1712 uno::Sequence
<uno::Any
> aArgs(comphelper::InitAnyPropertySequence(
1714 {"Uri", uno::Any(xSource
->m_xIdentifier
->getContentIdentifier())}
1716 ucbhelper::cancelCommandExecution(
1717 ucb::IOErrorCode_CANT_WRITE
,
1720 "Cannot remove persistent data of source object!",
1725 // Remove own and all children's Additional Core Properties.
1726 xSource
->removeAdditionalPropertySet();
1730 // HierarchyContentProperties Implementation.
1733 uno::Sequence
< ucb::ContentInfo
>
1734 HierarchyContentProperties::getCreatableContentsInfo() const
1736 if ( getIsFolder() )
1738 uno::Sequence
< ucb::ContentInfo
> aSeq( 2 );
1741 aSeq
.getArray()[ 0 ].Type
= HIERARCHY_FOLDER_CONTENT_TYPE
;
1742 aSeq
.getArray()[ 0 ].Attributes
= ucb::ContentInfoAttribute::KIND_FOLDER
;
1744 uno::Sequence
< beans::Property
> aFolderProps( 1 );
1745 aFolderProps
.getArray()[ 0 ] = beans::Property(
1748 cppu::UnoType
<OUString
>::get(),
1749 beans::PropertyAttribute::BOUND
);
1750 aSeq
.getArray()[ 0 ].Properties
= aFolderProps
;
1753 aSeq
.getArray()[ 1 ].Type
= HIERARCHY_LINK_CONTENT_TYPE
;
1754 aSeq
.getArray()[ 1 ].Attributes
= ucb::ContentInfoAttribute::KIND_LINK
;
1756 uno::Sequence
< beans::Property
> aLinkProps( 2 );
1757 aLinkProps
.getArray()[ 0 ] = beans::Property(
1760 cppu::UnoType
<OUString
>::get(),
1761 beans::PropertyAttribute::BOUND
);
1762 aLinkProps
.getArray()[ 1 ] = beans::Property(
1765 cppu::UnoType
<OUString
>::get(),
1766 beans::PropertyAttribute::BOUND
);
1767 aSeq
.getArray()[ 1 ].Properties
= aLinkProps
;
1773 return uno::Sequence
< ucb::ContentInfo
>( 0 );
1777 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */