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 "osl/doublecheckedlocking.h"
41 #include <rtl/ustring.h>
42 #include <rtl/ustring.hxx>
43 #include <com/sun/star/beans/PropertyAttribute.hpp>
44 #include <com/sun/star/beans/PropertyState.hpp>
45 #include <com/sun/star/beans/PropertyValue.hpp>
46 #include <com/sun/star/beans/XPropertyAccess.hpp>
47 #include <com/sun/star/lang/IllegalAccessException.hpp>
48 #include <com/sun/star/sdbc/XRow.hpp>
49 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
50 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
51 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
52 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
53 #include <com/sun/star/ucb/NameClash.hpp>
54 #include <com/sun/star/ucb/NameClashException.hpp>
55 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
56 #include <com/sun/star/ucb/TransferInfo.hpp>
57 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
58 #include <com/sun/star/ucb/XCommandInfo.hpp>
59 #include <com/sun/star/ucb/XPersistentPropertySet.hpp>
60 #include <com/sun/star/uno/Any.hxx>
61 #include <com/sun/star/uno/Sequence.hxx>
62 #include <comphelper/processfactory.hxx>
63 #include <ucbhelper/contentidentifier.hxx>
64 #include <ucbhelper/propertyvalueset.hxx>
65 #include <ucbhelper/cancelcommandexecution.hxx>
66 #include "hierarchycontent.hxx"
67 #include "hierarchyprovider.hxx"
68 #include "dynamicresultset.hxx"
69 #include "hierarchyuri.hxx"
71 #include "../inc/urihelper.hxx"
73 using namespace com::sun::star
;
74 using namespace hierarchy_ucp
;
79 // HierarchyContent Implementation.
84 // static ( "virtual" ctor )
85 HierarchyContent
* HierarchyContent::create(
86 const uno::Reference
< uno::XComponentContext
>& rxContext
,
87 HierarchyContentProvider
* pProvider
,
88 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
90 // Fail, if content does not exist.
91 HierarchyContentProperties aProps
;
92 if ( !loadData( rxContext
, pProvider
, Identifier
, aProps
) )
95 return new HierarchyContent( rxContext
, pProvider
, Identifier
, aProps
);
99 // static ( "virtual" ctor )
100 HierarchyContent
* HierarchyContent::create(
101 const uno::Reference
< uno::XComponentContext
>& rxContext
,
102 HierarchyContentProvider
* pProvider
,
103 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
104 const ucb::ContentInfo
& Info
)
106 if ( Info
.Type
.isEmpty() )
109 if ( Info
.Type
!= HIERARCHY_FOLDER_CONTENT_TYPE
&& Info
.Type
!= HIERARCHY_LINK_CONTENT_TYPE
)
112 return new HierarchyContent( rxContext
, pProvider
, Identifier
, Info
);
116 HierarchyContent::HierarchyContent(
117 const uno::Reference
< uno::XComponentContext
>& rxContext
,
118 HierarchyContentProvider
* pProvider
,
119 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
120 const HierarchyContentProperties
& rProps
)
121 : ContentImplHelper( rxContext
, pProvider
, Identifier
),
123 m_eState( PERSISTENT
),
124 m_pProvider( pProvider
),
125 m_bCheckedReadOnly( false ),
126 m_bIsReadOnly( true )
128 setKind( Identifier
);
132 HierarchyContent::HierarchyContent(
133 const uno::Reference
< uno::XComponentContext
>& rxContext
,
134 HierarchyContentProvider
* pProvider
,
135 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
136 const ucb::ContentInfo
& Info
)
137 : ContentImplHelper( rxContext
, pProvider
, Identifier
),
138 m_aProps( Info
.Type
== HIERARCHY_FOLDER_CONTENT_TYPE
? HierarchyEntryData::FOLDER
: HierarchyEntryData::LINK
),
139 m_eState( TRANSIENT
),
140 m_pProvider( pProvider
),
141 m_bCheckedReadOnly( false ),
142 m_bIsReadOnly( true )
144 setKind( Identifier
);
149 HierarchyContent::~HierarchyContent()
155 // XInterface methods.
160 void SAL_CALL
HierarchyContent::acquire()
163 ContentImplHelper::acquire();
168 void SAL_CALL
HierarchyContent::release()
171 ContentImplHelper::release();
176 uno::Any SAL_CALL
HierarchyContent::queryInterface( const uno::Type
& rType
)
177 throw ( uno::RuntimeException
, std::exception
)
179 uno::Any aRet
= ContentImplHelper::queryInterface( rType
);
181 if ( !aRet
.hasValue() )
183 // Note: isReadOnly may be relative expensive. So avoid calling it
184 // unless it is really necessary.
185 aRet
= cppu::queryInterface(
186 rType
, static_cast< ucb::XContentCreator
* >( this ) );
187 if ( aRet
.hasValue() )
189 if ( !isFolder() || isReadOnly() )
199 // XTypeProvider methods.
203 XTYPEPROVIDER_COMMON_IMPL( HierarchyContent
);
207 uno::Sequence
< uno::Type
> SAL_CALL
HierarchyContent::getTypes()
208 throw( uno::RuntimeException
, std::exception
)
210 cppu::OTypeCollection
* pCollection
= 0;
212 if ( isFolder() && !isReadOnly() )
214 static cppu::OTypeCollection
* pFolderTypes
= 0;
216 pCollection
= pFolderTypes
;
219 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
221 pCollection
= pFolderTypes
;
224 static cppu::OTypeCollection
aCollection(
225 CPPU_TYPE_REF( lang::XTypeProvider
),
226 CPPU_TYPE_REF( lang::XServiceInfo
),
227 CPPU_TYPE_REF( lang::XComponent
),
228 CPPU_TYPE_REF( ucb::XContent
),
229 CPPU_TYPE_REF( ucb::XCommandProcessor
),
230 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
231 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
232 CPPU_TYPE_REF( beans::XPropertyContainer
),
233 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
234 CPPU_TYPE_REF( container::XChild
),
235 CPPU_TYPE_REF( ucb::XContentCreator
) ); // !!
236 pCollection
= &aCollection
;
237 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
238 pFolderTypes
= pCollection
;
242 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
247 static cppu::OTypeCollection
* pDocumentTypes
= 0;
249 pCollection
= pDocumentTypes
;
252 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
254 pCollection
= pDocumentTypes
;
257 static cppu::OTypeCollection
aCollection(
258 CPPU_TYPE_REF( lang::XTypeProvider
),
259 CPPU_TYPE_REF( lang::XServiceInfo
),
260 CPPU_TYPE_REF( lang::XComponent
),
261 CPPU_TYPE_REF( ucb::XContent
),
262 CPPU_TYPE_REF( ucb::XCommandProcessor
),
263 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier
),
264 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier
),
265 CPPU_TYPE_REF( beans::XPropertyContainer
),
266 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier
),
267 CPPU_TYPE_REF( container::XChild
) );
268 pCollection
= &aCollection
;
269 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
270 pDocumentTypes
= pCollection
;
274 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
278 return (*pCollection
).getTypes();
283 // XServiceInfo methods.
288 OUString SAL_CALL
HierarchyContent::getImplementationName()
289 throw( uno::RuntimeException
, std::exception
)
291 return OUString( "com.sun.star.comp.ucb.HierarchyContent" );
296 uno::Sequence
< OUString
> SAL_CALL
297 HierarchyContent::getSupportedServiceNames()
298 throw( uno::RuntimeException
, std::exception
)
300 uno::Sequence
< OUString
> aSNS( 1 );
302 if ( m_eKind
== LINK
)
303 aSNS
.getArray()[ 0 ] = HIERARCHY_LINK_CONTENT_SERVICE_NAME
;
304 else if ( m_eKind
== FOLDER
)
305 aSNS
.getArray()[ 0 ] = HIERARCHY_FOLDER_CONTENT_SERVICE_NAME
;
307 aSNS
.getArray()[ 0 ] = HIERARCHY_ROOT_FOLDER_CONTENT_SERVICE_NAME
;
319 OUString SAL_CALL
HierarchyContent::getContentType()
320 throw( uno::RuntimeException
, std::exception
)
322 return m_aProps
.getContentType();
327 uno::Reference
< ucb::XContentIdentifier
> SAL_CALL
328 HierarchyContent::getIdentifier()
329 throw( uno::RuntimeException
, std::exception
)
332 if ( m_eState
== TRANSIENT
)
334 // Transient contents have no identifier.
335 return uno::Reference
< ucb::XContentIdentifier
>();
338 return ContentImplHelper::getIdentifier();
343 // XCommandProcessor methods.
348 uno::Any SAL_CALL
HierarchyContent::execute(
349 const ucb::Command
& aCommand
,
350 sal_Int32
/*CommandId*/,
351 const uno::Reference
< ucb::XCommandEnvironment
>& Environment
)
352 throw( uno::Exception
,
353 ucb::CommandAbortedException
,
354 uno::RuntimeException
, std::exception
)
358 if ( aCommand
.Name
== "getPropertyValues" )
364 uno::Sequence
< beans::Property
> Properties
;
365 if ( !( aCommand
.Argument
>>= Properties
) )
367 ucbhelper::cancelCommandExecution(
368 uno::makeAny( lang::IllegalArgumentException(
369 OUString( "Wrong argument type!" ),
370 static_cast< cppu::OWeakObject
* >( this ),
376 aRet
<<= getPropertyValues( Properties
);
378 else if ( aCommand
.Name
== "setPropertyValues" )
384 uno::Sequence
< beans::PropertyValue
> aProperties
;
385 if ( !( aCommand
.Argument
>>= aProperties
) )
387 ucbhelper::cancelCommandExecution(
388 uno::makeAny( lang::IllegalArgumentException(
389 OUString( "Wrong argument type!" ),
390 static_cast< cppu::OWeakObject
* >( this ),
396 if ( !aProperties
.getLength() )
398 ucbhelper::cancelCommandExecution(
399 uno::makeAny( lang::IllegalArgumentException(
400 OUString( "No properties!" ),
401 static_cast< cppu::OWeakObject
* >( this ),
407 aRet
<<= setPropertyValues( aProperties
, Environment
);
409 else if ( aCommand
.Name
== "getPropertySetInfo" )
412 // getPropertySetInfo
415 aRet
<<= getPropertySetInfo( Environment
);
417 else if ( aCommand
.Name
== "getCommandInfo" )
423 aRet
<<= getCommandInfo( Environment
);
425 else if ( aCommand
.Name
== "open" && isFolder() )
428 // open command for a folder content
431 ucb::OpenCommandArgument2 aOpenCommand
;
432 if ( !( aCommand
.Argument
>>= aOpenCommand
) )
434 ucbhelper::cancelCommandExecution(
435 uno::makeAny( lang::IllegalArgumentException(
436 OUString( "Wrong argument type!" ),
437 static_cast< cppu::OWeakObject
* >( this ),
443 uno::Reference
< ucb::XDynamicResultSet
> xSet
444 = new DynamicResultSet( m_xContext
, this, aOpenCommand
);
447 else if ( aCommand
.Name
== "insert" && ( m_eKind
!= ROOT
) && !isReadOnly() )
451 // ( Not available at root folder )
454 ucb::InsertCommandArgument aArg
;
455 if ( !( aCommand
.Argument
>>= aArg
) )
457 ucbhelper::cancelCommandExecution(
458 uno::makeAny( lang::IllegalArgumentException(
459 OUString( "Wrong argument type!" ),
460 static_cast< cppu::OWeakObject
* >( this ),
466 sal_Int32 nNameClash
= aArg
.ReplaceExisting
467 ? ucb::NameClash::OVERWRITE
468 : ucb::NameClash::ERROR
;
469 insert( nNameClash
, Environment
);
471 else if ( aCommand
.Name
== "delete" && ( m_eKind
!= ROOT
) && !isReadOnly() )
475 // ( Not available at root folder )
478 bool bDeletePhysical
= false;
479 aCommand
.Argument
>>= bDeletePhysical
;
480 destroy( bDeletePhysical
, Environment
);
482 // Remove own and all children's persistent data.
487 beans::PropertyValue(
490 uno::makeAny(m_xIdentifier
->
491 getContentIdentifier()),
492 beans::PropertyState_DIRECT_VALUE
));
493 ucbhelper::cancelCommandExecution(
494 ucb::IOErrorCode_CANT_WRITE
,
495 uno::Sequence
< uno::Any
>(&aProps
, 1),
497 OUString( "Cannot remove persistent data!" ),
502 // Remove own and all children's Additional Core Properties.
503 removeAdditionalPropertySet( true );
505 else if ( aCommand
.Name
== "transfer" && isFolder() && !isReadOnly() )
509 // ( Not available at link objects )
512 ucb::TransferInfo aInfo
;
513 if ( !( aCommand
.Argument
>>= aInfo
) )
515 OSL_FAIL( "Wrong argument type!" );
516 ucbhelper::cancelCommandExecution(
517 uno::makeAny( lang::IllegalArgumentException(
518 OUString( "Wrong argument type!" ),
519 static_cast< cppu::OWeakObject
* >( this ),
525 transfer( aInfo
, Environment
);
527 else if ( aCommand
.Name
== "createNewContent" && isFolder() && !isReadOnly() )
531 // ( Not available at link objects )
534 ucb::ContentInfo aInfo
;
535 if ( !( aCommand
.Argument
>>= aInfo
) )
537 OSL_FAIL( "Wrong argument type!" );
538 ucbhelper::cancelCommandExecution(
539 uno::makeAny( lang::IllegalArgumentException(
540 OUString( "Wrong argument type!" ),
541 static_cast< cppu::OWeakObject
* >( this ),
547 aRet
<<= createNewContent( aInfo
);
552 // Unsupported command
555 ucbhelper::cancelCommandExecution(
556 uno::makeAny( ucb::UnsupportedCommandException(
558 static_cast< cppu::OWeakObject
* >( this ) ) ),
568 void SAL_CALL
HierarchyContent::abort( sal_Int32
/*CommandId*/ )
569 throw( uno::RuntimeException
, std::exception
)
571 // @@@ Generally, no action takes much time...
576 // XContentCreator methods.
581 uno::Sequence
< ucb::ContentInfo
> SAL_CALL
582 HierarchyContent::queryCreatableContentsInfo()
583 throw( uno::RuntimeException
, std::exception
)
585 return m_aProps
.getCreatableContentsInfo();
590 uno::Reference
< ucb::XContent
> SAL_CALL
591 HierarchyContent::createNewContent( const ucb::ContentInfo
& Info
)
592 throw( uno::RuntimeException
, std::exception
)
596 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
598 if ( Info
.Type
.isEmpty() )
599 return uno::Reference
< ucb::XContent
>();
601 bool bCreateFolder
= Info
.Type
== HIERARCHY_FOLDER_CONTENT_TYPE
;
603 if ( !bCreateFolder
&& Info
.Type
!= HIERARCHY_LINK_CONTENT_TYPE
)
604 return uno::Reference
< ucb::XContent
>();
606 OUString aURL
= m_xIdentifier
->getContentIdentifier();
608 OSL_ENSURE( !aURL
.isEmpty(),
609 "HierarchyContent::createNewContent - empty identifier!" );
611 if ( ( aURL
.lastIndexOf( '/' ) + 1 ) != aURL
.getLength() )
615 aURL
+= "New_Folder";
619 uno::Reference
< ucb::XContentIdentifier
> xId
620 = new ::ucbhelper::ContentIdentifier( aURL
);
622 return create( m_xContext
, m_pProvider
, xId
, Info
);
626 OSL_FAIL( "createNewContent called on non-folder object!" );
627 return uno::Reference
< ucb::XContent
>();
633 OUString
HierarchyContent::getParentURL()
635 HierarchyUri
aUri( m_xIdentifier
->getContentIdentifier() );
636 return aUri
.getParentUri();
641 bool HierarchyContent::hasData(
642 const uno::Reference
< uno::XComponentContext
>& rxContext
,
643 HierarchyContentProvider
* pProvider
,
644 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
646 OUString aURL
= Identifier
->getContentIdentifier();
648 // Am I a root folder?
649 HierarchyUri
aUri( aURL
);
650 if ( aUri
.isRootFolder() )
652 // hasData must always return 'true' for root folder
653 // even if no persistent data exist!!!
657 return HierarchyEntry( rxContext
, pProvider
, aURL
).hasData();
662 bool HierarchyContent::loadData(
663 const uno::Reference
< uno::XComponentContext
>& rxContext
,
664 HierarchyContentProvider
* pProvider
,
665 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
,
666 HierarchyContentProperties
& rProps
)
668 OUString aURL
= Identifier
->getContentIdentifier();
670 // Am I a root folder?
671 HierarchyUri
aUri( aURL
);
672 if ( aUri
.isRootFolder() )
674 rProps
= HierarchyContentProperties( HierarchyEntryData::FOLDER
);
678 HierarchyEntry
aEntry( rxContext
, pProvider
, aURL
);
679 HierarchyEntryData aData
;
680 if ( !aEntry
.getData( aData
) )
683 rProps
= HierarchyContentProperties( aData
);
689 bool HierarchyContent::storeData()
691 HierarchyEntry
aEntry(
692 m_xContext
, m_pProvider
, m_xIdentifier
->getContentIdentifier() );
693 return aEntry
.setData( m_aProps
.getHierarchyEntryData(), true );
697 bool HierarchyContent::renameData(
698 const uno::Reference
< ucb::XContentIdentifier
>& xOldId
,
699 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
701 HierarchyEntry
aEntry(
702 m_xContext
, m_pProvider
, xOldId
->getContentIdentifier() );
703 return aEntry
.move( xNewId
->getContentIdentifier(),
704 m_aProps
.getHierarchyEntryData() );
708 bool HierarchyContent::removeData()
710 HierarchyEntry
aEntry(
711 m_xContext
, m_pProvider
, m_xIdentifier
->getContentIdentifier() );
712 return aEntry
.remove();
716 void HierarchyContent::setKind(
717 const uno::Reference
< ucb::XContentIdentifier
>& Identifier
)
719 if ( m_aProps
.getIsFolder() )
721 // Am I a root folder?
722 HierarchyUri
aUri( Identifier
->getContentIdentifier() );
723 if ( aUri
.isRootFolder() )
733 bool HierarchyContent::isReadOnly()
735 if ( !m_bCheckedReadOnly
)
737 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
738 if ( !m_bCheckedReadOnly
)
740 m_bCheckedReadOnly
= true;
741 m_bIsReadOnly
= true;
743 HierarchyUri
aUri( m_xIdentifier
->getContentIdentifier() );
744 uno::Reference
< lang::XMultiServiceFactory
> xConfigProv
745 = m_pProvider
->getConfigProvider( aUri
.getService() );
746 if ( xConfigProv
.is() )
748 uno::Sequence
< OUString
> aNames
749 = xConfigProv
->getAvailableServiceNames();
750 sal_Int32 nCount
= aNames
.getLength();
751 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
753 if ( aNames
[ n
] == "com.sun.star.ucb.HierarchyDataReadWriteAccess" )
755 m_bIsReadOnly
= false;
763 return m_bIsReadOnly
;
767 uno::Reference
< ucb::XContentIdentifier
>
768 HierarchyContent::makeNewIdentifier( const OUString
& rTitle
)
770 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
772 // Assemble new content identifier...
773 HierarchyUri
aUri( m_xIdentifier
->getContentIdentifier() );
774 OUString aNewURL
= aUri
.getParentUri();
776 aNewURL
+= ::ucb_impl::urihelper::encodeSegment( rTitle
);
778 return uno::Reference
< ucb::XContentIdentifier
>(
779 new ::ucbhelper::ContentIdentifier( aNewURL
) );
783 void HierarchyContent::queryChildren( HierarchyContentRefList
& rChildren
)
785 if ( ( m_eKind
!= FOLDER
) && ( m_eKind
!= ROOT
) )
788 // Obtain a list with a snapshot of all currently instantiated contents
789 // from provider and extract the contents which are direct children
792 ::ucbhelper::ContentRefList aAllContents
;
793 m_xProvider
->queryExistingContents( aAllContents
);
795 OUString aURL
= m_xIdentifier
->getContentIdentifier();
796 sal_Int32 nURLPos
= aURL
.lastIndexOf( '/' );
798 if ( nURLPos
!= ( aURL
.getLength() - 1 ) )
800 // No trailing slash found. Append.
804 sal_Int32 nLen
= aURL
.getLength();
806 ::ucbhelper::ContentRefList::const_iterator it
= aAllContents
.begin();
807 ::ucbhelper::ContentRefList::const_iterator end
= aAllContents
.end();
811 ::ucbhelper::ContentImplHelperRef xChild
= (*it
);
813 = xChild
->getIdentifier()->getContentIdentifier();
815 // Is aURL a prefix of aChildURL?
816 if ( ( aChildURL
.getLength() > nLen
) &&
817 ( aChildURL
.startsWith( aURL
) ) )
819 sal_Int32 nPos
= nLen
;
820 nPos
= aChildURL
.indexOf( '/', nPos
);
822 if ( ( nPos
== -1 ) ||
823 ( nPos
== ( aChildURL
.getLength() - 1 ) ) )
825 // No further slashes/ only a final slash. It's a child!
828 static_cast< HierarchyContent
* >( xChild
.get() ) ) );
836 bool HierarchyContent::exchangeIdentity(
837 const uno::Reference
< ucb::XContentIdentifier
>& xNewId
)
842 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
844 uno::Reference
< ucb::XContent
> xThis
= this;
846 // Already persistent?
847 if ( m_eState
!= PERSISTENT
)
849 OSL_FAIL( "HierarchyContent::exchangeIdentity - Not persistent!" );
853 // Am I the root folder?
854 if ( m_eKind
== ROOT
)
856 OSL_FAIL( "HierarchyContent::exchangeIdentity - "
857 "Not supported by root folder!" );
861 // Exchange own identitity.
863 // Fail, if a content with given id already exists.
864 if ( !hasData( xNewId
) )
866 OUString aOldURL
= m_xIdentifier
->getContentIdentifier();
869 if ( exchange( xNewId
) )
871 if ( m_eKind
== FOLDER
)
873 // Process instantiated children...
875 HierarchyContentRefList aChildren
;
876 queryChildren( aChildren
);
878 HierarchyContentRefList::const_iterator it
= aChildren
.begin();
879 HierarchyContentRefList::const_iterator end
= aChildren
.end();
883 HierarchyContentRef xChild
= (*it
);
885 // Create new content identifier for the child...
886 uno::Reference
< ucb::XContentIdentifier
> xOldChildId
887 = xChild
->getIdentifier();
888 OUString aOldChildURL
889 = xOldChildId
->getContentIdentifier();
890 OUString aNewChildURL
891 = aOldChildURL
.replaceAt(
894 xNewId
->getContentIdentifier() );
895 uno::Reference
< ucb::XContentIdentifier
> xNewChildId
896 = new ::ucbhelper::ContentIdentifier( aNewChildURL
);
898 if ( !xChild
->exchangeIdentity( xNewChildId
) )
908 OSL_FAIL( "HierarchyContent::exchangeIdentity - "
909 "Panic! Cannot exchange identity!" );
915 uno::Reference
< sdbc::XRow
> HierarchyContent::getPropertyValues(
916 const uno::Reference
< uno::XComponentContext
>& rxContext
,
917 const uno::Sequence
< beans::Property
>& rProperties
,
918 const HierarchyContentProperties
& rData
,
919 HierarchyContentProvider
* pProvider
,
920 const OUString
& rContentId
)
922 // Note: Empty sequence means "get values of all supported properties".
924 rtl::Reference
< ::ucbhelper::PropertyValueSet
> xRow
925 = new ::ucbhelper::PropertyValueSet( rxContext
);
927 sal_Int32 nCount
= rProperties
.getLength();
930 uno::Reference
< beans::XPropertySet
> xAdditionalPropSet
;
931 bool bTriedToGetAdditionalPropSet
= false;
933 const beans::Property
* pProps
= rProperties
.getConstArray();
934 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
936 const beans::Property
& rProp
= pProps
[ n
];
938 // Process Core properties.
940 if ( rProp
.Name
== "ContentType" )
942 xRow
->appendString ( rProp
, rData
.getContentType() );
944 else if ( rProp
.Name
== "Title" )
946 xRow
->appendString ( rProp
, rData
.getTitle() );
948 else if ( rProp
.Name
== "IsDocument" )
950 xRow
->appendBoolean( rProp
, rData
.getIsDocument() );
952 else if ( rProp
.Name
== "IsFolder" )
954 xRow
->appendBoolean( rProp
, rData
.getIsFolder() );
956 else if ( rProp
.Name
== "CreatableContentsInfo" )
959 rProp
, uno::makeAny( rData
.getCreatableContentsInfo() ) );
961 else if ( rProp
.Name
== "TargetURL" )
963 // TargetURL is only supported by links.
965 if ( rData
.getIsDocument() )
966 xRow
->appendString( rProp
, rData
.getTargetURL() );
968 xRow
->appendVoid( rProp
);
972 // Not a Core Property! Maybe it's an Additional Core Property?!
974 if ( !bTriedToGetAdditionalPropSet
&& !xAdditionalPropSet
.is() )
977 = uno::Reference
< beans::XPropertySet
>(
978 pProvider
->getAdditionalPropertySet( rContentId
,
981 bTriedToGetAdditionalPropSet
= true;
984 if ( xAdditionalPropSet
.is() )
986 if ( !xRow
->appendPropertySetValue(
990 // Append empty entry.
991 xRow
->appendVoid( rProp
);
996 // Append empty entry.
997 xRow
->appendVoid( rProp
);
1004 // Append all Core Properties.
1005 xRow
->appendString (
1006 beans::Property( OUString("ContentType"),
1008 cppu::UnoType
<OUString
>::get(),
1009 beans::PropertyAttribute::BOUND
1010 | beans::PropertyAttribute::READONLY
),
1011 rData
.getContentType() );
1012 xRow
->appendString (
1013 beans::Property( OUString("Title"),
1015 cppu::UnoType
<OUString
>::get(),
1016 // @@@ Might actually be read-only!
1017 beans::PropertyAttribute::BOUND
),
1019 xRow
->appendBoolean(
1020 beans::Property( OUString("IsDocument"),
1022 cppu::UnoType
<bool>::get(),
1023 beans::PropertyAttribute::BOUND
1024 | beans::PropertyAttribute::READONLY
),
1025 rData
.getIsDocument() );
1026 xRow
->appendBoolean(
1027 beans::Property( OUString("IsFolder"),
1029 cppu::UnoType
<bool>::get(),
1030 beans::PropertyAttribute::BOUND
1031 | beans::PropertyAttribute::READONLY
),
1032 rData
.getIsFolder() );
1034 if ( rData
.getIsDocument() )
1036 beans::Property( OUString("TargetURL"),
1038 cppu::UnoType
<OUString
>::get(),
1039 // @@@ Might actually be read-only!
1040 beans::PropertyAttribute::BOUND
),
1041 rData
.getTargetURL() );
1044 OUString("CreatableContentsInfo"),
1046 cppu::UnoType
<uno::Sequence
< ucb::ContentInfo
>>::get(),
1047 beans::PropertyAttribute::BOUND
1048 | beans::PropertyAttribute::READONLY
),
1049 uno::makeAny( rData
.getCreatableContentsInfo() ) );
1051 // Append all Additional Core Properties.
1053 uno::Reference
< beans::XPropertySet
> xSet(
1054 pProvider
->getAdditionalPropertySet( rContentId
, false ),
1056 xRow
->appendPropertySet( xSet
);
1059 return uno::Reference
< sdbc::XRow
>( xRow
.get() );
1063 uno::Reference
< sdbc::XRow
> HierarchyContent::getPropertyValues(
1064 const uno::Sequence
< beans::Property
>& rProperties
)
1066 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1067 return getPropertyValues( m_xContext
,
1071 m_xIdentifier
->getContentIdentifier() );
1075 uno::Sequence
< uno::Any
> HierarchyContent::setPropertyValues(
1076 const uno::Sequence
< beans::PropertyValue
>& rValues
,
1077 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1078 throw( uno::Exception
)
1080 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1082 uno::Sequence
< uno::Any
> aRet( rValues
.getLength() );
1083 uno::Sequence
< beans::PropertyChangeEvent
> aChanges( rValues
.getLength() );
1084 sal_Int32 nChanged
= 0;
1086 beans::PropertyChangeEvent aEvent
;
1087 aEvent
.Source
= static_cast< cppu::OWeakObject
* >( this );
1088 aEvent
.Further
= sal_False
;
1089 // aEvent.PropertyName =
1090 aEvent
.PropertyHandle
= -1;
1091 // aEvent.OldValue =
1092 // aEvent.NewValue =
1094 const beans::PropertyValue
* pValues
= rValues
.getConstArray();
1095 sal_Int32 nCount
= rValues
.getLength();
1097 uno::Reference
< ucb::XPersistentPropertySet
> xAdditionalPropSet
;
1098 bool bTriedToGetAdditionalPropSet
= false;
1100 bool bExchange
= false;
1103 sal_Int32 nTitlePos
= -1;
1105 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1107 const beans::PropertyValue
& rValue
= pValues
[ n
];
1109 if ( rValue
.Name
== "ContentType" )
1111 // Read-only property!
1112 aRet
[ n
] <<= lang::IllegalAccessException(
1113 OUString( "Property is read-only!" ),
1114 static_cast< cppu::OWeakObject
* >( this ) );
1116 else if ( rValue
.Name
== "IsDocument" )
1118 // Read-only property!
1119 aRet
[ n
] <<= lang::IllegalAccessException(
1120 OUString( "Property is read-only!" ),
1121 static_cast< cppu::OWeakObject
* >( this ) );
1123 else if ( rValue
.Name
== "IsFolder" )
1125 // Read-only property!
1126 aRet
[ n
] <<= lang::IllegalAccessException(
1127 OUString( "Property is read-only!" ),
1128 static_cast< cppu::OWeakObject
* >( this ) );
1130 else if ( rValue
.Name
== "CreatableContentsInfo" )
1132 // Read-only property!
1133 aRet
[ n
] <<= lang::IllegalAccessException(
1134 OUString( "Property is read-only!" ),
1135 static_cast< cppu::OWeakObject
* >( this ) );
1137 else if ( rValue
.Name
== "Title" )
1141 aRet
[ n
] <<= lang::IllegalAccessException(
1142 OUString( "Property is read-only!" ),
1143 static_cast< cppu::OWeakObject
* >( this ) );
1148 if ( rValue
.Value
>>= aNewValue
)
1151 if ( !aNewValue
.isEmpty() )
1153 if ( aNewValue
!= m_aProps
.getTitle() )
1155 // modified title -> modified URL -> exchange !
1156 if ( m_eState
== PERSISTENT
)
1159 aOldTitle
= m_aProps
.getTitle();
1160 aOldName
= m_aProps
.getName();
1162 m_aProps
.setTitle( aNewValue
);
1164 ::ucb_impl::urihelper::encodeSegment(
1167 // property change event will be set later...
1169 // remember position within sequence of values
1170 // (for error handling).
1176 aRet
[ n
] <<= lang::IllegalArgumentException(
1177 OUString( "Empty title not allowed!" ),
1178 static_cast< cppu::OWeakObject
* >( this ),
1184 aRet
[ n
] <<= beans::IllegalTypeException(
1185 OUString( "Property value has wrong type!" ),
1186 static_cast< cppu::OWeakObject
* >( this ) );
1190 else if ( rValue
.Name
== "TargetURL" )
1194 aRet
[ n
] <<= lang::IllegalAccessException(
1195 OUString( "Property is read-only!" ),
1196 static_cast< cppu::OWeakObject
* >( this ) );
1200 // TargetURL is only supported by links.
1202 if ( m_eKind
== LINK
)
1205 if ( rValue
.Value
>>= aNewValue
)
1207 // No empty target URL's!
1208 if ( !aNewValue
.isEmpty() )
1210 if ( aNewValue
!= m_aProps
.getTargetURL() )
1212 aEvent
.PropertyName
= rValue
.Name
;
1214 = uno::makeAny( m_aProps
.getTargetURL() );
1216 = uno::makeAny( aNewValue
);
1218 aChanges
.getArray()[ nChanged
] = aEvent
;
1220 m_aProps
.setTargetURL( aNewValue
);
1226 aRet
[ n
] <<= lang::IllegalArgumentException(
1227 OUString( "Empty target URL not allowed!" ),
1228 static_cast< cppu::OWeakObject
* >( this ),
1234 aRet
[ n
] <<= beans::IllegalTypeException(
1235 OUString( "Property value has wrong type!" ),
1236 static_cast< cppu::OWeakObject
* >( this ) );
1241 aRet
[ n
] <<= beans::UnknownPropertyException(
1242 OUString( "TargetURL only supported by links!" ),
1243 static_cast< cppu::OWeakObject
* >( this ) );
1249 // Not a Core Property! Maybe it's an Additional Core Property?!
1251 if ( !bTriedToGetAdditionalPropSet
&& !xAdditionalPropSet
.is() )
1253 xAdditionalPropSet
= getAdditionalPropertySet( false );
1254 bTriedToGetAdditionalPropSet
= true;
1257 if ( xAdditionalPropSet
.is() )
1261 uno::Any aOldValue
= xAdditionalPropSet
->getPropertyValue(
1263 if ( aOldValue
!= rValue
.Value
)
1265 xAdditionalPropSet
->setPropertyValue(
1266 rValue
.Name
, rValue
.Value
);
1268 aEvent
.PropertyName
= rValue
.Name
;
1269 aEvent
.OldValue
= aOldValue
;
1270 aEvent
.NewValue
= rValue
.Value
;
1272 aChanges
.getArray()[ nChanged
] = aEvent
;
1276 catch ( beans::UnknownPropertyException
const & e
)
1280 catch ( lang::WrappedTargetException
const & e
)
1284 catch ( beans::PropertyVetoException
const & e
)
1288 catch ( lang::IllegalArgumentException
const & e
)
1295 aRet
[ n
] <<= uno::Exception(
1296 OUString( "No property set for storing the value!" ),
1297 static_cast< cppu::OWeakObject
* >( this ) );
1304 uno::Reference
< ucb::XContentIdentifier
> xOldId
1306 uno::Reference
< ucb::XContentIdentifier
> xNewId
1307 = makeNewIdentifier( m_aProps
.getTitle() );
1310 if ( exchangeIdentity( xNewId
) )
1312 // Adapt persistent data.
1313 renameData( xOldId
, xNewId
);
1315 // Adapt Additional Core Properties.
1316 renameAdditionalPropertySet( xOldId
->getContentIdentifier(),
1317 xNewId
->getContentIdentifier(),
1323 m_aProps
.setTitle( aOldTitle
);
1324 m_aProps
.setName ( aOldName
);
1330 aRet
[ nTitlePos
] <<= uno::Exception(
1331 OUString("Exchange failed!"),
1332 static_cast< cppu::OWeakObject
* >( this ) );
1336 if ( !aOldTitle
.isEmpty() )
1338 aEvent
.PropertyName
= "Title";
1339 aEvent
.OldValue
= uno::makeAny( aOldTitle
);
1340 aEvent
.NewValue
= uno::makeAny( m_aProps
.getTitle() );
1342 aChanges
.getArray()[ nChanged
] = aEvent
;
1348 // Save changes, if content was already made persistent.
1349 if ( !bExchange
&& ( m_eState
== PERSISTENT
) )
1355 beans::PropertyValue(
1358 uno::makeAny(m_xIdentifier
->
1359 getContentIdentifier()),
1360 beans::PropertyState_DIRECT_VALUE
));
1361 ucbhelper::cancelCommandExecution(
1362 ucb::IOErrorCode_CANT_WRITE
,
1363 uno::Sequence
< uno::Any
>(&aProps
, 1),
1365 OUString( "Cannot store persistent data!" ),
1371 aChanges
.realloc( nChanged
);
1374 notifyPropertiesChange( aChanges
);
1381 void HierarchyContent::insert( sal_Int32 nNameClashResolve
,
1382 const uno::Reference
<
1383 ucb::XCommandEnvironment
> & xEnv
)
1384 throw( uno::Exception
)
1386 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1388 // Am I the root folder?
1389 if ( m_eKind
== ROOT
)
1391 ucbhelper::cancelCommandExecution(
1392 uno::makeAny( ucb::UnsupportedCommandException(
1393 OUString( "Not supported by root folder!" ),
1394 static_cast< cppu::OWeakObject
* >( this ) ) ),
1399 // Check, if all required properties were set.
1400 if ( m_aProps
.getTitle().isEmpty() )
1402 uno::Sequence
< OUString
> aProps( 1 );
1403 aProps
[ 0 ] = "Title";
1404 ucbhelper::cancelCommandExecution(
1405 uno::makeAny( ucb::MissingPropertiesException(
1407 static_cast< cppu::OWeakObject
* >( this ),
1413 // Assemble new content identifier...
1415 uno::Reference
< ucb::XContentIdentifier
> xId
1416 = makeNewIdentifier( m_aProps
.getTitle() );
1418 // Handle possible name clash...
1420 switch ( nNameClashResolve
)
1423 case ucb::NameClash::ERROR
:
1424 if ( hasData( xId
) )
1426 ucbhelper::cancelCommandExecution(
1428 ucb::NameClashException(
1430 static_cast< cppu::OWeakObject
* >( this ),
1431 task::InteractionClassification_ERROR
,
1432 m_aProps
.getTitle() ) ),
1438 // replace existing object.
1439 case ucb::NameClash::OVERWRITE
:
1442 // "invent" a new valid title.
1443 case ucb::NameClash::RENAME
:
1444 if ( hasData( xId
) )
1450 OUString aNewId
= xId
->getContentIdentifier();
1452 aNewId
+= OUString::number( ++nTry
);
1453 xId
= new ::ucbhelper::ContentIdentifier( aNewId
);
1455 while ( hasData( xId
) && ( nTry
< 1000 ) );
1459 ucbhelper::cancelCommandExecution(
1461 ucb::UnsupportedNameClashException(
1462 OUString( "Unable to resolve name clash!" ),
1463 static_cast< cppu::OWeakObject
* >( this ),
1464 nNameClashResolve
) ),
1470 OUString
aNewTitle( m_aProps
.getTitle() );
1472 aNewTitle
+= OUString::number( nTry
);
1473 m_aProps
.setTitle( aNewTitle
);
1478 case ucb::NameClash::KEEP
: // deprecated
1479 case ucb::NameClash::ASK
:
1481 if ( hasData( xId
) )
1483 ucbhelper::cancelCommandExecution(
1485 ucb::UnsupportedNameClashException(
1487 static_cast< cppu::OWeakObject
* >( this ),
1488 nNameClashResolve
) ),
1495 // Identifier changed?
1496 bool bNewId
= ( xId
->getContentIdentifier()
1497 != m_xIdentifier
->getContentIdentifier() );
1498 m_xIdentifier
= xId
;
1503 = uno::makeAny(beans::PropertyValue(
1506 uno::makeAny(m_xIdentifier
->
1507 getContentIdentifier()),
1508 beans::PropertyState_DIRECT_VALUE
));
1509 ucbhelper::cancelCommandExecution(
1510 ucb::IOErrorCode_CANT_WRITE
,
1511 uno::Sequence
< uno::Any
>(&aProps
, 1),
1513 OUString("Cannot store persistent data!"),
1518 m_eState
= PERSISTENT
;
1528 void HierarchyContent::destroy( bool bDeletePhysical
,
1529 const uno::Reference
<
1530 ucb::XCommandEnvironment
> & xEnv
)
1531 throw( uno::Exception
)
1533 // @@@ take care about bDeletePhysical -> trashcan support
1535 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1537 uno::Reference
< ucb::XContent
> xThis
= this;
1540 if ( m_eState
!= PERSISTENT
)
1542 ucbhelper::cancelCommandExecution(
1543 uno::makeAny( ucb::UnsupportedCommandException(
1544 OUString( "Not persistent!" ),
1545 static_cast< cppu::OWeakObject
* >( this ) ) ),
1550 // Am I the root folder?
1551 if ( m_eKind
== ROOT
)
1553 ucbhelper::cancelCommandExecution(
1554 uno::makeAny( ucb::UnsupportedCommandException(
1555 OUString( "Not supported by root folder!" ),
1556 static_cast< cppu::OWeakObject
* >( this ) ) ),
1566 if ( m_eKind
== FOLDER
)
1568 // Process instantiated children...
1570 HierarchyContentRefList aChildren
;
1571 queryChildren( aChildren
);
1573 HierarchyContentRefList::const_iterator it
= aChildren
.begin();
1574 HierarchyContentRefList::const_iterator end
= aChildren
.end();
1578 (*it
)->destroy( bDeletePhysical
, xEnv
);
1585 void HierarchyContent::transfer(
1586 const ucb::TransferInfo
& rInfo
,
1587 const uno::Reference
< ucb::XCommandEnvironment
> & xEnv
)
1588 throw( uno::Exception
)
1590 osl::ClearableGuard
< osl::Mutex
> aGuard( m_aMutex
);
1593 if ( m_eState
!= PERSISTENT
)
1595 ucbhelper::cancelCommandExecution(
1596 uno::makeAny( ucb::UnsupportedCommandException(
1597 OUString( "Not persistent!" ),
1598 static_cast< cppu::OWeakObject
* >( this ) ) ),
1603 // Is source a hierarchy content?
1604 if ( !rInfo
.SourceURL
.startsWith( HIERARCHY_URL_SCHEME
":/" ) )
1606 ucbhelper::cancelCommandExecution(
1607 uno::makeAny( ucb::InteractiveBadTransferURLException(
1609 static_cast< cppu::OWeakObject
* >( this ) ) ),
1614 // Is source not a parent of me / not me?
1615 OUString aId
= m_xIdentifier
->getContentIdentifier();
1616 sal_Int32 nPos
= aId
.lastIndexOf( '/' );
1617 if ( nPos
!= ( aId
.getLength() - 1 ) )
1619 // No trailing slash found. Append.
1623 if ( rInfo
.SourceURL
.getLength() <= aId
.getLength() )
1625 if ( aId
.startsWith( rInfo
.SourceURL
) )
1628 = uno::makeAny(beans::PropertyValue(
1631 uno::makeAny(rInfo
.SourceURL
),
1632 beans::PropertyState_DIRECT_VALUE
));
1633 ucbhelper::cancelCommandExecution(
1634 ucb::IOErrorCode_RECURSIVE
,
1635 uno::Sequence
< uno::Any
>(&aProps
, 1),
1637 OUString( "Target is equal to or is a child of source!" ),
1644 // 0) Obtain content object for source.
1647 uno::Reference
< ucb::XContentIdentifier
> xId
1648 = new ::ucbhelper::ContentIdentifier( rInfo
.SourceURL
);
1650 // Note: The static cast is okay here, because its sure that
1651 // m_xProvider is always the HierarchyContentProvider.
1652 rtl::Reference
< HierarchyContent
> xSource
;
1656 xSource
= static_cast< HierarchyContent
* >(
1657 m_xProvider
->queryContent( xId
).get() );
1659 catch ( ucb::IllegalIdentifierException
const & )
1664 if ( !xSource
.is() )
1667 = uno::makeAny(beans::PropertyValue(
1670 uno::makeAny(xId
->getContentIdentifier()),
1671 beans::PropertyState_DIRECT_VALUE
));
1672 ucbhelper::cancelCommandExecution(
1673 ucb::IOErrorCode_CANT_READ
,
1674 uno::Sequence
< uno::Any
>(&aProps
, 1),
1676 OUString( "Cannot instanciate source object!" ),
1682 // 1) Create new child content.
1685 OUString aType
= xSource
->isFolder()
1686 ? OUString( HIERARCHY_FOLDER_CONTENT_TYPE
)
1687 : OUString( HIERARCHY_LINK_CONTENT_TYPE
);
1688 ucb::ContentInfo aContentInfo
;
1689 aContentInfo
.Type
= aType
;
1690 aContentInfo
.Attributes
= 0;
1692 // Note: The static cast is okay here, because its sure that
1693 // createNewContent always creates a HierarchyContent.
1694 rtl::Reference
< HierarchyContent
> xTarget
1695 = static_cast< HierarchyContent
* >(
1696 createNewContent( aContentInfo
).get() );
1697 if ( !xTarget
.is() )
1700 = uno::makeAny(beans::PropertyValue(
1701 OUString( "Folder"),
1704 beans::PropertyState_DIRECT_VALUE
));
1705 ucbhelper::cancelCommandExecution(
1706 ucb::IOErrorCode_CANT_CREATE
,
1707 uno::Sequence
< uno::Any
>(&aProps
, 1),
1709 OUString( "XContentCreator::createNewContent failed!" ),
1715 // 2) Copy data from source content to child content.
1718 uno::Sequence
< beans::Property
> aSourceProps
1719 = xSource
->getPropertySetInfo( xEnv
)->getProperties();
1720 sal_Int32 nCount
= aSourceProps
.getLength();
1724 bool bHadTitle
= rInfo
.NewTitle
.isEmpty();
1726 // Get all source values.
1727 uno::Reference
< sdbc::XRow
> xRow
1728 = xSource
->getPropertyValues( aSourceProps
);
1730 uno::Sequence
< beans::PropertyValue
> aValues( nCount
);
1731 beans::PropertyValue
* pValues
= aValues
.getArray();
1733 const beans::Property
* pProps
= aSourceProps
.getConstArray();
1734 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
1736 const beans::Property
& rProp
= pProps
[ n
];
1737 beans::PropertyValue
& rValue
= pValues
[ n
];
1739 rValue
.Name
= rProp
.Name
;
1740 rValue
.Handle
= rProp
.Handle
;
1742 if ( !bHadTitle
&& rProp
.Name
== "Title" )
1744 // Set new title instead of original.
1746 rValue
.Value
<<= rInfo
.NewTitle
;
1749 rValue
.Value
= xRow
->getObject(
1751 uno::Reference
< container::XNameAccess
>() );
1753 rValue
.State
= beans::PropertyState_DIRECT_VALUE
;
1755 if ( rProp
.Attributes
& beans::PropertyAttribute::REMOVABLE
)
1757 // Add Additional Core Property.
1760 xTarget
->addProperty( rProp
.Name
,
1764 catch ( beans::PropertyExistException
const & )
1767 catch ( beans::IllegalTypeException
const & )
1770 catch ( lang::IllegalArgumentException
const & )
1776 // Set target values.
1777 xTarget
->setPropertyValues( aValues
, xEnv
);
1781 // 3) Commit (insert) child.
1784 xTarget
->insert( rInfo
.NameClash
, xEnv
);
1787 // 4) Transfer (copy) children of source.
1790 if ( xSource
->isFolder() )
1792 HierarchyEntry
aFolder(
1793 m_xContext
, m_pProvider
, xId
->getContentIdentifier() );
1794 HierarchyEntry::iterator it
;
1796 while ( aFolder
.next( it
) )
1798 const HierarchyEntryData
& rResult
= *it
;
1800 OUString aChildId
= xId
->getContentIdentifier();
1801 if ( ( aChildId
.lastIndexOf( '/' ) + 1 ) != aChildId
.getLength() )
1804 aChildId
+= rResult
.getName();
1806 ucb::TransferInfo aInfo
;
1807 aInfo
.MoveData
= sal_False
;
1808 aInfo
.NewTitle
.clear();
1809 aInfo
.SourceURL
= aChildId
;
1810 aInfo
.NameClash
= rInfo
.NameClash
;
1812 // Transfer child to target.
1813 xTarget
->transfer( aInfo
, xEnv
);
1818 // 5) Destroy source ( when moving only ) .
1821 if ( rInfo
.MoveData
)
1823 xSource
->destroy( true, xEnv
);
1825 // Remove all persistent data of source and its children.
1826 if ( !xSource
->removeData() )
1830 beans::PropertyValue(
1834 xSource
->m_xIdentifier
->
1835 getContentIdentifier()),
1836 beans::PropertyState_DIRECT_VALUE
));
1837 ucbhelper::cancelCommandExecution(
1838 ucb::IOErrorCode_CANT_WRITE
,
1839 uno::Sequence
< uno::Any
>(&aProps
, 1),
1841 OUString( "Cannot remove persistent data of source object!" ),
1846 // Remove own and all children's Additional Core Properties.
1847 xSource
->removeAdditionalPropertySet( true );
1854 // HierarchyContentProperties Implementation.
1859 uno::Sequence
< ucb::ContentInfo
>
1860 HierarchyContentProperties::getCreatableContentsInfo() const
1862 if ( getIsFolder() )
1864 uno::Sequence
< ucb::ContentInfo
> aSeq( 2 );
1867 aSeq
.getArray()[ 0 ].Type
= HIERARCHY_FOLDER_CONTENT_TYPE
;
1868 aSeq
.getArray()[ 0 ].Attributes
= ucb::ContentInfoAttribute::KIND_FOLDER
;
1870 uno::Sequence
< beans::Property
> aFolderProps( 1 );
1871 aFolderProps
.getArray()[ 0 ] = beans::Property(
1874 cppu::UnoType
<OUString
>::get(),
1875 beans::PropertyAttribute::BOUND
);
1876 aSeq
.getArray()[ 0 ].Properties
= aFolderProps
;
1879 aSeq
.getArray()[ 1 ].Type
= HIERARCHY_LINK_CONTENT_TYPE
;
1880 aSeq
.getArray()[ 1 ].Attributes
= ucb::ContentInfoAttribute::KIND_LINK
;
1882 uno::Sequence
< beans::Property
> aLinkProps( 2 );
1883 aLinkProps
.getArray()[ 0 ] = beans::Property(
1886 cppu::UnoType
<OUString
>::get(),
1887 beans::PropertyAttribute::BOUND
);
1888 aLinkProps
.getArray()[ 1 ] = beans::Property(
1889 OUString("TargetURL"),
1891 cppu::UnoType
<OUString
>::get(),
1892 beans::PropertyAttribute::BOUND
);
1893 aSeq
.getArray()[ 1 ].Properties
= aLinkProps
;
1899 return uno::Sequence
< ucb::ContentInfo
>( 0 );
1903 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */